imported irssi.
[silc.git] / apps / irssi / src / fe-text / statusbar-items.c
1 /*
2  statusbar-items.c : irssi
3
4     Copyright (C) 1999-2001 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22 #include "signals.h"
23 #include "misc.h"
24 #include "settings.h"
25 #include "special-vars.h"
26
27 #include "window-items.h"
28 #include "formats.h"
29
30 #include "statusbar.h"
31 #include "gui-printtext.h"
32
33 /* how often to redraw lagging time (seconds) */
34 #define LAG_REFRESH_TIME 10
35
36 /* how often to check for new mail (seconds) */
37 #define MAIL_REFRESH_TIME 60
38
39 /* If we haven't been able to check lag for this long, "(??)" is added after
40    the lag */
41 #define MAX_LAG_UNKNOWN_TIME 30
42
43 static STATUSBAR_REC *mainbar;
44 static MAIN_WINDOW_REC *mainbar_window;
45 static int use_colors;
46
47 /* clock */
48 static SBAR_ITEM_REC *clock_item;
49 static int clock_timetag;
50 static time_t clock_last;
51
52 /* nick */
53 static SBAR_ITEM_REC *nick_item;
54
55 /* channel */
56 static SBAR_ITEM_REC *window_item;
57
58 /* activity */
59 static SBAR_ITEM_REC *activity_item;
60 static GList *activity_list;
61
62 /* more */
63 static SBAR_ITEM_REC *more_item;
64
65 /* lag */
66 static SBAR_ITEM_REC *lag_item;
67 static int lag_timetag, lag_min_show;
68 static time_t lag_last_draw;
69
70 /* mbox counter */
71 static SBAR_ITEM_REC *mail_item;
72 static int mail_timetag, mail_last_count;
73 static time_t mail_last_mtime = -1;
74 static off_t mail_last_size = -1;
75
76 /* topic */
77 static SBAR_ITEM_REC *topic_item;
78 static STATUSBAR_REC *topic_bar;
79
80 static void item_default(SBAR_ITEM_REC *item, int get_size_only,
81                          const char *str, const char *data)
82 {
83         SERVER_REC *server;
84         WI_ITEM_REC *wiitem;
85         char *tmpstr, *tmpstr2;
86         int len;
87
88         if (active_win == NULL) {
89                 server = NULL;
90                 wiitem = NULL;
91         } else {
92                 server = active_win->active_server;
93                 wiitem = active_win->active;
94         }
95
96         /* expand $variables */
97         tmpstr = parse_special_string(str, server, wiitem, data, NULL,
98                                       PARSE_FLAG_ESCAPE_VARS);
99
100         /* expand templates */
101         str = tmpstr;
102         tmpstr2 = theme_format_expand_data(current_theme, &str,
103                                            'n', '0' + item->bar->color,
104                                            NULL, NULL,
105                                            EXPAND_FLAG_ROOT |
106                                            EXPAND_FLAG_IGNORE_REPLACES |
107                                            EXPAND_FLAG_IGNORE_EMPTY);
108         g_free(tmpstr);
109
110         /* remove color codes */
111         tmpstr = strip_codes(tmpstr2);
112         g_free(tmpstr2);
113
114         if (get_size_only) {
115                 item->min_size = item->max_size = format_get_length(tmpstr);
116         } else {
117                 if (item->size < item->min_size) {
118                         /* they're forcing us smaller than minimum size.. */
119                         len = format_real_length(tmpstr, item->size);
120                         tmpstr[len] = '\0';
121                 }
122
123                 tmpstr2 = g_strconcat(item->bar->color_string, tmpstr, NULL);
124                 gui_printtext(item->xpos, item->bar->ypos, tmpstr2);
125                 g_free(tmpstr2);
126         }
127         g_free(tmpstr);
128 }
129
130 /* redraw clock */
131 static void statusbar_clock(SBAR_ITEM_REC *item, int get_size_only)
132 {
133         item_default(item, get_size_only, "{sb $Z}", "");
134 }
135
136 /* check if we need to redraw clock.. */
137 static int statusbar_clock_timeout(void)
138 {
139         struct tm *tm;
140         time_t t;
141         int min;
142
143         tm = localtime(&clock_last);
144         min = tm->tm_min;
145
146         t = time(NULL);
147         tm = localtime(&t);
148
149         if (tm->tm_min != min) {
150                 /* minute changed, redraw! */
151                 clock_last = t;
152                 statusbar_item_redraw(clock_item);
153         }
154         return 1;
155 }
156
157 /* redraw nick */
158 static void statusbar_nick(SBAR_ITEM_REC *item, int get_size_only)
159 {
160         item_default(item, get_size_only,
161                      "{sb $P$N{sbmode $usermode}{sbaway $A}}", "");
162 }
163
164 static void sig_statusbar_nick_redraw(void)
165 {
166         statusbar_item_redraw(nick_item);
167 }
168
169 /* redraw window */
170 static void statusbar_window(SBAR_ITEM_REC *item, int get_size_only)
171 {
172         if (active_win->active != NULL) {
173                 item_default(item, get_size_only,
174                              "{sb $winref:$T{sbmode $M}}", "");
175         } else {
176                 item_default(item, get_size_only,
177                              "{sb $winref{sbservertag $tag}}", "");
178         }
179 }
180
181 static void sig_statusbar_window_redraw(void)
182 {
183         statusbar_item_redraw(window_item);
184 }
185
186 static void sig_statusbar_window_redraw_window(WINDOW_REC *window)
187 {
188         if (is_window_visible(window))
189                 statusbar_item_redraw(window_item);
190 }
191
192 static void sig_statusbar_window_redraw_window_item(WI_ITEM_REC *item)
193 {
194         WINDOW_REC *window;
195
196         window = window_item_window(item);
197         if (window->active == item && is_window_visible(window))
198                 statusbar_item_redraw(window_item);
199 }
200
201 static char *get_activity_list(int normal, int hilight)
202 {
203         GString *str;
204         GList *tmp;
205         char *ret;
206         int is_det;
207
208         str = g_string_new(NULL);
209
210         for (tmp = activity_list; tmp != NULL; tmp = tmp->next) {
211                 WINDOW_REC *window = tmp->data;
212
213                 is_det = window->data_level >= DATA_LEVEL_HILIGHT;
214                 if ((!is_det && !normal) || (is_det && !hilight))
215                         continue;
216
217                 g_string_append(str, "%c");
218                 if (str->len > 2)
219                         g_string_append_c(str, ',');
220
221                 switch (window->data_level) {
222                 case DATA_LEVEL_NONE:
223                 case DATA_LEVEL_TEXT:
224                         break;
225                 case DATA_LEVEL_MSG:
226                         g_string_append(str, "%W");
227                         break;
228                 default:
229                         g_string_append(str, window->hilight_color == NULL ?
230                                         "%M" : window->hilight_color);
231                         break;
232                 }
233                 g_string_sprintfa(str, "%d", window->refnum);
234
235                 /* make sure the background is returned to default */
236                 g_string_append(str, "%n");
237         }
238
239         ret = str->len == 0 ? NULL : str->str;
240         g_string_free(str, ret == NULL);
241         return ret;
242 }
243
244 /* redraw activity, FIXME: if we didn't get enough size, this gets buggy.
245    At least "Det:" isn't printed properly. also we should rearrange the
246    act list so that the highest priority items comes first. */
247 static void statusbar_activity(SBAR_ITEM_REC *item, int get_size_only)
248 {
249         char *actlist, *detlist, *data;
250
251         if (use_colors) {
252                 actlist = get_activity_list(TRUE, TRUE);
253                 detlist = NULL;
254         } else {
255                 actlist = get_activity_list(TRUE, FALSE);
256                 detlist = get_activity_list(FALSE, TRUE);
257         }
258
259         if (actlist == NULL && detlist == NULL) {
260                 if (get_size_only)
261                         item->min_size = item->max_size = 0;
262                 return;
263         }
264
265         data = g_strconcat("{sbact ", actlist != NULL ? actlist : "",
266                            " ", detlist != NULL ? detlist : "", "}", NULL);
267         item_default(item, get_size_only, data, "");
268         g_free(data);
269
270         g_free_not_null(actlist);
271         g_free_not_null(detlist);
272 }
273
274 static void sig_statusbar_activity_hilight(WINDOW_REC *window, gpointer oldlevel)
275 {
276         GList *tmp;
277         int inspos;
278
279         g_return_if_fail(window != NULL);
280
281         if (settings_get_bool("actlist_moves")) {
282                 /* Move the window to the first in the activity list */
283                 if (g_list_find(activity_list, window) != NULL)
284                         activity_list = g_list_remove(activity_list, window);
285                 if (window->data_level != 0)
286                         activity_list = g_list_prepend(activity_list, window);
287                 statusbar_item_redraw(activity_item);
288                 return;
289         }
290
291         if (g_list_find(activity_list, window) != NULL) {
292                 /* already in activity list */
293                 if (window->data_level == 0) {
294                         /* remove from activity list */
295                         activity_list = g_list_remove(activity_list, window);
296                         statusbar_item_redraw(activity_item);
297                 } else if (window->data_level != GPOINTER_TO_INT(oldlevel) ||
298                          window->hilight_color != 0) {
299                         /* different level as last time (or maybe different
300                            hilight color?), just redraw it. */
301                         statusbar_item_redraw(activity_item);
302                 }
303                 return;
304         }
305
306         if (window->data_level == 0)
307                 return;
308
309         /* add window to activity list .. */
310         inspos = 0;
311         for (tmp = activity_list; tmp != NULL; tmp = tmp->next, inspos++) {
312                 WINDOW_REC *rec = tmp->data;
313
314                 if (window->refnum < rec->refnum) {
315                         activity_list =
316                                 g_list_insert(activity_list, window, inspos);
317                         break;
318                 }
319         }
320         if (tmp == NULL)
321                 activity_list = g_list_append(activity_list, window);
322
323         statusbar_item_redraw(activity_item);
324 }
325
326 static void sig_statusbar_activity_window_destroyed(WINDOW_REC *window)
327 {
328         g_return_if_fail(window != NULL);
329
330         if (g_list_find(activity_list, window) != NULL)
331                 activity_list = g_list_remove(activity_list, window);
332         statusbar_item_redraw(activity_item);
333 }
334
335 static void sig_statusbar_activity_updated(void)
336 {
337         statusbar_item_redraw(activity_item);
338 }
339
340 /* redraw -- more -- */
341 static void statusbar_more(SBAR_ITEM_REC *item, int get_size_only)
342 {
343         item_default(item, get_size_only, "{sbmore}", "");
344 }
345
346 static void sig_statusbar_more_check_remove(WINDOW_REC *window)
347 {
348         g_return_if_fail(window != NULL);
349
350         if (!is_window_visible(window))
351                 return;
352
353         if (more_item != NULL && WINDOW_GUI(window)->view->bottom) {
354                 statusbar_item_remove(more_item);
355                 more_item = NULL;
356         }
357 }
358
359 static void sig_statusbar_more_check(WINDOW_REC *window)
360 {
361         if (window == NULL || !is_window_visible(window))
362                 return;
363
364         if (!WINDOW_GUI(window)->view->bottom) {
365                 if (more_item == NULL) {
366                         more_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_more);
367                         statusbar_redraw(mainbar);
368                 }
369         } else if (more_item != NULL) {
370                 statusbar_item_remove(more_item);
371                 more_item = NULL;
372         }
373 }
374
375 static void statusbar_lag(SBAR_ITEM_REC *item, int get_size_only)
376 {
377         SERVER_REC *server;
378         GString *str;
379         int lag_unknown;
380         time_t now;
381
382         server = active_win == NULL ? NULL : active_win->active_server;
383         if (server == NULL || server->lag_last_check == 0) {
384                 /* No lag information */
385                 if (get_size_only)
386                         item->min_size = item->max_size = 0;
387                 return;
388         }
389
390         now = time(NULL);
391         str = g_string_new(NULL);
392
393         /* FIXME: ugly ugly.. */
394         if (server->lag_sent == 0 || now-server->lag_sent < 5) {
395                 lag_unknown = now-server->lag_last_check >
396                         MAX_LAG_UNKNOWN_TIME+settings_get_int("lag_check_time");
397
398                 if (lag_min_show < 0 || (server->lag < lag_min_show && !lag_unknown)) {
399                         /* small lag, don't display */
400                 } else {
401                         g_string_sprintfa(str, "%d.%02d", server->lag/1000,
402                                           (server->lag % 1000)/10);
403                         if (lag_unknown)
404                                 g_string_append(str, " (??)");
405                 }
406         } else {
407                 /* big lag, still waiting .. */
408                 g_string_sprintfa(str, "%ld (??)",
409                                   (long) (now-server->lag_sent));
410         }
411
412         item_default(item, get_size_only, "{sblag $0-}", str->str);
413
414         g_string_free(str, TRUE);
415 }
416
417 static void sig_statusbar_lag_redraw(void)
418 {
419         statusbar_item_redraw(lag_item);
420 }
421
422 static int statusbar_lag_timeout(void)
423 {
424         /* refresh statusbar every 10 seconds */
425         if (time(NULL)-lag_last_draw < LAG_REFRESH_TIME)
426                 return 1;
427
428         statusbar_item_redraw(lag_item);
429         return 1;
430 }
431
432 /* FIXME: this isn't very good.. it handles only mbox mailboxes.
433    this whole mail feature should really be in it's own module with lots
434    of other mail formats supported and people who don't want to use it
435    wouldn't need to.. */
436 static int get_mail_count(void)
437 {
438         struct stat statbuf;
439         FILE *f;
440         char str[512], *fname;
441         int count;
442
443         fname = g_getenv("MAIL");
444         if (fname == NULL) return 0;
445
446         if (stat(fname, &statbuf) != 0) {
447                 mail_last_mtime = -1;
448                 mail_last_size = -1;
449                 mail_last_count = 0;
450                 return 0;
451         }
452
453         if (statbuf.st_mtime == mail_last_mtime &&
454             statbuf.st_size == mail_last_size)
455                 return mail_last_count;
456         mail_last_mtime = statbuf.st_mtime;
457         mail_last_size = statbuf.st_size;
458
459         f = fopen(fname, "r");
460         if (f == NULL) {
461                 mail_last_count = 0;
462                 return 0;
463         }
464
465         count = 0;
466         while (fgets(str, sizeof(str), f) != NULL) {
467                 if (strncmp(str, "From ", 5) == 0)
468                         count++;
469                 if (strncmp(str, "Subject: ", 9) == 0 &&
470                     strstr(str, "FOLDER INTERNAL DATA")) {
471                         /* don't count these. */
472                         count--;
473                 }
474         }
475
476         fclose(f);
477         mail_last_count = count;
478         return count;
479 }
480
481 static void statusbar_mail(SBAR_ITEM_REC *item, int get_size_only)
482 {
483         char countstr[MAX_INT_STRLEN];
484         int mail_count;
485
486         mail_count = settings_get_bool("mail_counter") ? get_mail_count() : 0;
487
488         if (mail_count <= 0) {
489                 if (get_size_only)
490                         item->min_size = item->max_size = 0;
491                 return;
492         }
493
494         ltoa(countstr, mail_count);
495         item_default(item, get_size_only, "{sbmail $0-}", countstr);
496 }
497
498 static int statusbar_mail_timeout(void)
499 {
500         statusbar_item_redraw(mail_item);
501         return 1;
502 }
503
504 static void statusbar_topic(SBAR_ITEM_REC *item, int get_size_only)
505 {
506         item_default(item, get_size_only, "$topic", "");
507 }
508
509 static void sig_statusbar_topic_redraw(void)
510 {
511         if (topic_item != NULL) statusbar_item_redraw(topic_item);
512 }
513
514 static void sig_sidebars_redraw(void)
515 {
516         GSList *tmp;
517
518         for (tmp = mainwindows; tmp != NULL; tmp = tmp->next) {
519                 MAIN_WINDOW_REC *rec = tmp->data;
520
521                 if (rec->statusbar_window_item != NULL)
522                         statusbar_item_redraw(rec->statusbar_window_item);
523         }
524 }
525
526 static void topicbar_create(void)
527 {
528         if (topic_bar != NULL)
529                 return;
530
531         topic_bar = statusbar_create(STATUSBAR_POS_UP, 0);
532         topic_item = statusbar_item_create(topic_bar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_topic);
533         topic_item->max_size = TRUE;
534         statusbar_redraw(topic_bar);
535
536         signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
537         signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
538         signal_add("channel topic changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
539         signal_add("query address changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
540 }
541
542 static void topicbar_destroy(void)
543 {
544         if (topic_bar == NULL)
545                 return;
546
547         statusbar_destroy(topic_bar);
548         topic_item = NULL;
549         topic_bar = NULL;
550
551         signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
552         signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
553         signal_remove("channel topic changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
554         signal_remove("query address changed", (SIGNAL_FUNC) sig_statusbar_topic_redraw);
555 }
556
557 static void mainbar_remove_items(void)
558 {
559         statusbar_item_remove(clock_item);
560         statusbar_item_remove(nick_item);
561         statusbar_item_remove(window_item);
562         statusbar_item_remove(mail_item);
563         statusbar_item_remove(lag_item);
564         statusbar_item_remove(activity_item);
565 }
566
567 static void mainbar_add_items(MAIN_WINDOW_REC *window)
568 {
569         mainbar = window->statusbar;
570         mainbar_window = window;
571
572         clock_item = statusbar_item_create(mainbar, SBAR_PRIORITY_HIGH, FALSE, statusbar_clock);
573         nick_item = statusbar_item_create(mainbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_nick);
574         window_item = statusbar_item_create(mainbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_window);
575         mail_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_mail);
576         lag_item = statusbar_item_create(mainbar, SBAR_PRIORITY_LOW, FALSE, statusbar_lag);
577         activity_item = statusbar_item_create(mainbar, SBAR_PRIORITY_HIGH, FALSE, statusbar_activity);
578 }
579
580 static void sidebar_add_items(MAIN_WINDOW_REC *window)
581 {
582         window->statusbar_window_item =
583                 statusbar_item_create(window->statusbar, SBAR_PRIORITY_NORMAL, FALSE, statusbar_window);
584 }
585
586 static void sidebar_remove_items(MAIN_WINDOW_REC *window)
587 {
588         if (window->statusbar_window_item != NULL) {
589                 statusbar_item_remove(window->statusbar_window_item);
590                 window->statusbar_window_item = NULL;
591         }
592 }
593
594 static void sig_mainwindow_created(MAIN_WINDOW_REC *window)
595 {
596         window->statusbar =
597                 statusbar_create(STATUSBAR_POS_MIDDLE,
598                                  window->first_line+window->height);
599         ((STATUSBAR_REC *) window->statusbar)->window = window;
600         sidebar_add_items(window);
601 }
602
603 static void sig_mainwindow_destroyed(MAIN_WINDOW_REC *window)
604 {
605         if (window == mainbar_window) {
606                 mainbar = NULL;
607                 mainbar_window = NULL;
608         }
609
610         if (window->statusbar != NULL)
611                 statusbar_destroy(window->statusbar);
612 }
613
614 static void sig_main_statusbar_changed(WINDOW_REC *window)
615 {
616         MAIN_WINDOW_REC *parent;
617
618         if (window == NULL)
619                 return;
620
621         parent = WINDOW_GUI(window)->parent;
622         if (mainbar == parent->statusbar)
623                 return;
624
625         if (mainbar != NULL) {
626                 mainbar_remove_items();
627                 sidebar_add_items(mainbar_window);
628         }
629         sidebar_remove_items(parent);
630         mainbar_add_items(parent);
631 }
632
633 static void read_settings(void)
634 {
635         use_colors = settings_get_bool("colors") && has_colors();
636         if (settings_get_bool("topicbar"))
637                 topicbar_create();
638         else
639                 topicbar_destroy();
640
641         lag_min_show = settings_get_int("lag_min_show")*10;
642         statusbar_redraw(NULL);
643 }
644
645 void statusbar_items_init(void)
646 {
647         GSList *tmp;
648
649         settings_add_int("misc", "lag_min_show", 100);
650         settings_add_bool("lookandfeel", "topicbar", TRUE);
651         settings_add_bool("lookandfeel", "actlist_moves", FALSE);
652         settings_add_bool("misc", "mail_counter", TRUE);
653
654         /* clock */
655         clock_timetag = g_timeout_add(1000, (GSourceFunc) statusbar_clock_timeout, NULL);
656
657         /* nick */
658         signal_add("server connected", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
659         signal_add("channel wholist", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
660         signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
661         signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
662         signal_add("nick mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
663         signal_add("user mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
664         signal_add("server nick changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
665         signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
666         signal_add("away mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
667
668         /* channel */
669         signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_window_redraw);
670         signal_add("window item changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
671         signal_add("channel mode changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window_item);
672         signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
673         signal_add("window refnum changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
674
675         /* activity */
676         activity_list = NULL;
677         signal_add("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
678         signal_add("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
679         signal_add("window refnum changed", (SIGNAL_FUNC) sig_statusbar_activity_updated);
680
681         /* more */
682         more_item = NULL;
683         signal_add("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
684         signal_add("window changed", (SIGNAL_FUNC) sig_statusbar_more_check);
685         signal_add("gui print text", (SIGNAL_FUNC) sig_statusbar_more_check);
686
687         /* lag */
688         lag_timetag = g_timeout_add(1000*LAG_REFRESH_TIME, (GSourceFunc) statusbar_lag_timeout, NULL);
689         signal_add("server lag", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
690         signal_add("window server changed", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
691
692         /* mail */
693         mail_timetag = g_timeout_add(1000*MAIL_REFRESH_TIME, (GSourceFunc) statusbar_mail_timeout, NULL);
694
695         /* topic */
696         topic_item = NULL; topic_bar = NULL;
697         signal_add("setup changed", (SIGNAL_FUNC) read_settings);
698
699         read_settings();
700         statusbar_redraw(NULL);
701
702         /* middle bars */
703         signal_add("mainwindow created", (SIGNAL_FUNC) sig_mainwindow_created);
704         signal_add("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
705         signal_add("window changed", (SIGNAL_FUNC) sig_main_statusbar_changed);
706         signal_add("window refnum changed", (SIGNAL_FUNC) sig_sidebars_redraw);
707
708         /* add statusbars to existing windows */
709         for (tmp = mainwindows; tmp != NULL; tmp = tmp->next)
710                 sig_mainwindow_created(tmp->data);
711         sig_main_statusbar_changed(active_win);
712 }
713
714 void statusbar_items_deinit(void)
715 {
716         /* clock */
717         g_source_remove(clock_timetag);
718
719         /* nick */
720         signal_remove("server connected", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
721         signal_remove("channel wholist", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
722         signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
723         signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
724         signal_remove("nick mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
725         signal_remove("user mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
726         signal_remove("server nick changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
727         signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
728         signal_remove("away mode changed", (SIGNAL_FUNC) sig_statusbar_nick_redraw);
729
730         /* channel */
731         signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_window_redraw);
732         signal_remove("window item changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
733         signal_remove("channel mode changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window_item);
734         signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
735         signal_remove("window refnum changed", (SIGNAL_FUNC) sig_statusbar_window_redraw_window);
736
737         /* activity */
738         signal_remove("window activity", (SIGNAL_FUNC) sig_statusbar_activity_hilight);
739         signal_remove("window destroyed", (SIGNAL_FUNC) sig_statusbar_activity_window_destroyed);
740         signal_remove("window refnum changed", (SIGNAL_FUNC) sig_statusbar_activity_updated);
741         g_list_free(activity_list);
742
743         /* more */
744         signal_remove("gui page scrolled", (SIGNAL_FUNC) sig_statusbar_more_check_remove);
745         signal_remove("window changed", (SIGNAL_FUNC) sig_statusbar_more_check);
746         signal_remove("gui print text", (SIGNAL_FUNC) sig_statusbar_more_check);
747
748         /* lag */
749         g_source_remove(lag_timetag);
750         signal_remove("server lag", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
751         signal_remove("window server changed", (SIGNAL_FUNC) sig_statusbar_lag_redraw);
752
753         /* mail */
754         g_source_remove(mail_timetag);
755
756         /* topic */
757         topicbar_destroy();
758         signal_remove("setup changed", (SIGNAL_FUNC) read_settings);
759
760         /* middle bars */
761         signal_remove("mainwindow created", (SIGNAL_FUNC) sig_mainwindow_created);
762         signal_remove("mainwindow destroyed", (SIGNAL_FUNC) sig_mainwindow_destroyed);
763         signal_remove("window changed", (SIGNAL_FUNC) sig_main_statusbar_changed);
764         signal_remove("window refnum changed", (SIGNAL_FUNC) sig_sidebars_redraw);
765 }