-const char* SortIcons[3] = {
- "static/up_pointer.gif",
- "static/down_pointer.gif",
- "static/sort_none.gif"
-};
-
-enum {/// SortByEnum
- eDate,
- eRDate,
- eSubject,
- eRSubject,
- eSender,
- eRSender,
- eReverse,
- eUnSet
-};
-
-/* SortEnum to plain string representation */
-static const char* SortByStrings[] = {
- "date",
- "rdate",
- "subject",
- "rsubject",
- "sender",
- "rsender",
- "reverse",
- "unset"
-};
-
-/* SortEnum to sort-Function Table */
-const CompareFunc SortFuncs[eUnSet] = {
- summcmp_date,
- summcmp_rdate,
- summcmp_subj,
- summcmp_rsubj,
- summcmp_sender,
- summcmp_rsender,
- summcmp_rdate
-};
-
-/* given a SortEnum, which icon should we choose? */
-const int SortDateToIcon[eUnSet] = { eUp, eDown, eNone, eNone, eNone, eNone, eNone};
-const int SortSubjectToIcon[eUnSet] = { eNone, eNone, eUp, eDown, eNone, eNone, eNone};
-const int SortSenderToIcon[eUnSet] = { eNone, eNone, eNone, eNone, eUp, eDown, eNone};
-
-/* given a SortEnum, which would be the "opposite" search option? */
-const int DateInvertSortString[eUnSet] = { eRDate, eDate, eDate, eDate, eDate, eDate, eDate};
-const int SubjectInvertSortString[eUnSet] = { eSubject, eSubject, eRSubject, eUnSet, eSubject, eSubject, eSubject};
-const int SenderInvertSortString[eUnSet] = { eSender, eSender, eSender, eSender, eRSender, eUnSet, eSender};
-
-
-
/*----------------------------------------------------------------------------*/
-/*
- * Translates sortoption String to its SortEnum representation
- * returns the enum matching the string; defaults to RDate
- */
-//SortByEnum
-int StrToESort (const StrBuf *sortby)
-{////todoo: hash
- int result = eDate;
-
- if (!IsEmptyStr(ChrPtr(sortby))) while (result < eUnSet){
- if (!strcasecmp(ChrPtr(sortby),
- SortByStrings[result]))
- return result;
- result ++;
- }
- return eRDate;
-}
-
-
-typedef int (*QSortFunction) (const void*, const void*);
-
-/*
- * qsort() compatible function to compare two longs in descending order.
- */
-int longcmp_r(const void *s1, const void *s2) {
- long l1;
- long l2;
-
- l1 = *(long *)GetSearchPayload(s1);
- l2 = *(long *)GetSearchPayload(s2);
-
- if (l1 > l2) return(-1);
- if (l1 < l2) return(+1);
- return(0);
-}
-
-/*
- * qsort() compatible function to compare two longs in descending order.
- */
-int qlongcmp_r(const void *s1, const void *s2) {
- long l1 = (long) s1;
- long l2 = (long) s2;
-
- if (l1 > l2) return(-1);
- if (l1 < l2) return(+1);
- return(0);
-}
-
-
-/*
- * qsort() compatible function to compare two message summary structs by ascending subject.
- */
-int summcmp_subj(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
- return strcasecmp(ChrPtr(summ1->subj), ChrPtr(summ2->subj));
-}
-
-/*
- * qsort() compatible function to compare two message summary structs by descending subject.
- */
-int summcmp_rsubj(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
- return strcasecmp(ChrPtr(summ2->subj), ChrPtr(summ1->subj));
-}
-
-/*
- * qsort() compatible function to compare two message summary structs by ascending sender.
- */
-int summcmp_sender(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
- return strcasecmp(ChrPtr(summ1->from), ChrPtr(summ2->from));
-}
-
-/*
- * qsort() compatible function to compare two message summary structs by descending sender.
- */
-int summcmp_rsender(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
- return strcasecmp(ChrPtr(summ2->from), ChrPtr(summ1->from));
-}
-
-/*
- * qsort() compatible function to compare two message summary structs by ascending date.
- */
-int summcmp_date(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
-
- if (summ1->date < summ2->date) return -1;
- else if (summ1->date > summ2->date) return +1;
- else return 0;
-}
-
-/*
- * qsort() compatible function to compare two message summary structs by descending date.
- */
-int summcmp_rdate(const void *s1, const void *s2) {
- message_summary *summ1;
- message_summary *summ2;
-
- summ1 = (message_summary *)GetSearchPayload(s1);
- summ2 = (message_summary *)GetSearchPayload(s2);
-
- if (summ1->date < summ2->date) return +1;
- else if (summ1->date > summ2->date) return -1;
- else return 0;
-}
-
-
-
-
/*
Done = 1;
if (state < 2) {
lprintf(1, _("unexpected end of message"));
- StrBufAppendPrintf(Target, "<i>");
- StrBufAppendPrintf(Target, _("unexpected end of message"));
- StrBufAppendPrintf(Target, " (1)</i><br /><br />\n");
- StrBufAppendPrintf(Target, "</div>\n");
- FreeStrBuf(&Buf);
- FreeStrBuf(&HdrToken);
- DestroyMessageSummary(Msg);
- FreeStrBuf(&FoundCharset);
- return 0;
- }
- else {
- break;
+
+ Msg->MsgBody->ContentType = NewStrBufPlain(HKEY("text/html"));
+ StrBufAppendPrintf(Msg->MsgBody->Data, "<div><i>");
+ StrBufAppendPrintf(Msg->MsgBody->Data, _("unexpected end of message"));
+ StrBufAppendPrintf(Msg->MsgBody->Data, " (1)</i><br /><br />\n");
+ StrBufAppendPrintf(Msg->MsgBody->Data, "</div>\n");
}
+ break;
}
switch (state) {
case 0:/* Citadel Message Headers */
if (Msg->AllAttach == NULL)
Msg->AllAttach = NewHash(1,NULL);
Put(Msg->AllAttach, SKEY(Msg->MsgBody->PartNum), Msg->MsgBody, DestroyMime);
-
/* strip the bare contenttype, so we ommit charset etc. */
StrBufExtract_token(Buf, Msg->MsgBody->ContentType, 0, ';');
StrBufAppendBuf(Msg->reply_to, Msg->from, 0);
}
}
- it = GetNewHashPos();
+ it = GetNewHashPos(Msg->AllAttach, 0);
while (GetNextHashPos(Msg->AllAttach, it, &len, &Key, &vMime) &&
(vMime != NULL)) {
wc_mime_attachment *Mime = (wc_mime_attachment*) vMime;
////int sbjlen;
int maxload = 0;
long len;
-
+ int n;
////int num_summ_alloc = 0;
if (WCC->summ != NULL) {
}
WCC->summ = NewHash(1, Flathash);
nummsgs = 0;
- maxload = 1000;/// TODO
+ maxload = 10000;
Buf = NewStrBuf();
serv_puts(servcmd);
StrBuf_Utf8StrCut(Msg->from, 23);
StrBufAppendBufPlain(Msg->from, HKEY("..."), 0);
}
- Put(WCC->summ, (const char*)&Msg->msgnum, sizeof(Msg->msgnum), Msg, DestroyMessageSummary);
+ n = Msg->msgnum;
+ Put(WCC->summ, (const char *)&n, sizeof(n), Msg, DestroyMessageSummary);
}
nummsgs++;
}
}
+inline message_summary* GetMessagePtrAt(int n, HashList *Summ)
+{
+ void *vMsg;
+ if (Summ == NULL)
+ return NULL;
+ GetHash(Summ, (const char*)&n, sizeof(n), &vMsg);
+ return (message_summary*) vMsg;
+}
+void DrawMessageSummarySelector(StrBuf *BBViewToolBar, long maxmsgs, long startmsg)
+{
+ struct wcsession *WCC = WC;
+ message_summary* Msg;
+ int lo, hi, n;
+ int i = 0;
+ long StartMsg;
+ void *vMsg;
+ long hklen;
+ const char *key;
+ int done = 0;
+ int nItems;
+ HashPos *At;
+ long vector[16];
+ StrBuf *Selector = NewStrBuf();
+
+ At = GetNewHashPos(WCC->summ, (lbstr("SortOrder") == 1)? -maxmsgs : maxmsgs);
+ nItems = GetCount(WCC->summ);
+
+ vector[0] = 7;
+ vector[1] = startmsg;
+ vector[2] = maxmsgs;
+ vector[3] = 0;
+ vector[4] = 1;
+
+ while (!done) {
+ lo = GetHashPosCounter(At);
+ if (lo + maxmsgs > nItems) {
+ hi = nItems;
+ }
+ else {
+ hi = lo + maxmsgs;
+ }
+ done = !GetNextHashPos(WCC->summ, At, &hklen, &key, &vMsg);
+ Msg = (message_summary*) vMsg;
+ n = (Msg==NULL)? 0 : Msg->msgnum;
+ if (i == 0)
+ StartMsg = n;
+ vector[4] = lo;
+ vector[5] = hi;
+ vector[6] = n;
+ FlushStrBuf(BBViewToolBar); /** abuse our target buffer to contstruct one item in it */
+ DoTemplate(HKEY("select_messageindex"), BBViewToolBar, &vector, CTX_LONGVECTOR);
+ StrBufAppendBuf(Selector, BBViewToolBar, 0);
+ i++;
+ }
+ vector[6] = StartMsg;
+ FlushStrBuf(BBViewToolBar);
+ DoTemplate(HKEY("select_messageindex_all"), BBViewToolBar, &vector, CTX_LONGVECTOR);
+ StrBufAppendBuf(Selector, BBViewToolBar, 0);
+
+ FlushStrBuf(BBViewToolBar);
+ DoTemplate(HKEY("msg_listselector"), BBViewToolBar, Selector, CTX_STRBUF);
+ FreeStrBuf(&Selector);
+}
/*
*/
void readloop(char *oper)
{
+ StrBuf *BBViewToolBar = NULL;
void *vMsg;
message_summary *Msg;
char cmd[256] = "";
char buf[SIZ];
char old_msgs[SIZ];
int a = 0;
- int b = 0;
+ ///int b = 0;
int nummsgs;
- long startmsg;
+ long startmsg = 0;
int maxmsgs;
long *displayed_msgs = NULL;
int num_displayed = 0;
int is_tasks = 0;
int is_notes = 0;
int is_bbview = 0;
- int lo, hi;
int lowest_displayed = (-1);
int highest_displayed = 0;
addrbookent *addrbook = NULL;
int num_ab = 0;
- const StrBuf *sortby = NULL;
- //SortByEnum
- int SortBy = eRDate;
- const StrBuf *sortpref_value;
int bbs_reverse = 0;
- struct wcsession *WCC = WC; /* This is done to make it run faster; WC is a function */
+ struct wcsession *WCC = WC;
HashPos *at;
const char *HashKey;
long HKLen;
+ int care_for_empty_list = 0;
+ int load_seen = 0;
+ int sortit = 0;
- if (WCC->wc_view == VIEW_WIKI) {
+ switch (WCC->wc_view) {
+ case VIEW_WIKI:
sprintf(buf, "wiki?room=%s&page=home", WCC->wc_roomname);
http_redirect(buf);
return;
- }
-
- startmsg = lbstr("startmsg");
- maxmsgs = ibstr("maxmsgs");
- is_summary = (ibstr("is_summary") && !WCC->is_mobile);
- if (maxmsgs == 0) maxmsgs = DEFAULT_MAXMSGS;
-
- sortpref_value = get_room_pref("sort");
-
- sortby = sbstr("sortby");
- if ( (!IsEmptyStr(ChrPtr(sortby))) &&
- (strcasecmp(ChrPtr(sortby), ChrPtr(sortpref_value)) != 0)) {
- set_room_pref("sort", NewStrBufDup(sortby), 1);
- sortpref_value = NULL;
- sortpref_value = sortby;
- }
-
- SortBy = StrToESort(sortpref_value);
- /* message board sort */
- if (SortBy == eReverse) {
- bbs_reverse = 1;
- }
- else {
- bbs_reverse = 0;
- }
-
- output_headers(1, 1, 1, 0, 0, 0);
-
- /*
- * When in summary mode, always show ALL messages instead of just
- * new or old. Otherwise, show what the user asked for.
- */
- if (!strcmp(oper, "readnew")) {
- strcpy(cmd, "MSGS NEW");
- }
- else if (!strcmp(oper, "readold")) {
- strcpy(cmd, "MSGS OLD");
- }
- else if (!strcmp(oper, "do_search")) {
- snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query"));
- }
- else {
+ case VIEW_CALENDAR:
+ load_seen = 1;
+ is_calendar = 1;
+ strcpy(cmd, "MSGS ALL|||1");
+ maxmsgs = 32767;
+ parse_calendar_view_request(&calv);
+ break;
+ case VIEW_TASKS:
+ is_tasks = 1;
strcpy(cmd, "MSGS ALL");
- }
+ maxmsgs = 32767;
+ break;
+ case VIEW_NOTES:
+ is_notes = 1;
+ strcpy(cmd, "MSGS ALL");
+ maxmsgs = 32767;
+ wprintf("<div id=\"new_notes_here\"></div>\n");
+ break;
+ case VIEW_ADDRESSBOOK:
+ is_singlecard = ibstr("is_singlecard");
+ if (maxmsgs > 1) {
+ is_addressbook = 1;
+ if (!strcmp(oper, "do_search")) {
+ snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query"));
+ }
+ else {
+ strcpy(cmd, "MSGS ALL");
+ }
+ maxmsgs = 9999999;
+ break;
+ }
- if ((WCC->wc_view == VIEW_MAILBOX) && (maxmsgs > 1) && !WCC->is_mobile) {
- is_summary = 1;
- if (!strcmp(oper, "do_search")) {
- snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query"));
+ default:
+ care_for_empty_list = 1;
+ startmsg = lbstr("startmsg");
+ if (havebstr("maxmsgs"))
+ maxmsgs = ibstr("maxmsgs");
+ is_summary = (ibstr("is_summary") && !WCC->is_mobile);
+ if (maxmsgs == 0) maxmsgs = DEFAULT_MAXMSGS;
+
+
+
+ /*
+ * When in summary mode, always show ALL messages instead of just
+ * new or old. Otherwise, show what the user asked for.
+ */
+ if (!strcmp(oper, "readnew")) {
+ strcpy(cmd, "MSGS NEW");
}
- else {
- strcpy(cmd, "MSGS ALL");
+ else if (!strcmp(oper, "readold")) {
+ strcpy(cmd, "MSGS OLD");
}
- }
-
- if ((WCC->wc_view == VIEW_ADDRESSBOOK) && (maxmsgs > 1)) {
- is_addressbook = 1;
- if (!strcmp(oper, "do_search")) {
+ else if (!strcmp(oper, "do_search")) {
snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query"));
}
else {
strcpy(cmd, "MSGS ALL");
}
- maxmsgs = 9999999;
+
+ if ((WCC->wc_view == VIEW_MAILBOX) && (maxmsgs > 1) && !WCC->is_mobile) {
+ is_summary = 1;
+ if (!strcmp(oper, "do_search")) {
+ snprintf(cmd, sizeof(cmd), "MSGS SEARCH|%s", bstr("query"));
+ }
+ else {
+ strcpy(cmd, "MSGS ALL");
+ }
+ }
+
+ is_bbview = !is_summary;
+ if (is_summary) { /**< fetch header summary */
+ load_seen = 1;
+ snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1",
+ (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"),
+ (!strcmp(oper, "do_search") ? bstr("query") : "")
+ );
+ startmsg = 1;
+ maxmsgs = 9999999;
+ }
+ if (startmsg == 0L) {
+ if (bbs_reverse) {
+ Msg = GetMessagePtrAt((nummsgs >= maxmsgs) ? (nummsgs - maxmsgs) : 0, WCC->summ);
+ startmsg = (Msg==NULL)? 0 : Msg->msgnum;
+ }
+ else {
+ Msg = GetMessagePtrAt(0, WCC->summ);
+ startmsg = (Msg==NULL)? 0 : Msg->msgnum;
+ }
+ }
+ sortit = is_summary || WCC->is_mobile;
}
- if (is_summary) { /**< fetch header summary */
- snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1",
- (!strcmp(oper, "do_search") ? "SEARCH" : "ALL"),
- (!strcmp(oper, "do_search") ? bstr("query") : "")
- );
- startmsg = 1;
- maxmsgs = 9999999;
- }
+
+ output_headers(1, 1, 1, 0, 0, 0);
+
+ /*
if (WCC->is_mobile) {
maxmsgs = 20;
snprintf(cmd, sizeof(cmd), "MSGS %s|%s||1",
* and new messages, so we can do that pretty boldface thing for the
* new messages.
*/
- strcpy(old_msgs, "");
- if ((is_summary) || (WCC->wc_default_view == VIEW_CALENDAR) || WCC->is_mobile){
- serv_puts("GTSN");
- serv_getln(buf, sizeof buf);
- if (buf[0] == '2') {
- strcpy(old_msgs, &buf[4]);
- }
- }
-
- is_singlecard = ibstr("is_singlecard");
-
- if (WCC->wc_default_view == VIEW_CALENDAR) { /**< calendar */
- is_calendar = 1;
- strcpy(cmd, "MSGS ALL|||1");
- maxmsgs = 32767;
- parse_calendar_view_request(&calv);
- }
- if (WCC->wc_default_view == VIEW_TASKS) { /**< tasks */
- is_tasks = 1;
- strcpy(cmd, "MSGS ALL");
- maxmsgs = 32767;
- }
- if (WCC->wc_default_view == VIEW_NOTES) { /**< notes */
- is_notes = 1;
- strcpy(cmd, "MSGS ALL");
- maxmsgs = 32767;
- }
- if (is_notes) {
- wprintf("<div id=\"new_notes_here\"></div>\n");
- }
nummsgs = load_msg_ptrs(cmd, (is_summary || WCC->is_mobile));
if (nummsgs == 0) {
-
- if ((!is_tasks) && (!is_calendar) && (!is_notes) && (!is_addressbook)) {
+ if (care_for_empty_list) {
wprintf("<div align=\"center\"><br /><em>");
if (!strcmp(oper, "readnew")) {
wprintf(_("No new messages."));
goto DONE;
}
- if ((is_summary) || (WCC->wc_default_view == VIEW_CALENDAR) || WCC->is_mobile){
+ if (load_seen){
void *vMsg;
- message_summary *Msg;
- at = GetNewHashPos();
+ strcpy(old_msgs, "");
+ serv_puts("GTSN");
+ serv_getln(buf, sizeof buf);
+ if (buf[0] == '2') {
+ strcpy(old_msgs, &buf[4]);
+ }
+ at = GetNewHashPos(WCC->summ, 0);
while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
/** Are you a new message, or an old message? */
Msg = (message_summary*) vMsg;
- if (is_summary) {
- if (is_msg_in_mset(old_msgs, Msg->msgnum)) {
- Msg->is_new = 0;
- }
- else {
- Msg->is_new = 1;
- }
+ if (is_msg_in_mset(old_msgs, Msg->msgnum)) {
+ Msg->is_new = 0;
+ }
+ else {
+ Msg->is_new = 1;
}
}
DeleteHashPos(&at);
}
- if (startmsg == 0L) {
- if (bbs_reverse) {
- startmsg = WCC->msgarr[(nummsgs >= maxmsgs) ? (nummsgs - maxmsgs) : 0];
- }
- else {
- startmsg = WCC->msgarr[0];
- }
- }
-
- if (is_summary || WCC->is_mobile) {
- SortByPayload(WCC->summ, SortFuncs[SortBy]);
+ if (sortit) {
+ CompareFunc SortIt;
+ SortIt = RetrieveSort(CTX_MAILSUM, NULL,
+ HKEY("date"), 2);
+ if (SortIt != NULL)
+ SortByPayload(WCC->summ, SortIt);
}
if (is_summary) {
-
- wprintf("<script language=\"javascript\" type=\"text/javascript\">"
- " document.onkeydown = CtdlMsgListKeyPress; "
- " if (document.layers) { "
- " document.captureEvents(Event.KEYPRESS); "
- " } "
- "</script>\n"
- );
-
- /** note that Date and Delete are now in the same column */
- wprintf("<div id=\"message_list_hdr\">"
- "<div class=\"fix_scrollbar_bug\">"
- "<table cellspacing=0 style=\"width:100%%\">"
- "<tr>"
- );
- wprintf("<th width=%d%%>%s <a href=\"readfwd?startmsg=1?maxmsgs=9999999?is_summary=1?sortby=%s\"><img border=\"0\" src=\"%s\" /></a> </th>\n"
- "<th width=%d%%>%s <a href=\"readfwd?startmsg=1?maxmsgs=9999999?is_summary=1?sortby=%s\"><img border=\"0\" src=\"%s\" /></a> </th>\n"
- "<th width=%d%%>%s <a href=\"readfwd?startmsg=1?maxmsgs=9999999?is_summary=1?sortby=%s\"><img border=\"0\" src=\"%s\" /></a> \n"
- " "
- "<input type=\"submit\" name=\"delete_button\" id=\"delbutton\" "
- " onClick=\"CtdlDeleteSelectedMessages(event)\" "
- " value=\"%s\">"
- "</th>"
- "</tr>\n"
- ,
- SUBJ_COL_WIDTH_PCT,
- _("Subject"),
- SortByStrings[SubjectInvertSortString[SortBy]],
- SortIcons[SortSubjectToIcon[SortBy]],
- SENDER_COL_WIDTH_PCT,
- _("Sender"),
- SortByStrings[SenderInvertSortString[SortBy]],
- SortIcons[SortSenderToIcon[SortBy]],
- DATE_PLUS_BUTTONS_WIDTH_PCT,
- _("Date"),
- SortByStrings[DateInvertSortString[SortBy]],
- SortIcons[SortDateToIcon[SortBy]],
- _("Delete")
- );
- wprintf("</table></div></div>\n");
- wprintf("<div id=\"message_list\">"
-
- "<div class=\"fix_scrollbar_bug\">\n"
- "<table class=\"mailbox_summary\" id=\"summary_headers\" "
- "cellspacing=0 style=\"width:100%%;-moz-user-select:none;\">"
- );
+ do_template("summary_header", NULL);
} else if (WCC->is_mobile) {
wprintf("<div id=\"message_list\">");
}
- /**
- * Set the "is_bbview" variable if it appears that we are looking at
- * a classic bulletin board view.
- */
- if ((!is_tasks) && (!is_calendar) && (!is_addressbook)
- && (!is_notes) && (!is_singlecard) && (!is_summary)) {
- is_bbview = 1;
- }
-
/**
* If we're not currently looking at ALL requested
* messages, then display the selector bar
*/
- if (is_bbview) {
- /** begin bbview scroller */
- wprintf("<form name=\"msgomatictop\" class=\"selector_top\" > \n <p>");
- wprintf(_("Reading #"));//// TODO this isn't used, should it? : , lowest_displayed, highest_displayed);
-
- wprintf("<select name=\"whichones\" size=\"1\" "
- "OnChange=\"location.href=msgomatictop.whichones.options"
- "[selectedIndex].value\">\n");
-
- if (bbs_reverse) {
- for (b=nummsgs-1; b>=0; b = b - maxmsgs) {
- hi = b + 1;
- lo = b - maxmsgs + 2;
- if (lo < 1) lo = 1;
- wprintf("<option %s value="
- "\"%s"
- "&startmsg=%ld"
- "&maxmsgs=%d"
- "&is_summary=%d\">"
- "%d-%d</option> \n",
- ((WCC->msgarr[lo-1] == startmsg) ? "selected" : ""),
- oper,
- WCC->msgarr[lo-1],
- maxmsgs,
- is_summary,
- hi, lo);
- }
- }
- else {
- for (b=0; b<nummsgs; b = b + maxmsgs) {
- lo = b + 1;
- hi = b + maxmsgs + 1;
- if (hi > nummsgs) hi = nummsgs;
- wprintf("<option %s value="
- "\"%s"
- "&startmsg=%ld"
- "&maxmsgs=%d"
- "&is_summary=%d\">"
- "%d-%d</option> \n",
- ((WCC->msgarr[b] == startmsg) ? "selected" : ""),
- oper,
- WCC->msgarr[lo-1],
- maxmsgs,
- is_summary,
- lo, hi);
- }
- }
+ if (is_bbview) {
+ BBViewToolBar = NewStrBuf();
+ maxmsgs = 20; //// todo?
- wprintf("<option value=\"%s?startmsg=%ld"
- "&maxmsgs=9999999&is_summary=%d\">",
- oper,
- WCC->msgarr[0], is_summary);
- wprintf(_("All"));
- wprintf("</option>");
- wprintf("</select> ");
- wprintf(_("of %d messages."), nummsgs);
-
- /** forward/reverse */
- wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
- "OnChange=\"location.href='%s?sortby=forward'\"",
- (bbs_reverse ? "" : "checked"),
- oper
- );
- wprintf(">");
- wprintf(_("oldest to newest"));
- wprintf(" ");
-
- wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
- "OnChange=\"location.href='%s?sortby=reverse'\"",
- (bbs_reverse ? "checked" : ""),
- oper
- );
- wprintf(">");
- wprintf(_("newest to oldest"));
- wprintf("\n");
-
- wprintf("</p></form>\n");
- /** end bbview scroller */
+ DrawMessageSummarySelector(BBViewToolBar, maxmsgs, startmsg);
+ StrBufAppendBuf(WCC->WBuf, BBViewToolBar, 0);
}
- at = GetNewHashPos();
+ at = GetNewHashPos(WCC->summ, 0);
while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
Msg = (message_summary*) vMsg;
if ((Msg->msgnum >= startmsg) && (num_displayed < maxmsgs)) {
/** Output loop */
if (displayed_msgs != NULL) {
if (bbs_reverse) {
- qsort(displayed_msgs, num_displayed, sizeof(long), qlongcmp_r);
+ ////TODOqsort(displayed_msgs, num_displayed, sizeof(long), qlongcmp_r);
}
/** if we do a split bbview in the future, begin messages div here */
*/
if (is_bbview) {
/** begin bbview scroller */
- wprintf("<form name=\"msgomatic\" class=\"selector_bottom\" > \n <p>");
- wprintf(_("Reading #")); /// TODO: this isn't used: , lowest_displayed, highest_displayed);
-
- wprintf("<select name=\"whichones\" size=\"1\" "
- "OnChange=\"location.href=msgomatic.whichones.options"
- "[selectedIndex].value\">\n");
-
- if (bbs_reverse) {
- for (b=nummsgs-1; b>=0; b = b - maxmsgs) {
- hi = b + 1;
- lo = b - maxmsgs + 2;
- if (lo < 1) lo = 1;
- wprintf("<option %s value="
- "\"%s"
- "&startmsg=%ld"
- "&maxmsgs=%d"
- "&is_summary=%d\">"
- "%d-%d</option> \n",
- ((WCC->msgarr[lo-1] == startmsg) ? "selected" : ""),
- oper,
- WCC->msgarr[lo-1],
- maxmsgs,
- is_summary,
- hi, lo);
- }
- }
- else {
- for (b=0; b<nummsgs; b = b + maxmsgs) {
- lo = b + 1;
- hi = b + maxmsgs + 1;
- if (hi > nummsgs) hi = nummsgs;
- wprintf("<option %s value="
- "\"%s"
- "&startmsg=%ld"
- "&maxmsgs=%d"
- "&is_summary=%d\">"
- "%d-%d</option> \n",
- ((WCC->msgarr[b] == startmsg) ? "selected" : ""),
- oper,
- WCC->msgarr[lo-1],
- maxmsgs,
- is_summary,
- lo, hi);
- }
- }
-
- wprintf("<option value=\"%s&startmsg=%ld"
- "&maxmsgs=9999999&is_summary=%d\">",
- oper,
- WCC->msgarr[0], is_summary);
- wprintf(_("All"));
- wprintf("</option>");
- wprintf("</select> ");
- wprintf(_("of %d messages."), nummsgs);
-
- /** forward/reverse */
- wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
- "OnChange=\"location.href='%s&sortby=forward'\"",
- (bbs_reverse ? "" : "checked"),
- oper
- );
- wprintf(">");
- wprintf(_("oldest to newest"));
- wprintf(" ");
- wprintf("<input type=\"radio\" %s name=\"direction\" value=\"\""
- "OnChange=\"location.href='%s&sortby=reverse'\"",
- (bbs_reverse ? "checked" : ""),
- oper
- );
- wprintf(">");
- wprintf(_("newest to oldest"));
- wprintf("\n");
-
- wprintf("</p></form>\n");
- /** end bbview scroller */
+ StrBufAppendBuf(WCC->WBuf, BBViewToolBar, 0);
}
DONE:
DeleteHash(&WCC->summ);
}
if (addrbook != NULL) free(addrbook);
+ FreeStrBuf(&BBViewToolBar);
}
HashPos *it;
/* Add in the attachments */
- it = GetNewHashPos();
+ it = GetNewHashPos(WCC->attachments, 0);
while (GetNextHashPos(WCC->attachments, it, &len, &Key, &vAtt)) {
att = (wc_attachment*)vAtt;
encoded_length = ((att->length * 150) / 100);
void display_enter(void)
{
char buf[SIZ];
- StrBuf *ebuf;
long now;
const StrBuf *display_name = NULL;
/////wc_attachment *att;
int subject_required = 0;
int recipient_bad = 0;
int is_anonymous = 0;
- long existing_page = (-1L);
- struct wcsession *WCC = WC;
+
+ struct wcsession *WCC = WC;
now = time(NULL);
* Otherwise proceed normally.
* Do a custom room banner with no navbar...
*/
- output_headers(1, 1, 2, 0, 0, 0);
-/*
- wprintf("<div id=\"banner\">\n");
- embed_room_banner(NULL, navbar_none);
- wprintf("</div>\n");
- wprintf("<div id=\"content\">\n"
- "<div class=\"fix_scrollbar_bug message \">");
-*/
- /* Now check our actual recipients if there are any */
if (recipient_required) {
const StrBuf *Recp = NULL;
const StrBuf *Cc = NULL;
}
else if (buf[0] != '2') { /** Any other error means that we cannot continue */
wprintf("<em>%s</em><br />\n", &buf[4]);/// -> important message
- goto DONE;
+ return;
}
}
svputlong("RCPTREQUIRED", recipient_required);
svputlong("SUBJREQUIRED", recipient_required || subject_required);
- DoTemplate(HKEY("edit_message"), NULL, NULL, CTX_NONE);
- address_book_popup();
- wDumpContent(1);
+ begin_burst();
+ output_headers(1, 0, 0, 0, 1, 0);
+ DoTemplate(HKEY("edit_message"), NULL, NULL, CTX_NONE);
+ end_burst();
return;
-
-
- /** If we got this far, we can display the message entry screen. */
-
- /* begin message entry screen */
- wprintf("<form "
- "enctype=\"multipart/form-data\" "
- "method=\"POST\" "
- "accept-charset=\"UTF-8\" "
- "action=\"post\" "
- "name=\"enterform\""
- ">\n");
- wprintf("<input type=\"hidden\" name=\"postseq\" value=\"%ld\">\n", now);
- if (WCC->wc_view == VIEW_WIKI) {
- wprintf("<input type=\"hidden\" name=\"wikipage\" value=\"%s\">\n", bstr("wikipage"));
- }
- wprintf("<input type=\"hidden\" name=\"return_to\" value=\"%s\">\n", bstr("return_to"));
- wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WCC->nonce);
- wprintf("<input type=\"hidden\" name=\"force_room\" value=\"");
- escputs(WCC->wc_roomname);
- wprintf("\">\n");
- wprintf("<input type=\"hidden\" name=\"references\" value=\"");
- escputs(bstr("references"));
- wprintf("\">\n");
-
- /** submit or cancel buttons */
- wprintf("<p class=\"send_edit_msg\">");
- wprintf("<input type=\"submit\" name=\"send_button\" value=\"");
- if (recipient_required) {
- wprintf(_("Send message"));
- } else {
- wprintf(_("Post message"));
- }
- wprintf("\"> "
- "<input type=\"submit\" name=\"cancel_button\" value=\"%s\">\n", _("Cancel"));
- wprintf("</p>");
-
- /** header bar */
-
- wprintf("<img src=\"static/newmess3_24x.gif\" class=\"imgedit\">");
- wprintf(" "); /** header bar */
- webcit_fmt_date(buf, now, 0);
- wprintf("%s", buf);
- wprintf("\n"); /** header bar */
-
- wprintf("<table width=\"100%%\" class=\"edit_msg_table\">");
- wprintf("<tr>");
- wprintf("<th><label for=\"from_id\" > ");
- wprintf(_(" <I>from</I> "));
- wprintf("</label></th>");
-
- wprintf("<td colspan=\"2\">");
-
- /* Allow the user to select any of his valid screen names */
-
- wprintf("<select name=\"display_name\" size=1 id=\"from_id\">\n");
-
- serv_puts("GVSN");
- serv_getln(buf, sizeof buf);
- if (buf[0] == '1') {
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- wprintf("<option %s value=\"",
- ((!strcasecmp(bstr("display_name"), buf)) ? "selected" : "")
- );
- escputs(buf);
- wprintf("\">");
- escputs(buf);
- wprintf("</option>\n");
- }
- }
-
- if (WCC->room_flags & QR_ANONOPT) {
- wprintf("<option %s value=\"__ANONYMOUS__\">%s</option>\n",
- ((!strcasecmp(bstr("__ANONYMOUS__"), WCC->wc_fullname)) ? "selected" : ""),
- _("Anonymous")
- );
- }
-
- wprintf("</select>\n");
-
- /* If this is an email (not a post), allow the user to select any of his
- * valid email addresses.
- */
- if (recipient_required) {
- serv_puts("GVEA");
- serv_getln(buf, sizeof buf);
- if (buf[0] == '1') {
- wprintf("<select name=\"my_email_addr\" size=1>\n");
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- wprintf("<option value=\"");
- escputs(buf);
- wprintf("\"><");
- escputs(buf);
- wprintf("></option>\n");
- }
- wprintf("</select>\n");
- }
- }
-
- wprintf(_(" <I>in</I> "));
- escputs(WCC->wc_roomname);
-
- wprintf("</td></tr>");
-
- if (recipient_required) {
- char *ccraw;
- char *copy;
- size_t len;
- wprintf("<tr><th><label for=\"recp_id\"> ");
- wprintf(_("To:"));
- wprintf("</label></th>"
- "<td><input autocomplete=\"off\" type=\"text\" name=\"recp\" id=\"recp_id\" value=\"");
- ccraw = xbstr("recp", &len);
- copy = (char*) malloc(len * 2 + 1);
- memcpy(copy, ccraw, len + 1);
- utf8ify_rfc822_string(copy);
- escputs(copy);
- free(copy);
- wprintf("\" size=45 maxlength=1000 />");
- wprintf("<div class=\"auto_complete\" id=\"recp_name_choices\"></div>");
- wprintf("</td><td rowspan=\"3\" align=\"left\" valign=\"top\">");
-
- /** Pop open an address book -- begin **/
- wprintf(
- "<a href=\"javascript:PopOpenAddressBook('recp_id|%s|cc_id|%s|bcc_id|%s');\" "
- "title=\"%s\">"
- "<img align=middle border=0 width=24 height=24 src=\"static/viewcontacts_24x.gif\">"
- " %s</a>",
- _("To:"), _("CC:"), _("BCC:"),
- _("Contacts"), _("Contacts")
- );
- /** Pop open an address book -- end **/
-
- wprintf("</td></tr>");
-
- wprintf("<tr><th><label for=\"cc_id\"> ");
- wprintf(_("CC:"));
- wprintf("</label></th>"
- "<td><input autocomplete=\"off\" type=\"text\" name=\"cc\" id=\"cc_id\" value=\"");
- ccraw = xbstr("cc", &len);
- copy = (char*) malloc(len * 2 + 1);
- memcpy(copy, ccraw, len + 1);
- utf8ify_rfc822_string(copy);
- escputs(copy);
- free(copy);
- wprintf("\" size=45 maxlength=1000 />");
- wprintf("<div class=\"auto_complete\" id=\"cc_name_choices\"></div>");
- wprintf("</td></tr>");
-
- wprintf("<tr><th><label for=\"bcc_id\"> ");
- wprintf(_("BCC:"));
- wprintf("</label></th>"
- "<td><input autocomplete=\"off\" type=\"text\" name=\"bcc\" id=\"bcc_id\" value=\"");
- ccraw = xbstr("bcc", &len);
- copy = (char*) malloc(len * 2 + 1);
- memcpy(copy, ccraw, len + 1);
- utf8ify_rfc822_string(copy);
- escputs(copy);
- free(copy);
- wprintf("\" size=45 maxlength=1000 />");
- wprintf("<div class=\"auto_complete\" id=\"bcc_name_choices\"></div>");
- wprintf("</td></tr>");
-
- /** Initialize the autocomplete ajax helpers (found in wclib.js) */
- wprintf("<script type=\"text/javascript\"> \n"
- " activate_entmsg_autocompleters(); \n"
- "</script> \n"
- );
-
- }
-
- wprintf("<tr><th><label for=\"subject_id\" > ");
- if (recipient_required || subject_required) {
- wprintf(_("Subject:"));
- }
- else {
- wprintf(_("Subject (optional):"));
- }
- wprintf("</label></th>"
- "<td colspan=\"2\">"
- "<input type=\"text\" name=\"subject\" id=\"subject_id\" value=\"");
- escputs(bstr("subject"));
- wprintf("\" size=45 maxlength=70>\n");
- wprintf("</td></tr>");
-
- wprintf("<tr><td colspan=\"3\">\n");
-
- wprintf("<textarea name=\"msgtext\" cols=\"80\" rows=\"15\">");
-
- /** If we're continuing from a previous edit, put our partially-composed message back... */
- msgescputs(bstr("msgtext"));
-
- /* If we're forwarding a message, insert it here... */
- if (lbstr("fwdquote") > 0L) {
- wprintf("<br><div align=center><i>");
- wprintf(_("--- forwarded message ---"));
- wprintf("</i></div><br>");
- pullquote_message(lbstr("fwdquote"), 1, 1);
- }
-
- /** If we're replying quoted, insert the quote here... */
- else if (lbstr("replyquote") > 0L) {
- wprintf("<br>"
- "<blockquote>");
- pullquote_message(lbstr("replyquote"), 0, 1);
- wprintf("</blockquote><br>");
- }
-
- /** If we're editing a wiki page, insert the existing page here... */
- else if (WCC->wc_view == VIEW_WIKI) {
- safestrncpy(buf, bstr("wikipage"), sizeof buf);
- str_wiki_index(buf);
- existing_page = locate_message_by_uid(buf);
- if (existing_page >= 0L) {
- pullquote_message(existing_page, 1, 0);
- }
- }
-
- /** Insert our signature if appropriate... */
- if ( (WCC->is_mailbox) && !yesbstr("sig_inserted") ) {
- int UseSig;
- get_pref_yesno("use_sig", &UseSig, 0);
- if (UseSig) {
- StrBuf *Sig;
- const char *sig, *esig;
-
- get_preference("signature", &ebuf);
- Sig = NewStrBuf();
- StrBufEUid_unescapize(Sig, ebuf);
- sig = ChrPtr(Sig);
- esig = sig + StrLength(Sig);
- wprintf("<br>--<br>");
- while (sig <= esig) {
- if (*sig == '\n') {
- wprintf("<br>");
- }
- else if (*sig == '<') {
- wprintf("<");
- }
- else if (*sig == '>') {
- wprintf(">");
- }
- else if (*sig == '&') {
- wprintf("&");
- }
- else if (*sig == '\"') {
- wprintf(""");
- }
- else if (*sig == '\'') {
- wprintf("'");
- }
- else /* since we're utf 8, is this a good idea? if (isprint(*sig))*/ {
- wprintf("%c", *sig);
- }
- sig ++;
- }
- FreeStrBuf(&Sig);
- }
- }
-
- wprintf("</textarea>\n");
-
- /** Make sure we only insert our signature once */
- /** We don't care if it was there or not before, it needs to be there now. */
- wprintf("<input type=\"hidden\" name=\"sig_inserted\" value=\"yes\">\n");
-
- /**
- * The following template embeds the TinyMCE richedit control, and automatically
- * transforms the textarea into a richedit textarea.
- */
- do_template("richedit", NULL);
-
- /** Enumerate any attachments which are already in place... */
- wprintf("<div class=\"attachment buttons\"><img src=\"static/diskette_24x.gif\" class=\"imgedit\" > ");
- wprintf(_("Attachments:"));
- wprintf(" ");
- wprintf("<select name=\"which_attachment\" size=1>");
-/*
- for (att = WCC->first_attachment; att != NULL; att = att->next) {
- wprintf("<option value=\"");
- urlescputs(att->filename);
- wprintf("\">");
- escputs(att->filename);
- / * wprintf(" (%s, %d bytes)",att->content_type,att->length); * /
- wprintf("</option>\n");
- }
-*/
- wprintf("</select>");
-
- /** Now offer the ability to attach additional files... */
- wprintf(" ");
- wprintf(_("Attach file:"));
- wprintf(" <input name=\"attachfile\" class=\"attachfile\" "
- "size=16 type=\"file\">\n "
- "<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Add"));
- wprintf("</div>"); /* End of "attachment buttons" div */
-
-
- wprintf("</td></tr></table>");
-
- wprintf("</form>\n");
- wprintf("</div>\n"); /* end of "fix_scrollbar_bug" div */
-
- /* NOTE: address_book_popup() will close the "content" div. Don't close it here. */
-DONE: address_book_popup();
- wDumpContent(1);
}
-
/**
* \brief delete a message
*/
InitModule_MSG
(void)
{
- WebcitAddUrlHandler(HKEY("readnew"), readnew, 0);
- WebcitAddUrlHandler(HKEY("readold"), readold, 0);
- WebcitAddUrlHandler(HKEY("readfwd"), readfwd, 0);
- WebcitAddUrlHandler(HKEY("headers"), headers, 0);
+ WebcitAddUrlHandler(HKEY("readnew"), readnew, NEED_URL);
+ WebcitAddUrlHandler(HKEY("readold"), readold, NEED_URL);
+ WebcitAddUrlHandler(HKEY("readfwd"), readfwd, NEED_URL);
+ WebcitAddUrlHandler(HKEY("headers"), headers, NEED_URL);
WebcitAddUrlHandler(HKEY("do_search"), do_search, 0);
WebcitAddUrlHandler(HKEY("display_enter"), display_enter, 0);
WebcitAddUrlHandler(HKEY("post"), post_message, 0);
WebcitAddUrlHandler(HKEY("mobilemsg"), mobile_message_view, NEED_URL);
WebcitAddUrlHandler(HKEY("msgheaders"), display_headers, NEED_URL);
+
return ;
}