* add first draft of group-change detection
authorWilfried Göesgens <willi@citadel.org>
Sat, 27 Dec 2008 23:19:17 +0000 (23:19 +0000)
committerWilfried Göesgens <willi@citadel.org>
Sat, 27 Dec 2008 23:19:17 +0000 (23:19 +0000)
* templatize downloads

16 files changed:
webcit/downloads.c
webcit/inetconf.c
webcit/msg_renderers.c
webcit/netconf.c
webcit/preferences.c
webcit/pushemail.c
webcit/roomops.c
webcit/static/t/files.html [new file with mode: 0644]
webcit/static/t/files_jspicview.html [new file with mode: 0644]
webcit/static/t/menu_basic_commands.html
webcit/static/t/section_files_onefile.html [new file with mode: 0644]
webcit/static/t/section_files_onefile_picview.html [new file with mode: 0644]
webcit/subst.c
webcit/subst.h
webcit/useredit.c
webcit/who.c

index 4706d0042f5693d5f7345315ade8f4fb398f6fce..b5052d82ea2be6661af2fa4852cc9b8971d82682 100644 (file)
@@ -4,19 +4,57 @@
 #include "webcit.h"
 #include "webserver.h"
 
+extern char* static_dirs[];
+
 typedef struct _FileListStruct {
-       char Filename[256];
-       int FilenameLen;
+       StrBuf *Filename;
        long FileSize;
-       char MimeType[64];
-       int MimeTypeLen;
-       char Comment[512];
-       int CommentLen;
+       StrBuf *MimeType;
+       StrBuf *Comment;
        int IsPic;
        int Sequence;
-}FileListStruct;
+} FileListStruct;
+
+void FreeFiles(void *vFile)
+{
+       FileListStruct *F = (FileListStruct*) vFile;
+       FreeStrBuf(&F->Filename);
+       FreeStrBuf(&F->MimeType);
+       FreeStrBuf(&F->Comment);
+       free(F);
+}
+
+/* -------------------------------------------------------------------------------- */
+void tmplput_FILE_NAME(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+       FileListStruct *F = (FileListStruct*) Context;
+       StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->Filename, 0);
+}
+void tmplput_FILE_SIZE(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+       FileListStruct *F = (FileListStruct*) Context;
+       StrBufAppendPrintf(Target, "%ld", F->FileSize);
+}
+void tmplput_FILEMIMETYPE(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+       FileListStruct *F = (FileListStruct*) Context;
+       StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->MimeType, 0);
+}
+void tmplput_FILE_COMMENT(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+       FileListStruct *F = (FileListStruct*) Context;
+       StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, F->Comment, 0);
+}
 
+/* -------------------------------------------------------------------------------- */
 
+int Conditional_FILE_ISPIC(WCTemplateToken *Tokens, void *Context, int ContextType)
+{
+       FileListStruct *F = (FileListStruct*) Context;
+       return F->IsPic;
+}
+
+/* -------------------------------------------------------------------------------- */
 int CompareFilelistByMime(const void *vFile1, const void *vFile2)
 {
        FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
@@ -24,7 +62,7 @@ int CompareFilelistByMime(const void *vFile1, const void *vFile2)
 
        if (File1->IsPic != File2->IsPic)
                return File1->IsPic > File2->IsPic;
-       return strcasecmp(File1->MimeType, File2->MimeType);
+       return strcasecmp(ChrPtr(File1->MimeType), ChrPtr(File2->MimeType));
 }
 int CompareFilelistByMimeRev(const void *vFile1, const void *vFile2)
 {
@@ -32,9 +70,45 @@ int CompareFilelistByMimeRev(const void *vFile1, const void *vFile2)
        FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
        if (File1->IsPic != File2->IsPic)
                return File1->IsPic < File2->IsPic;
-       return strcasecmp(File2->MimeType, File1->MimeType);
+       return strcasecmp(ChrPtr(File2->MimeType), ChrPtr(File1->MimeType));
+}
+int GroupchangeFilelistByMime(const void *vFile1, const void *vFile2)
+{
+       FileListStruct *File1 = (FileListStruct*) vFile1;
+       FileListStruct *File2 = (FileListStruct*) vFile2;
+
+       if (File1->IsPic != File2->IsPic)
+               return File1->IsPic > File2->IsPic;
+       return strcasecmp(ChrPtr(File1->MimeType), ChrPtr(File2->MimeType)) != 0;
 }
 
+
+int CompareFilelistByName(const void *vFile1, const void *vFile2)
+{
+       FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
+       FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
+
+       if (File1->IsPic != File2->IsPic)
+               return File1->IsPic > File2->IsPic;
+       return strcasecmp(ChrPtr(File1->Filename), ChrPtr(File2->Filename));
+}
+int CompareFilelistByNameRev(const void *vFile1, const void *vFile2)
+{
+       FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
+       FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
+       if (File1->IsPic != File2->IsPic)
+               return File1->IsPic < File2->IsPic;
+       return strcasecmp(ChrPtr(File2->Filename), ChrPtr(File1->Filename));
+}
+int GroupchangeFilelistByName(const void *vFile1, const void *vFile2)
+{
+       FileListStruct *File1 = (FileListStruct*) vFile1;
+       FileListStruct *File2 = (FileListStruct*) vFile2;
+
+       return ChrPtr(File1->Filename)[0] != ChrPtr(File2->Filename)[0];
+}
+
+
 int CompareFilelistBySize(const void *vFile1, const void *vFile2)
 {
        FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
@@ -43,7 +117,6 @@ int CompareFilelistBySize(const void *vFile1, const void *vFile2)
                return 0;
        return (File1->FileSize > File2->FileSize);
 }
-
 int CompareFilelistBySizeRev(const void *vFile1, const void *vFile2)
 {
        FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
@@ -52,19 +125,31 @@ int CompareFilelistBySizeRev(const void *vFile1, const void *vFile2)
                return 0;
        return (File1->FileSize < File2->FileSize);
 }
