* fix tiny memory leak; hashpos needs to be freed.
[citadel.git] / webcit / iconbar.c
1 /*
2  * $Id$
3  *
4  * Displays and customizes the iconbar.
5  */
6
7 #include "webcit.h"
8
9
10 /** Values for ib_displayas */
11 #define IB_PICTEXT      0 /**< picture and text */
12 #define IB_PICONLY      1 /**< just a picture */
13 #define IB_TEXTONLY     2 /**< just text */
14
15 void DontDeleteThis(void *Data){}
16
17 #define IconbarIsEnabled(a, b) IconbarIsENABLED(a, sizeof(a) - 1, b)
18
19 long IconbarIsENABLED(const char *key, size_t keylen, long defval)
20 {
21         void *Data;
22         if (GetHash(WC->IconBarSettings, key, keylen,
23                     &Data))
24                 return (long) Data;
25         else 
26                 return defval;
27 }
28
29 #ifdef DBG_ICONBAR_HASH
30 static char nbuf[32];
31 inline const char *PrintInt(void *Prefstr)
32 {
33         snprintf(nbuf, sizeof(nbuf), "%ld", (long)Prefstr);
34         return nbuf;
35 }
36 #endif
37
38 /** Produces a stylesheet which hides any iconbar icons the user does not want */
39 void doUserIconStylesheet(void) {
40   HashPos *pos;
41   void *Data;
42   long value;
43   const char *key;
44   long HKLen;
45
46   LoadIconSettings();
47   output_custom_content_header("text/css");
48   hprintf("Cache-Control: private\r\n");
49   
50   begin_burst();
51   pos = GetNewHashPos(WC->IconBarSettings, 0);
52   while(GetNextHashPos(WC->IconBarSettings, pos, &HKLen, &key, &Data)) {
53     value = (long) Data;
54     if (value == 0 
55         && strncasecmp("ib_displayas",key,12) 
56         && strncasecmp("ib_logoff", key, 9)) {
57             /* Don't shoot me for this */
58       wprintf("#%s { display: none !important; }\r\n",key);
59     } else if (!strncasecmp("ib_users",key, 8) && value == 2) {
60       wprintf("#online_users { display: block; !important } \r\n");
61     }
62   }
63   DeleteHashPos(&pos);
64   end_burst();
65 }
66
67 int ConditionalIsActiveStylesheet(StrBuf *Target, WCTemplputParams *TP) {
68   long testFor = TP->Tokens->Params[3]->lvalue;
69   int ib_displayas = IconbarIsEnabled("ib_displayas",IB_PICTEXT);
70   return (testFor == ib_displayas);
71 }
72
73 void LoadIconSettings(void)
74 {
75         wcsession *WCC = WC;
76         StrBuf *iconbar = NULL;
77         StrBuf *buf;
78         StrBuf *key;
79         long val;
80         int i, nTokens;
81
82         buf = NewStrBuf();;
83         key = NewStrBuf();
84         if (WCC->IconBarSettings == NULL)
85                 WCC->IconBarSettings = NewHash(1, NULL);
86         /**
87          * The initialized values of these variables also happen to
88          * specify the default values for users who haven't customized
89          * their iconbars.  These should probably be set in a master
90          * configuration somewhere.
91          */
92
93         if (get_preference("iconbar", &iconbar)) {
94                 nTokens = StrBufNum_tokens(iconbar, ',');
95                 for (i=0; i<nTokens; ++i) {
96                         StrBufExtract_token(buf, iconbar, i, ',');
97                         StrBufExtract_token(key, buf, 0, '=');
98                         val = StrBufExtract_long(buf, 1, '=');
99                         Put(WCC->IconBarSettings, 
100                             ChrPtr(key), StrLength(key),
101                             (void*)val, DontDeleteThis);
102                 }
103         }
104
105 #ifdef DBG_ICONBAR_HASH
106         dbg_PrintHash(WCC->IconBarSetttings, PrintInt, NULL);
107 #endif
108
109         FreeStrBuf(&key);
110         FreeStrBuf(&buf);
111 }
112
113 /**
114  * \brief display a customized version of the iconbar
115  */
116 void display_customize_iconbar(void) {
117         int i;
118         int bar = 0;
119         long val;
120
121         int ib_displayas;
122
123         LoadIconSettings();
124
125         output_headers(1, 1, 2, 0, 0, 0);
126         wprintf("<div id=\"banner\">");
127         wprintf("<h1>");
128         wprintf(_("Customize the icon bar"));
129         wprintf("</h1></div>\n");
130
131         wprintf("<div id=\"content\" class=\"service\">\n");
132
133         wprintf("<div class=\"fix_scrollbar_bug\">");
134
135         wprintf("<form method=\"post\" action=\"commit_iconbar\">\n");
136         wprintf("<input type=\"hidden\" name=\"nonce\" value=\"%d\">\n", WC->nonce);
137
138         wprintf("<table class=\"altern\" >\n");
139         wprintf("<tr><td></td><td colspan=\"2\"><b>");
140         wprintf(_("Display icons as:"));
141         wprintf("</b>");
142         ib_displayas = IconbarIsEnabled("ib_displayas",IB_PICTEXT);
143         for (i=0; i<=2; ++i) {
144                 wprintf("<input type=\"radio\" name=\"ib_displayas\" value=\"%d\"", i);
145                 if (ib_displayas == i) wprintf(" CHECKED");
146                 wprintf(">");
147                 if (i == IB_PICTEXT)    wprintf(_("pictures and text"));
148                 if (i == IB_PICONLY)    wprintf(_("pictures only"));
149                 if (i == IB_TEXTONLY)   wprintf(_("text only"));
150                 wprintf("\n");
151         }
152         wprintf("<br />\n");
153
154         wprintf(_("Select the icons you would like to see displayed "
155                 "in the 'icon bar' menu on the left side of the "
156                 "screen."));
157         wprintf("</td></tr>\n");
158
159         bar = 1 - bar;
160         val = IconbarIsEnabled("ib_logo", 0);
161         wprintf("<tr class=\"%s\"><td>"
162                 "<input type=\"radio\" name=\"ib_logo\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
163                 "<input type=\"radio\" name=\"ib_logo\" value=\"no\" %s> %s <br />"
164                 "</td><td>"
165                 "<img src=\"image&name=hello\" width=\"48\" alt=\"&nbsp;\">"
166                 "</td><td>"
167                 "<b>%s</b><br />"
168                 "%s"
169                 "</td></tr>\n",
170                 (bar ? "even" : "odd"),
171                 (val ? "CHECKED" : ""),_("Yes"),
172                 (!val ? "CHECKED" : ""),_("No"),
173                 _("Site logo"),
174                 _("An icon describing this site")
175         );
176
177         bar = 1 - bar;
178         val = IconbarIsEnabled("ib_summary", 1);
179         wprintf("<tr class=\"%s\"><td>"
180                 "<input type=\"radio\" name=\"ib_summary\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
181                 "<input type=\"radio\" name=\"ib_summary\" value=\"no\" %s> %s <br />"
182                 "</td><td>"
183                 "<img src=\"static/summscreen_48x.gif\" alt=\"&nbsp;\">"
184                 "</td><td>"
185                 "<b>%s</b><br />"
186                 "%s"
187                 "</td></tr>\n",
188                 (bar ? "even" : "odd"),
189                 (val ? "CHECKED" : ""),_("Yes"),
190                 (!val ? "CHECKED" : ""),_("No"),
191                 _("Summary"),
192                 _("Your summary page")
193         );
194
195         bar = 1 - bar;
196         val = IconbarIsEnabled("ib_inbox", 1);
197         wprintf("<tr class=\"%s\"><td>"
198                 "<input type=\"radio\" name=\"ib_inbox\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
199                 "<input type=\"radio\" name=\"ib_inbox\" value=\"no\" %s> %s <br />"
200                 "</td><td>"
201                 "<img src=\"static/privatemess_48x.gif\" alt=\"&nbsp;\">"
202                 "</td><td>"
203                 "<b>%s</b><br />"
204                 "%s"
205                 "</td></tr>\n",
206                 (bar ? "even" : "odd"),
207                 (val ? "CHECKED" : ""),_("Yes"),
208                 (!val ? "CHECKED" : ""),_("No"),
209                 _("Mail (inbox)"),
210                 _("A shortcut to your email Inbox")
211         );
212
213         bar = 1 - bar;
214         val = IconbarIsEnabled("ib_contacts", 1);
215         wprintf("<tr class=\"%s\"><td>"
216                 "<input type=\"radio\" name=\"ib_contacts\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
217                 "<input type=\"radio\" name=\"ib_contacts\" value=\"no\" %s> %s <br />"
218                 "</td><td>"
219                 "<img src=\"static/viewcontacts_48x.gif\" alt=\"&nbsp;\">"
220                 "</td><td>"
221                 "<b>%s</b><br />"
222                 "%s"
223                 "</td></tr>\n",
224                 (bar ? "even" : "odd"),
225                 (val ? "CHECKED" : ""),_("Yes"),
226                 (!val ? "CHECKED" : ""),_("No"),
227                 _("Contacts"),
228                 _("Your personal address book")
229         );
230
231         bar = 1 - bar;
232         val = IconbarIsEnabled("ib_notes", 1);
233         wprintf("<tr class=\"%s\"><td>"
234                 "<input type=\"radio\" name=\"ib_notes\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
235                 "<input type=\"radio\" name=\"ib_notes\" value=\"no\" %s> %s <br />"
236                 "</td><td>"
237                 "<img src=\"static/storenotes_48x.gif\" alt=\"&nbsp;\">"
238                 "</td><td>"
239                 "<b>%s</b><br />"
240                 "%s"
241                 "</td></tr>\n",
242                 (bar ? "even" : "odd"),
243                 (val ? "CHECKED" : ""),_("Yes"),
244                 (!val ? "CHECKED" : ""),_("No"),
245                 _("Notes"),
246                 _("Your personal notes")
247         );
248
249         bar = 1 - bar;
250         val = IconbarIsEnabled("ib_calendar", 1);
251         wprintf("<tr class=\"%s\"><td>"
252                 "<input type=\"radio\" name=\"ib_calendar\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
253                 "<input type=\"radio\" name=\"ib_calendar\" value=\"no\" %s> %s <br />"
254                 "</td><td>"
255                 "<img src=\"static/calarea_48x.gif\" alt=\"&nbsp;\">"
256                 "</td><td>"
257                 "<b>%s</b><br />"
258                 "%s"
259                 "</td></tr>\n",
260                 (bar ? "even" : "odd"),
261                 (val ? "CHECKED" : ""),_("Yes"),
262                 (!val ? "CHECKED" : ""),_("No"),
263                 _("Calendar"),
264                 _("A shortcut to your personal calendar")
265         );
266
267         bar = 1 - bar;
268         val = IconbarIsEnabled("ib_tasks", 1);
269         wprintf("<tr class=\"%s\"><td>"
270                 "<input type=\"radio\" name=\"ib_tasks\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
271                 "<input type=\"radio\" name=\"ib_tasks\" value=\"no\" %s> %s <br />"
272                 "</td><td>"
273                 "<img src=\"static/taskmanag_48x.gif\" alt=\"&nbsp;\">"
274                 "</td><td>"
275                 "<b>%s</b><br />"
276                 "%s"
277                 "</td></tr>\n",
278                 (bar ? "even" : "odd"),
279                 (val ? "CHECKED" : ""),_("Yes"),
280                 (!val ? "CHECKED" : ""),_("No"),
281                 _("Tasks"),
282                 _("A shortcut to your personal task list")
283         );
284
285         bar = 1 - bar;
286         val = IconbarIsEnabled("ib_rooms", 1);
287         wprintf("<tr class=\"%s\"><td>"
288                 "<input type=\"radio\" name=\"ib_rooms\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
289                 "<input type=\"radio\" name=\"ib_rooms\" value=\"no\" %s> %s <br />"
290                 "</td><td>"
291                 "<img src=\"static/chatrooms_48x.gif\" alt=\"&nbsp;\">"
292                 "</td><td>"
293                 "<b>%s</b><br />"
294                 "%s"
295                 "</td></tr>\n",
296                 (bar ? "even" : "odd"),
297                 (val ? "CHECKED" : ""),_("Yes"),
298                 (!val ? "CHECKED" : ""),_("No"),
299                 _("Rooms"),
300                 _("Clicking this icon displays a list of all accessible "
301                 "rooms (or folders) available.")
302         );
303
304         bar = 1 - bar;
305         val = IconbarIsEnabled("ib_users", 1);
306         wprintf("<tr class=\"%s\"><td>"
307                 "<input type=\"radio\" name=\"ib_users\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
308                 "<input type=\"radio\" name=\"ib_users\" value=\"no\" %s> %s <br />"
309                 "<input type=\"radio\" name=\"ib_users\" value=\"yeslist\" %s> %s"
310                 "</td><td>"
311                 "<img src=\"static/usermanag_48x.gif\" alt=\"&nbsp;\">"
312                 "</td><td>"
313                 "<b>%s</b>"
314                 "<br />%s"
315                 "</td></tr>\n",
316                 (bar ? "even" : "odd"),
317                 (val ? "CHECKED" : ""),_("Yes"),
318                 (!val ? "CHECKED" : ""),_("No"),
319                 ((val > 1) ? "CHECKED" : ""),_("Yes with users list"),
320                 _("Who is online?"),
321                 _("Clicking this icon displays a list of all users "
322                 "currently logged in.")
323         );
324
325         bar = 1 - bar;
326         val = IconbarIsEnabled("ib_chat", 1);
327         wprintf("<tr class=\"%s\"><td>"
328                 "<input type=\"radio\" name=\"ib_chat\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
329                 "<input type=\"radio\" name=\"ib_chat\" value=\"no\" %s> %s <br />"
330                 "</td><td>"
331                 "<img src=\"static/citadelchat_48x.gif\" alt=\"&nbsp;\">"
332                 "</td><td>"
333                 "<b>%s</b><br />"
334                 "%s"
335                 "</td></tr>\n",
336                 (bar ? "even" : "odd"),
337                 (val ? "CHECKED" : ""),_("Yes"),
338                 (!val ? "CHECKED" : ""),_("No"),
339                 _("Chat"),
340                 _("Clicking this icon enters real-time chat mode "
341                 "with other users in the same room.")
342                 
343         );
344
345         bar = 1 - bar;
346         val = IconbarIsEnabled("ib_advanced", 1);
347         wprintf("<tr class=\"%s\"><td>"
348                 "<input type=\"radio\" name=\"ib_advanced\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
349                 "<input type=\"radio\" name=\"ib_advanced\" value=\"no\" %s> %s <br />"
350                 "</td><td>"
351                 "<img src=\"static/advanpage2_48x.gif\" alt=\"&nbsp;\">"
352                 "</td><td>"
353                 "<b>%s</b><br />"
354                 "%s"
355                 "</td></tr>\n",
356                 (bar ? "even" : "odd"),
357                 (val ? "CHECKED" : ""),_("Yes"),
358                 (!val ? "CHECKED" : ""),_("No"),
359                 _("Advanced options"),
360                 _("Access to the complete menu of Citadel functions.")
361
362         );
363
364         bar = 1 - bar;
365         val = IconbarIsEnabled("ib_citadel", 1);
366         wprintf("<tr class=\"%s\"><td>"
367                 "<input type=\"radio\" name=\"ib_citadel\" value=\"yes\" %s> %s &nbsp;&nbsp;&nbsp;"
368                 "<input type=\"radio\" name=\"ib_citadel\" value=\"no\" %s> %s <br />"
369                 "</td><td>"
370                 "<img border=\"0\" width=\"48\" height=\"48\" "
371                 "src=\"static/citadel-logo.gif\" alt=\"&nbsp;\">"
372                 "</td><td>"
373                 "<b>%s</b><br />"
374                 "%s"
375                 "</td></tr>\n",
376                 (bar ? "even" : "odd"),
377                 (val ? "CHECKED" : ""),_("Yes"),
378                 (!val ? "CHECKED" : ""),_("No"),
379                 _("Citadel logo"),
380                 _("Displays the 'Powered by Citadel' icon")
381         );
382
383         wprintf("</table><br />\n"
384                 "<center>"
385                 "<input type=\"submit\" name=\"ok_button\" value=\"%s\">"
386                 "&nbsp;"
387                 "<input type=\"submit\" name=\"cancel_button\" value=\"%s\">"
388                 "</center>\n",
389                 _("Save changes"),
390                 _("Cancel")
391         );
392
393         wprintf("</form></div>\n");
394         wDumpContent(2);
395 }
396
397 /**
398  * \brief commit the changes of an edited iconbar ????
399  */
400 void commit_iconbar(void) {
401         StrBuf *iconbar;
402         StrBuf *buf;
403         int i;
404
405         char *boxen[] = {
406                 "ib_logo",
407                 "ib_summary",
408                 "ib_inbox",
409                 "ib_calendar",
410                 "ib_contacts",
411                 "ib_notes",
412                 "ib_tasks",
413                 "ib_rooms",
414                 "ib_users",
415                 "ib_chat",
416                 "ib_advanced",
417                 "ib_logoff",
418                 "ib_citadel"
419         };
420
421         if (!havebstr("ok_button")) {
422                 display_main_menu();
423                 return;
424         }
425
426         iconbar = NewStrBuf();
427         buf = NewStrBuf();
428         StrBufPrintf(iconbar, "ib_displayas=%d", ibstr("ib_displayas"));
429         for (i=0; i<(sizeof(boxen)/sizeof(char *)); ++i) {
430                 char *Val;
431                 if (!strcasecmp(BSTR(boxen[i]), "yes")) {
432                         Val = "1";
433                 }
434                 else if (!strcasecmp(BSTR(boxen[i]), "yeslist")) {
435                         Val = "2";
436                 }
437                 else {
438                         Val = "0";
439                 }
440                 StrBufPrintf(buf, ",%s=%s", boxen[i], Val);
441                 StrBufAppendBuf(iconbar, buf, 0);
442
443         }
444         FreeStrBuf(&buf);
445         set_preference("iconbar", iconbar, 1);
446
447         output_headers(1, 1, 2, 0, 0, 0);
448         /* TODO: TEMPLATE */
449         wprintf("<div id=\"banner\">\n");
450         wprintf("<h1>");
451         wprintf(_("Customize the icon bar"));
452         wprintf("</h1></div>\n");
453
454         wprintf("<div id=\"content\" class=\"service\">\n");
455         wprintf(
456                 "<center><table border=1 bgcolor=\"#ffffff\"><tr><td>"
457                 "<img src=\"static/advanpage2_48x.gif\">"
458                 "&nbsp;");
459         wprintf(_("Your icon bar has been updated.  Please select any of its "
460                   "choices to continue.<br/><span style=\"font-weight: bold;\">You may need to force refresh (SHIFT-F5) in order for changes to take effect</span>"));
461         wprintf("</td></tr></table>\n");
462         wDumpContent(2);
463 #ifdef DBG_ICONBAR_HASH
464         dbg_PrintHash(WC->IconBarSetttings, PrintInt, NULL);
465 #endif
466 }
467
468
469 void tmplput_iconbar(StrBuf *Target, WCTemplputParams *TP)
470 {
471         wcsession *WCC = WC;
472         
473         if ((WCC != NULL) && (WCC->logged_in)) {
474           DoTemplate(HKEY("iconbar"), NULL, &NoCtx);
475         }
476 }
477
478 void 
479 InitModule_ICONBAR
480 (void)
481 {
482   WebcitAddUrlHandler(HKEY("user_iconbar"), doUserIconStylesheet, 0);
483   WebcitAddUrlHandler(HKEY("commit_iconbar"), commit_iconbar, 0);
484   RegisterConditional(HKEY("COND:ICONBAR:ACTIVE"), 3, ConditionalIsActiveStylesheet, CTX_NONE);
485         WebcitAddUrlHandler(HKEY("display_customize_iconbar"), display_customize_iconbar, 0);
486         RegisterNamespace("ICONBAR", 0, 0, tmplput_iconbar, 0);
487
488 }
489
490
491 /*@}*/