2004-11-11 [paul] 0.9.12cvs145
[claws.git] / src / mainwindow.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2004 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #include "defs.h"
21
22 #include <glib.h>
23 #include <gdk/gdkkeysyms.h>
24 #include <gtk/gtkmain.h>
25 #include <gtk/gtkwindow.h>
26 #include <gtk/gtkwidget.h>
27 #include <gtk/gtksignal.h>
28 #include <gtk/gtkvbox.h>
29 #include <gtk/gtkcontainer.h>
30 #include <gtk/gtkstatusbar.h>
31 #include <gtk/gtkprogressbar.h>
32 #include <gtk/gtkhpaned.h>
33 #include <gtk/gtkvpaned.h>
34 #include <gtk/gtkcheckmenuitem.h>
35 #include <gtk/gtkitemfactory.h>
36 #include <gtk/gtkeditable.h>
37 #include <gtk/gtkmenu.h>
38 #include <gtk/gtkmenuitem.h>
39 #include <gtk/gtkhandlebox.h>
40 #include <gtk/gtktoolbar.h>
41 #include <gtk/gtkbutton.h>
42 #include <gtk/gtktooltips.h>
43 #include <string.h>
44
45 #include "intl.h"
46 #include "main.h"
47 #include "mainwindow.h"
48 #include "folderview.h"
49 #include "foldersel.h"
50 #include "summaryview.h"
51 #include "summary_search.h"
52 #include "messageview.h"
53 #include "message_search.h"
54 #include "headerview.h"
55 #include "menu.h"
56 #include "stock_pixmap.h"
57 #include "folder.h"
58 #include "inc.h"
59 #include "compose.h"
60 #include "procmsg.h"
61 #include "import.h"
62 #include "export.h"
63 #include "prefs_common.h"
64 #include "prefs_actions.h"
65 #include "prefs_filtering.h"
66 #include "prefs_account.h"
67 #include "prefs_summary_column.h"
68 #include "prefs_template.h"
69 #include "action.h"
70 #include "account.h"
71 #include "addressbook.h"
72 #include "logwindow.h"
73 #include "manage_window.h"
74 #include "alertpanel.h"
75 #include "statusbar.h"
76 #include "inputdialog.h"
77 #include "utils.h"
78 #include "gtkutils.h"
79 #include "codeconv.h"
80 #include "about.h"
81 #include "manual.h"
82 #include "version.h"
83 #include "ssl_manager.h"
84 #include "sslcertwindow.h"
85 #include "prefs_gtk.h"
86 #include "pluginwindow.h"
87 #include "hooks.h"
88 #include "progressindicator.h"
89 #include "localfolder.h"
90 #include "filtering.h"
91 #include "folderutils.h"
92 #include "foldersort.h"
93
94 #define AC_LABEL_WIDTH  240
95
96 /* list of all instantiated MainWindow */
97 static GList *mainwin_list = NULL;
98
99 static GdkCursor *watch_cursor;
100
101 static void main_window_menu_callback_block     (MainWindow     *mainwin);
102 static void main_window_menu_callback_unblock   (MainWindow     *mainwin);
103
104 static void main_window_show_cur_account        (MainWindow     *mainwin);
105
106 static void main_window_set_widgets             (MainWindow     *mainwin,
107                                                  SeparateType    type);
108
109 #if 0
110 static void toolbar_account_button_pressed      (GtkWidget      *widget,
111                                                  GdkEventButton *event,
112                                                  gpointer        data);
113 #endif
114
115 static void toolbar_child_attached              (GtkWidget      *widget,
116                                                  GtkWidget      *child,
117                                                  gpointer        data);
118 static void toolbar_child_detached              (GtkWidget      *widget,
119                                                  GtkWidget      *child,
120                                                  gpointer        data);
121
122 static void ac_label_button_pressed             (GtkWidget      *widget,
123                                                  GdkEventButton *event,
124                                                  gpointer        data);
125 static void ac_menu_popup_closed                (GtkMenuShell   *menu_shell,
126                                                  gpointer        data);
127
128 static gint main_window_close_cb                (GtkWidget      *widget,
129                                                  GdkEventAny    *event,
130                                                  gpointer        data);
131 static gint folder_window_close_cb              (GtkWidget      *widget,
132                                                  GdkEventAny    *event,
133                                                  gpointer        data);
134 static gint message_window_close_cb             (GtkWidget      *widget,
135                                                  GdkEventAny    *event,
136                                                  gpointer        data);
137
138 static void main_window_size_allocate_cb        (GtkWidget      *widget,
139                                                  GtkAllocation  *allocation,
140                                                  gpointer        data);
141 static void folder_window_size_allocate_cb      (GtkWidget      *widget,
142                                                  GtkAllocation  *allocation,
143                                                  gpointer        data);
144 static void message_window_size_allocate_cb     (GtkWidget      *widget,
145                                                  GtkAllocation  *allocation,
146                                                  gpointer        data);
147
148 static void update_folderview_cb (MainWindow    *mainwin,
149                                   guint          action,
150                                   GtkWidget     *widget);
151 static void add_mailbox_cb       (MainWindow    *mainwin,
152                                   guint          action,
153                                   GtkWidget     *widget);
154 static void foldersort_cb        (MainWindow    *mainwin,
155                                   guint          action,
156                                   GtkWidget     *widget);
157 static void import_mbox_cb       (MainWindow    *mainwin,
158                                   guint          action,
159                                   GtkWidget     *widget);
160 static void export_mbox_cb       (MainWindow    *mainwin,
161                                   guint          action,
162                                   GtkWidget     *widget);
163 static void empty_trash_cb       (MainWindow    *mainwin,
164                                   guint          action,
165                                   GtkWidget     *widget);
166
167 static void save_as_cb           (MainWindow    *mainwin,
168                                   guint          action,
169                                   GtkWidget     *widget);
170 static void print_cb             (MainWindow    *mainwin,
171                                   guint          action,
172                                   GtkWidget     *widget);
173 static void app_exit_cb          (MainWindow    *mainwin,
174                                   guint          action,
175                                   GtkWidget     *widget);
176
177 static void search_cb            (MainWindow    *mainwin,
178                                   guint          action,
179                                   GtkWidget     *widget);
180
181 static void toggle_folder_cb     (MainWindow    *mainwin,
182                                   guint          action,
183                                   GtkWidget     *widget);
184 static void toggle_message_cb    (MainWindow    *mainwin,
185                                   guint          action,
186                                   GtkWidget     *widget);
187 static void toggle_toolbar_cb    (MainWindow    *mainwin,
188                                   guint          action,
189                                   GtkWidget     *widget);
190 static void toggle_statusbar_cb  (MainWindow    *mainwin,
191                                   guint          action,
192                                   GtkWidget     *widget);
193 static void separate_widget_cb   (MainWindow    *mainwin,
194                                   guint          action,
195                                   GtkWidget     *widget);
196
197 static void addressbook_open_cb (MainWindow     *mainwin,
198                                  guint           action,
199                                  GtkWidget      *widget);
200 static void log_window_show_cb  (MainWindow     *mainwin,
201                                  guint           action,
202                                  GtkWidget      *widget);
203
204 static void inc_cancel_cb               (MainWindow     *mainwin,
205                                          guint           action,
206                                          GtkWidget      *widget);
207
208 static void open_msg_cb                 (MainWindow     *mainwin,
209                                          guint           action,
210                                          GtkWidget      *widget);
211
212 static void view_source_cb              (MainWindow     *mainwin,
213                                          guint           action,
214                                          GtkWidget      *widget);
215
216 static void show_all_header_cb          (MainWindow     *mainwin,
217                                          guint           action,
218                                          GtkWidget      *widget);
219
220 static void move_to_cb                  (MainWindow     *mainwin,
221                                          guint           action,
222                                          GtkWidget      *widget);
223 static void copy_to_cb                  (MainWindow     *mainwin,
224                                          guint           action,
225                                          GtkWidget      *widget);
226 static void delete_cb                   (MainWindow     *mainwin,
227                                          guint           action,
228                                          GtkWidget      *widget);
229
230 static void cancel_cb                   (MainWindow     *mainwin,
231                                          guint           action,
232                                          GtkWidget      *widget);
233
234 static void mark_cb                     (MainWindow     *mainwin,
235                                          guint           action,
236                                          GtkWidget      *widget);
237 static void unmark_cb                   (MainWindow     *mainwin,
238                                          guint           action,
239                                          GtkWidget      *widget);
240
241 static void mark_as_unread_cb           (MainWindow     *mainwin,
242                                          guint           action,
243                                          GtkWidget      *widget);
244 static void mark_as_read_cb             (MainWindow     *mainwin,
245                                          guint           action,
246                                          GtkWidget      *widget);
247 static void mark_all_read_cb            (MainWindow     *mainwin,
248                                          guint           action,
249                                          GtkWidget      *widget);
250
251 static void reedit_cb                   (MainWindow     *mainwin,
252                                          guint           action,
253                                          GtkWidget      *widget);
254
255 static void add_address_cb              (MainWindow     *mainwin,
256                                          guint           action,
257                                          GtkWidget      *widget);
258
259 static void set_charset_cb              (MainWindow     *mainwin,
260                                          guint           action,
261                                          GtkWidget      *widget);
262
263 static void set_decode_cb               (MainWindow     *mainwin,
264                                          guint           action,
265                                          GtkWidget      *widget);
266
267 static void hide_read_messages   (MainWindow    *mainwin,
268                                   guint          action,
269                                   GtkWidget     *widget);
270
271 static void thread_cb            (MainWindow    *mainwin,
272                                   guint          action,
273                                   GtkWidget     *widget);
274 static void expand_threads_cb    (MainWindow    *mainwin,
275                                   guint          action,
276                                   GtkWidget     *widget);
277 static void collapse_threads_cb  (MainWindow    *mainwin,
278                                   guint          action,
279                                   GtkWidget     *widget);
280
281 static void set_display_item_cb  (MainWindow    *mainwin,
282                                   guint          action,
283                                   GtkWidget     *widget);
284 static void sort_summary_cb      (MainWindow    *mainwin,
285                                   guint          action,
286                                   GtkWidget     *widget);
287 static void sort_summary_type_cb (MainWindow    *mainwin,
288                                   guint          action,
289                                   GtkWidget     *widget);
290 static void attract_by_subject_cb(MainWindow    *mainwin,
291                                   guint          action,
292                                   GtkWidget     *widget);
293
294 static void delete_duplicated_cb (MainWindow    *mainwin,
295                                   guint          action,
296                                   GtkWidget     *widget);
297 static void delete_duplicated_all_cb (MainWindow        *mainwin,
298                                   guint          action,
299                                   GtkWidget     *widget);
300 static void filter_cb            (MainWindow    *mainwin,
301                                   guint          action,
302                                   GtkWidget     *widget);
303 static void execute_summary_cb   (MainWindow    *mainwin,
304                                   guint          action,
305                                   GtkWidget     *widget);
306 static void update_summary_cb    (MainWindow    *mainwin,
307                                   guint          action,
308                                   GtkWidget     *widget);
309
310 static void prev_cb              (MainWindow    *mainwin,
311                                   guint          action,
312                                   GtkWidget     *widget);
313 static void next_cb              (MainWindow    *mainwin,
314                                   guint          action,
315                                   GtkWidget     *widget);
316 static void next_unread_cb       (MainWindow    *mainwin,
317                                   guint          action,
318                                   GtkWidget     *widget);
319 static void prev_unread_cb       (MainWindow    *mainwin,
320                                   guint          action,
321                                   GtkWidget     *widget);
322
323 static void prev_new_cb          (MainWindow    *mainwin,
324                                   guint          action,
325                                   GtkWidget     *widget);
326 static void next_new_cb          (MainWindow    *mainwin,
327                                   guint          action,
328                                   GtkWidget     *widget);
329 static void prev_marked_cb       (MainWindow    *mainwin,
330                                   guint          action,
331                                   GtkWidget     *widget);
332 static void next_marked_cb       (MainWindow    *mainwin,
333                                   guint          action,
334                                   GtkWidget     *widget);
335 static void prev_labeled_cb      (MainWindow    *mainwin,
336                                   guint          action,
337                                   GtkWidget     *widget);
338 static void next_labeled_cb      (MainWindow    *mainwin,
339                                   guint          action,
340                                   GtkWidget     *widget);
341
342 static void goto_folder_cb       (MainWindow    *mainwin,
343                                   guint          action,
344                                   GtkWidget     *widget);
345
346 static void copy_cb              (MainWindow    *mainwin,
347                                   guint          action,
348                                   GtkWidget     *widget);
349 static void allsel_cb            (MainWindow    *mainwin,
350                                   guint          action,
351                                   GtkWidget     *widget);
352 static void select_thread_cb     (MainWindow    *mainwin,
353                                   guint          action,
354                                   GtkWidget     *widget);
355
356 static void create_filter_cb     (MainWindow    *mainwin,
357                                   guint          action,
358                                   GtkWidget     *widget);
359 static void create_processing_cb (MainWindow    *mainwin,
360                                   guint          action,
361                                   GtkWidget     *widget);
362
363 static void prefs_common_open_cb        (MainWindow     *mainwin,
364                                          guint           action,
365                                          GtkWidget      *widget);
366 static void prefs_template_open_cb      (MainWindow     *mainwin,
367                                          guint           action,
368                                          GtkWidget      *widget);
369 static void prefs_actions_open_cb       (MainWindow     *mainwin,
370                                          guint           action,
371                                          GtkWidget      *widget);
372 static void prefs_account_open_cb       (MainWindow     *mainwin,
373                                          guint           action,
374                                          GtkWidget      *widget);
375
376 static void prefs_pre_processing_open_cb  (MainWindow   *mainwin,
377                                            guint         action,
378                                            GtkWidget    *widget);
379
380 static void prefs_post_processing_open_cb (MainWindow   *mainwin,
381                                            guint         action,
382                                            GtkWidget    *widget);
383
384 static void prefs_filtering_open_cb     (MainWindow     *mainwin,
385                                          guint           action,
386                                          GtkWidget      *widget);
387 #ifdef USE_OPENSSL
388 static void ssl_manager_open_cb         (MainWindow     *mainwin,
389                                          guint           action,
390                                          GtkWidget      *widget);
391 #endif
392 static void new_account_cb       (MainWindow    *mainwin,
393                                   guint          action,
394                                   GtkWidget     *widget);
395
396 static void account_selector_menu_cb     (GtkMenuItem   *menuitem,
397                                           gpointer       data);
398 static void account_receive_menu_cb      (GtkMenuItem   *menuitem,
399                                           gpointer       data);
400
401 static void prefs_open_cb       (GtkMenuItem    *menuitem,
402                                  gpointer        data);
403 static void plugins_open_cb     (GtkMenuItem    *menuitem,
404                                  gpointer        data);
405
406 static void online_switch_clicked(GtkButton     *btn, 
407                                   gpointer data);
408
409 static void manual_open_cb       (MainWindow    *mainwin,
410                                   guint          action,
411                                   GtkWidget     *widget);
412
413 static void scan_tree_func       (Folder        *folder,
414                                   FolderItem    *item,
415                                   gpointer       data);
416                                   
417 static void toggle_work_offline_cb(MainWindow *mainwin, guint action, GtkWidget *widget);
418
419 static void addr_harvest_cb      ( MainWindow  *mainwin,
420                                    guint       action,
421                                    GtkWidget   *widget );
422
423 static void addr_harvest_msg_cb  ( MainWindow  *mainwin,
424                                    guint       action,
425                                    GtkWidget   *widget );
426
427 static gboolean mainwindow_focus_in_event       (GtkWidget      *widget, 
428                                                  GdkEventFocus  *focus,
429                                                  gpointer        data);
430 void main_window_reply_cb                       (MainWindow     *mainwin, 
431                                                  guint           action,
432                                                  GtkWidget      *widget);
433 gboolean mainwindow_progressindicator_hook      (gpointer        source,
434                                                  gpointer        userdata);
435 #define  SEPARATE_ACTION 500 
436
437 static GtkItemFactoryEntry mainwin_entries[] =
438 {
439         {N_("/_File"),                          NULL, NULL, 0, "<Branch>"},
440         {N_("/_File/_Add mailbox"),             NULL, NULL, 0, "<Branch>"},
441         {N_("/_File/_Add mailbox/MH..."),       NULL, add_mailbox_cb, 0, NULL},
442         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
443         {N_("/_File/Change folder order"),      NULL, foldersort_cb,  0, NULL},
444         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
445         {N_("/_File/_Import mbox file..."),     NULL, import_mbox_cb, 0, NULL},
446         {N_("/_File/_Export to mbox file..."),  NULL, export_mbox_cb, 0, NULL},
447         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
448         {N_("/_File/Empty all _Trash folders"), "<shift>D", empty_trash_cb, 0, NULL},
449         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
450         {N_("/_File/_Save as..."),              "<control>S", save_as_cb, 0, NULL},
451         {N_("/_File/_Print..."),                NULL, print_cb, 0, NULL},
452         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
453         {N_("/_File/_Work offline"),            "<control>W", toggle_work_offline_cb, 0, "<ToggleItem>"},
454         {N_("/_File/---"),                      NULL, NULL, 0, "<Separator>"},
455         /* {N_("/_File/_Close"),                "<alt>W", app_exit_cb, 0, NULL}, */
456         {N_("/_File/E_xit"),                    "<control>Q", app_exit_cb, 0, NULL},
457
458         {N_("/_Edit"),                          NULL, NULL, 0, "<Branch>"},
459         {N_("/_Edit/_Copy"),                    "<control>C", copy_cb, 0, NULL},
460         {N_("/_Edit/Select _all"),              "<control>A", allsel_cb, 0, NULL},
461         {N_("/_Edit/Select _thread"),           NULL, select_thread_cb, 0, NULL},
462         {N_("/_Edit/---"),                      NULL, NULL, 0, "<Separator>"},
463         {N_("/_Edit/_Find in current message..."),
464                                                 "<control>F", search_cb, 0, NULL},
465         {N_("/_Edit/_Search folder..."),        "<shift><control>F", search_cb, 1, NULL},
466         {N_("/_View"),                          NULL, NULL, 0, "<Branch>"},
467         {N_("/_View/Show or hi_de"),            NULL, NULL, 0, "<Branch>"},
468         {N_("/_View/Show or hi_de/_Folder tree"),
469                                                 NULL, toggle_folder_cb, 0, "<ToggleItem>"},
470         {N_("/_View/Show or hi_de/_Message view"),
471                                                 "V", toggle_message_cb, 0, "<ToggleItem>"},
472         {N_("/_View/Show or hi_de/_Toolbar"),
473                                                 NULL, NULL, 0, "<Branch>"},
474         {N_("/_View/Show or hi_de/_Toolbar/Icon _and text"),
475                                                 NULL, toggle_toolbar_cb, TOOLBAR_BOTH, "<RadioItem>"},
476         {N_("/_View/Show or hi_de/_Toolbar/_Icon"),
477                                                 NULL, toggle_toolbar_cb, TOOLBAR_ICON, "/View/Show or hide/Toolbar/Icon and text"},
478         {N_("/_View/Show or hi_de/_Toolbar/_Text"),
479                                                 NULL, toggle_toolbar_cb, TOOLBAR_TEXT, "/View/Show or hide/Toolbar/Icon and text"},
480         {N_("/_View/Show or hi_de/_Toolbar/_None"),
481                                                 NULL, toggle_toolbar_cb, TOOLBAR_NONE, "/View/Show or hide/Toolbar/Icon and text"},
482         {N_("/_View/Show or hi_de/Status _bar"),
483                                                 NULL, toggle_statusbar_cb, 0, "<ToggleItem>"},
484         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
485         {N_("/_View/Separate f_older tree"),    NULL, separate_widget_cb, SEPARATE_FOLDER, "<ToggleItem>"},
486         {N_("/_View/Separate m_essage view"),   NULL, separate_widget_cb, SEPARATE_MESSAGE, "<ToggleItem>"},
487         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
488         {N_("/_View/_Sort"),                    NULL, NULL, 0, "<Branch>"},
489         {N_("/_View/_Sort/by _number"),         NULL, sort_summary_cb, SORT_BY_NUMBER, "<RadioItem>"},
490         {N_("/_View/_Sort/by s_ize"),           NULL, sort_summary_cb, SORT_BY_SIZE, "/View/Sort/by number"},
491         {N_("/_View/_Sort/by _date"),           NULL, sort_summary_cb, SORT_BY_DATE, "/View/Sort/by number"},
492         {N_("/_View/_Sort/by _from"),           NULL, sort_summary_cb, SORT_BY_FROM, "/View/Sort/by number"},
493         {N_("/_View/_Sort/by _recipient"),      NULL, sort_summary_cb, SORT_BY_TO, "/View/Sort/by number"},
494         {N_("/_View/_Sort/by _subject"),        NULL, sort_summary_cb, SORT_BY_SUBJECT, "/View/Sort/by number"},
495         {N_("/_View/_Sort/by _color label"),
496                                                 NULL, sort_summary_cb, SORT_BY_LABEL, "/View/Sort/by number"},
497         {N_("/_View/_Sort/by _mark"),           NULL, sort_summary_cb, SORT_BY_MARK, "/View/Sort/by number"},
498         {N_("/_View/_Sort/by _status"),         NULL, sort_summary_cb, SORT_BY_STATUS, "/View/Sort/by number"},
499         {N_("/_View/_Sort/by a_ttachment"),
500                                                 NULL, sort_summary_cb, SORT_BY_MIME, "/View/Sort/by number"},
501         {N_("/_View/_Sort/by score"),           NULL, sort_summary_cb, SORT_BY_SCORE, "/View/Sort/by number"},
502         {N_("/_View/_Sort/by locked"),          NULL, sort_summary_cb, SORT_BY_LOCKED, "/View/Sort/by number"},
503         {N_("/_View/_Sort/D_on't sort"),        NULL, sort_summary_cb, SORT_BY_NONE, "/View/Sort/by number"},
504         {N_("/_View/_Sort/---"),                NULL, NULL, 0, "<Separator>"},
505         {N_("/_View/_Sort/Ascending"),          NULL, sort_summary_type_cb, SORT_ASCENDING, "<RadioItem>"},
506         {N_("/_View/_Sort/Descending"),         NULL, sort_summary_type_cb, SORT_DESCENDING, "/View/Sort/Ascending"},
507         {N_("/_View/_Sort/---"),                NULL, NULL, 0, "<Separator>"},
508         {N_("/_View/_Sort/_Attract by subject"),
509                                                 NULL, attract_by_subject_cb, 0, NULL},
510         {N_("/_View/Th_read view"),             "<control>T", thread_cb, 0, "<ToggleItem>"},
511         {N_("/_View/E_xpand all threads"),      NULL, expand_threads_cb, 0, NULL},
512         {N_("/_View/Co_llapse all threads"),    NULL, collapse_threads_cb, 0, NULL},
513         {N_("/_View/_Hide read messages"),      NULL, hide_read_messages, 0, "<ToggleItem>"},
514         {N_("/_View/Set displayed _items..."),  NULL, set_display_item_cb, 0, NULL},
515
516         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
517         {N_("/_View/_Go to"),                   NULL, NULL, 0, "<Branch>"},
518         {N_("/_View/_Go to/_Prev message"),     "P", prev_cb, 0, NULL},
519         {N_("/_View/_Go to/_Next message"),     "N", next_cb, 0, NULL},
520         {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
521         {N_("/_View/_Go to/P_rev unread message"),
522                                                 "<shift>P", prev_unread_cb, 0, NULL},
523         {N_("/_View/_Go to/N_ext unread message"),
524                                                 "<shift>N", next_unread_cb, 0, NULL},
525         {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
526         {N_("/_View/_Go to/Prev ne_w message"), NULL, prev_new_cb, 0, NULL},
527         {N_("/_View/_Go to/Ne_xt new message"), NULL, next_new_cb, 0, NULL},
528         {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
529         {N_("/_View/_Go to/Prev _marked message"),
530                                                 NULL, prev_marked_cb, 0, NULL},
531         {N_("/_View/_Go to/Next m_arked message"),
532                                                 NULL, next_marked_cb, 0, NULL},
533         {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
534         {N_("/_View/_Go to/Prev _labeled message"),
535                                                 NULL, prev_labeled_cb, 0, NULL},
536         {N_("/_View/_Go to/Next la_beled message"),
537                                                 NULL, next_labeled_cb, 0, NULL},
538         {N_("/_View/_Go to/---"),               NULL, NULL, 0, "<Separator>"},
539         {N_("/_View/_Go to/Other _folder..."),  "G", goto_folder_cb, 0, NULL},
540         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
541
542 #define CODESET_SEPARATOR \
543         {N_("/_View/_Code set/---"),            NULL, NULL, 0, "<Separator>"}
544 #define CODESET_ACTION(action) \
545          NULL, set_charset_cb, action, "/View/Code set/Auto detect"
546
547         {N_("/_View/_Code set"),                NULL, NULL, 0, "<Branch>"},
548         {N_("/_View/_Code set/_Auto detect"),
549          NULL, set_charset_cb, C_AUTO, "<RadioItem>"},
550         {N_("/_View/_Code set/---"),            NULL, NULL, 0, "<Separator>"},
551         {N_("/_View/_Code set/7bit ascii (US-ASC_II)"),
552          CODESET_ACTION(C_US_ASCII)},
553
554 #if HAVE_ICONV
555         {N_("/_View/_Code set/Unicode (_UTF-8)"),
556          CODESET_ACTION(C_UTF_8)},
557         CODESET_SEPARATOR,
558 #endif
559         {N_("/_View/_Code set/Western European (ISO-8859-_1)"),
560          CODESET_ACTION(C_ISO_8859_1)},
561         {N_("/_View/_Code set/Western European (ISO-8859-15)"),
562          CODESET_ACTION(C_ISO_8859_15)},
563         CODESET_SEPARATOR,
564 #if HAVE_ICONV
565         {N_("/_View/_Code set/Central European (ISO-8859-_2)"),
566          CODESET_ACTION(C_ISO_8859_2)},
567         CODESET_SEPARATOR,
568         {N_("/_View/_Code set/_Baltic (ISO-8859-13)"),
569          CODESET_ACTION(C_ISO_8859_13)},
570         {N_("/_View/_Code set/Baltic (ISO-8859-_4)"),
571          CODESET_ACTION(C_ISO_8859_4)},
572         CODESET_SEPARATOR,
573         {N_("/_View/_Code set/Greek (ISO-8859-_7)"),
574          CODESET_ACTION(C_ISO_8859_7)},
575         CODESET_SEPARATOR,
576         {N_("/_View/_Code set/Turkish (ISO-8859-_9)"),
577          CODESET_ACTION(C_ISO_8859_9)},
578         CODESET_SEPARATOR,
579         {N_("/_View/_Code set/Cyrillic (ISO-8859-_5)"),
580          CODESET_ACTION(C_ISO_8859_5)},
581         {N_("/_View/_Code set/Cyrillic (KOI8-_R)"),
582          CODESET_ACTION(C_KOI8_R)},
583         {N_("/_View/_Code set/Cyrillic (KOI8-U)"),
584          CODESET_ACTION(C_KOI8_U)},
585         {N_("/_View/_Code set/Cyrillic (Windows-1251)"),
586          CODESET_ACTION(C_WINDOWS_1251)},
587         CODESET_SEPARATOR,
588 #endif
589         {N_("/_View/_Code set/Japanese (ISO-2022-_JP)"),
590          CODESET_ACTION(C_ISO_2022_JP)},
591 #if HAVE_ICONV
592         {N_("/_View/_Code set/Japanese (ISO-2022-JP-2)"),
593          CODESET_ACTION(C_ISO_2022_JP_2)},
594 #endif
595         {N_("/_View/_Code set/Japanese (_EUC-JP)"),
596          CODESET_ACTION(C_EUC_JP)},
597         {N_("/_View/_Code set/Japanese (_Shift__JIS)"),
598          CODESET_ACTION(C_SHIFT_JIS)},
599 #if HAVE_ICONV
600         CODESET_SEPARATOR,
601         {N_("/_View/_Code set/Simplified Chinese (_GB2312)"),
602          CODESET_ACTION(C_GB2312)},
603         {N_("/_View/_Code set/Traditional Chinese (_Big5)"),
604          CODESET_ACTION(C_BIG5)},
605         {N_("/_View/_Code set/Traditional Chinese (EUC-_TW)"),
606          CODESET_ACTION(C_EUC_TW)},
607         {N_("/_View/_Code set/Chinese (ISO-2022-_CN)"),
608          CODESET_ACTION(C_ISO_2022_CN)},
609         CODESET_SEPARATOR,
610         {N_("/_View/_Code set/Korean (EUC-_KR)"),
611          CODESET_ACTION(C_EUC_KR)},
612         {N_("/_View/_Code set/Korean (ISO-2022-KR)"),
613          CODESET_ACTION(C_ISO_2022_KR)},
614         CODESET_SEPARATOR,
615         {N_("/_View/_Code set/Thai (TIS-620)"),
616          CODESET_ACTION(C_TIS_620)},
617         {N_("/_View/_Code set/Thai (Windows-874)"),
618          CODESET_ACTION(C_WINDOWS_874)},
619 #endif
620
621 #undef CODESET_SEPARATOR
622 #undef CODESET_ACTION
623
624 #define DECODE_SEPARATOR \
625         {N_("/_View/Decode/---"),               NULL, NULL, 0, "<Separator>"}
626 #define DECODE_ACTION(action) \
627          NULL, set_decode_cb, action, "/View/Decode/Auto detect"
628         {N_("/_View/Decode"),           NULL, NULL, 0, "<Branch>"},
629         {N_("/_View/Decode/_Auto detect"),
630          NULL, set_decode_cb, 0, "<RadioItem>"},
631         {N_("/_View/Decode/---"),               NULL, NULL, 0, "<Separator>"},
632         {N_("/_View/Decode/_8bit"),             DECODE_ACTION(ENC_8BIT)},
633         {N_("/_View/Decode/_Quoted printable"), DECODE_ACTION(ENC_QUOTED_PRINTABLE)},
634         {N_("/_View/Decode/_Base64"),           DECODE_ACTION(ENC_BASE64)},
635         {N_("/_View/Decode/_Uuencode"),         DECODE_ACTION(ENC_X_UUENCODE)},
636
637 #undef DECODE_SEPARATOR
638 #undef DECODE_ACTION
639
640         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
641         {N_("/_View/Open in new _window"),      "<control><alt>N", open_msg_cb, 0, NULL},
642         {N_("/_View/Mess_age source"),          "<control>U", view_source_cb, 0, NULL},
643         {N_("/_View/Show all _headers"),        "<control>H", show_all_header_cb, 0, "<ToggleItem>"},
644         {N_("/_View/---"),                      NULL, NULL, 0, "<Separator>"},
645         {N_("/_View/_Update summary"),          "<control><alt>U", update_summary_cb,  0, NULL},
646
647         {N_("/_Message"),                       NULL, NULL, 0, "<Branch>"},
648         {N_("/_Message/Recei_ve"),              NULL, NULL, 0, "<Branch>"},
649         {N_("/_Message/Recei_ve/Get from _current account"),
650                                                 "<control>I",   inc_mail_cb, 0, NULL},
651         {N_("/_Message/Recei_ve/Get from _all accounts"),
652                                                 "<shift><control>I", inc_all_account_mail_cb, 0, NULL},
653         {N_("/_Message/Recei_ve/Cancel receivin_g"),
654                                                 NULL, inc_cancel_cb, 0, NULL},
655         {N_("/_Message/Recei_ve/---"),          NULL, NULL, 0, "<Separator>"},
656         {N_("/_Message/_Send queued messages"), NULL, send_queue_cb, 0, NULL},
657         {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
658         {N_("/_Message/Compose a_n email message"),     "<control>M", compose_mail_cb, 0, NULL},
659         {N_("/_Message/Compose a news message"),        NULL,   compose_news_cb, 0, NULL},
660         {N_("/_Message/_Reply"),                "<control>R",   main_window_reply_cb, COMPOSE_REPLY, NULL},
661         {N_("/_Message/Repl_y to"),             NULL, NULL, 0, "<Branch>"},
662         {N_("/_Message/Repl_y to/_all"),        "<shift><control>R", main_window_reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
663         {N_("/_Message/Repl_y to/_sender"),     NULL, main_window_reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
664         {N_("/_Message/Repl_y to/mailing _list"),
665                                                 "<control>L", main_window_reply_cb, COMPOSE_REPLY_TO_LIST, NULL},
666         {N_("/_Message/Follow-up and reply to"),NULL, main_window_reply_cb, COMPOSE_FOLLOWUP_AND_REPLY_TO, NULL},
667         {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
668         {N_("/_Message/_Forward"),              "<control><alt>F", main_window_reply_cb, COMPOSE_FORWARD, NULL},
669         {N_("/_Message/Redirect"),              NULL, main_window_reply_cb, COMPOSE_REDIRECT, NULL},
670         {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
671         {N_("/_Message/M_ove..."),              "<control>O", move_to_cb, 0, NULL},
672         {N_("/_Message/_Copy..."),              "<shift><control>O", copy_to_cb, 0, NULL},
673         {N_("/_Message/_Delete"),               "<control>D", delete_cb,  0, NULL},
674         {N_("/_Message/Cancel a news message"), "", cancel_cb,  0, NULL},
675         {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
676         {N_("/_Message/_Mark"),                 NULL, NULL, 0, "<Branch>"},
677         {N_("/_Message/_Mark/_Mark"),           "<shift>asterisk", mark_cb, 0, NULL},
678         {N_("/_Message/_Mark/_Unmark"),         "U", unmark_cb, 0, NULL},
679         {N_("/_Message/_Mark/---"),             NULL, NULL, 0, "<Separator>"},
680         {N_("/_Message/_Mark/Mark as unr_ead"), "<shift>exclam", mark_as_unread_cb, 0, NULL},
681         {N_("/_Message/_Mark/Mark as rea_d"),
682                                                 NULL, mark_as_read_cb, 0, NULL},
683         {N_("/_Message/_Mark/Mark all _read"),  NULL, mark_all_read_cb, 0, NULL},
684         {N_("/_Message/---"),                   NULL, NULL, 0, "<Separator>"},
685         {N_("/_Message/Re-_edit"),              NULL, reedit_cb, 0, NULL},
686
687         {N_("/_Tools"),                         NULL, NULL, 0, "<Branch>"},
688         {N_("/_Tools/_Address book..."),        "<shift><control>A", addressbook_open_cb, 0, NULL},
689         {N_("/_Tools/Add sender to address boo_k"),
690                                                 NULL, add_address_cb, 0, NULL},
691         {N_("/_Tools/_Harvest addresses"),      NULL, NULL, 0, "<Branch>"},
692         {N_("/_Tools/_Harvest addresses/from _Folder..."),
693                                                 NULL, addr_harvest_cb, 0, NULL},
694         {N_("/_Tools/_Harvest addresses/from _Messages..."),
695                                                 NULL, addr_harvest_msg_cb, 0, NULL},
696         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
697         {N_("/_Tools/_Filter all messages in folder"),
698                                                 NULL, filter_cb, 0, NULL},
699         {N_("/_Tools/Filter _selected messages"),
700                                                 NULL, filter_cb, 1, NULL},
701         {N_("/_Tools/_Create filter rule"),     NULL, NULL, 0, "<Branch>"},
702         {N_("/_Tools/_Create filter rule/_Automatically"),
703                                                 NULL, create_filter_cb, FILTER_BY_AUTO, NULL},
704         {N_("/_Tools/_Create filter rule/by _From"),
705                                                 NULL, create_filter_cb, FILTER_BY_FROM, NULL},
706         {N_("/_Tools/_Create filter rule/by _To"),
707                                                 NULL, create_filter_cb, FILTER_BY_TO, NULL},
708         {N_("/_Tools/_Create filter rule/by _Subject"),
709                                                 NULL, create_filter_cb, FILTER_BY_SUBJECT, NULL},
710         {N_("/_Tools/_Create processing rule"), NULL, NULL, 0, "<Branch>"},
711         {N_("/_Tools/_Create processing rule/_Automatically"),
712                                                 NULL, create_processing_cb, FILTER_BY_AUTO, NULL},
713         {N_("/_Tools/_Create processing rule/by _From"),
714                                                 NULL, create_processing_cb, FILTER_BY_FROM, NULL},
715         {N_("/_Tools/_Create processing rule/by _To"),
716                                                 NULL, create_processing_cb, FILTER_BY_TO, NULL},
717         {N_("/_Tools/_Create processing rule/by _Subject"),
718                                                 NULL, create_processing_cb, FILTER_BY_SUBJECT, NULL},
719         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
720         {N_("/_Tools/Actio_ns"),                NULL, NULL, 0, "<Branch>"},
721         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
722         {N_("/_Tools/_Check for new messages in all folders"),
723                                                 NULL, update_folderview_cb, 0, NULL},
724         {N_("/_Tools/Delete du_plicated messages"),
725                                                 NULL, NULL, 0, "<Branch>"},
726         {N_("/_Tools/Delete du_plicated messages/In selected folder"),
727                                                 NULL, delete_duplicated_cb,   0, NULL},
728         {N_("/_Tools/Delete du_plicated messages/In all folders"),
729                                                 NULL, delete_duplicated_all_cb,   0, NULL},
730         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
731         {N_("/_Tools/E_xecute"),                "X", execute_summary_cb, 0, NULL},
732 #ifdef USE_OPENSSL
733         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
734         {N_("/_Tools/SSL certi_ficates..."),    
735                                                 NULL, ssl_manager_open_cb, 0, NULL},
736 #endif
737         {N_("/_Tools/---"),                     NULL, NULL, 0, "<Separator>"},
738         {N_("/_Tools/_Log window"),             "<shift><control>L", log_window_show_cb, 0, NULL},
739
740         {N_("/_Configuration"),                 NULL, NULL, 0, "<Branch>"},
741         {N_("/_Configuration/C_hange current account"),
742                                                 NULL, NULL, 0, "<Branch>"},
743         {N_("/_Configuration/_Preferences for current account..."),
744                                                 NULL, prefs_account_open_cb, 0, NULL},
745         {N_("/_Configuration/Create _new account..."),
746                                                 NULL, new_account_cb, 0, NULL},
747         {N_("/_Configuration/_Edit accounts..."),
748                                                 NULL, account_edit_open, 0, NULL},
749         {N_("/_Configuration/---"),             NULL, NULL, 0, "<Separator>"},
750         {N_("/_Configuration/_Common preferences..."),
751                                                 NULL, prefs_common_open_cb, 0, NULL},
752         {N_("/_Configuration/Pre-processing..."),
753                                                 NULL, prefs_pre_processing_open_cb, 0, NULL},
754         {N_("/_Configuration/Post-processing..."),
755                                                 NULL, prefs_post_processing_open_cb, 0, NULL},
756         {N_("/_Configuration/_Filtering..."),
757                                                 NULL, prefs_filtering_open_cb, 0, NULL},
758         {N_("/_Configuration/_Templates..."),   NULL, prefs_template_open_cb, 0, NULL},
759         {N_("/_Configuration/_Actions..."),     NULL, prefs_actions_open_cb, 0, NULL},
760         {N_("/_Configuration/_Other Preferences..."),  NULL, prefs_open_cb, 0, NULL},
761         {N_("/_Configuration/Plugins..."),      NULL, plugins_open_cb, 0, NULL},
762
763         {N_("/_Help"),                          NULL, NULL, 0, "<Branch>"},
764         {N_("/_Help/_Manual (Local)"),          NULL, manual_open_cb, MANUAL_MANUAL_LOCAL, NULL},
765         {N_("/_Help/_Manual (Sylpheed Doc Homepage)"),
766                                                 NULL, manual_open_cb, MANUAL_MANUAL_SYLDOC, NULL},
767         {N_("/_Help/_FAQ (Local)"),             NULL, manual_open_cb, MANUAL_FAQ_LOCAL, NULL},
768         {N_("/_Help/_FAQ (Sylpheed Doc Homepage)"),
769                                                 NULL, manual_open_cb, MANUAL_FAQ_SYLDOC, NULL},
770         {N_("/_Help/_Claws FAQ (Claws Documentation)"),
771                                                 NULL, manual_open_cb, MANUAL_FAQ_CLAWS, NULL},
772         {N_("/_Help/---"),                      NULL, NULL, 0, "<Separator>"},
773         {N_("/_Help/_About"),                   NULL, about_show, 0, NULL}
774 };
775
776 MainWindow *main_window_create(SeparateType type)
777 {
778         MainWindow *mainwin;
779         GtkWidget *window;
780         GtkWidget *vbox;
781         GtkWidget *menubar;
782         GtkWidget *handlebox;
783         GtkWidget *vbox_body;
784         GtkWidget *hbox_stat;
785         GtkWidget *statusbar;
786         GtkWidget *progressbar;
787         GtkWidget *statuslabel;
788         GtkWidget *ac_button;
789         GtkWidget *ac_label;
790         GtkWidget *online_pixmap;
791         GtkWidget *offline_pixmap;
792         GtkWidget *online_switch;
793         GtkWidget *offline_switch;
794         GtkTooltips *offline_tip;
795         GtkTooltips *online_tip;
796         GtkTooltips *sel_ac_tip;
797
798         FolderView *folderview;
799         SummaryView *summaryview;
800         MessageView *messageview;
801         GdkColormap *colormap;
802         GdkColor color[4];
803         gboolean success[4];
804         GtkItemFactory *ifactory;
805         GtkWidget *ac_menu;
806         GtkWidget *menuitem;
807         gint i;
808         guint n_menu_entries;
809         gboolean hide_messageview = FALSE;
810
811         static GdkGeometry geometry;
812
813         debug_print("Creating main window...\n");
814         mainwin = g_new0(MainWindow, 1);
815
816         /* main window */
817         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
818         gtk_window_set_title(GTK_WINDOW(window), PROG_VERSION);
819         gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
820         gtk_window_set_wmclass(GTK_WINDOW(window), "main_window", "Sylpheed");
821
822         if (!geometry.min_height) {
823                 geometry.min_width = 320;
824                 geometry.min_height = 200;
825         }
826         gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
827                                       GDK_HINT_MIN_SIZE);
828
829         gtk_signal_connect(GTK_OBJECT(window), "delete_event",
830                            GTK_SIGNAL_FUNC(main_window_close_cb), mainwin);
831         MANAGE_WINDOW_SIGNALS_CONNECT(window);
832         gtk_signal_connect(GTK_OBJECT(window), "focus_in_event",
833                            GTK_SIGNAL_FUNC(mainwindow_focus_in_event),
834                            mainwin);
835         gtk_signal_connect(GTK_OBJECT(window), "key_press_event",
836                                 GTK_SIGNAL_FUNC(mainwindow_key_pressed), mainwin);
837
838         gtk_widget_realize(window);
839         gtk_widget_add_events(window, GDK_KEY_PRESS_MASK|GDK_KEY_RELEASE_MASK);
840         
841
842         gtkut_widget_set_app_icon(window);
843
844         vbox = gtk_vbox_new(FALSE, 0);
845         gtk_widget_show(vbox);
846         gtk_container_add(GTK_CONTAINER(window), vbox);
847
848         /* menu bar */
849         n_menu_entries = sizeof(mainwin_entries) / sizeof(mainwin_entries[0]);
850         menubar = menubar_create(window, mainwin_entries, 
851                                  n_menu_entries, "<Main>", mainwin);
852         gtk_widget_show(menubar);
853         gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
854         ifactory = gtk_item_factory_from_widget(menubar);
855
856         menu_set_sensitive(ifactory, "/Help/Manual (Local)", manual_available(MANUAL_MANUAL_LOCAL));
857         menu_set_sensitive(ifactory, "/Help/FAQ (Local)", manual_available(MANUAL_FAQ_LOCAL));
858
859         handlebox = gtk_handle_box_new();
860         gtk_widget_show(handlebox);
861         gtk_box_pack_start(GTK_BOX(vbox), handlebox, FALSE, FALSE, 0);
862         gtk_signal_connect(GTK_OBJECT(handlebox), "child_attached",
863                            GTK_SIGNAL_FUNC(toolbar_child_attached), mainwin);
864         gtk_signal_connect(GTK_OBJECT(handlebox), "child_detached",
865                            GTK_SIGNAL_FUNC(toolbar_child_detached), mainwin);
866
867         /* link window to mainwin->window to avoid gdk warnings */
868         mainwin->window       = window;
869         
870         /* create toolbar */
871         mainwin->toolbar = toolbar_create(TOOLBAR_MAIN, 
872                                           handlebox, 
873                                           (gpointer)mainwin);
874
875         /* vbox that contains body */
876         vbox_body = gtk_vbox_new(FALSE, BORDER_WIDTH);
877         gtk_widget_show(vbox_body);
878         gtk_container_set_border_width(GTK_CONTAINER(vbox_body), BORDER_WIDTH);
879         gtk_box_pack_start(GTK_BOX(vbox), vbox_body, TRUE, TRUE, 0);
880
881         hbox_stat = gtk_hbox_new(FALSE, 2);
882         gtk_box_pack_end(GTK_BOX(vbox_body), hbox_stat, FALSE, FALSE, 0);
883
884         statusbar = statusbar_create();
885         gtk_box_pack_start(GTK_BOX(hbox_stat), statusbar, TRUE, TRUE, 0);
886
887         progressbar = gtk_progress_bar_new();
888         gtk_widget_set_usize(progressbar, 120, 1);
889         gtk_box_pack_start(GTK_BOX(hbox_stat), progressbar, FALSE, FALSE, 0);
890
891         online_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_ONLINE);
892         offline_pixmap = stock_pixmap_widget(hbox_stat, STOCK_PIXMAP_OFFLINE);
893         online_tip = gtk_tooltips_new();
894         online_switch = gtk_button_new ();
895         gtk_tooltips_set_tip(GTK_TOOLTIPS(online_tip),online_switch, 
896                              _("You are online. Click the icon to go offline"), NULL);
897         offline_tip = gtk_tooltips_new();
898         offline_switch = gtk_button_new ();
899         gtk_tooltips_set_tip(GTK_TOOLTIPS(offline_tip),offline_switch, 
900                              _("You are offline. Click the icon to go online"),
901                              NULL);
902         gtk_container_add (GTK_CONTAINER(online_switch), online_pixmap);
903         gtk_button_set_relief (GTK_BUTTON(online_switch), GTK_RELIEF_NONE);
904         gtk_signal_connect (GTK_OBJECT(online_switch), "clicked", (GtkSignalFunc)online_switch_clicked, mainwin);
905         gtk_box_pack_start (GTK_BOX(hbox_stat), online_switch, FALSE, FALSE, 0);
906         gtk_container_add (GTK_CONTAINER(offline_switch), offline_pixmap);
907         gtk_button_set_relief (GTK_BUTTON(offline_switch), GTK_RELIEF_NONE);
908         gtk_signal_connect (GTK_OBJECT(offline_switch), "clicked", (GtkSignalFunc)online_switch_clicked, mainwin);
909         gtk_box_pack_start (GTK_BOX(hbox_stat), offline_switch, FALSE, FALSE, 0);
910         
911         statuslabel = gtk_label_new("");
912         gtk_box_pack_start(GTK_BOX(hbox_stat), statuslabel, FALSE, FALSE, 0);
913
914         sel_ac_tip = gtk_tooltips_new();
915         ac_button = gtk_button_new();
916         gtk_tooltips_set_tip(GTK_TOOLTIPS(sel_ac_tip),
917                              ac_button, _("Select account"), NULL);
918         gtk_button_set_relief(GTK_BUTTON(ac_button), GTK_RELIEF_NONE);
919         GTK_WIDGET_UNSET_FLAGS(ac_button, GTK_CAN_FOCUS);
920         gtk_widget_set_usize(ac_button, -1, 1);
921         gtk_box_pack_end(GTK_BOX(hbox_stat), ac_button, FALSE, FALSE, 0);
922         gtk_signal_connect(GTK_OBJECT(ac_button), "button_press_event",
923                            GTK_SIGNAL_FUNC(ac_label_button_pressed), mainwin);
924
925         ac_label = gtk_label_new("");
926         gtk_container_add(GTK_CONTAINER(ac_button), ac_label);
927
928         gtk_widget_show_all(hbox_stat);
929
930         gtk_widget_hide(offline_switch);
931         /* create views */
932         mainwin->folderview  = folderview  = folderview_create();
933         mainwin->summaryview = summaryview = summary_create();
934         mainwin->messageview = messageview = messageview_create(mainwin);
935         mainwin->logwin      = log_window_create();
936
937         folderview->mainwin      = mainwin;
938         folderview->summaryview  = summaryview;
939
940         summaryview->mainwin     = mainwin;
941         summaryview->folderview  = folderview;
942         summaryview->messageview = messageview;
943         summaryview->window      = window;
944
945         messageview->statusbar   = statusbar;
946         mainwin->vbox           = vbox;
947         mainwin->menubar        = menubar;
948         mainwin->menu_factory   = ifactory;
949         mainwin->handlebox      = handlebox;
950         mainwin->vbox_body      = vbox_body;
951         mainwin->hbox_stat      = hbox_stat;
952         mainwin->statusbar      = statusbar;
953         mainwin->progressbar    = progressbar;
954         mainwin->statuslabel    = statuslabel;
955         mainwin->online_switch  = online_switch;
956         mainwin->online_pixmap  = online_pixmap;
957         mainwin->offline_pixmap = offline_pixmap;
958         mainwin->ac_button      = ac_button;
959         mainwin->ac_label       = ac_label;
960         mainwin->offline_switch    = offline_switch;
961         
962         /* set context IDs for status bar */
963         mainwin->mainwin_cid = gtk_statusbar_get_context_id
964                 (GTK_STATUSBAR(statusbar), "Main Window");
965         mainwin->folderview_cid = gtk_statusbar_get_context_id
966                 (GTK_STATUSBAR(statusbar), "Folder View");
967         mainwin->summaryview_cid = gtk_statusbar_get_context_id
968                 (GTK_STATUSBAR(statusbar), "Summary View");
969         mainwin->messageview_cid = gtk_statusbar_get_context_id
970                 (GTK_STATUSBAR(statusbar), "Message View");
971
972         messageview->statusbar_cid = mainwin->messageview_cid;
973
974         /* allocate colors for summary view and folder view */
975         summaryview->color_marked.red = summaryview->color_marked.green = 0;
976         summaryview->color_marked.blue = (guint16)65535;
977
978         summaryview->color_dim.red = summaryview->color_dim.green =
979                 summaryview->color_dim.blue = COLOR_DIM;
980
981         gtkut_convert_int_to_gdk_color(prefs_common.color_new,
982                                        &folderview->color_new);
983
984         gtkut_convert_int_to_gdk_color(prefs_common.tgt_folder_col,
985                                        &folderview->color_op);
986
987         summaryview->color_important.red = 0;
988         summaryview->color_important.green = 0;
989         summaryview->color_important.blue = (guint16)65535;
990
991         color[0] = summaryview->color_marked;
992         color[1] = summaryview->color_dim;
993         color[2] = folderview->color_new;
994         color[3] = folderview->color_op;
995
996         colormap = gdk_window_get_colormap(window->window);
997         gdk_colormap_alloc_colors(colormap, color, 4, FALSE, TRUE, success);
998         for (i = 0; i < 4; i++) {
999                 if (success[i] == FALSE)
1000                         g_warning("MainWindow: color allocation %d failed\n", i);
1001         }
1002
1003         debug_print("done.\n");
1004
1005         messageview->visible = prefs_common.msgview_visible;
1006         hide_messageview = !messageview->visible;
1007         
1008         main_window_set_widgets(mainwin, type);
1009
1010         gtk_signal_connect(GTK_OBJECT(window), "size_allocate",
1011                            GTK_SIGNAL_FUNC(main_window_size_allocate_cb),
1012                            mainwin);
1013
1014         /* set menu items */
1015         menuitem = gtk_item_factory_get_item
1016                 (ifactory, "/View/Code set/Auto detect");
1017         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1018
1019         switch (prefs_common.toolbar_style) {
1020         case TOOLBAR_NONE:
1021                 menuitem = gtk_item_factory_get_item
1022                         (ifactory, "/View/Show or hide/Toolbar/None");
1023                 break;
1024         case TOOLBAR_ICON:
1025                 menuitem = gtk_item_factory_get_item
1026                         (ifactory, "/View/Show or hide/Toolbar/Icon");
1027                 break;
1028         case TOOLBAR_TEXT:
1029                 menuitem = gtk_item_factory_get_item
1030                         (ifactory, "/View/Show or hide/Toolbar/Text");
1031                 break;
1032         case TOOLBAR_BOTH:
1033                 menuitem = gtk_item_factory_get_item
1034                         (ifactory, "/View/Show or hide/Toolbar/Icon and text");
1035         }
1036         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1037
1038         gtk_widget_hide(mainwin->hbox_stat);
1039         menuitem = gtk_item_factory_get_item
1040                 (ifactory, "/View/Show or hide/Status bar");
1041         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
1042                                        prefs_common.show_statusbar);
1043         
1044         /* set account selection menu */
1045         ac_menu = gtk_item_factory_get_widget
1046                 (ifactory, "/Configuration/Change current account");
1047         gtk_signal_connect(GTK_OBJECT(ac_menu), "selection_done",
1048                            GTK_SIGNAL_FUNC(ac_menu_popup_closed), mainwin);
1049         mainwin->ac_menu = ac_menu;
1050
1051         toolbar_main_set_sensitive(mainwin);
1052
1053         /* create actions menu */
1054         main_window_update_actions_menu(mainwin);
1055
1056         /* attach accel groups to main window */
1057 #define ADD_MENU_ACCEL_GROUP_TO_WINDOW(menu,win)        \
1058         gtk_window_add_accel_group                      \
1059                 (GTK_WINDOW(win),                       \
1060                  gtk_item_factory_from_widget(menu)->accel_group)                
1061         
1062         ADD_MENU_ACCEL_GROUP_TO_WINDOW(summaryview->popupmenu, mainwin->window);
1063         
1064         /* connect the accelerators for equivalent 
1065            menu items in different menus             */
1066         menu_connect_identical_items();
1067
1068
1069         
1070         /* show main window */
1071         gtk_widget_show(mainwin->window);
1072
1073         /* initialize views */
1074         folderview_init(folderview);
1075         summary_init(summaryview);
1076         messageview_init(messageview);
1077         log_window_init(mainwin->logwin);
1078         log_window_set_clipping(mainwin->logwin, prefs_common.cliplog,
1079                                 prefs_common.loglength);
1080 #ifdef USE_OPENSSL
1081         sslcertwindow_register_hook();
1082 #endif
1083         mainwin->lock_count = 0;
1084         mainwin->menu_lock_count = 0;
1085         mainwin->cursor_count = 0;
1086
1087         mainwin->progressindicator_hook =
1088                 hooks_register_hook(PROGRESSINDICATOR_HOOKLIST, mainwindow_progressindicator_hook, mainwin);
1089
1090         if (!watch_cursor)
1091                 watch_cursor = gdk_cursor_new(GDK_WATCH);
1092
1093         mainwin_list = g_list_append(mainwin_list, mainwin);
1094
1095         /* init work_offline */
1096         if (prefs_common.work_offline)
1097                 online_switch_clicked (GTK_BUTTON(online_switch), mainwin);
1098
1099         if (mainwin->type == SEPARATE_NONE && hide_messageview)
1100                 main_window_toggle_message_view(mainwin);
1101
1102         return mainwin;
1103 }
1104
1105 void main_window_destroy(MainWindow *mainwin)
1106 {
1107         /* TODO : destroy other component */
1108         messageview_destroy(mainwin->messageview);
1109 }
1110
1111 void main_window_update_actions_menu(MainWindow *mainwin)
1112 {
1113         GtkItemFactory *ifactory;
1114
1115         ifactory = gtk_item_factory_from_widget(mainwin->menubar);
1116         action_update_mainwin_menu(ifactory, "/Tools/Actions", mainwin);
1117 }
1118
1119 void main_window_cursor_wait(MainWindow *mainwin)
1120 {
1121
1122         if (mainwin->cursor_count == 0)
1123                 gdk_window_set_cursor(mainwin->window->window, watch_cursor);
1124
1125         mainwin->cursor_count++;
1126
1127         gdk_flush();
1128 }
1129
1130 void main_window_cursor_normal(MainWindow *mainwin)
1131 {
1132         if (mainwin->cursor_count)
1133                 mainwin->cursor_count--;
1134
1135         if (mainwin->cursor_count == 0)
1136                 gdk_window_set_cursor(mainwin->window->window, NULL);
1137
1138         gdk_flush();
1139 }
1140
1141 /* lock / unlock the user-interface */
1142 void main_window_lock(MainWindow *mainwin)
1143 {
1144         if (mainwin->lock_count == 0)
1145                 gtk_widget_set_sensitive(mainwin->ac_button, FALSE);
1146
1147         mainwin->lock_count++;
1148
1149         main_window_set_menu_sensitive(mainwin);
1150         toolbar_main_set_sensitive(mainwin);
1151 }
1152
1153 void main_window_unlock(MainWindow *mainwin)
1154 {
1155         if (mainwin->lock_count)
1156                 mainwin->lock_count--;
1157
1158         main_window_set_menu_sensitive(mainwin);
1159         toolbar_main_set_sensitive(mainwin);
1160
1161         if (mainwin->lock_count == 0)
1162                 gtk_widget_set_sensitive(mainwin->ac_button, TRUE);
1163 }
1164
1165 static void main_window_menu_callback_block(MainWindow *mainwin)
1166 {
1167         mainwin->menu_lock_count++;
1168 }
1169
1170 static void main_window_menu_callback_unblock(MainWindow *mainwin)
1171 {
1172         if (mainwin->menu_lock_count)
1173                 mainwin->menu_lock_count--;
1174 }
1175
1176 void main_window_reflect_prefs_all(void)
1177 {
1178         main_window_reflect_prefs_all_real(FALSE);
1179 }
1180
1181 void main_window_reflect_prefs_all_real(gboolean pixmap_theme_changed)
1182 {
1183         GList *cur;
1184         MainWindow *mainwin;
1185         GtkWidget *pixmap;
1186
1187         for (cur = mainwin_list; cur != NULL; cur = cur->next) {
1188                 mainwin = (MainWindow *)cur->data;
1189
1190                 main_window_show_cur_account(mainwin);
1191                 main_window_set_menu_sensitive(mainwin);
1192                 toolbar_main_set_sensitive(mainwin);
1193
1194                 /* pixmap themes */
1195                 if (pixmap_theme_changed) {
1196                         toolbar_update(TOOLBAR_MAIN, mainwin);
1197                         messageview_reflect_prefs_pixmap_theme();
1198                         compose_reflect_prefs_pixmap_theme();
1199                         folderview_reflect_prefs_pixmap_theme(mainwin->folderview);
1200                         summary_reflect_prefs_pixmap_theme(mainwin->summaryview);
1201
1202                         pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_ONLINE);
1203                         gtk_container_remove(GTK_CONTAINER(mainwin->online_switch), 
1204                                              mainwin->online_pixmap);
1205                         gtk_container_add (GTK_CONTAINER(mainwin->online_switch), pixmap);
1206                         gtk_widget_show(pixmap);
1207                         mainwin->online_pixmap = pixmap;
1208                         pixmap = stock_pixmap_widget(mainwin->hbox_stat, STOCK_PIXMAP_OFFLINE);
1209                         gtk_container_remove(GTK_CONTAINER(mainwin->offline_switch), 
1210                                              mainwin->offline_pixmap);
1211                         gtk_container_add (GTK_CONTAINER(mainwin->offline_switch), pixmap);
1212                         gtk_widget_show(pixmap);
1213                         mainwin->offline_pixmap = pixmap;
1214                 }
1215                 
1216                 summary_redisplay_msg(mainwin->summaryview);
1217                 headerview_set_visibility(mainwin->messageview->headerview,
1218                                           prefs_common.display_header_pane);
1219         }
1220 }
1221
1222 void main_window_set_summary_column(void)
1223 {
1224         GList *cur;
1225         MainWindow *mainwin;
1226
1227         for (cur = mainwin_list; cur != NULL; cur = cur->next) {
1228                 mainwin = (MainWindow *)cur->data;
1229                 summary_set_column_order(mainwin->summaryview);
1230         }
1231 }
1232
1233 static void main_window_set_account_selector_menu(MainWindow *mainwin,
1234                                                   GList *account_list)
1235 {
1236         GList *cur_ac, *cur_item;
1237         GtkWidget *menuitem;
1238         PrefsAccount *ac_prefs;
1239
1240         /* destroy all previous menu item */
1241         cur_item = GTK_MENU_SHELL(mainwin->ac_menu)->children;
1242         while (cur_item != NULL) {
1243                 GList *next = cur_item->next;
1244                 gtk_widget_destroy(GTK_WIDGET(cur_item->data));
1245                 cur_item = next;
1246         }
1247
1248         for (cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) {
1249                 ac_prefs = (PrefsAccount *)cur_ac->data;
1250
1251                 menuitem = gtk_menu_item_new_with_label
1252                         (ac_prefs->account_name
1253                          ? ac_prefs->account_name : _("Untitled"));
1254                 gtk_widget_show(menuitem);
1255                 gtk_menu_append(GTK_MENU(mainwin->ac_menu), menuitem);
1256                 gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
1257                                    GTK_SIGNAL_FUNC(account_selector_menu_cb),
1258                                    ac_prefs);
1259         }
1260 }
1261
1262 static void main_window_set_account_receive_menu(MainWindow *mainwin,
1263                                                  GList *account_list)
1264 {
1265         GList *cur_ac, *cur_item;
1266         GtkWidget *menu;
1267         GtkWidget *menuitem;
1268         PrefsAccount *ac_prefs;
1269
1270         menu = gtk_item_factory_get_widget(mainwin->menu_factory,
1271                                            "/Message/Receive");
1272
1273         /* search for separator */
1274         for (cur_item = GTK_MENU_SHELL(menu)->children; cur_item != NULL;
1275              cur_item = cur_item->next) {
1276                 if (GTK_BIN(cur_item->data)->child == NULL) {
1277                         cur_item = cur_item->next;
1278                         break;
1279                 }
1280         }
1281
1282         /* destroy all previous menu item */
1283         while (cur_item != NULL) {
1284                 GList *next = cur_item->next;
1285                 gtk_widget_destroy(GTK_WIDGET(cur_item->data));
1286                 cur_item = next;
1287         }
1288
1289         for (cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) {
1290                 ac_prefs = (PrefsAccount *)cur_ac->data;
1291
1292                 menuitem = gtk_menu_item_new_with_label
1293                         (ac_prefs->account_name ? ac_prefs->account_name
1294                          : _("Untitled"));
1295                 gtk_widget_show(menuitem);
1296                 gtk_menu_append(GTK_MENU(menu), menuitem);
1297                 gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
1298                                    GTK_SIGNAL_FUNC(account_receive_menu_cb),
1299                                    ac_prefs);
1300         }
1301 }
1302
1303 void main_window_set_account_menu(GList *account_list)
1304 {
1305         GList *cur;
1306         MainWindow *mainwin;
1307
1308         for (cur = mainwin_list; cur != NULL; cur = cur->next) {
1309                 mainwin = (MainWindow *)cur->data;
1310                 main_window_set_account_selector_menu(mainwin, account_list);
1311                 main_window_set_account_receive_menu(mainwin, account_list);
1312         }
1313 }
1314
1315 static void main_window_show_cur_account(MainWindow *mainwin)
1316 {
1317         gchar *buf;
1318         gchar *ac_name;
1319
1320         ac_name = g_strdup(cur_account
1321                            ? (cur_account->account_name
1322                               ? cur_account->account_name : _("Untitled"))
1323                            : _("none"));
1324
1325         if (cur_account)
1326                 buf = g_strdup_printf("%s - %s", ac_name, PROG_VERSION);
1327         else
1328                 buf = g_strdup(PROG_VERSION);
1329         gtk_window_set_title(GTK_WINDOW(mainwin->window), buf);
1330         g_free(buf);
1331
1332         gtk_label_set_text(GTK_LABEL(mainwin->ac_label), ac_name);
1333         gtk_widget_queue_resize(mainwin->ac_button);
1334
1335         g_free(ac_name);
1336 }
1337
1338 GtkWidget *main_window_get_folder_window(MainWindow *mainwin)
1339 {
1340         switch (mainwin->type) {
1341         case SEPARATE_FOLDER:
1342                 return mainwin->win.sep_folder.folderwin;
1343         case SEPARATE_BOTH:
1344                 return mainwin->win.sep_both.folderwin;
1345         default:
1346                 return NULL;
1347         }
1348 }
1349
1350 GtkWidget *main_window_get_message_window(MainWindow *mainwin)
1351 {
1352         switch (mainwin->type) {
1353         case SEPARATE_MESSAGE:
1354                 return mainwin->win.sep_message.messagewin;
1355         case SEPARATE_BOTH:
1356                 return mainwin->win.sep_both.messagewin;
1357         default:
1358                 return NULL;
1359         }
1360 }
1361
1362 void main_window_separation_change(MainWindow *mainwin, SeparateType type)
1363 {
1364         GtkWidget *folder_wid  = GTK_WIDGET_PTR(mainwin->folderview);
1365         GtkWidget *summary_wid = GTK_WIDGET_PTR(mainwin->summaryview);
1366         /* GtkWidget *message_wid = GTK_WIDGET_PTR(mainwin->messageview); */
1367         GtkWidget *message_wid = mainwin->messageview->vbox;
1368
1369         debug_print("Changing window separation type from %d to %d\n",
1370                     mainwin->type, type);
1371
1372         if (mainwin->type == type) return;
1373
1374         /* remove widgets from those containers */
1375         gtk_widget_ref(folder_wid);
1376         gtk_widget_ref(summary_wid);
1377         gtk_widget_ref(message_wid);
1378         gtkut_container_remove
1379                 (GTK_CONTAINER(folder_wid->parent), folder_wid);
1380         gtkut_container_remove
1381                 (GTK_CONTAINER(summary_wid->parent), summary_wid);
1382         gtkut_container_remove
1383                 (GTK_CONTAINER(message_wid->parent), message_wid);
1384
1385         /* clean containers */
1386         switch (mainwin->type) {
1387         case SEPARATE_NONE:
1388                 gtk_widget_destroy(mainwin->win.sep_none.hpaned);
1389                 break;
1390         case SEPARATE_FOLDER:
1391                 gtk_widget_destroy(mainwin->win.sep_folder.vpaned);
1392                 gtk_widget_destroy(mainwin->win.sep_folder.folderwin);
1393                 break;
1394         case SEPARATE_MESSAGE:
1395                 gtk_widget_destroy(mainwin->win.sep_message.hpaned);
1396                 gtk_widget_destroy(mainwin->win.sep_message.messagewin);
1397                 break;
1398         case SEPARATE_BOTH:
1399                 gtk_widget_destroy(mainwin->win.sep_both.messagewin);
1400                 gtk_widget_destroy(mainwin->win.sep_both.folderwin);
1401                 break;
1402         }
1403
1404         gtk_widget_hide(mainwin->window);
1405         main_window_set_widgets(mainwin, type);
1406         gtk_widget_show(mainwin->window);
1407
1408         gtk_widget_unref(folder_wid);
1409         gtk_widget_unref(summary_wid);
1410         gtk_widget_unref(message_wid);
1411 }
1412
1413 void main_window_toggle_message_view(MainWindow *mainwin)
1414 {
1415         SummaryView *summaryview = mainwin->summaryview;
1416         union CompositeWin *cwin = &mainwin->win;
1417         GtkWidget *vpaned = NULL;
1418         GtkWidget *container = NULL;
1419         GtkWidget *msgwin = NULL;
1420
1421         switch (mainwin->type) {
1422         case SEPARATE_NONE:
1423                 vpaned = cwin->sep_none.vpaned;
1424                 container = cwin->sep_none.hpaned;
1425                 break;
1426         case SEPARATE_FOLDER:
1427                 vpaned = cwin->sep_folder.vpaned;
1428                 container = mainwin->vbox_body;
1429                 break;
1430         case SEPARATE_MESSAGE:
1431                 msgwin = mainwin->win.sep_message.messagewin;
1432                 break;
1433         case SEPARATE_BOTH:
1434                 msgwin = mainwin->win.sep_both.messagewin;
1435                 break;
1436         }
1437
1438         if (msgwin) {
1439                 if (GTK_WIDGET_VISIBLE(msgwin)) {
1440                         gtk_widget_hide(msgwin);
1441                         mainwin->messageview->visible = FALSE;
1442                         summaryview->displayed = NULL;
1443                 } else {
1444                         gtk_widget_show(msgwin);
1445                         mainwin->messageview->visible = TRUE;
1446                 }
1447         } else if (vpaned->parent != NULL) {
1448                 mainwin->messageview->visible = FALSE;
1449                 summaryview->displayed = NULL;
1450                 gtk_widget_ref(vpaned);
1451                 gtkut_container_remove(GTK_CONTAINER(container), vpaned);
1452                 gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), container);
1453                 gtk_arrow_set(GTK_ARROW(summaryview->toggle_arrow),
1454                               GTK_ARROW_UP, GTK_SHADOW_OUT);
1455         } else {
1456                 mainwin->messageview->visible = TRUE;
1457                 gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), vpaned);
1458                 gtk_container_add(GTK_CONTAINER(container), vpaned);
1459                 gtk_widget_unref(vpaned);
1460                 gtk_arrow_set(GTK_ARROW(summaryview->toggle_arrow),
1461                               GTK_ARROW_DOWN, GTK_SHADOW_OUT);
1462         }
1463
1464         if (mainwin->messageview->visible == FALSE)
1465                 messageview_clear(mainwin->messageview);
1466
1467         main_window_set_menu_sensitive(mainwin);
1468
1469         prefs_common.msgview_visible = mainwin->messageview->visible;
1470
1471         gtk_widget_grab_focus(summaryview->ctree);
1472 }
1473
1474 void main_window_get_size(MainWindow *mainwin)
1475 {
1476         GtkAllocation *allocation;
1477
1478         allocation = &(GTK_WIDGET_PTR(mainwin->summaryview)->allocation);
1479
1480         if (allocation->width > 1 && allocation->height > 1) {
1481                 prefs_common.summaryview_width = allocation->width;
1482
1483                 if ((mainwin->type == SEPARATE_NONE ||
1484                      mainwin->type == SEPARATE_FOLDER) &&
1485                     messageview_is_visible(mainwin->messageview))
1486                         prefs_common.summaryview_height = allocation->height;
1487
1488                 prefs_common.mainview_width = allocation->width;
1489         }
1490
1491         allocation = &mainwin->window->allocation;
1492         if (allocation->width > 1 && allocation->height > 1) {
1493                 prefs_common.mainview_height = allocation->height;
1494                 prefs_common.mainwin_width   = allocation->width;
1495                 prefs_common.mainwin_height  = allocation->height;
1496         }
1497
1498         allocation = &(GTK_WIDGET_PTR(mainwin->folderview)->allocation);
1499         if (allocation->width > 1 && allocation->height > 1) {
1500                 prefs_common.folderview_width  = allocation->width;
1501                 prefs_common.folderview_height = allocation->height;
1502         }
1503
1504         allocation = &(GTK_WIDGET_PTR(mainwin->messageview)->allocation);
1505         if (allocation->width > 1 && allocation->height > 1) {
1506                 prefs_common.msgview_width = allocation->width;
1507                 prefs_common.msgview_height = allocation->height;
1508         }
1509
1510         debug_print("summaryview size: %d x %d\n",
1511                     prefs_common.summaryview_width,
1512                     prefs_common.summaryview_height);
1513         debug_print("folderview size: %d x %d\n",
1514                     prefs_common.folderview_width,
1515                     prefs_common.folderview_height);
1516         debug_print("messageview size: %d x %d\n",
1517                     prefs_common.msgview_width,
1518                     prefs_common.msgview_height);
1519 }
1520
1521 void main_window_get_position(MainWindow *mainwin)
1522 {
1523         gint x, y;
1524         GtkWidget *window;
1525
1526         gtkut_widget_get_uposition(mainwin->window, &x, &y);
1527
1528         prefs_common.mainview_x = x;
1529         prefs_common.mainview_y = y;
1530         prefs_common.mainwin_x = x;
1531         prefs_common.mainwin_y = y;
1532
1533         debug_print("main window position: %d, %d\n", x, y);
1534
1535         window = main_window_get_folder_window(mainwin);
1536         if (window) {
1537                 gtkut_widget_get_uposition(window, &x, &y);
1538                 prefs_common.folderwin_x = x;
1539                 prefs_common.folderwin_y = y;
1540                 debug_print("folder window position: %d, %d\n", x, y);
1541         }
1542         window = main_window_get_message_window(mainwin);
1543         if (window) {
1544                 gtkut_widget_get_uposition(window, &x, &y);
1545                 prefs_common.main_msgwin_x = x;
1546                 prefs_common.main_msgwin_y = y;
1547                 debug_print("message window position: %d, %d\n", x, y);
1548         }
1549 }
1550
1551 void main_window_progress_on(MainWindow *mainwin)
1552 {
1553         gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), TRUE);
1554         gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
1555 }
1556
1557 void main_window_progress_off(MainWindow *mainwin)
1558 {
1559         gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), FALSE);
1560         gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar), 0.0);
1561         gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
1562 }
1563
1564 void main_window_progress_set(MainWindow *mainwin, gint cur, gint total)
1565 {
1566         gchar buf[32];
1567
1568         g_snprintf(buf, sizeof(buf), "%d / %d", cur, total);
1569         gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), buf);
1570         gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar),
1571                                 (cur == 0 && total == 0) ? 0 :
1572                                 (gfloat)cur / (gfloat)total);
1573 }
1574
1575 void main_window_empty_trash(MainWindow *mainwin, gboolean confirm)
1576 {
1577         GList *list;
1578         guint has_trash;
1579         Folder *folder;
1580
1581         for (has_trash = 0, list = folder_get_list(); list != NULL; list = list->next) {
1582                 folder = FOLDER(list->data);
1583                 if (folder && folder->trash && folder->trash->total_msgs > 0)
1584                         has_trash++;
1585         }
1586
1587         if (!has_trash) return;
1588         
1589         if (confirm) {
1590                 if (alertpanel(_("Empty trash"),
1591                                _("Empty all messages in trash?"),
1592                                _("Yes"), _("No"), NULL) != G_ALERTDEFAULT)
1593                         return;
1594                 manage_window_focus_in(mainwin->window, NULL, NULL);
1595         }
1596
1597         procmsg_empty_all_trash();
1598
1599         if (mainwin->summaryview->folder_item &&
1600             mainwin->summaryview->folder_item->stype == F_TRASH)
1601                 gtk_widget_grab_focus(mainwin->folderview->ctree);
1602 }
1603
1604 void main_window_add_mailbox(MainWindow *mainwin)
1605 {
1606         gchar *path;
1607         Folder *folder;
1608
1609         path = input_dialog(_("Add mailbox"),
1610                             _("Input the location of mailbox.\n"
1611                               "If the existing mailbox is specified, it will be\n"
1612                               "scanned automatically."),
1613                             "Mail");
1614         if (!path) return;
1615         if (folder_find_from_path(path)) {
1616                 alertpanel_error(_("The mailbox `%s' already exists."), path);
1617                 g_free(path);
1618                 return;
1619         }
1620         folder = folder_new(folder_get_class_from_string("mh"), 
1621                             !strcmp(path, "Mail") ? _("Mailbox") : g_basename(path),
1622                             path);
1623         g_free(path);
1624
1625         if (folder->klass->create_tree(folder) < 0) {
1626                 alertpanel_error(_("Creation of the mailbox failed.\n"
1627                                    "Maybe some files already exist, or you don't have the permission to write there."));
1628                 folder_destroy(folder);
1629                 return;
1630         }
1631
1632         folder_add(folder);
1633         folder_set_ui_func(folder, scan_tree_func, mainwin);
1634         folder_scan_tree(folder);
1635         folder_set_ui_func(folder, NULL, NULL);
1636 }
1637
1638 SensitiveCond main_window_get_current_state(MainWindow *mainwin)
1639 {
1640         SensitiveCond state = 0;
1641         SummarySelection selection;
1642         FolderItem *item = mainwin->summaryview->folder_item;
1643         GList *account_list = account_get_list();
1644         
1645         selection = summary_get_selection_type(mainwin->summaryview);
1646
1647         if (mainwin->lock_count == 0)
1648                 state |= M_UNLOCKED;
1649         if (selection != SUMMARY_NONE)
1650                 state |= M_MSG_EXIST;
1651         if (item && item->path && folder_item_parent(item) && !item->no_select) {
1652                 state |= M_EXEC;
1653                 /*              if (item->folder->type != F_NEWS) */
1654                 state |= M_ALLOW_DELETE;
1655
1656                 if (prefs_common.immediate_exec == 0
1657                     && mainwin->lock_count == 0)
1658                         state |= M_DELAY_EXEC;
1659
1660                 if ((selection == SUMMARY_NONE && item->hide_read_msgs)
1661                     || selection != SUMMARY_NONE)
1662                         state |= M_HIDE_READ_MSG;       
1663         }               
1664         if (mainwin->summaryview->threaded)
1665                 state |= M_THREADED;
1666         else
1667                 state |= M_UNTHREADED;  
1668         if (selection == SUMMARY_SELECTED_SINGLE ||
1669             selection == SUMMARY_SELECTED_MULTIPLE)
1670                 state |= M_TARGET_EXIST;
1671         if (selection == SUMMARY_SELECTED_SINGLE)
1672                 state |= M_SINGLE_TARGET_EXIST;
1673         if (mainwin->summaryview->folder_item &&
1674             mainwin->summaryview->folder_item->folder->klass->type == F_NEWS)
1675                 state |= M_NEWS;
1676         else
1677                 state |= M_NOT_NEWS;
1678         if (selection == SUMMARY_SELECTED_SINGLE &&
1679             (item &&
1680              (item->stype == F_OUTBOX || item->stype == F_DRAFT ||
1681               item->stype == F_QUEUE)))
1682                 state |= M_ALLOW_REEDIT;
1683         if (cur_account)
1684                 state |= M_HAVE_ACCOUNT;
1685         
1686         for ( ; account_list != NULL; account_list = account_list->next) {
1687                 if (((PrefsAccount*)account_list->data)->protocol == A_NNTP) {
1688                         state |= M_HAVE_NEWS_ACCOUNT;
1689                         break;
1690                 }
1691         }
1692
1693         if (inc_is_active())
1694                 state |= M_INC_ACTIVE;
1695
1696         return state;
1697 }
1698
1699
1700
1701 void main_window_set_menu_sensitive(MainWindow *mainwin)
1702 {
1703         GtkItemFactory *ifactory = mainwin->menu_factory;
1704         SensitiveCond state;
1705         gboolean sensitive;
1706         GtkWidget *menu;
1707         GtkWidget *menuitem;
1708         SummaryView *summaryview;
1709         gchar *menu_path;
1710         gint i;
1711         GList *cur_item;
1712
1713         static const struct {
1714                 gchar *const entry;
1715                 SensitiveCond cond;
1716         } entry[] = {
1717                 {"/File/Add mailbox"                          , M_UNLOCKED},
1718
1719                 {"/File/Add mailbox/MH..."                    , M_UNLOCKED},
1720                 {"/File/Change folder order"                  , M_UNLOCKED},
1721                 {"/File/Export to mbox file..."               , M_UNLOCKED},
1722                 {"/File/Empty all Trash folders"              , M_UNLOCKED},
1723                 {"/File/Work offline"                         , M_UNLOCKED},
1724
1725                 {"/File/Save as...", M_TARGET_EXIST|M_UNLOCKED},
1726                 {"/File/Print..."  , M_TARGET_EXIST|M_UNLOCKED},
1727                 /* {"/File/Close"  , M_UNLOCKED}, */
1728                 {"/File/Exit"      , M_UNLOCKED},
1729
1730                 {"/Edit/Select thread"             , M_SINGLE_TARGET_EXIST},
1731
1732                 {"/View/Sort"                      , M_EXEC},
1733                 {"/View/Thread view"               , M_EXEC},
1734                 {"/View/Expand all threads"        , M_MSG_EXIST},
1735                 {"/View/Collapse all threads"      , M_MSG_EXIST},
1736                 {"/View/Hide read messages"        , M_HIDE_READ_MSG},
1737                 {"/View/Go to/Prev message"        , M_MSG_EXIST},
1738                 {"/View/Go to/Next message"        , M_MSG_EXIST},
1739                 {"/View/Go to/Prev unread message" , M_MSG_EXIST},
1740                 {"/View/Go to/Prev new message"    , M_MSG_EXIST},
1741                 {"/View/Go to/Prev marked message" , M_MSG_EXIST},
1742                 {"/View/Go to/Next marked message" , M_MSG_EXIST},
1743                 {"/View/Go to/Prev labeled message", M_MSG_EXIST},
1744                 {"/View/Go to/Next labeled message", M_MSG_EXIST},
1745                 {"/View/Open in new window"        , M_SINGLE_TARGET_EXIST},
1746                 {"/View/Show all headers"          , M_SINGLE_TARGET_EXIST},
1747                 {"/View/Message source"            , M_SINGLE_TARGET_EXIST},
1748
1749                 {"/Message/Receive/Get from current account"
1750                                                  , M_HAVE_ACCOUNT|M_UNLOCKED},
1751                 {"/Message/Receive/Get from all accounts"
1752                                                  , M_HAVE_ACCOUNT|M_UNLOCKED},
1753                 {"/Message/Receive/Cancel receiving"
1754                                                  , M_INC_ACTIVE},
1755
1756                 {"/Message/Compose a news message", M_HAVE_NEWS_ACCOUNT},
1757                 {"/Message/Reply"                 , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
1758                 {"/Message/Reply to"             , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
1759                 {"/Message/Follow-up and reply to", M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST|M_NEWS},
1760                 {"/Message/Forward"               , M_HAVE_ACCOUNT|M_TARGET_EXIST},
1761                 {"/Message/Redirect"              , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
1762                 {"/Message/Move..."               , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED},
1763                 {"/Message/Copy..."               , M_TARGET_EXIST|M_EXEC|M_UNLOCKED},
1764                 {"/Message/Delete"                , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NOT_NEWS},
1765                 {"/Message/Cancel a news message" , M_TARGET_EXIST|M_ALLOW_DELETE|M_UNLOCKED|M_NEWS},
1766                 {"/Message/Mark"                  , M_TARGET_EXIST},
1767                 {"/Message/Re-edit"              , M_HAVE_ACCOUNT|M_ALLOW_REEDIT},
1768
1769                 {"/Tools/Add sender to address book"   , M_SINGLE_TARGET_EXIST},
1770                 {"/Tools/Harvest addresses"            , M_UNLOCKED},
1771                 {"/Tools/Filter all messages in folder", M_MSG_EXIST|M_EXEC|M_UNLOCKED},
1772                 {"/Tools/Filter selected messages"     , M_TARGET_EXIST|M_EXEC|M_UNLOCKED},
1773                 {"/Tools/Create filter rule"           , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
1774                 {"/Tools/Actions"                      , M_TARGET_EXIST|M_UNLOCKED},
1775                 {"/Tools/Execute"                      , M_DELAY_EXEC},
1776                 {"/Tools/Delete duplicated messages/In selected folder"   , M_MSG_EXIST|M_ALLOW_DELETE|M_UNLOCKED},
1777
1778                 {"/Configuration", M_UNLOCKED},
1779
1780                 {NULL, 0}
1781         };
1782
1783         state = main_window_get_current_state(mainwin);
1784
1785         for (i = 0; entry[i].entry != NULL; i++) {
1786                 sensitive = ((entry[i].cond & state) == entry[i].cond);
1787                 menu_set_sensitive(ifactory, entry[i].entry, sensitive);
1788         }
1789
1790         menu = gtk_item_factory_get_widget(ifactory, "/Message/Receive");
1791
1792         /* search for separator */
1793         for (cur_item = GTK_MENU_SHELL(menu)->children; cur_item != NULL;
1794              cur_item = cur_item->next) {
1795                 if (GTK_BIN(cur_item->data)->child == NULL) {
1796                         cur_item = cur_item->next;
1797                         break;
1798                 }
1799         }
1800
1801         for (; cur_item != NULL; cur_item = cur_item->next) {
1802                 gtk_widget_set_sensitive(GTK_WIDGET(cur_item->data),
1803                                          (M_UNLOCKED & state) != 0);
1804         }
1805
1806         main_window_menu_callback_block(mainwin);
1807
1808 #define SET_CHECK_MENU_ACTIVE(path, active) \
1809 { \
1810         menuitem = gtk_item_factory_get_widget(ifactory, path); \
1811         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), active); \
1812 }
1813
1814         SET_CHECK_MENU_ACTIVE("/View/Show or hide/Message view",
1815                               messageview_is_visible(mainwin->messageview));
1816
1817         summaryview = mainwin->summaryview;
1818         menu_path = "/View/Sort/Don't sort";
1819
1820         switch (summaryview->sort_key) {
1821         case SORT_BY_NUMBER:
1822                 menu_path = "/View/Sort/by number"; break;
1823         case SORT_BY_SIZE:
1824                 menu_path = "/View/Sort/by size"; break;
1825         case SORT_BY_DATE:
1826                 menu_path = "/View/Sort/by date"; break;
1827         case SORT_BY_FROM:
1828                 menu_path = "/View/Sort/by from"; break;
1829         case SORT_BY_TO:
1830                 menu_path = "/View/Sort/by recipient"; break;
1831         case SORT_BY_SUBJECT:
1832                 menu_path = "/View/Sort/by subject"; break;
1833         case SORT_BY_LABEL:
1834                 menu_path = "/View/Sort/by color label"; break;
1835         case SORT_BY_MARK:
1836                 menu_path = "/View/Sort/by mark"; break;
1837         case SORT_BY_STATUS:
1838                 menu_path = "/View/Sort/by status"; break;
1839         case SORT_BY_MIME:
1840                 menu_path = "/View/Sort/by attachment"; break;
1841         case SORT_BY_SCORE:
1842                 menu_path = "/View/Sort/by score"; break;
1843         case SORT_BY_LOCKED:
1844                 menu_path = "/View/Sort/by locked"; break;
1845         case SORT_BY_NONE:
1846         default:
1847                 menu_path = "/View/Sort/Don't sort"; break;
1848         }
1849         SET_CHECK_MENU_ACTIVE(menu_path, TRUE);
1850
1851         if (summaryview->sort_type == SORT_ASCENDING) {
1852                 SET_CHECK_MENU_ACTIVE("/View/Sort/Ascending", TRUE);
1853         } else {
1854                 SET_CHECK_MENU_ACTIVE("/View/Sort/Descending", TRUE);
1855         }
1856
1857         if (summaryview->sort_key != SORT_BY_NONE) {
1858                 menu_set_sensitive(ifactory, "/View/Sort/Ascending", TRUE);
1859                 menu_set_sensitive(ifactory, "/View/Sort/Descending", TRUE);
1860         } else {
1861                 menu_set_sensitive(ifactory, "/View/Sort/Ascending", FALSE);
1862                 menu_set_sensitive(ifactory, "/View/Sort/Descending", FALSE);
1863         }
1864
1865         SET_CHECK_MENU_ACTIVE("/View/Show all headers",
1866                               mainwin->messageview->mimeview->textview->show_all_headers);
1867         SET_CHECK_MENU_ACTIVE("/View/Thread view", (state & M_THREADED) != 0);
1868
1869 #undef SET_CHECK_MENU_ACTIVE
1870
1871         main_window_menu_callback_unblock(mainwin);
1872 }
1873
1874 void main_window_popup(MainWindow *mainwin)
1875 {
1876         gtkut_window_popup(mainwin->window);
1877
1878         switch (mainwin->type) {
1879         case SEPARATE_FOLDER:
1880                 gtkut_window_popup(mainwin->win.sep_folder.folderwin);
1881                 break;
1882         case SEPARATE_MESSAGE:
1883                 gtkut_window_popup(mainwin->win.sep_message.messagewin);
1884                 break;
1885         case SEPARATE_BOTH:
1886                 gtkut_window_popup(mainwin->win.sep_both.folderwin);
1887                 gtkut_window_popup(mainwin->win.sep_both.messagewin);
1888                 break;
1889         default:
1890                 break;
1891         }
1892 }
1893
1894 void main_window_show(MainWindow *mainwin)
1895 {
1896         gtk_widget_show(mainwin->window);
1897         gtk_widget_show(mainwin->vbox_body);
1898
1899         gtk_widget_set_uposition(mainwin->window,
1900                                  prefs_common.mainwin_x,
1901                                  prefs_common.mainwin_y);
1902
1903         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->folderview),
1904                              prefs_common.folderview_width,
1905                              prefs_common.folderview_height);
1906         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->summaryview),
1907                              prefs_common.summaryview_width,
1908                              prefs_common.summaryview_height);
1909         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->messageview),
1910                              prefs_common.msgview_width,
1911                              prefs_common.msgview_height);
1912
1913         if (mainwin->type & SEPARATE_FOLDER) {
1914                 GtkWidget *folderwin;
1915
1916                 folderwin = main_window_get_folder_window(mainwin);
1917                 gtk_widget_show(folderwin);
1918                 gtk_widget_set_uposition(folderwin, prefs_common.folderwin_x,
1919                                          prefs_common.folderwin_y);
1920         }
1921
1922         if (mainwin->type & SEPARATE_MESSAGE) {
1923                 GtkWidget *messagewin;
1924
1925                 messagewin = main_window_get_message_window(mainwin);
1926                 gtk_widget_show(messagewin);
1927                 gtk_widget_set_uposition(messagewin, prefs_common.main_msgwin_x,
1928                                          prefs_common.main_msgwin_y);
1929         }
1930 }
1931
1932 void main_window_hide(MainWindow *mainwin)
1933 {
1934         main_window_get_size(mainwin);
1935         main_window_get_position(mainwin);
1936
1937         gtk_widget_hide(mainwin->window);
1938         gtk_widget_hide(mainwin->vbox_body);
1939
1940         if (mainwin->type & SEPARATE_FOLDER) {
1941                 gtk_widget_hide(mainwin->win.sep_folder.folderwin);
1942         }
1943
1944         if (mainwin->type & SEPARATE_MESSAGE) {
1945                 gtk_widget_hide(mainwin->win.sep_message.messagewin);
1946         }
1947 }
1948
1949 static void main_window_set_widgets(MainWindow *mainwin, SeparateType type)
1950 {
1951         GtkWidget *folderwin = NULL;
1952         GtkWidget *messagewin = NULL;
1953         GtkWidget *hpaned;
1954         GtkWidget *vpaned;
1955         GtkWidget *vbox_body = mainwin->vbox_body;
1956         GtkItemFactory *ifactory = mainwin->menu_factory;
1957         GtkWidget *menuitem;
1958         GtkItemFactory *msgview_ifactory;
1959
1960         debug_print("Setting widgets... ");
1961
1962         /* create separated window(s) if needed */
1963         if (type & SEPARATE_FOLDER) {
1964                 folderwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1965                 gtk_window_set_title(GTK_WINDOW(folderwin),
1966                                      _("Sylpheed - Folder View"));
1967                 gtk_window_set_wmclass(GTK_WINDOW(folderwin),
1968                                        "folder_view", "Sylpheed");
1969                 gtk_window_set_policy(GTK_WINDOW(folderwin),
1970                                       TRUE, TRUE, FALSE);
1971                 gtk_widget_set_uposition(folderwin, prefs_common.folderwin_x,
1972                                          prefs_common.folderwin_y);
1973                 gtk_container_set_border_width(GTK_CONTAINER(folderwin),
1974                                                BORDER_WIDTH);
1975                 gtk_signal_connect(GTK_OBJECT(folderwin), "delete_event",
1976                                    GTK_SIGNAL_FUNC(folder_window_close_cb),
1977                                    mainwin);
1978                 gtk_container_add(GTK_CONTAINER(folderwin),
1979                                   GTK_WIDGET_PTR(mainwin->folderview));
1980                 gtk_widget_realize(folderwin);
1981                 if (prefs_common.folderview_visible)
1982                         gtk_widget_show(folderwin);
1983         }
1984         if (type & SEPARATE_MESSAGE) {
1985                 messagewin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1986                 gtk_window_set_title(GTK_WINDOW(messagewin),
1987                                      _("Sylpheed - Message View"));
1988                 gtk_window_set_wmclass(GTK_WINDOW(messagewin),
1989                                        "message_view", "Sylpheed");
1990                 gtk_window_set_policy(GTK_WINDOW(messagewin),
1991                                       TRUE, TRUE, FALSE);
1992                 gtk_widget_set_uposition(messagewin, prefs_common.main_msgwin_x,
1993                                          prefs_common.main_msgwin_y);
1994                 gtk_container_set_border_width(GTK_CONTAINER(messagewin),
1995                                                BORDER_WIDTH);
1996                 gtk_signal_connect(GTK_OBJECT(messagewin), "delete_event",
1997                                    GTK_SIGNAL_FUNC(message_window_close_cb),
1998                                    mainwin);
1999                 if (messageview_is_visible(mainwin->messageview))
2000                         gtk_widget_show(messagewin);
2001         }
2002
2003         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->folderview),
2004                              prefs_common.folderview_width,
2005                              prefs_common.folderview_height);
2006         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->summaryview),
2007                              prefs_common.summaryview_width,
2008                              prefs_common.summaryview_height);
2009         gtk_widget_set_usize(GTK_WIDGET_PTR(mainwin->messageview),
2010                              prefs_common.msgview_width,
2011                              prefs_common.msgview_height);
2012
2013         switch (type) {
2014         case SEPARATE_NONE:
2015                 hpaned = gtk_hpaned_new();
2016                 gtk_box_pack_start(GTK_BOX(vbox_body), hpaned, TRUE, TRUE, 0);
2017                 gtk_paned_add1(GTK_PANED(hpaned),
2018                                GTK_WIDGET_PTR(mainwin->folderview));
2019                 gtk_widget_show(hpaned);
2020                 gtk_widget_queue_resize(hpaned);
2021
2022                 vpaned = gtk_vpaned_new();
2023                 if (messageview_is_visible(mainwin->messageview)) {
2024                         gtk_paned_add2(GTK_PANED(hpaned), vpaned);
2025                         gtk_paned_add1(GTK_PANED(vpaned),
2026                                        GTK_WIDGET_PTR(mainwin->summaryview));
2027                 } else {
2028                         gtk_paned_add2(GTK_PANED(hpaned),
2029                                        GTK_WIDGET_PTR(mainwin->summaryview));
2030                         gtk_widget_ref(vpaned);
2031                 }
2032                 gtk_paned_add2(GTK_PANED(vpaned),
2033                                GTK_WIDGET_PTR(mainwin->messageview));
2034                 gtk_widget_show(vpaned);
2035                 gtk_widget_queue_resize(vpaned);
2036
2037                 mainwin->win.sep_none.hpaned = hpaned;
2038                 mainwin->win.sep_none.vpaned = vpaned;
2039                 
2040                 /* remove headerview if not in prefs */
2041                 headerview_set_visibility(mainwin->messageview->headerview,
2042                                           prefs_common.display_header_pane);
2043                 break;
2044         case SEPARATE_FOLDER:
2045                 vpaned = gtk_vpaned_new();
2046                 if (messageview_is_visible(mainwin->messageview)) {
2047                         gtk_box_pack_start(GTK_BOX(vbox_body), vpaned,
2048                                            TRUE, TRUE, 0);
2049                         gtk_paned_add1(GTK_PANED(vpaned),
2050                                        GTK_WIDGET_PTR(mainwin->summaryview));
2051                 } else {
2052                         gtk_box_pack_start(GTK_BOX(vbox_body),
2053                                            GTK_WIDGET_PTR(mainwin->summaryview),
2054                                            TRUE, TRUE, 0);
2055                         gtk_widget_ref(vpaned);
2056                 }
2057                 gtk_paned_add2(GTK_PANED(vpaned),
2058                                GTK_WIDGET_PTR(mainwin->messageview));
2059                 gtk_widget_show(vpaned);
2060                 gtk_widget_queue_resize(vpaned);
2061
2062                 mainwin->win.sep_folder.folderwin = folderwin;
2063                 mainwin->win.sep_folder.vpaned    = vpaned;
2064
2065                 /* remove headerview if not in prefs */
2066                 headerview_set_visibility(mainwin->messageview->headerview,
2067                                           prefs_common.display_header_pane);
2068                 
2069                 break;
2070         case SEPARATE_MESSAGE:
2071                 hpaned = gtk_hpaned_new();
2072                 gtk_box_pack_start(GTK_BOX(vbox_body), hpaned, TRUE, TRUE, 0);
2073                 gtk_paned_add1(GTK_PANED(hpaned),
2074                                GTK_WIDGET_PTR(mainwin->folderview));
2075                 gtk_paned_add2(GTK_PANED(hpaned),
2076                                GTK_WIDGET_PTR(mainwin->summaryview));
2077                 gtk_widget_show(hpaned);
2078                 gtk_widget_queue_resize(hpaned);
2079                 messageview_add_toolbar(mainwin->messageview, messagewin);
2080                 msgview_ifactory = gtk_item_factory_from_widget(mainwin->messageview->menubar);
2081                 menu_set_sensitive(msgview_ifactory, "/File/Close", FALSE);
2082
2083                 mainwin->win.sep_message.messagewin = messagewin;
2084                 mainwin->win.sep_message.hpaned     = hpaned;
2085
2086                 gtk_widget_realize(messagewin);
2087                 gtk_widget_show_all(GTK_WIDGET_PTR(mainwin->messageview));
2088                 gtk_widget_show_all(messagewin);
2089                 toolbar_set_style(mainwin->messageview->toolbar->toolbar, 
2090                                   mainwin->messageview->handlebox, 
2091                                   prefs_common.toolbar_style);
2092
2093                 break;
2094         case SEPARATE_BOTH:
2095                 messageview_add_toolbar(mainwin->messageview, messagewin);
2096                 msgview_ifactory = gtk_item_factory_from_widget(mainwin->messageview->menubar);
2097                 menu_set_sensitive(msgview_ifactory, "/File/Close", FALSE);
2098
2099                 gtk_box_pack_start(GTK_BOX(vbox_body),
2100                                    GTK_WIDGET_PTR(mainwin->summaryview),
2101                                    TRUE, TRUE, 0);
2102                 
2103                 mainwin->win.sep_both.folderwin = folderwin;
2104                 mainwin->win.sep_both.messagewin = messagewin;
2105                 
2106                 gtk_widget_realize(messagewin);
2107                 gtk_widget_show_all(GTK_WIDGET_PTR(mainwin->messageview));
2108                 gtk_widget_show_all(messagewin);
2109                 toolbar_set_style(mainwin->messageview->toolbar->toolbar, 
2110                                   mainwin->messageview->handlebox, 
2111                                   prefs_common.toolbar_style);          
2112
2113                 break;
2114         }
2115
2116         gtk_widget_set_uposition(mainwin->window,
2117                                  prefs_common.mainwin_x,
2118                                  prefs_common.mainwin_y);
2119
2120         gtk_widget_queue_resize(vbox_body);
2121         gtk_widget_queue_resize(mainwin->vbox);
2122         gtk_widget_queue_resize(mainwin->window);
2123         /* CLAWS: previous "gtk_widget_show_all" makes noticeview
2124          * and mimeview icon list/ctree lose track of their visibility states */
2125         if (!noticeview_is_visible(mainwin->messageview->noticeview)) 
2126                 gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->noticeview));
2127         if (!noticeview_is_visible(mainwin->messageview->mimeview->siginfoview)) 
2128                 gtk_widget_hide(GTK_WIDGET_PTR(mainwin->messageview->mimeview->siginfoview));
2129         if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mainwin->messageview->mimeview->mime_toggle)))
2130                 gtk_widget_hide(mainwin->messageview->mimeview->icon_mainbox);
2131         else 
2132                 gtk_widget_hide(mainwin->messageview->mimeview->ctree_mainbox);
2133
2134         mainwin->type = type;
2135
2136
2137         /* toggle menu state */
2138         menuitem = gtk_item_factory_get_item
2139                 (ifactory, "/View/Show or hide/Folder tree");
2140         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2141                                        (type & SEPARATE_FOLDER) == 0 ? TRUE :
2142                                        prefs_common.folderview_visible);
2143         gtk_widget_set_sensitive(menuitem, ((type & SEPARATE_FOLDER) != 0));
2144         menuitem = gtk_item_factory_get_item
2145                 (ifactory, "/View/Show or hide/Message view");
2146         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2147                                        (type & SEPARATE_MESSAGE) == 0 ? TRUE :
2148                                        prefs_common.msgview_visible);
2149
2150         menuitem = gtk_item_factory_get_item
2151                 (ifactory, "/View/Separate folder tree");
2152         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2153                                        ((type & SEPARATE_FOLDER) != 0));
2154         menuitem = gtk_item_factory_get_item
2155                 (ifactory, "/View/Separate message view");
2156         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2157                                        ((type & SEPARATE_MESSAGE) != 0));
2158
2159         if (folderwin) {
2160                 gtk_signal_connect
2161                         (GTK_OBJECT(folderwin), "size_allocate",
2162                          GTK_SIGNAL_FUNC(folder_window_size_allocate_cb),
2163                          mainwin);
2164         }
2165         if (messagewin) {
2166                 gtk_signal_connect
2167                         (GTK_OBJECT(messagewin), "size_allocate",
2168                          GTK_SIGNAL_FUNC(message_window_size_allocate_cb),
2169                          mainwin);
2170         }
2171
2172         debug_print("done.\n");
2173 }
2174
2175 void main_window_destroy_all(void)
2176 {
2177         while (mainwin_list != NULL) {
2178                 MainWindow *mainwin = (MainWindow*)mainwin_list->data;
2179                 
2180                 /* free toolbar stuff */
2181                 toolbar_clear_list(TOOLBAR_MAIN);
2182                 TOOLBAR_DESTROY_ACTIONS(mainwin->toolbar->action_list);
2183                 TOOLBAR_DESTROY_ITEMS(mainwin->toolbar->item_list);
2184
2185                 g_free(mainwin->toolbar);
2186                 g_free(mainwin);
2187                 
2188                 mainwin_list = g_list_remove(mainwin_list, mainwin);
2189         }
2190         g_list_free(mainwin_list);
2191 }
2192
2193 #if 0
2194 static void toolbar_account_button_pressed(GtkWidget *widget,
2195                                            GdkEventButton *event,
2196                                            gpointer data)
2197 {
2198         MainWindow *mainwin = (MainWindow *)data;
2199
2200         if (!event) return;
2201         if (event->button != 3) return;
2202
2203         gtk_button_set_relief(GTK_BUTTON(widget), GTK_RELIEF_NORMAL);
2204         gtk_object_set_data(GTK_OBJECT(mainwin->ac_menu), "menu_button",
2205                             widget);
2206
2207         gtk_menu_popup(GTK_MENU(mainwin->ac_menu), NULL, NULL,
2208                        menu_button_position, widget,
2209                        event->button, event->time);
2210 }
2211 #endif
2212
2213 static void toolbar_child_attached(GtkWidget *widget, GtkWidget *child,
2214                                    gpointer data)
2215 {
2216         gtk_widget_set_usize(child, 1, -1);
2217 }
2218
2219 static void toolbar_child_detached(GtkWidget *widget, GtkWidget *child,
2220                                    gpointer data)
2221 {
2222         gtk_widget_set_usize(child, -1, -1);
2223 }
2224
2225 static void ac_label_button_pressed(GtkWidget *widget, GdkEventButton *event,
2226                                     gpointer data)
2227 {
2228         MainWindow *mainwin = (MainWindow *)data;
2229
2230         if (!event) return;
2231
2232         gtk_button_set_relief(GTK_BUTTON(widget), GTK_RELIEF_NORMAL);
2233         gtk_object_set_data(GTK_OBJECT(mainwin->ac_menu), "menu_button",
2234                             widget);
2235
2236         gtk_menu_popup(GTK_MENU(mainwin->ac_menu), NULL, NULL,
2237                        menu_button_position, widget,
2238                        event->button, event->time);
2239 }
2240
2241 static void ac_menu_popup_closed(GtkMenuShell *menu_shell, gpointer data)
2242 {
2243         MainWindow *mainwin = (MainWindow *)data;
2244         GtkWidget *button;
2245
2246         button = gtk_object_get_data(GTK_OBJECT(menu_shell), "menu_button");
2247         if (!button) return;
2248         gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
2249         gtk_object_remove_data(GTK_OBJECT(mainwin->ac_menu), "menu_button");
2250         manage_window_focus_in(mainwin->window, NULL, NULL);
2251 }
2252
2253 static gint main_window_close_cb(GtkWidget *widget, GdkEventAny *event,
2254                                  gpointer data)
2255 {
2256         MainWindow *mainwin = (MainWindow *)data;
2257
2258         if (mainwin->lock_count == 0)
2259                 app_exit_cb(data, 0, widget);
2260
2261         return TRUE;
2262 }
2263
2264 static gint folder_window_close_cb(GtkWidget *widget, GdkEventAny *event,
2265                                    gpointer data)
2266 {
2267         MainWindow *mainwin = (MainWindow *)data;
2268         GtkWidget *menuitem;
2269
2270         menuitem = gtk_item_factory_get_item
2271                 (mainwin->menu_factory, "/View/Show or hide/Folder tree");
2272         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE);
2273
2274         return TRUE;
2275 }
2276
2277 static gint message_window_close_cb(GtkWidget *widget, GdkEventAny *event,
2278                                     gpointer data)
2279 {
2280         MainWindow *mainwin = (MainWindow *)data;
2281         GtkWidget *menuitem;
2282
2283         menuitem = gtk_item_factory_get_item
2284                 (mainwin->menu_factory, "/View/Show or hide/Message view");
2285         gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE);
2286
2287         return TRUE;
2288 }
2289
2290 static void main_window_size_allocate_cb(GtkWidget *widget,
2291                                          GtkAllocation *allocation,
2292                                          gpointer data)
2293 {
2294         MainWindow *mainwin = (MainWindow *)data;
2295
2296         main_window_get_size(mainwin);
2297 }
2298
2299 static void folder_window_size_allocate_cb(GtkWidget *widget,
2300                                            GtkAllocation *allocation,
2301                                            gpointer data)
2302 {
2303         MainWindow *mainwin = (MainWindow *)data;
2304
2305         main_window_get_size(mainwin);
2306 }
2307
2308 static void message_window_size_allocate_cb(GtkWidget *widget,
2309                                             GtkAllocation *allocation,
2310                                             gpointer data)
2311 {
2312         MainWindow *mainwin = (MainWindow *)data;
2313
2314         main_window_get_size(mainwin);
2315 }
2316
2317 static void add_mailbox_cb(MainWindow *mainwin, guint action,
2318                            GtkWidget *widget)
2319 {
2320         main_window_add_mailbox(mainwin);
2321 }
2322
2323 static void update_folderview_cb(MainWindow *mainwin, guint action,
2324                                  GtkWidget *widget)
2325 {
2326         summary_show(mainwin->summaryview, NULL);
2327         folderview_check_new_all();
2328 }
2329
2330 static void foldersort_cb(MainWindow *mainwin, guint action,
2331                            GtkWidget *widget)
2332 {
2333         foldersort_open();
2334 }
2335
2336 static void import_mbox_cb(MainWindow *mainwin, guint action,
2337                            GtkWidget *widget)
2338 {
2339         import_mbox(mainwin->summaryview->folder_item);
2340 }
2341
2342 static void export_mbox_cb(MainWindow *mainwin, guint action,
2343                            GtkWidget *widget)
2344 {
2345         export_mbox(mainwin->summaryview->folder_item);
2346 }
2347
2348 static void empty_trash_cb(MainWindow *mainwin, guint action,
2349                            GtkWidget *widget)
2350 {
2351         main_window_empty_trash(mainwin, TRUE);
2352 }
2353
2354 static void save_as_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2355 {
2356         summary_save_as(mainwin->summaryview);
2357 }
2358
2359 static void print_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2360 {
2361         summary_print(mainwin->summaryview);
2362 }
2363
2364 static void app_exit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2365 {
2366         if (prefs_common.confirm_on_exit) {
2367                 if (alertpanel(_("Exit"), _("Exit this program?"),
2368                                _("OK"), _("Cancel"), NULL) != G_ALERTDEFAULT)
2369                         return;
2370                 manage_window_focus_in(mainwin->window, NULL, NULL);
2371         }
2372
2373         app_will_exit(widget, mainwin);
2374 }
2375
2376 static void search_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2377 {
2378         if (action == 1)
2379                 summary_search(mainwin->summaryview);
2380         else
2381                 message_search(mainwin->messageview);
2382 }
2383
2384 static void toggle_folder_cb(MainWindow *mainwin, guint action,
2385                              GtkWidget *widget)
2386 {
2387         gboolean active;
2388
2389         active = GTK_CHECK_MENU_ITEM(widget)->active;
2390
2391         switch (mainwin->type) {
2392         case SEPARATE_NONE:
2393         case SEPARATE_MESSAGE:
2394 #if 0
2395                 if (active)
2396                         gtk_widget_show(GTK_WIDGET_PTR(mainwin->folderview));
2397                 else
2398                         gtk_widget_hide(GTK_WIDGET_PTR(mainwin->folderview));
2399 #endif
2400                 break;
2401         case SEPARATE_FOLDER:
2402                 debug_print("separate folder\n");
2403                 if (active)
2404                         gtk_widget_show(mainwin->win.sep_folder.folderwin);
2405                 else
2406                         gtk_widget_hide(mainwin->win.sep_folder.folderwin);
2407                 break;
2408         case SEPARATE_BOTH:
2409                 if (active)
2410                         gtk_widget_show(mainwin->win.sep_both.folderwin);
2411                 else
2412                         gtk_widget_hide(mainwin->win.sep_both.folderwin);
2413                 break;
2414         }
2415
2416         prefs_common.folderview_visible = active;
2417 }
2418
2419 static void toggle_message_cb(MainWindow *mainwin, guint action,
2420                               GtkWidget *widget)
2421 {
2422         gboolean active;
2423
2424         active = GTK_CHECK_MENU_ITEM(widget)->active;
2425
2426         if (active != messageview_is_visible(mainwin->messageview))
2427                 summary_toggle_view(mainwin->summaryview);
2428 }
2429
2430 static void toggle_toolbar_cb(MainWindow *mainwin, guint action,
2431                               GtkWidget *widget)
2432 {
2433         toolbar_toggle(action, mainwin);
2434 }
2435
2436 void main_window_reply_cb(MainWindow *mainwin, guint action,
2437                           GtkWidget *widget)
2438 {
2439         MessageView *msgview = (MessageView*)mainwin->messageview;
2440         GSList *msginfo_list = NULL;
2441         gchar *body;
2442
2443         g_return_if_fail(msgview != NULL);
2444
2445         msginfo_list = summary_get_selection(mainwin->summaryview);
2446         g_return_if_fail(msginfo_list != NULL);
2447         
2448         body = messageview_get_selection(msgview);
2449         compose_reply_mode((ComposeMode)action, msginfo_list, body);
2450         g_free(body);
2451         g_slist_free(msginfo_list);
2452 }
2453
2454
2455 static void toggle_statusbar_cb(MainWindow *mainwin, guint action,
2456                                 GtkWidget *widget)
2457 {
2458         if (GTK_CHECK_MENU_ITEM(widget)->active) {
2459                 gtk_widget_show(mainwin->hbox_stat);
2460                 prefs_common.show_statusbar = TRUE;
2461         } else {
2462                 gtk_widget_hide(mainwin->hbox_stat);
2463                 prefs_common.show_statusbar = FALSE;
2464         }
2465 }
2466
2467 static void separate_widget_cb(MainWindow *mainwin, guint action,
2468                                GtkWidget *widget)
2469 {
2470         SeparateType type;
2471
2472         if (GTK_CHECK_MENU_ITEM(widget)->active)
2473                 type = mainwin->type | action;
2474         else
2475                 type = mainwin->type & ~action;
2476
2477         main_window_separation_change(mainwin, type);
2478
2479         prefs_common.sep_folder = (type & SEPARATE_FOLDER)  != 0;
2480         prefs_common.sep_msg    = (type & SEPARATE_MESSAGE) != 0;
2481 }
2482
2483 void main_window_toggle_work_offline (MainWindow *mainwin, gboolean offline)
2484 {
2485         if (offline)
2486                 online_switch_clicked (GTK_BUTTON(mainwin->online_switch), mainwin);
2487         else
2488                 online_switch_clicked (GTK_BUTTON(mainwin->offline_switch), mainwin);
2489 }
2490
2491 static void toggle_work_offline_cb (MainWindow *mainwin, guint action, GtkWidget *widget)
2492 {
2493         main_window_toggle_work_offline(mainwin, GTK_CHECK_MENU_ITEM(widget)->active);
2494 }
2495
2496 static void online_switch_clicked (GtkButton *btn, gpointer data) 
2497 {
2498         MainWindow *mainwin;
2499         GtkItemFactory *ifactory;
2500         GtkCheckMenuItem *menuitem;
2501
2502         mainwin = (MainWindow *) data;
2503         
2504         ifactory = gtk_item_factory_from_widget(mainwin->menubar);
2505         menuitem = GTK_CHECK_MENU_ITEM (gtk_item_factory_get_widget(ifactory, "/File/Work offline"));
2506         
2507         g_return_if_fail(mainwin != NULL);
2508         g_return_if_fail(menuitem != NULL);
2509         
2510         if (btn == GTK_BUTTON(mainwin->online_switch)) {
2511                 /* go offline */
2512                 gtk_widget_hide (mainwin->online_switch);
2513                 gtk_widget_show (mainwin->offline_switch);
2514                 menuitem->active = TRUE;
2515                 prefs_common.work_offline = TRUE;
2516                 inc_autocheck_timer_remove();           
2517         } else {
2518                 /*go online */
2519                 gtk_widget_hide (mainwin->offline_switch);
2520                 gtk_widget_show (mainwin->online_switch);
2521                 menuitem->active = FALSE;
2522                 prefs_common.work_offline = FALSE;
2523                 inc_autocheck_timer_set();
2524         }
2525 }
2526
2527 static void addressbook_open_cb(MainWindow *mainwin, guint action,
2528                                 GtkWidget *widget)
2529 {
2530         addressbook_open(NULL);
2531 }
2532
2533 static void log_window_show_cb(MainWindow *mainwin, guint action,
2534                                GtkWidget *widget)
2535 {
2536         log_window_show(mainwin->logwin);
2537 }
2538
2539 static void inc_cancel_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2540 {
2541         inc_cancel_all();
2542 }
2543
2544 static void move_to_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2545 {
2546         summary_move_to(mainwin->summaryview);
2547 }
2548
2549 static void copy_to_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2550 {
2551         summary_copy_to(mainwin->summaryview);
2552 }
2553
2554 static void delete_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2555 {
2556         summary_delete(mainwin->summaryview);
2557 }
2558
2559 static void cancel_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2560 {
2561         summary_cancel(mainwin->summaryview);
2562 }
2563
2564 static void open_msg_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2565 {
2566         summary_open_msg(mainwin->summaryview);
2567 }
2568
2569 static void view_source_cb(MainWindow *mainwin, guint action,
2570                            GtkWidget *widget)
2571 {
2572         summary_view_source(mainwin->summaryview);
2573 }
2574
2575 static void show_all_header_cb(MainWindow *mainwin, guint action,
2576                                GtkWidget *widget)
2577 {
2578         if (mainwin->menu_lock_count) return;
2579         summary_display_msg_selected(mainwin->summaryview,
2580                                      GTK_CHECK_MENU_ITEM(widget)->active);
2581 }
2582
2583 static void mark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2584 {
2585         summary_mark(mainwin->summaryview);
2586 }
2587
2588 static void unmark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2589 {
2590         summary_unmark(mainwin->summaryview);
2591 }
2592
2593 static void mark_as_unread_cb(MainWindow *mainwin, guint action,
2594                               GtkWidget *widget)
2595 {
2596         summary_mark_as_unread(mainwin->summaryview);
2597 }
2598
2599 static void mark_as_read_cb(MainWindow *mainwin, guint action,
2600                             GtkWidget *widget)
2601 {
2602         summary_mark_as_read(mainwin->summaryview);
2603 }
2604
2605 static void mark_all_read_cb(MainWindow *mainwin, guint action,
2606                              GtkWidget *widget)
2607 {
2608         summary_mark_all_read(mainwin->summaryview);
2609 }
2610
2611 static void reedit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2612 {
2613         summary_reedit(mainwin->summaryview);
2614 }
2615
2616 static void add_address_cb(MainWindow *mainwin, guint action,
2617                            GtkWidget *widget)
2618 {
2619         summary_add_address(mainwin->summaryview);
2620 }
2621
2622 static void set_charset_cb(MainWindow *mainwin, guint action,
2623                            GtkWidget *widget)
2624 {
2625         const gchar *str;
2626
2627         if (GTK_CHECK_MENU_ITEM(widget)->active) {
2628                 str = conv_get_charset_str((CharSet)action);
2629                 
2630                 g_free(mainwin->messageview->forced_charset);
2631                 mainwin->messageview->forced_charset = str ? g_strdup(str) : NULL;
2632                 procmime_force_charset(str);
2633                 
2634                 summary_redisplay_msg(mainwin->summaryview);
2635                 
2636                 debug_print("forced charset: %s\n", str ? str : "Auto-Detect");
2637         }
2638 }
2639
2640 static void set_decode_cb(MainWindow *mainwin, guint action,
2641                            GtkWidget *widget)
2642 {
2643         if (GTK_CHECK_MENU_ITEM(widget)->active) {
2644                 mainwin->messageview->forced_encoding = (EncodingType)action;
2645                 
2646                 summary_redisplay_msg(mainwin->summaryview);
2647                 
2648                 debug_print("forced encoding: %d\n", action);
2649         }
2650 }
2651
2652 static void hide_read_messages (MainWindow *mainwin, guint action,
2653                                 GtkWidget *widget)
2654 {
2655         if (!mainwin->summaryview->folder_item
2656             || gtk_object_get_data(GTK_OBJECT(widget), "dont_toggle"))
2657                 return;
2658         summary_toggle_show_read_messages(mainwin->summaryview);
2659 }
2660
2661 static void thread_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2662 {
2663         if (mainwin->menu_lock_count) return;
2664         if (!mainwin->summaryview->folder_item) return;
2665
2666         if (GTK_CHECK_MENU_ITEM(widget)->active) {
2667                 summary_thread_build(mainwin->summaryview);
2668 /*              mainwin->summaryview->folder_item->threaded = TRUE; */
2669         } else {
2670                 summary_unthread(mainwin->summaryview);
2671 /*              mainwin->summaryview->folder_item->threaded = FALSE; */
2672         }
2673 }
2674
2675 static void expand_threads_cb(MainWindow *mainwin, guint action,
2676                               GtkWidget *widget)
2677 {
2678         summary_expand_threads(mainwin->summaryview);
2679 }
2680
2681 static void collapse_threads_cb(MainWindow *mainwin, guint action,
2682                                 GtkWidget *widget)
2683 {
2684         summary_collapse_threads(mainwin->summaryview);
2685 }
2686
2687 static void set_display_item_cb(MainWindow *mainwin, guint action,
2688                                 GtkWidget *widget)
2689 {
2690         prefs_summary_column_open();
2691 }
2692
2693 static void sort_summary_cb(MainWindow *mainwin, guint action,
2694                             GtkWidget *widget)
2695 {
2696         FolderItem *item = mainwin->summaryview->folder_item;
2697         GtkWidget *menuitem;
2698
2699         if (mainwin->menu_lock_count) return;
2700
2701         if (GTK_CHECK_MENU_ITEM(widget)->active && item) {
2702                 menuitem = gtk_item_factory_get_item
2703                         (mainwin->menu_factory, "/View/Sort/Ascending");
2704                 summary_sort(mainwin->summaryview, (FolderSortKey)action,
2705                              GTK_CHECK_MENU_ITEM(menuitem)->active
2706                              ? SORT_ASCENDING : SORT_DESCENDING);
2707         }
2708 }
2709
2710 static void sort_summary_type_cb(MainWindow *mainwin, guint action,
2711                                  GtkWidget *widget)
2712 {
2713         FolderItem *item = mainwin->summaryview->folder_item;
2714
2715         if (mainwin->menu_lock_count) return;
2716
2717         if (GTK_CHECK_MENU_ITEM(widget)->active && item)
2718                 summary_sort(mainwin->summaryview,
2719                              item->sort_key, (FolderSortType)action);
2720 }
2721
2722 static void attract_by_subject_cb(MainWindow *mainwin, guint action,
2723                                   GtkWidget *widget)
2724 {
2725         summary_attract_by_subject(mainwin->summaryview);
2726 }
2727
2728 static void delete_duplicated_cb(MainWindow *mainwin, guint action,
2729                                  GtkWidget *widget)
2730 {
2731         FolderItem *item;
2732
2733         item = folderview_get_selected_item(mainwin->folderview);
2734         if (item) {
2735                 main_window_cursor_wait(mainwin);
2736                 STATUSBAR_PUSH(mainwin, _("Deleting duplicated messages..."));
2737
2738                 folderutils_delete_duplicates(item, prefs_common.immediate_exec ?
2739                                               DELETE_DUPLICATES_REMOVE : DELETE_DUPLICATES_SETFLAG);
2740
2741                 STATUSBAR_POP(mainwin);
2742                 main_window_cursor_normal(mainwin);
2743         }
2744 }
2745
2746 struct DelDupsData
2747 {
2748         guint   dups;
2749         guint   folders;
2750 };
2751
2752 static void deldup_all(FolderItem *item, gpointer _data)
2753 {
2754         struct DelDupsData *data = _data;
2755         gint result;
2756         
2757         result = folderutils_delete_duplicates(item, DELETE_DUPLICATES_REMOVE);
2758         if (result >= 0) {
2759                 data->dups += result;
2760                 data->folders += 1;
2761         }
2762 }
2763
2764 static void delete_duplicated_all_cb(MainWindow *mainwin, guint action,
2765                                  GtkWidget *widget)
2766 {
2767         struct DelDupsData data = {0, 0};
2768
2769         folder_func_to_all_folders(deldup_all, &data);
2770         alertpanel_notice(_("Deleted %d duplicate message(s) in %d folders.\n"),
2771                           data.dups, data.folders);
2772 }
2773
2774 static void filter_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2775 {
2776         summary_filter(mainwin->summaryview, (gboolean)action);
2777 }
2778
2779 static void execute_summary_cb(MainWindow *mainwin, guint action,
2780                                GtkWidget *widget)
2781 {
2782         summary_execute(mainwin->summaryview);
2783 }
2784
2785 static void update_summary_cb(MainWindow *mainwin, guint action,
2786                               GtkWidget *widget)
2787 {
2788         FolderItem *fitem;
2789         FolderView *folderview = mainwin->folderview;
2790
2791         if (!mainwin->summaryview->folder_item) return;
2792         if (!folderview->opened) return;
2793
2794         folder_update_op_count();
2795
2796         fitem = gtk_ctree_node_get_row_data(GTK_CTREE(folderview->ctree),
2797                                             folderview->opened);
2798         if (!fitem) return;
2799
2800         folder_item_scan(fitem);
2801         summary_show(mainwin->summaryview, fitem);
2802 }
2803
2804 static void prev_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2805 {
2806         summary_step(mainwin->summaryview, GTK_SCROLL_STEP_BACKWARD);
2807 }
2808
2809 static void next_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2810 {
2811         summary_step(mainwin->summaryview, GTK_SCROLL_STEP_FORWARD);
2812 }
2813
2814 static void prev_unread_cb(MainWindow *mainwin, guint action,
2815                            GtkWidget *widget)
2816 {
2817         summary_select_prev_unread(mainwin->summaryview);
2818 }
2819
2820 static void next_unread_cb(MainWindow *mainwin, guint action,
2821                            GtkWidget *widget)
2822 {
2823         summary_select_next_unread(mainwin->summaryview);
2824 }
2825
2826 static void prev_new_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2827 {
2828         summary_select_prev_new(mainwin->summaryview);
2829 }
2830
2831 static void next_new_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2832 {
2833         summary_select_next_new(mainwin->summaryview);
2834 }
2835
2836 static void prev_marked_cb(MainWindow *mainwin, guint action,
2837                            GtkWidget *widget)
2838 {
2839         summary_select_prev_marked(mainwin->summaryview);
2840 }
2841
2842 static void next_marked_cb(MainWindow *mainwin, guint action,
2843                            GtkWidget *widget)
2844 {
2845         summary_select_next_marked(mainwin->summaryview);
2846 }
2847
2848 static void prev_labeled_cb(MainWindow *mainwin, guint action,
2849                             GtkWidget *widget)
2850 {
2851         summary_select_prev_labeled(mainwin->summaryview);
2852 }
2853
2854 static void next_labeled_cb(MainWindow *mainwin, guint action,
2855                             GtkWidget *widget)
2856 {
2857         summary_select_next_labeled(mainwin->summaryview);
2858 }
2859
2860 static void goto_folder_cb(MainWindow *mainwin, guint action,
2861                            GtkWidget *widget)
2862 {
2863         FolderItem *to_folder;
2864
2865         to_folder = foldersel_folder_sel(NULL, FOLDER_SEL_ALL, NULL);
2866
2867         if (to_folder)
2868                 folderview_select(mainwin->folderview, to_folder);
2869 }
2870
2871 static void copy_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2872 {
2873         messageview_copy_clipboard(mainwin->messageview);
2874 }
2875
2876 static void allsel_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
2877 {
2878         MessageView *msgview = mainwin->messageview;
2879
2880         if (GTK_WIDGET_HAS_FOCUS(mainwin->summaryview->ctree))
2881                 summary_select_all(mainwin->summaryview);
2882         else if (messageview_is_visible(msgview) &&
2883                  (GTK_WIDGET_HAS_FOCUS(msgview->mimeview->textview->text)))
2884                 messageview_select_all(mainwin->messageview);
2885 }
2886
2887 static void select_thread_cb(MainWindow *mainwin, guint action,
2888                              GtkWidget *widget)
2889 {
2890         summary_select_thread(mainwin->summaryview);
2891 }
2892
2893 static void create_filter_cb(MainWindow *mainwin, guint action,
2894                              GtkWidget *widget)
2895 {
2896         summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 0);
2897 }
2898
2899 static void create_processing_cb(MainWindow *mainwin, guint action,
2900                              GtkWidget *widget)
2901 {
2902         summary_filter_open(mainwin->summaryview, (PrefsFilterType)action, 1);
2903 }
2904
2905 static void prefs_common_open_cb(MainWindow *mainwin, guint action,
2906                                  GtkWidget *widget)
2907 {
2908         prefs_common_open();
2909 }
2910
2911 static void prefs_pre_processing_open_cb(MainWindow *mainwin, guint action,
2912                                          GtkWidget *widget)
2913 {
2914         prefs_filtering_open(&pre_global_processing,
2915                              _("Processing rules to apply before folder rules"),
2916                              NULL, NULL);
2917 }
2918
2919 static void prefs_post_processing_open_cb(MainWindow *mainwin, guint action,
2920                                           GtkWidget *widget)
2921 {
2922         prefs_filtering_open(&post_global_processing,
2923                              _("Processing rules to apply after folder rules"),
2924                              NULL, NULL);
2925 }
2926
2927 static void prefs_filtering_open_cb(MainWindow *mainwin, guint action,
2928                                     GtkWidget *widget)
2929 {
2930         prefs_filtering_open(&filtering_rules,
2931                              _("Filtering configuration"),
2932                              NULL, NULL);
2933 }
2934
2935 static void prefs_template_open_cb(MainWindow *mainwin, guint action,
2936                                    GtkWidget *widget)
2937 {
2938         prefs_template_open();
2939 }
2940
2941 static void prefs_actions_open_cb(MainWindow *mainwin, guint action,
2942                                   GtkWidget *widget)
2943 {
2944         prefs_actions_open(mainwin);
2945 }
2946 #ifdef USE_OPENSSL
2947 static void ssl_manager_open_cb(MainWindow *mainwin, guint action,
2948                                   GtkWidget *widget)
2949 {
2950         ssl_manager_open(mainwin);
2951 }
2952 #endif
2953 static void prefs_account_open_cb(MainWindow *mainwin, guint action,
2954                                   GtkWidget *widget)
2955 {
2956         if (!cur_account) {
2957                 new_account_cb(mainwin, 0, widget);
2958         } else {
2959                 account_open(cur_account);
2960         }
2961 }
2962
2963 static void new_account_cb(MainWindow *mainwin, guint action,
2964                            GtkWidget *widget)
2965 {
2966         account_edit_open();
2967         if (!compose_get_compose_list()) account_add();
2968 }
2969
2970 static void account_selector_menu_cb(GtkMenuItem *menuitem, gpointer data)
2971 {
2972         cur_account = (PrefsAccount *)data;
2973         main_window_reflect_prefs_all();
2974 }
2975
2976 static void account_receive_menu_cb(GtkMenuItem *menuitem, gpointer data)
2977 {
2978         MainWindow *mainwin = (MainWindow *)mainwin_list->data;
2979         PrefsAccount *account = (PrefsAccount *)data;
2980
2981         inc_account_mail(mainwin, account);
2982 }
2983
2984 static void prefs_open_cb(GtkMenuItem *menuitem, gpointer data)
2985 {
2986         prefs_gtk_open();
2987 }
2988
2989 static void plugins_open_cb(GtkMenuItem *menuitem, gpointer data)
2990 {
2991         pluginwindow_create();
2992 }
2993
2994 static void manual_open_cb(MainWindow *mainwin, guint action,
2995                            GtkWidget *widget)
2996 {
2997         manual_open((ManualType)action);
2998 }
2999
3000 static void scan_tree_func(Folder *folder, FolderItem *item, gpointer data)
3001 {
3002         MainWindow *mainwin = (MainWindow *)data;
3003         gchar *str;
3004
3005         if (item->path)
3006                 str = g_strdup_printf(_("Scanning folder %s%c%s ..."),
3007                                       LOCAL_FOLDER(folder)->rootpath,
3008                                       G_DIR_SEPARATOR,
3009                                       item->path);
3010         else
3011                 str = g_strdup_printf(_("Scanning folder %s ..."),
3012                                       LOCAL_FOLDER(folder)->rootpath);
3013
3014         STATUSBAR_PUSH(mainwin, str);
3015         STATUSBAR_POP(mainwin);
3016         g_free(str);
3017 }
3018
3019 static gboolean mainwindow_focus_in_event(GtkWidget *widget, GdkEventFocus *focus,
3020                                           gpointer data)
3021 {
3022         SummaryView *summary;
3023
3024         g_return_val_if_fail(data, FALSE);
3025         summary = ((MainWindow *)data)->summaryview;
3026         g_return_val_if_fail(summary, FALSE);
3027
3028         if (GTK_CLIST(summary->ctree)->selection && 
3029             g_list_length(GTK_CLIST(summary->ctree)->selection) > 1)
3030                 return FALSE;
3031
3032         if (summary->selected != summary->displayed)
3033                 summary_select_node(summary, summary->displayed, FALSE, TRUE);
3034         return FALSE;
3035 }
3036
3037 #define BREAK_ON_MODIFIER_KEY() \
3038         if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0) break
3039
3040 void mainwindow_key_pressed (GtkWidget *widget, GdkEventKey *event,
3041                                     gpointer data)
3042 {
3043         MainWindow *mainwin = (MainWindow*) data;
3044         
3045         if (!mainwin || !event) return;
3046                 
3047         switch (event->keyval) {
3048         case GDK_Q:             /* Quit */
3049                 BREAK_ON_MODIFIER_KEY();
3050
3051                 app_exit_cb(mainwin, 0, NULL);
3052                 return;
3053         case GDK_space:
3054                 if (mainwin->folderview && mainwin->summaryview
3055                     && !mainwin->summaryview->displayed) {
3056                         summary_lock(mainwin->summaryview);
3057                         folderview_select_next_unread(mainwin->folderview);
3058                         summary_unlock(mainwin->summaryview);
3059                 }
3060                 break;
3061         default:
3062                 break;
3063         }
3064 }
3065
3066 #undef BREAK_ON_MODIFIER_KEY
3067
3068 /*
3069  * Harvest addresses for selected folder.
3070  */
3071 static void addr_harvest_cb( MainWindow *mainwin,
3072                             guint action,
3073                             GtkWidget *widget )
3074 {
3075         addressbook_harvest( mainwin->summaryview->folder_item, FALSE, NULL );
3076 }
3077
3078 /*
3079  * Harvest addresses for selected messages in summary view.
3080  */
3081 static void addr_harvest_msg_cb( MainWindow *mainwin,
3082                             guint action,
3083                             GtkWidget *widget )
3084 {
3085         summary_harvest_address( mainwin->summaryview );
3086 }
3087
3088 /*!
3089  *\brief        get a MainWindow
3090  *
3091  *\return       MainWindow * The first mainwindow in the mainwin_list
3092  */
3093 MainWindow *mainwindow_get_mainwindow(void)
3094 {
3095         if (mainwin_list && mainwin_list->data)
3096                 return (MainWindow *)(mainwin_list->data);
3097         else
3098                 return NULL;
3099 }
3100
3101 gboolean mainwindow_progressindicator_hook(gpointer source, gpointer userdata)
3102 {
3103         ProgressData *data = (ProgressData *) source;
3104         MainWindow *mainwin = (MainWindow *) userdata;
3105
3106         switch (data->cmd) {
3107         case PROGRESS_COMMAND_START:
3108         case PROGRESS_COMMAND_STOP:
3109                 gtk_progress_set_percentage(GTK_PROGRESS(mainwin->progressbar), 0.0);
3110                 break;
3111         case PROGRESS_COMMAND_SET_PERCENTAGE:
3112                 gtk_progress_set_percentage(GTK_PROGRESS(mainwin->progressbar), data->value);
3113                 break;          
3114         }
3115         while (gtk_events_pending()) gtk_main_iteration ();
3116
3117         return FALSE;
3118 }
3119
3120 /*
3121 * End of Source.
3122 */