+int GroupchangeFilelistBySize(const void *vFile1, const void *vFile2)
+{
+       return 0;
+}
+
 
 int CompareFilelistByComment(const void *vFile1, const void *vFile2)
 {
        FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
        FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
-       return strcasecmp(File1->Comment, File2->Comment);
+       return strcasecmp(ChrPtr(File1->Comment), ChrPtr(File2->Comment));
 }
 int CompareFilelistByCommentRev(const void *vFile1, const void *vFile2)
 {
        FileListStruct *File1 = (FileListStruct*) GetSearchPayload(vFile1);
        FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
-       return strcasecmp(File2->Comment, File1->Comment);
+       return strcasecmp(ChrPtr(File2->Comment), ChrPtr(File1->Comment));
 }
+int GroupchangeFilelistByComment(const void *vFile1, const void *vFile2)
+{
+       FileListStruct *File1 = (FileListStruct*) vFile1;
+       FileListStruct *File2 = (FileListStruct*) vFile2;
+       return ChrPtr(File1->Comment)[9] != ChrPtr(File2->Comment)[0];
+}
+
 
 int CompareFilelistBySequence(const void *vFile1, const void *vFile2)
 {
@@ -72,298 +157,67 @@ int CompareFilelistBySequence(const void *vFile1, const void *vFile2)
        FileListStruct *File2 = (FileListStruct*) GetSearchPayload(vFile2);
        return (File2->Sequence >  File1->Sequence);
 }
+int GroupchangeFilelistBySequence(const void *vFile1, const void *vFile2)
+{
+       return 0;
+}
 
