]> code.citadel.org Git - citadel.git/blobdiff - webcit/msg_renderers.c
* the json view shouldn't call begin/endburst itself, its done by readloop.
[citadel.git] / webcit / msg_renderers.c
index d8630588fdde7762a8ac0a046cb60886ac1aeb3b..2ff94b66a30b7c2aa397830b00812391a9f0292c 100644 (file)
@@ -837,11 +837,6 @@ void render_MAIL_text_plain(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *F
                MimeLoadData(Mime);
        }
 
-       /* Boring old 80-column fixed format text gets handled this way... */
-       if ((strcasecmp(ChrPtr(Mime->Charset), "us-ascii") == 0) &&
-           (strcasecmp(ChrPtr(Mime->Charset), "UTF-8") == 0))
-               ConvertIt = 0;
-
 #ifdef HAVE_ICONV
        if (ConvertIt) {
                if (StrLength(Mime->Charset) != 0)
@@ -853,6 +848,12 @@ void render_MAIL_text_plain(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *F
                if (cs == NULL) {
                        ConvertIt = 0;
                }
+               else if (!strcasecmp(ChrPtr(cs), "utf-8")) {
+                       ConvertIt = 0;
+               }
+               else if (!strcasecmp(ChrPtr(cs), "us-ascii")) {
+                       ConvertIt = 0;
+               }
                else {
                        ctdl_iconv_open("UTF-8", ChrPtr(cs), &ic);
                        if (ic == (iconv_t)(-1) ) {
@@ -897,7 +898,7 @@ void render_MAIL_text_plain(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *F
                for (i = bq; i < bn; i++)                               
                        StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
 
-               if (ConvertIt == 1) {
+               if (ConvertIt) {
                        StrBufConvert(Line, Line1, &ic);
                }
 
@@ -1069,6 +1070,98 @@ void tmplput_MIME_Length(StrBuf *Target, WCTemplputParams *TP)
        StrBufAppendPrintf(Target, "%ld", mime->length);
 }
 
+/* startmsg is an index within the message list.
+ * starting_from is the Citadel message number to be supplied to a "MSGS GT" operation
+ */
+long DrawMessageDropdown(StrBuf *Selector, long maxmsgs, long startmsg, int nMessages, long starting_from)
+{
+       StrBuf *TmpBuf;
+       wcsession *WCC = WC;
+       void *vMsg;
+       int lo, hi;
+       long ret;
+       long hklen;
+       const char *key;
+       int done = 0;
+       int nItems;
+       HashPos *At;
+       long vector[16];
+       WCTemplputParams SubTP;
+
+       memset(&SubTP, 0, sizeof(WCTemplputParams));
+       SubTP.Filter.ContextType = CTX_LONGVECTOR;
+       SubTP.Context = &vector;
+       TmpBuf = NewStrBufPlain(NULL, SIZ);
+       At = GetNewHashPos(WCC->summ, nMessages);
+       nItems = GetCount(WCC->summ);
+       ret = nMessages;
+       vector[0] = 7;
+       vector[2] = 1;
+       vector[1] = startmsg;
+       vector[3] = 0;
+       vector[7] = starting_from;
+
+       while (!done) {
+               vector[3] = abs(nMessages);
+               lo = GetHashPosCounter(At);
+               if (nMessages > 0) {
+                       if (lo + nMessages >= nItems) {
+                               hi = nItems - 1;
+                               vector[3] = nItems - lo;
+                               if (startmsg == lo) 
+                                       ret = vector[3];
+                       }
+                       else {
+                               hi = lo + nMessages - 1;
+                       }
+               } else {
+                       if (lo + nMessages < -1) {
+                               hi = 0;
+                       }
+                       else {
+                               if ((lo % abs(nMessages)) != 0) {
+                                       int offset = (lo % abs(nMessages) *
+                                                     (nMessages / abs(nMessages)));
+                                       hi = lo + offset;
+                                       vector[3] = abs(offset);
+                                       if (startmsg == lo)
+                                                ret = offset;
+                               }
+                               else
+                                       hi = lo + nMessages;
+                       }
+               }
+               done = !GetNextHashPos(WCC->summ, At, &hklen, &key, &vMsg);
+               
+               /*
+                * Bump these because although we're thinking in zero base, the user
+                * is a drooling idiot and is thinking in one base.
+                */
+               vector[4] = lo + 1;
+               vector[5] = hi + 1;
+               vector[6] = lo;
+               FlushStrBuf(TmpBuf);
+               dbg_print_longvector(vector);
+               DoTemplate(HKEY("select_messageindex"), TmpBuf, &SubTP);
+               StrBufAppendBuf(Selector, TmpBuf, 0);
+       }
+       vector[6] = 0;
+       FlushStrBuf(TmpBuf);
+       if (maxmsgs == 9999999) {
+               vector[1] = 1;
+               ret = maxmsgs;
+       }
+       else
+               vector[1] = 0;          
+       vector[2] = 0;
+       dbg_print_longvector(vector);
+       DoTemplate(HKEY("select_messageindex_all"), TmpBuf, &SubTP);
+       StrBufAppendBuf(Selector, TmpBuf, 0);
+       FreeStrBuf(&TmpBuf);
+       DeleteHashPos(&At);
+       return ret;
+}
+
 HashList *iterate_get_registered_Attachments(StrBuf *Target, WCTemplputParams *TP)
 {
        return WC->attachments;
@@ -1089,6 +1182,11 @@ void servcmd_readfwd(char *buf, long bufsize)
        snprintf(buf, bufsize, "MSGS ALL");
 }
 
+void servcmd_readgt(char *buf, long bufsize)
+{
+       snprintf(buf, bufsize, "MSGS GT|%s", bstr("gt"));
+}
+
 void servcmd_readnew(char *buf, long bufsize)
 {
        snprintf(buf, bufsize, "MSGS NEW");
@@ -1105,34 +1203,246 @@ readloop_struct rlid[] = {
        { {HKEY("headers")},   servcmd_headers},
        { {HKEY("readfwd")},   servcmd_readfwd},
        { {HKEY("readnew")},   servcmd_readnew},
-       { {HKEY("readold")},   servcmd_readold}
+       { {HKEY("readold")},   servcmd_readold},
+       { {HKEY("readgt")},    servcmd_readgt}
 };
 
+/* Spit out the new summary view. This is basically a static page, so clients can cache the layout, all the dirty work is javascript :) */
+void new_summary_view(void) {
+       DoTemplate(HKEY("msg_listview"),NULL,&NoCtx);
+       DoTemplate(HKEY("trailing"),NULL,&NoCtx);
+}
+
+
+int mailview_GetParamsGetServerCall(SharedMessageStatus *Stat, 
+                                   void **ViewSpecific, 
+                                   long oper, 
+                                   char *cmd, 
+                                   long len)
+{
+       if (!WC->is_ajax) {
+               new_summary_view();
+               return 200;
+       } else {
+               Stat->defaultsortorder = 2;
+               Stat->sortit = 1;
+               Stat->load_seen = 1;
+               /* Generally using maxmsgs|startmsg is not required
+                  in mailbox view, but we have a 'safemode' for clients
+                  (*cough* Exploder) that simply can't handle too many */
+               if (havebstr("maxmsgs"))  Stat->maxmsgs  = ibstr("maxmsgs");
+               else                      Stat->maxmsgs  = 9999999;
+               if (havebstr("startmsg")) Stat->startmsg = lbstr("startmsg");
+               snprintf(cmd, len, "MSGS %s|%s||1",
+                        (oper == do_search) ? "SEARCH" : "ALL",
+                        (oper == do_search) ? bstr("query") : ""
+                       );
+       }
+       return 200;
+}
 
+int mailview_RenderView_or_Tail(SharedMessageStatus *Stat, 
+                               void **ViewSpecific, 
+                               long oper)
+{
+       WCTemplputParams SubTP;
+
+       DoTemplate(HKEY("mailsummary_json"),NULL, &SubTP);
+       return 0;
+}
 
-void SetAccessCommand(long Oper)
+int mailview_Cleanup(void **ViewSpecific)
 {
-/* TODO: whats achieved by this?
-       wcsession *WCC = WC;    
+       /* Note: wDumpContent() will output one additional </div> tag. */
+       /* We ought to move this out into template */
+       if (WC->is_ajax) 
+               end_burst();
+       else
+               wDumpContent(1);
+       return 0;
+}
+
+
+
+typedef struct _bbsview_stuct {
+       StrBuf *BBViewToolBar;
+       StrBuf *MessageDropdown;
+       long *displayed_msgs;
+       int a;
+}bbsview_struct;
 
-       if (WCC->UrlFragment1 != NULL ) {
-               FlushStrBuf(WCC->UrlFragment1);
-               StrBufAppendBufPlain(WCC->UrlFragment1, 
-                                    rlid[Oper].name.Key, rlid[Oper].name.len, 0);
+int bbsview_GetParamsGetServerCall(SharedMessageStatus *Stat, 
+                                  void **ViewSpecific, 
+                                  long oper, 
+                                  char *cmd, 
+                                  long len)
+{
+       bbsview_struct *VS;
+
+       VS = (bbsview_struct*) malloc(sizeof(bbsview_struct));
+       memset(VS, 0, sizeof(bbsview_struct));
+       *ViewSpecific = (void*)VS;
+       Stat->defaultsortorder = 1;
+       Stat->startmsg = -1;
+       Stat->sortit = 1;
+       
+       rlid[oper].cmd(cmd, len);
+       
+       if (havebstr("maxmsgs"))
+               Stat->maxmsgs = ibstr("maxmsgs");
+       if (Stat->maxmsgs == 0) Stat->maxmsgs = DEFAULT_MAXMSGS;
+       
+       if (havebstr("startmsg")) {
+               Stat->startmsg = lbstr("startmsg");
+       }
+       if (lbstr("SortOrder") == 2) {
+               Stat->reverse = 1;
+               Stat->num_displayed = -DEFAULT_MAXMSGS;
+       }
+       else {
+               Stat->reverse = 0;
+               Stat->num_displayed = DEFAULT_MAXMSGS;
+       }
+
+       return 200;
+}
+
+int bbsview_PrintViewHeader(SharedMessageStatus *Stat, void **ViewSpecific)
+{
+       bbsview_struct *VS;
+       WCTemplputParams SubTP;
+
+       VS = (bbsview_struct*)*ViewSpecific;
+
+       VS->BBViewToolBar = NewStrBufPlain(NULL, SIZ);
+       VS->MessageDropdown = NewStrBufPlain(NULL, SIZ);
+
+       /*** startmsg->maxmsgs = **/DrawMessageDropdown(VS->MessageDropdown, 
+                                                       Stat->maxmsgs, 
+                                                       Stat->startmsg,
+                                                       Stat->num_displayed, 
+                                                       Stat->lowest_found-1);
+       if (Stat->num_displayed < 0) {
+               Stat->startmsg += Stat->maxmsgs;
+               if (Stat->num_displayed != Stat->maxmsgs)                               
+                       Stat->maxmsgs = abs(Stat->maxmsgs) + 1;
+               else
+                       Stat->maxmsgs = abs(Stat->maxmsgs);
+
+       }
+       memset(&SubTP, 0, sizeof(WCTemplputParams));
+       SubTP.Filter.ContextType = CTX_STRBUF;
+       SubTP.Context = VS->MessageDropdown;
+       DoTemplate(HKEY("msg_listselector_top"), VS->BBViewToolBar, &SubTP);
+       StrBufAppendBuf(WC->WBuf, VS->BBViewToolBar, 0);
+       FlushStrBuf(VS->BBViewToolBar);
+       return 200;
+}
+
+int bbsview_LoadMsgFromServer(SharedMessageStatus *Stat, 
+                             void **ViewSpecific, 
+                             message_summary* Msg, 
+                             int is_new, 
+                             int i)
+{
+       bbsview_struct *VS;
+
+       VS = (bbsview_struct*)*ViewSpecific;
+       if (VS->displayed_msgs == NULL) {
+               VS->displayed_msgs = malloc(sizeof(long) *
+                                           ((Stat->maxmsgs < Stat->nummsgs) ? 
+                                            Stat->maxmsgs + 1 : 
+                                            Stat->nummsgs + 1));
+       }
+       if ((i >= Stat->startmsg) && (i < Stat->startmsg + Stat->maxmsgs)) {
+               VS->displayed_msgs[Stat->num_displayed] = Msg->msgnum;
+               Stat->num_displayed++;
+       }
+       return 200;
+}
+
+
+int bbsview_RenderView_or_Tail(SharedMessageStatus *Stat, 
+                              void **ViewSpecific, 
+                              long oper)
+{
+       wcsession *WCC = WC;
+       bbsview_struct *VS;
+       WCTemplputParams SubTP;
+       const StrBuf *Mime;
+
+       VS = (bbsview_struct*)*ViewSpecific;
+       if (Stat->nummsgs == 0) {
+               wprintf("<div class=\"nomsgs\"><br><em>");
+               switch (oper) {
+               case readnew:
+                       wprintf(_("No new messages."));
+                       break;
+               case readold:
+                       wprintf(_("No old messages."));
+                       break;
+               default:
+                       wprintf(_("No messages here."));
+               }
+               wprintf("</em><br></div>\n");
        }
        else 
-               WCC->UrlFragment1 = NewStrBufPlain(rlid[Oper].name.Key, rlid[Oper].name.len);
-*/
+       {
+               if (VS->displayed_msgs != NULL) {
+                       /* if we do a split bbview in the future, begin messages div here */
+                       int a;/// todo  
+                       for (a=0; a < Stat->num_displayed; ++a) {
+                               read_message(WCC->WBuf, HKEY("view_message"), VS->displayed_msgs[a], NULL, &Mime);
+                       }
+                       
+                       /* if we do a split bbview in the future, end messages div here */
+                       
+                       free(VS->displayed_msgs);
+                       VS->displayed_msgs = NULL;
+               }
+               memset(&SubTP, 0, sizeof(WCTemplputParams));
+               SubTP.Filter.ContextType = CTX_STRBUF;
+               SubTP.Context = VS->MessageDropdown;
+               DoTemplate(HKEY("msg_listselector_bottom"), VS->BBViewToolBar, &SubTP);
+               StrBufAppendBuf(WCC->WBuf, VS->BBViewToolBar, 0);
+       }
+       return 0;
+
 }
-               
 
 
+int bbsview_Cleanup(void **ViewSpecific)
+{
+       bbsview_struct *VS;
 
+       VS = (bbsview_struct*)*ViewSpecific;
+       end_burst();
+       FreeStrBuf(&VS->BBViewToolBar);
+       FreeStrBuf(&VS->MessageDropdown);
+       free(VS);
+       return 0;
+}
 
 void 
 InitModule_MSGRENDERERS
 (void)
 {
+       RegisterReadLoopHandlerset(
+               VIEW_MAILBOX,
+               mailview_GetParamsGetServerCall,
+               NULL, /// TODO: is this right?
+               NULL, //// ""
+               mailview_RenderView_or_Tail,
+               mailview_Cleanup);
+
+       RegisterReadLoopHandlerset(
+               VIEW_BBS,
+               bbsview_GetParamsGetServerCall,
+               bbsview_PrintViewHeader,
+               bbsview_LoadMsgFromServer,
+               bbsview_RenderView_or_Tail,
+               bbsview_Cleanup);
+
        RegisterSortFunc(HKEY("date"), 
                         NULL, 0,
                         summcmp_date,
@@ -1265,6 +1575,7 @@ ServerStartModule_MSGRENDERERS
 {
        MsgHeaderHandler = NewHash(1, NULL);
        MimeRenderHandler = NewHash(1, NULL);
+       ReadLoopHandler = NewHash(1, NULL);
 }
 
 void 
@@ -1273,6 +1584,7 @@ ServerShutdownModule_MSGRENDERERS
 {
        DeleteHash(&MsgHeaderHandler);
        DeleteHash(&MimeRenderHandler);
+       DeleteHash(&ReadLoopHandler);
 }