-HashList* LoadFileList(int *HavePic)
+/* -------------------------------------------------------------------------------- */
+HashList* LoadFileList(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
 {
        FileListStruct *Entry;
+       StrBuf *Buf;
        HashList *Files;
-       int HavePics = 0;
-       int Order;
+       int Done = 0;
        int sequence = 0;
        char buf[1024];
+       CompareFunc SortIt;
+       int HavePic;
 
        serv_puts("RDIR");
        serv_getln(buf, sizeof buf);
-       if (buf[0] == '1') {
-               Files = NewHash(1, NULL);
-               while (serv_getln(buf, sizeof buf), strcmp(buf, "000"))
-               {
-                       Entry = (FileListStruct*) malloc(sizeof (FileListStruct));
-
-                       Entry->FilenameLen = extract_token(
-                               Entry->Filename, buf, 0, '|', 
-                               sizeof(Entry->Filename));
-                       Entry->FileSize = extract_long(buf, 1);
-                       Entry->MimeTypeLen = extract_token(
-                               Entry->MimeType, buf, 2, '|', 
-                               sizeof(Entry->MimeType));
-                       Entry->CommentLen = extract_token(
-                               Entry->Comment,  buf, 3, '|', 
-                               sizeof(Entry->Comment));
-                       
-                       Entry->Sequence = sequence++;
-                       Entry->IsPic = (strstr(Entry->MimeType, "image") != NULL);
-                       if (!HavePics && Entry->IsPic) {
-                               HavePics = 1;
-                               *HavePic = 1;
-                       }
-                       Put(Files, Entry->Filename, 
-                           Entry->FilenameLen, 
-                           Entry, NULL);
-               }
-               Order = ibstr("SortOrder");
-               switch (ibstr("SortBy")){
-               case 1: /*NAME*/
-                       SortByHashKey(Files,Order);
-                       break;
-               case 2: /* SIZE*/
-                       SortByPayload(Files, (Order)? 
-                                     CompareFilelistBySize:
-                                     CompareFilelistBySizeRev);
-                       break;
-               case 3: /*MIME*/
-                       SortByPayload(Files, (Order)? 
-                                     CompareFilelistByMime:
-                                     CompareFilelistByMimeRev);
-                       break;
-               case 4: /*COMM*/
-                       SortByPayload(Files, (Order)? 
-                                     CompareFilelistByComment:
-                                     CompareFilelistByCommentRev);
-                       break;
-               default:
-                       SortByPayload(Files, CompareFilelistBySequence);
-               }
-               return Files;
-       }
-       else
-               return NULL;
-}
-
-void FilePrintEntry(const char *FileName, void *vFile, int odd)
-{
-       FileListStruct *File = (FileListStruct*) vFile;
-
-       wprintf("<tr bgcolor=\"#%s\">", (odd ? "DDDDDD" : "FFFFFF"));
-       wprintf("<td>"
-               "<a href=\"download_file/");
-       urlescputs(File->Filename);
-       wprintf("\"><img src=\"display_mime_icon?type=%s\" border=0 align=middle>\n", 
-               File->MimeType);
-       escputs(File->Filename);        wprintf("</a></td>");
-       wprintf("<td>%ld</td>", File->FileSize);
-       wprintf("<td>");        escputs(File->MimeType);        wprintf("</td>");
-       wprintf("<td>");        escputs(File->Comment); wprintf("</td>");
-       wprintf("</tr>\n");
-}
+       if (buf[0] != '1') return NULL;
 
-void FilePrintTransition(void *vFile1, void *vFile2, int odd)
-{
-       FileListStruct *File1 = (FileListStruct*) vFile1;
-       FileListStruct *File2 = (FileListStruct*) vFile2;
-       char StartChar[2] = "\0\0";
-       char *SectionName;
-
-       switch (ibstr("SortBy")){
-       case 1: /*NAME*/
-               if ((File2 != NULL) && 
-                   ((File1 == NULL) ||
-                    (File1->Filename[0] != File2->Filename[0]))) {
-                       StartChar[0] = File2->Filename[0];
-                       SectionName = StartChar;
+       Buf = NewStrBuf();             
+       Files = NewHash(1, NULL);
+       while (!Done && (StrBuf_ServGetln(Buf)>=0)) {
+               if ( (StrLength(Buf)==3) && 
+                   !strcmp(ChrPtr(Buf), "000")) 
+               {
+                       Done = 1;
+                       continue;
                }
-               else return;
-               break;
-       case 2: /* SIZE*/
-               return;
-       case 3: /*MIME*/
-               return; /*TODO*/
-               break;
-       case 4: /*COMM*/
-               return;
-       default:
-               return;
-       }
-
-       wprintf("<tr bgcolor=\"#%s\"><th colspan = 4>%s</th></tr>", 
-               (odd ? "DDDDDD" : "FFFFFF"),  SectionName);
-}
 
+               Entry = (FileListStruct*) malloc(sizeof (FileListStruct));
+               Entry->Filename = NewStrBufPlain(NULL, StrLength(Buf));
+               Entry->MimeType = NewStrBufPlain(NULL, StrLength(Buf));
+               Entry->Comment = NewStrBufPlain(NULL, StrLength(Buf));
 
-void display_room_directory(void)
-{
-       char title[256];
-       int havepics = 0;
-       HashList *Files;
-       int Order;
-       int SortRow;
-       int i;
-
-       long SortDirections[5] = {2,2,2,2,2};
-       const char* SortIcons[3] = {
-               "static/up_pointer.gif",
-               "static/down_pointer.gif",
-               "static/sort_none.gif"};
-       char *RowNames[5];
-       RowNames[0] = "";
-       RowNames[1] = _("Filename");
-       RowNames[2] = _("Size");
-       RowNames[3] = _("Content");
-       RowNames[4] = _("Description");
-
-       Files = LoadFileList (&havepics);
-       output_headers(1, 1, 2, 0, 0, 0);
-       wprintf("<div id=\"banner\">\n");
-       wprintf("<h1>");
-       snprintf(title, sizeof title, _("Files available for download in %s"), WC->wc_roomname);
-       escputs(title);
-       wprintf("</h1>");
-       wprintf("</div>\n");
-
-       wprintf("<div id=\"content\" class=\"service\">\n");
-
-       wprintf("<div class=\"fix_scrollbar_bug\">"
-               "<table class=\"downloads_background\"><tr><td>\n");
-
-
-       Order = ibstr("SortOrder");
-       if (!havebstr("SortOrder") || Order > 2)
-               Order = 2; /* <- Unsorted... */
-       SortRow = ibstr("SortBy");
-
-       SortDirections[SortRow] = Order;
-
-       wprintf("<tr>\n");
-       for (i = 1; i < 5; i++) {
-               switch (SortDirections[i]) {
-               default:
-               case 0:
-                       Order = 2;
-                       break;
-               case 1:
-                       Order = 0;
-                       break;
-               case 2:
-                       Order = 1;
-                       break;
-               }                       
-
-               wprintf("  <th>%s \n"
-                       "      <a href=\"display_room_directory?SortOrder=%d&SortBy=%d\"> \n"
-                       "       <img src=\"%s\" border=\"0\"></a>\n"
-                       "  </th>\n",
-                       RowNames[i],
-                       Order, i,
-                       SortIcons[SortDirections[i]]
-                       );
+               Entry->Sequence = sequence++;
 
-       }
-       wprintf("</tr>\n");
-//<th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n",
-       //);
+               StrBufExtract_token(Entry->Filename, Buf, 0, '|');
+               Entry->FileSize = StrBufExtract_long(Buf, 1, '|');
+               StrBufExtract_token(Entry->MimeType, Buf, 2, '|');
+               StrBufExtract_token(Entry->Comment, Buf, 3, '|');
 
-       if (Files != NULL) {
-               PrintHash(Files, FilePrintTransition, FilePrintEntry);
-               DeleteHash(&Files);
-       }
-       wprintf("</table>\n");
 
-       /** Now offer the ability to upload files... */
-       if (WC->room_flags & QR_UPLOAD)
-       {
-               wprintf("<hr>");
-               wprintf("<form "
-                       "enctype=\"multipart/form-data\" "
-                       "method=\"POST\" "
-                       "accept-charset=\"UTF-8\" "
-                       "action=\"upload_file\" "
-                       "name=\"upload_file_form\""
-                       ">\n"
-               );
-               wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
-
-               wprintf(_("Upload a file:"));
-               wprintf("&nbsp;<input NAME=\"filename\" SIZE=16 TYPE=\"file\">&nbsp;\n");
-               wprintf(_("Description:"));
-               wprintf("&nbsp;<input type=\"text\" name=\"description\" maxlength=\"64\" size=\"64\">&nbsp;");
-               wprintf("<input type=\"submit\" name=\"attach_button\" value=\"%s\">\n", _("Upload"));
-
-               wprintf("</form>\n");
-       }
 
-       wprintf("</div>\n");
-       if (havepics)
-               wprintf("<div class=\"buttons\"><a href=\"display_pictureview&frame=1\">%s</a></div>", _("Slideshow"));
-       wDumpContent(1);
-}
-
-
-void display_pictureview(void)
-{
-       char buf[1024];
-       char filename[256];
-       char filesize[256];
-       char mimetype[64];
-       char comment[512];
-       char title[256];
-       int n = 0;
-               
-
-       if (lbstr("frame") == 1) {
-
-               output_headers(1, 1, 2, 0, 0, 0);
-               wprintf("<div id=\"banner\">\n");
-               wprintf("<h1>");
-               snprintf(title, sizeof title, _("Pictures in %s"), WC->wc_roomname);
-               escputs(title);
-               wprintf("</h1>");
-               wprintf("</div>\n");
-               
-               wprintf("<div id=\"content\" class=\"service\">\n");
-
-               wprintf("<div class=\"fix_scrollbar_bug\">"
-                       "<table class=\"downloads_background\"><tr><td>\n");
-
-
-
-               wprintf("<script type=\"text/javascript\" language=\"JavaScript\" > \nvar fadeimages=new Array()\n");
-
-               serv_puts("RDIR");
-               serv_getln(buf, sizeof buf);
-               if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000"))  {
-                               extract_token(filename, buf, 0, '|', sizeof filename);
-                               extract_token(filesize, buf, 1, '|', sizeof filesize);
-                               extract_token(mimetype, buf, 2, '|', sizeof mimetype);
-                               extract_token(comment,  buf, 3, '|', sizeof comment);
-                               if (strstr(mimetype, "image") != NULL) {
-                                       wprintf("fadeimages[%d]=[\"download_file/", n);
-                                       escputs(filename);
-                                       wprintf("\", \"\", \"\"]\n");
-
-                                       /*
-                                                          //mimetype);
-                                          escputs(filename);   wprintf("</a></td>");
-                                          wprintf("<td>");     escputs(filesize);      wprintf("</td>");
-                                          wprintf("<td>");     escputs(mimetype);      wprintf("</td>");
-                                          wprintf("<td>");     escputs(comment);       wprintf("</td>");
-                                          wprintf("</tr>\n");
-                                       */
-                                       n++;
-                               }
-                       }
-               wprintf("</script>\n");
-               wprintf("<tr><td><script type=\"text/javascript\" src=\"static/fadeshow.js\">\n</script>\n");
-               wprintf("<script type=\"text/javascript\" >\n");
-               wprintf("new fadeshow(fadeimages, 500, 400, 0, 3000, 1, \"R\");\n");
-               wprintf("</script></td><th>\n");
-               wprintf("</div>\n");
+               Entry->IsPic = (strstr(ChrPtr(Entry->MimeType), "image") != NULL);
+               if (Entry->IsPic) {
+                       HavePic = 1;
+               }
+               Put(Files, SKEY(Entry->Filename), Entry, FreeFiles);
        }
-       wDumpContent(1);
-
-
+       SortIt = RetrieveSort(CTX_FILELIST, NULL, HKEY("fileunsorted"), 0);
+       if (SortIt != NULL)
+               SortByPayload(Files, SortIt);
+       else 
+               SortByPayload(Files, CompareFilelistBySequence);
+       FreeStrBuf(&Buf);
+       svputlong("FILE:HAVEPICS", HavePic);
+       return Files;
 }
 
-extern char* static_dirs[];
 void display_mime_icon(void)
 {
        char FileBuf[SIZ];
@@ -379,7 +233,6 @@ void display_mime_icon(void)
        else
                snprintf (FileBuf, SIZ, "%s%s", static_dirs[3], FileName);
        output_static(FileBuf);
-
 }
 
 void download_file(void)
@@ -418,7 +271,6 @@ void download_file(void)
                wprintf(_("An error occurred while retrieving this file: %s\n"), &buf[4]);
                end_burst();
        }
-
 }
 
 
@@ -437,7 +289,7 @@ void upload_file(void)
        if (buf[0] != '2')
        {
                strcpy(WCC->ImportantMessage, &buf[4]);
-               display_room_directory();
+               do_template("files", NULL);
                return;
        }
 
@@ -461,7 +313,7 @@ void upload_file(void)
        serv_puts("UCLS 1");
        serv_getln(buf, sizeof buf);
        strcpy(WCC->ImportantMessage, &buf[4]);
-       display_room_directory();
+       do_template("files", CTX_NONE);
 }
 
 
@@ -470,7 +322,7 @@ void upload_file(void)
  * When the browser requests an image file from the Citadel server,
  * this function is called to transmit it.
  */
-void output_image()
+void output_image(void)
 {
        char blank_gif[SIZ];
        wcsession *WCC = WC;
@@ -509,18 +361,55 @@ void output_image()
        output_static(blank_gif);
 }
 
-
-
-
 void 
 InitModule_DOWNLOAD
 (void)
 {
+
+       RegisterIterator("ROOM:FILES", 0, NULL, LoadFileList,
+                        NULL,NULL, CTX_FILELIST, CTX_NONE, 
+                        IT_FLAG_DETECT_GROUPCHANGE);
+
+       RegisterSortFunc(HKEY("filemime"),
+                        NULL, 0,
+                        CompareFilelistByMime,
+                        CompareFilelistByMimeRev,
+                        GroupchangeFilelistByMime,
+                        CTX_FILELIST);
+       RegisterSortFunc(HKEY("filename"),
+                        NULL, 0,
+                        CompareFilelistByName,
+                        CompareFilelistByNameRev,
+                        GroupchangeFilelistByName,
+                        CTX_FILELIST);
+       RegisterSortFunc(HKEY("filesize"),
+                        NULL, 0,
+                        CompareFilelistBySize,
+                        CompareFilelistBySizeRev,
+                        GroupchangeFilelistBySize,
+                        CTX_FILELIST);
+       RegisterSortFunc(HKEY("filesubject"),
+                        NULL, 0,
+                        CompareFilelistByComment,
+                        CompareFilelistByCommentRev,
+                        GroupchangeFilelistByComment,
+                        CTX_FILELIST);
+       RegisterSortFunc(HKEY("fileunsorted"),
+                        NULL, 0,
+                        CompareFilelistBySequence,
+                        CompareFilelistBySequence,
+                        GroupchangeFilelistBySequence,
+                        CTX_FILELIST);
+
+       RegisterNamespace("FILE:NAME", 0, 2, tmplput_FILE_NAME, CTX_FILELIST);
+       RegisterNamespace("FILE:SIZE", 0, 1, tmplput_FILE_SIZE, CTX_FILELIST);
+       RegisterNamespace("FILE:MIMETYPE", 0, 2, tmplput_FILEMIMETYPE, CTX_FILELIST);
+       RegisterNamespace("FILE:COMMENT", 0, 2, tmplput_FILE_COMMENT, CTX_FILELIST);
+
+       RegisterConditional(HKEY("COND:FILE:ISPIC"), 0, Conditional_FILE_ISPIC, CTX_FILELIST);
+
        WebcitAddUrlHandler(HKEY("image"), output_image, 0);
        WebcitAddUrlHandler(HKEY("display_mime_icon"), display_mime_icon , 0);
-
-       WebcitAddUrlHandler(HKEY("display_room_directory"), display_room_directory, 0);
-       WebcitAddUrlHandler(HKEY("display_pictureview"), display_pictureview, 0);
        WebcitAddUrlHandler(HKEY("download_file"), download_file, NEED_URL);
        WebcitAddUrlHandler(HKEY("upload_file"), upload_file, 0);
 }
index f50a045bdafb164077e3234a8f99e471b9b45207..97820b7ab6473208726daee9f53405b6bd5e9826 100644 (file)
@@ -207,6 +207,6 @@ InitModule_INETCONF
 (void)
 {
        WebcitAddUrlHandler(HKEY("save_inetconf"), new_save_inetconf, AJAX);
-       RegisterIterator("SERVCFG:INET", 1, NULL, GetInetConfHash, InetCfgSubst, NULL, CTX_INETCFG, CTX_NONE);
+       RegisterIterator("SERVCFG:INET", 1, NULL, GetInetConfHash, InetCfgSubst, NULL, CTX_INETCFG, CTX_NONE, IT_NOFLAG);
        RegisterNamespace("SERVCFG:FLUSHINETCFG",0, 0, DeleteInetConfHash, CTX_NONE);
 }
index abf6b55e4d834d863da3c94fbb8b84cd699d85ab..6ac25d56af629fd33fd4155bf74e1c6fec5b0da7 100644 (file)
@@ -124,6 +124,17 @@ int summcmp_rsubj(const void *s1, const void *s2) {
        summ2 = (message_summary *)GetSearchPayload(s2);
        return strcasecmp(ChrPtr(summ2->subj), ChrPtr(summ1->subj));
 }
+/*
+ * comparator for message summary structs by descending subject.
+ */
+int groupchange_subj(const void *s1, const void *s2) {
+       message_summary *summ1;
+       message_summary *summ2;
+       
+       summ1 = (message_summary *)s1;
+       summ2 = (message_summary *)s2;
+       return ChrPtr(summ2->subj)[0] != ChrPtr(summ1->subj)[0];
+}
 
 /*
  * comparator for message summary structs by ascending sender.
@@ -148,6 +159,18 @@ int summcmp_rsender(const void *s1, const void *s2) {
        summ2 = (message_summary *)GetSearchPayload(s2);
        return strcasecmp(ChrPtr(summ2->from), ChrPtr(summ1->from));
 }
+/*
+ * comparator for message summary structs by descending sender.
+ */
+int groupchange_sender(const void *s1, const void *s2) {
+       message_summary *summ1;
+       message_summary *summ2;
+       
+       summ1 = (message_summary *)s1;
+       summ2 = (message_summary *)s2;
+       return strcasecmp(ChrPtr(summ2->from), ChrPtr(summ1->from)) != 0;
+
+}
 
 /*
  * comparator for message summary structs by ascending date.
@@ -179,6 +202,21 @@ int summcmp_rdate(const void *s1, const void *s2) {
        else return 0;
 }
 
+/*
+ * comparator for message summary structs by descending date.
+ */
+const long DAYSECONDS = 24 * 60 * 60;
+int groupchange_date(const void *s1, const void *s2) {
+       message_summary *summ1;
+       message_summary *summ2;
+       
+       summ1 = (message_summary *)s1;
+       summ2 = (message_summary *)s2;
+
+       return (summ1->date % DAYSECONDS) != (summ2->date %DAYSECONDS);
+}
+
+
 /*----------------------------------------------------------------------------*/
 /* Don't wanna know... or? */
 void examine_pref(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset) {return;}
@@ -1012,21 +1050,24 @@ InitModule_MSGRENDERERS
                         NULL, 0,
                         summcmp_date,
                         summcmp_rdate,
+                        groupchange_date,
                         CTX_MAILSUM);
        RegisterSortFunc(HKEY("subject"), 
                         NULL, 0,
                         summcmp_subj,
                         summcmp_rsubj,
+                        groupchange_subj,
                         CTX_MAILSUM);
        RegisterSortFunc(HKEY("sender"),
                         NULL, 0,
                         summcmp_sender,
                         summcmp_rsender,
+                        groupchange_sender,
                         CTX_MAILSUM);
 
        /* iterate over all known mails in WC->summ */
        RegisterIterator("MAIL:SUMM:MSGS", 0, NULL, iterate_get_mailsumm_All,
-                        NULL,NULL, CTX_MAILSUM, CTX_NONE);
+                        NULL,NULL, CTX_MAILSUM, CTX_NONE, IT_NOFLAG);
 
        /* render parts of the message struct */
        RegisterNamespace("MAIL:SUMM:DATESTR", 0, 0, tmplput_MAIL_SUMM_DATE_STR, CTX_MAILSUM);
@@ -1060,13 +1101,13 @@ InitModule_MSGRENDERERS
        RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:LINKS"), 0, Conditional_MAIL_MIME_ATTACHLINKS, CTX_MAILSUM);
        RegisterConditional(HKEY("COND:MAIL:MIME:ATTACH:ATT"), 0, Conditional_MAIL_MIME_ATTACH, CTX_MAILSUM);
        RegisterIterator("MAIL:MIME:ATTACH", 0, NULL, iterate_get_mime_All, 
-                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
        RegisterIterator("MAIL:MIME:ATTACH:SUBMESSAGES", 0, NULL, iterate_get_mime_Submessages, 
-                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
        RegisterIterator("MAIL:MIME:ATTACH:LINKS", 0, NULL, iterate_get_mime_AttachLinks, 
-                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
        RegisterIterator("MAIL:MIME:ATTACH:ATT", 0, NULL, iterate_get_mime_Attachments, 
-                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM);
+                        NULL, NULL, CTX_MIME_ATACH, CTX_MAILSUM, IT_NOFLAG);
 
        /* Parts of a mime attachent */
        RegisterNamespace("MAIL:MIME:NAME", 0, 2, tmplput_MIME_Name, CTX_MIME_ATACH);
@@ -1083,7 +1124,7 @@ InitModule_MSGRENDERERS
 
        /* iterate the WC->attachments; use the above tokens for their contents */
        RegisterIterator("MSG:ATTACHNAMES", 0, NULL, iterate_get_registered_Attachments, 
-                        NULL, NULL, CTX_MIME_ATACH, CTX_NONE);
+                        NULL, NULL, CTX_MIME_ATACH, CTX_NONE, IT_NOFLAG);
 
        /* mime renderers translate an attachment into webcit viewable html text */
        RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL);
index d95c6ea5e15fdbd252702553748d079c075571d6..456b7f6c7340bdf601435685aa32e5b54ed296c9 100644 (file)
@@ -282,6 +282,6 @@ InitModule_NETCONF
        WebcitAddUrlHandler(HKEY("display_netconf"), display_netconf, 0);
        WebcitAddUrlHandler(HKEY("display_confirm_delete_node"), display_confirm_delete_node, 0);
        WebcitAddUrlHandler(HKEY("delete_node"), delete_node, 0);
-       RegisterIterator("NODECONFIG", 0, NULL, load_netconf, NodeCfgSubst, DeleteHash, CTX_NODECONF, CTX_NONE);
+       RegisterIterator("NODECONFIG", 0, NULL, load_netconf, NodeCfgSubst, DeleteHash, CTX_NODECONF, CTX_NONE, IT_NOFLAG);
 }
 /*@}*/
index b66a3bd383536baff970c2289aecc72a67ec49e0..a2efb4402b65b9359cfa21e287804169ce1c952a 100644 (file)
@@ -606,15 +606,15 @@ InitModule_PREFERENCES
        
        RegisterNamespace("PREF:VALUE", 1, 2, tmplput_CFG_Value, CTX_NONE);
        RegisterNamespace("PREF:DESCR", 1, 1, tmplput_CFG_Descr, CTX_NONE);
-       RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE);
+       RegisterIterator("PREF:ZONE", 0, ZoneHash, NULL, CfgZoneTempl, NULL, CTX_PREF, CTX_NONE, IT_NOFLAG);
 
        RegisterConditional(HKEY("COND:PREF"), 4, ConditionalPreference, CTX_NONE);
        RegisterConditional(HKEY("COND:PREF:SET"), 4, ConditionalHazePreference, CTX_NONE);
        
        RegisterIterator("PREF:VALID:EMAIL:ADDR", 0, NULL, 
-                        GetGVEAHash, NULL, DeleteGVEAHash, CTX_STRBUF, CTX_NONE);
+                        GetGVEAHash, NULL, DeleteGVEAHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
        RegisterIterator("PREF:VALID:EMAIL:NAME", 0, NULL, 
-                        GetGVSNHash, NULL, DeleteGVSNHash, CTX_STRBUF, CTX_NONE);
+                        GetGVSNHash, NULL, DeleteGVSNHash, CTX_STRBUF, CTX_NONE, IT_NOFLAG);
 
 }
 /*@}*/
index d4e06bed52e2fd450b583fd39c24d341369fc226..3346d83ba2061de9ead1acf3b96f2a6946d1f86e 100644 (file)
@@ -30,10 +30,10 @@ void display_pushemail(void) {
                serv_printf("MSG0 %d", msgnum);
                serv_getln(buf, sizeof buf);
                if (buf[0] == '1') {
+                       int i =0;
                        while (serv_getln(buf, sizeof buf),
                                (strcmp(buf, "text") && strcmp(buf, "000"))) {
                        }
-                       int i =0;
                        if (!strcmp(buf, "text")) {
                                while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) { 
                                        if (strncasecmp(buf, "none", 4) == 0) {
@@ -64,7 +64,7 @@ void display_pushemail(void) {
        }
        output_headers(1, 1, 2, 0, 0, 0);
        do_template("pushemail", NULL);
-//do_template("endbox");
+/*do_template("endbox"); */
        wDumpContent(1);
 }
 
index 4c47999e4b85a2ac08a28491f2bfb2c218701617..1e20e12a168715079b037d8e906a2b8a824c8e2f 100644 (file)
@@ -489,7 +489,7 @@ void embed_room_banner(char *got, int navbar_style) {
                if (buf2[0] == '1') while (serv_getln(buf2, sizeof buf2), strcmp(buf2, "000"))
                        file_count++;
                snprintf (with_files, sizeof with_files, 
-                         "; <a href=\"display_room_directory\"> %d %s </a>", 
+                         "; <a href=\"do_template?template=files\"> %d %s </a>", 
                          file_count, 
                          ((file_count>1) || (file_count == 0)  ? _("files") : _("file")));
        }
diff --git a/webcit/static/t/files.html b/webcit/static/t/files.html
new file mode 100644 (file)
index 0000000..a4aecba
--- /dev/null
@@ -0,0 +1,50 @@
+<?=("head")>
+<?=("important_msg")>
+<?ICONBAR>
+<div id="banner"><h1><?_("Files available for download in")> <?ROOMNAME></h1></div>
+
+<script language="javascript" type="text/javascript">
+  document.onkeydown = CtdlMsgListKeyPress;
+  if (document.layers) {
+       document.captureEvents(Event.KEYPRESS);
+  }
+</script>
+
+<div id="content" class="service">
+
+<div class="fix_scrollbar_bug">
+
+<table class="downloads_background">
+<tr>
+  <th><?_("Filename")>&nbsp;<a href="do_template?template=files&SortOrder=<?SORT:ORDER("filename")>&SortBy=<?SORT:NEXT("filename")>"><img border="0" src="<?SORT:ICON("filename")>" /></a> </th>
+  <th><?_("Size")>&nbsp;<a href="do_template?template=files&SortOrder=<?SORT:ORDER("filesize")>&SortBy=<?SORT:NEXT("filesize")>"><img border="0" src="<?SORT:ICON("filesize")>" /></a> </th>
+  <th><?_("Content")>&nbsp;<a href="do_template?template=files&SortOrder=<?SORT:ORDER("filemime")>&SortBy=<?SORT:NEXT("filemime")>"><img border="0" src="<?SORT:ICON("filemime")>" /></a> </th>
+  <th><?_("Description")>&nbsp;<a href="do_template?template=files&SortOrder=<?SORT:ORDER("filesubject")>&SortBy=<?SORT:NEXT("filesubject")>"><img border="0" src="<?SORT:ICON("filesubject")>" /></a> </th>
+</tr>
+<?ITERATE("ROOM:FILES", "section_files_onefile")>
+
+
+
+
+
+
+
+<??("COND:ROOM:FLAGS:QR_UPLOAD", 2)>
+<hr>
+<form enctype="multipart/form-data" method="POST" accept-charset="UTF-8" action="upload_file" name="upload_file_form">
+<input type="hidden" name="nonce" value="<?NONCE>">
+<?_("Upload a file:")>
+&nbsp;
+<input NAME="filename" SIZE=16 TYPE="file">&nbsp;
+<?_("Description:")>&nbsp;
+<input type="text" name="description" maxlength="64" size="64">&nbsp;
+<input type="submit" name="attach_button" value="<?_("Upload")>">
+</form>
+</div>
+<??("X", 1)>
+
+
+</div>
+
+
+<?=("trailing")>
diff --git a/webcit/static/t/files_jspicview.html b/webcit/static/t/files_jspicview.html
new file mode 100644 (file)
index 0000000..72ecb6e
--- /dev/null
@@ -0,0 +1,22 @@
+<??("COND:BSTR", 1, "frame")>
+<?=("head")>
+<?=("important_msg")>
+<?ICONBAR>
+<div id="banner">
+<h1>
+<?_("Pictures in")><?ROOM:NAME>
+</h1>
+</div>
+<div id="content" class="service">
+<div class="fix_scrollbar_bug">
+<table class="downloads_background"><tr><td>
+<script type="text/javascript" language="JavaScript" > nvar fadeimages=new Array()
+<?ITERATE("ROOM:FILES", "seciton_files_onefile_picview")>
+</script>
+<tr><td><script type="text/javascript" src="static/fadeshow.js">
+</script>
+<script type="text/javascript" >
+new fadeshow(fadeimages, 500, 400, 0, 3000, 1, "R");
+</script></td><th>
+</div>
+<?=("trailing")>
index 79efe1372ee949fd5fe9ca42fc41c5e2e7201fe7..7dcf179ca8195bbf2b847cb52eee127075f0ee2e 100644 (file)
@@ -10,7 +10,7 @@
 <li><a href="readnew"><?_("Read new messages")></a><span><?_("...in this room")></span></li>
 <li><a href="readfwd"><?_("Read all messages")></a><span><?_("...old <EM>and</EM> new")></span></li>
 <li><a href="display_enter"><?_("Enter a message")></a><span><?_("(post in this room)")></span></li>
-<??("COND:ROOM:FLAGS:QR_VISIDIR", 2)><li><a href="display_room_directory"><?_("File library")></a><span><?_("(List files available for download)")></span></li><??("X", 2)>
+<??("COND:ROOM:FLAGS:QR_VISIDIR", 2)><li><a href="do_template?template=files"><?_("File library")></a><span><?_("(List files available for download)")></span></li><??("X", 2)>
 </ul>
 <!-- start of third column -->
 <ul class="adminitems lastcol">
diff --git a/webcit/static/t/section_files_onefile.html b/webcit/static/t/section_files_onefile.html
new file mode 100644 (file)
index 0000000..76d0521
--- /dev/null
@@ -0,0 +1,21 @@
+<?!("COND:SUBST", 1, "ITERATE:ISGROUPCHANGE", 1)><?!("COND:BSTR", 2, "SortOrder", "filename")>
+<tr class="<?ITERATE:ODDEVEN>"><th colspan = 4><?FILE:NAME("U", 1)></th></tr>
+<?!("X", 2)><?!("X", 1)>
+
+<tr class="<?ITERATE:ODDEVEN>">
+<td>
+ <a href="download_file/<?FILE:NAME("U")>">
+  <img src="display_mime_icon?type=<?FILE:MIMETYPE>" border=0 align=middle>
+  <?FILE:NAME></a>
+</td>
+<td><?FILE:SIZE></td>
+<td><?FILE:MIMETYPE></td>
+<td><?FILE:COMMENT("X")></td>
+</tr>
+
+<?!("COND:SUBST", 2, "ITERATE:LASTN", 1)>
+</table>
+<??("COND:FILE:ISPIC", 3)>
+<div class="buttons"><a href="do_template?template=files_jspicview&frame=1"><?_("Slideshow")></a></div>
+<??("X", 3)>
+<?!("X", 2)>
diff --git a/webcit/static/t/section_files_onefile_picview.html b/webcit/static/t/section_files_onefile_picview.html
new file mode 100644 (file)
index 0000000..f56e409
--- /dev/null
@@ -0,0 +1,3 @@
+<??("COND:FILE:ISPIC", 2)>
+fadeimages[<?ITERATE:N>]=["download_file/<?FILE:NAME("X")>"]
+<??("X", 2)>
index ac0dd07874475cebb21101103975a623f39bb818..e5adac22356bfa3108d74bbeda44ce8c55007ffd 100644 (file)
@@ -59,6 +59,25 @@ typedef struct _HashHandler {
 void *load_template(StrBuf *filename, StrBuf *Key, HashList *PutThere);
 int EvaluateConditional(StrBuf *Target, WCTemplateToken *Tokens, WCTemplate *pTmpl, void *Context, int Neg, int state, int ContextType);
 
+typedef struct _SortStruct {
+       StrBuf *Name;
+       StrBuf *PrefPrepend;
+       CompareFunc Forward;
+       CompareFunc Reverse;
+       CompareFunc GroupChange;
+
+       long ContextType;
+}SortStruct;
+
+void DestroySortStruct(void *vSort)
+{
+       SortStruct *Sort = (SortStruct*) vSort;
+       FreeStrBuf(&Sort->Name);
+       FreeStrBuf(&Sort->PrefPrepend);
+       free (Sort);
+}
+
+
 void RegisterNS(const char *NSName, 
                long len, 
                int nMinArgs, 
@@ -1450,6 +1469,7 @@ typedef struct _HashIterator {
        int AdditionalParams;
        int ContextType;
        int XPectContextType;
+       int Flags;
        RetrieveHashlistFunc GetHash;
        HashDestructorFunc Destructor;
        SubTemplFunc DoSubTemplate;
@@ -1462,7 +1482,8 @@ void RegisterITERATOR(const char *Name, long len,
                      SubTemplFunc DoSubTempl,
                      HashDestructorFunc Destructor,
                      int ContextType, 
-                     int XPectContextType)
+                     int XPectContextType, 
+                     int Flags)
 {
        HashIterator *It = (HashIterator*)malloc(sizeof(HashIterator));
        It->StaticList = StaticList;
@@ -1472,6 +1493,7 @@ void RegisterITERATOR(const char *Name, long len,
        It->Destructor = Destructor;
        It->ContextType = ContextType;
        It->XPectContextType = XPectContextType;
+       It->Flags = Flags;
        Put(Iterators, Name, len, It, NULL);
 }
 
@@ -1481,11 +1503,15 @@ void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, vo
        HashIterator *It;
        HashList *List;
        HashPos  *it;
+       SortStruct *SortBy;
+       void *vSortBy;
+       int DetectGroupChange = 0;
        int nMembersUsed;
        int nMembersCounted = 0;
        long len; 
        const char *Key;
        void *vContext;
+       void *vLastContext;
        StrBuf *SubBuf;
        int oddeven = 0;
        
@@ -1558,10 +1584,35 @@ void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, vo
        else
                List = It->StaticList;
 
+       DetectGroupChange = (It->Flags & IT_FLAG_DETECT_GROUPCHANGE) != 0;
+       if (DetectGroupChange) {
+               const StrBuf *BSort;
+               DetectGroupChange = 0;
+               if (havebstr("SortBy")) {
+                       BSort = sbstr("SortBy");
+                       if (GetHash(SortHash, SKEY(BSort), &vSortBy) &&
+                           (vSortBy != NULL)) {
+                               SortBy = (SortStruct*)vSortBy;
+                               /** Ok, its us, lets see in which direction we should sort... */
+                               if (havebstr("SortOrder")) {
+                                       int SortOrder;
+                                       SortOrder = LBSTR("SortOrder");
+                                       if (SortOrder != 0)
+                                               DetectGroupChange = 1;
+                               }
+                       }
+               }
+       }
        nMembersUsed = GetCount(List);
        SubBuf = NewStrBuf();
        it = GetNewHashPos(List, 0);
        while (GetNextHashPos(List, it, &len, &Key, &vContext)) {
+               if (DetectGroupChange && nMembersCounted > 0) {
+                       if (SortBy->GroupChange(vContext, vLastContext))
+                               svputlong("ITERATE:ISGROUPCHANGE", 1);                  
+                       else
+                               svputlong("ITERATE:ISGROUPCHANGE", 0);
+               }
                svprintf(HKEY("ITERATE:ODDEVEN"), WCS_STRING, "%s", 
                         (oddeven) ? "odd" : "even");
                svprintf(HKEY("ITERATE:KEY"), WCS_STRING, "%s", Key);
@@ -1575,6 +1626,7 @@ void tmpl_iterate_subtmpl(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, vo
                StrBufAppendBuf(Target, SubBuf, 0);
                FlushStrBuf(SubBuf);
                oddeven = ~ oddeven;
+               vLastContext = vContext;
        }
        FreeStrBuf(&SubBuf);
        DeleteHashPos(&it);
@@ -1761,27 +1813,12 @@ void tmpl_do_tabbed(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Co
  *                      Sorting-API
  */
 
-typedef struct _SortStruct {
-       StrBuf *Name;
-       StrBuf *PrefPrepend;
-       CompareFunc Forward;
-       CompareFunc Reverse;
-
-       long ContextType;
-}SortStruct;
-
-void DestroySortStruct(void *vSort)
-{
-       SortStruct *Sort = (SortStruct*) vSort;
-       FreeStrBuf(&Sort->Name);
-       FreeStrBuf(&Sort->PrefPrepend);
-       free (Sort);
-}
 
 void RegisterSortFunc(const char *name, long len, 
                      const char *prepend, long preplen,
                      CompareFunc Forward, 
                      CompareFunc Reverse, 
+                     CompareFunc GroupChange, 
                      long ContextType)
 {
        SortStruct *NewSort = (SortStruct*) malloc(sizeof(SortStruct));
@@ -1792,6 +1829,7 @@ void RegisterSortFunc(const char *name, long len,
                NewSort->PrefPrepend = NULL;
        NewSort->Forward = Forward;
        NewSort->Reverse = Reverse;
+       NewSort->GroupChange = GroupChange;
        NewSort->ContextType = ContextType;
        Put(SortHash, name, len, NewSort, DestroySortStruct);
 }
index 58eaa797b4abbc714248e346a79d8a406aa22397..bffa39d20a9bd1b9a9b02405b6ab8a4b8f841d0c 100644 (file)
@@ -85,6 +85,7 @@ typedef struct _wcsubst {
 #define CTX_USERLIST 8
 #define CTX_MAILSUM 9
 #define CTX_MIME_ATACH 10
+#define CTX_FILELIST 11
 #define CTX_STRBUF 12
 #define CTX_LONGVECTOR 13
 
@@ -120,8 +121,13 @@ void RegisterITERATOR(const char *Name, long len, /* Our identifier */
                      SubTemplFunc DoSubTempl,       /* call this function on each iteration for svput & friends */
                      HashDestructorFunc Destructor, /* use this function to shut down the hash; NULL if its a reference */
                      int ContextType,               /* which context do we provide to the subtemplate? */
-                     int XPectContextType);         /* which context do we expct to be called in? */
-#define RegisterIterator(a, b, c, d, e, f, g, h) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f, g, h)
+                     int XPectContextType,          /* which context do we expct to be called in? */
+                     int Flags);
+
+#define IT_NOFLAG 0
+#define IT_FLAG_DETECT_GROUPCHANGE (1<<0)
+
+#define RegisterIterator(a, b, c, d, e, f, g, h, i) RegisterITERATOR(a, sizeof(a)-1, b, c, d, e, f, g, h, i)
 
 void GetTemplateTokenString(WCTemplateToken *Tokens,
                            int N, 
@@ -160,6 +166,7 @@ void RegisterSortFunc(const char *name, long len,
                      const char *prepend, long preplen,
                      CompareFunc Forward, 
                      CompareFunc Reverse, 
+                     CompareFunc GroupChange, 
                      long ContextType);
 
 void dbg_print_longvector(long *LongVector);
index 312dc65ab98efba853d4954b0265a70e517e4a50..728580dcd4332ee175ea29f1d40d9d5500ee1ede 100644 (file)
@@ -688,5 +688,5 @@ InitModule_USEREDIT
        RegisterConditional(HKEY("COND:USERACCESS"), 0,   ConditionalUserAccess, CTX_USERLIST);
        RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
 
-       RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE);
+       RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG);
 }
index b4a9771977de1baf7f5d3ad67588e0fcf43255de..2edf9c64a1bb2d77897dbee4821d005f2688383e 100644 (file)
@@ -319,7 +319,7 @@ InitModule_WHO
        WebcitAddUrlHandler(HKEY("terminate_session"), _terminate_session, 0);
        WebcitAddUrlHandler(HKEY("edit_me"), edit_me, 0);
 
-       RegisterIterator("WHOLIST", 0, NULL, GetWholistHash, NULL, DeleteWholistHash, CTX_WHO, CTX_NONE);
+       RegisterIterator("WHOLIST", 0, NULL, GetWholistHash, NULL, DeleteWholistHash, CTX_WHO, CTX_NONE, IT_NOFLAG);
 
        RegisterNamespace("WHO:NAME",        0, 1, tmplput_who_username, CTX_WHO);
        RegisterNamespace("WHO:ROOM",        0, 1, tmplput_who_room, CTX_WHO);