Statistics
| Revision:

root / src / mainwindow.c @ 3134

History | View | Annotate | Download (126.5 kB)

1
/*
2
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3
 * Copyright (C) 1999-2012 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 <glib/gi18n.h>
24
#include <gdk/gdkkeysyms.h>
25
#include <gtk/gtkmain.h>
26
#include <gtk/gtkversion.h>
27
#include <gtk/gtkwindow.h>
28
#include <gtk/gtkwidget.h>
29
#include <gtk/gtksignal.h>
30
#include <gtk/gtkvbox.h>
31
#include <gtk/gtkcontainer.h>
32
#include <gtk/gtkstatusbar.h>
33
#include <gtk/gtkprogressbar.h>
34
#include <gtk/gtkhpaned.h>
35
#include <gtk/gtkvpaned.h>
36
#include <gtk/gtkcheckmenuitem.h>
37
#include <gtk/gtkitemfactory.h>
38
#include <gtk/gtkeditable.h>
39
#include <gtk/gtkmenu.h>
40
#include <gtk/gtkmenuitem.h>
41
#include <gtk/gtktoolbar.h>
42
#include <gtk/gtktoolitem.h>
43
#include <gtk/gtktoolbutton.h>
44
#include <gtk/gtkseparatortoolitem.h>
45
#include <gtk/gtkbutton.h>
46
#include <gtk/gtktooltips.h>
47
#include <gtk/gtkarrow.h>
48
#include <gtk/gtkstock.h>
49
#include <gtk/gtkimage.h>
50
#include <string.h>
51
52
#include "main.h"
53
#include "mainwindow.h"
54
#include "folderview.h"
55
#include "foldersel.h"
56
#include "summaryview.h"
57
#include "quick_search.h"
58
#include "query_search.h"
59
#include "messageview.h"
60
#include "mimeview.h"
61
#include "message_search.h"
62
#include "headerview.h"
63
#include "menu.h"
64
#include "stock_pixmap.h"
65
#include "folder.h"
66
#include "inc.h"
67
#include "rpop3.h"
68
#include "compose.h"
69
#include "procmsg.h"
70
#include "send_message.h"
71
#include "import.h"
72
#include "export.h"
73
#include "prefs_common.h"
74
#include "prefs_common_dialog.h"
75
#include "prefs_filter.h"
76
#include "prefs_actions.h"
77
#include "prefs_account.h"
78
#include "prefs_summary_column.h"
79
#include "prefs_template.h"
80
#include "prefs_search_folder.h"
81
#include "prefs_toolbar.h"
82
#include "plugin_manager.h"
83
#include "action.h"
84
#include "account.h"
85
#include "account_dialog.h"
86
#include "addressbook.h"
87
#include "logwindow.h"
88
#include "manage_window.h"
89
#include "alertpanel.h"
90
#include "statusbar.h"
91
#include "inputdialog.h"
92
#include "trayicon.h"
93
#include "printing.h"
94
#include "utils.h"
95
#include "gtkutils.h"
96
#include "codeconv.h"
97
#include "about.h"
98
#include "manual.h"
99
#include "update_check.h"
100
#include "setup.h"
101
#include "version.h"
102
103
#define AC_LABEL_WIDTH        240
104
105
#define STATUSBAR_PUSH(mainwin, str) \
106
{ \
107
        gtk_statusbar_push(GTK_STATUSBAR(mainwin->statusbar), \
108
                           mainwin->mainwin_cid, str); \
109
        gtkut_widget_draw_now(mainwin->statusbar); \
110
}
111
112
#define STATUSBAR_POP(mainwin) \
113
{ \
114
        gtk_statusbar_pop(GTK_STATUSBAR(mainwin->statusbar), \
115
                          mainwin->mainwin_cid); \
116
}
117
118
/* list of all instantiated MainWindow */
119
static GList *mainwin_list = NULL;
120
121
static GdkCursor *watch_cursor;
122
123
static void main_window_menu_callback_block        (MainWindow        *mainwin);
124
static void main_window_menu_callback_unblock        (MainWindow        *mainwin);
125
126
static void main_window_show_cur_account        (MainWindow        *mainwin);
127
128
static void main_window_set_toolbar_button_visibility
129
                                                (MainWindow        *mainwin);
130
131
static void main_window_set_widgets                (MainWindow        *mainwin,
132
                                                 LayoutType         layout,
133
                                                 SeparateType         type);
134
static GtkWidget *main_window_toolbar_create        (MainWindow        *mainwin);
135
static GtkWidget *main_window_toolbar_create_from_list
136
                                                (MainWindow        *mainwin,
137
                                                 GList                *item_list);
138
static void main_window_toolbar_toggle_menu_set_active
139
                                                (MainWindow        *mainwin,
140
                                                 ToolbarStyle         style);
141
142
/* callback functions */
143
static void toolbar_inc_cb                (GtkWidget        *widget,
144
                                         gpointer         data);
145
static void toolbar_inc_all_cb                (GtkWidget        *widget,
146
                                         gpointer         data);
147
static void toolbar_rpop3_cb                (GtkWidget        *widget,
148
                                         gpointer         data);
149
static void toolbar_send_cb                (GtkWidget        *widget,
150
                                         gpointer         data);
151
152
static void toolbar_compose_cb                (GtkWidget        *widget,
153
                                         gpointer         data);
154
static void toolbar_reply_cb                (GtkWidget        *widget,
155
                                         gpointer         data);
156
static void toolbar_reply_to_all_cb        (GtkWidget        *widget,
157
                                         gpointer         data);
158
static void toolbar_forward_cb                (GtkWidget        *widget,
159
                                         gpointer         data);
160
161
static void toolbar_delete_cb                (GtkWidget        *widget,
162
                                         gpointer         data);
163
static void toolbar_junk_cb                (GtkWidget        *widget,
164
                                         gpointer         data);
165
static void toolbar_notjunk_cb                (GtkWidget        *widget,
166
                                         gpointer         data);
167
static void toolbar_exec_cb                (GtkWidget        *widget,
168
                                         gpointer         data);
169
170
static void toolbar_next_unread_cb        (GtkWidget        *widget,
171
                                         gpointer         data);
172
static void toolbar_prev_unread_cb        (GtkWidget        *widget,
173
                                         gpointer         data);
174
static void toolbar_address_cb                (GtkWidget        *widget,
175
                                         gpointer         data);
176
static void toolbar_search_cb                (GtkWidget        *widget,
177
                                         gpointer         data);
178
static void toolbar_print_cb                (GtkWidget        *widget,
179
                                         gpointer         data);
180
static void toolbar_stop_cb                (GtkWidget        *widget,
181
                                         gpointer         data);
182
static void toolbar_prefs_common_cb        (GtkWidget        *widget,
183
                                         gpointer         data);
184
static void toolbar_prefs_account_cb        (GtkWidget        *widget,
185
                                         gpointer         data);
186
187
static gboolean toolbar_button_pressed        (GtkWidget        *widget,
188
                                         GdkEventButton        *event,
189
                                         gpointer         data);
190
191
static void online_switch_clicked                (GtkWidget        *widget,
192
                                                 gpointer         data);
193
static gboolean ac_label_button_pressed                (GtkWidget        *widget,
194
                                                 GdkEventButton        *event,
195
                                                 gpointer         data);
196
static void ac_menu_popup_closed                (GtkMenuShell        *menu_shell,
197
                                                 gpointer         data);
198
199
static gboolean main_window_key_pressed                (GtkWidget        *widget,
200
                                                 GdkEventKey        *event,
201
                                                 gpointer         data);
202
203
static gint main_window_close_cb                (GtkWidget        *widget,
204
                                                 GdkEventAny        *event,
205
                                                 gpointer         data);
206
static gint folder_window_close_cb                (GtkWidget        *widget,
207
                                                 GdkEventAny        *event,
208
                                                 gpointer         data);
209
static gint message_window_close_cb                (GtkWidget        *widget,
210
                                                 GdkEventAny        *event,
211
                                                 gpointer         data);
212
213
static void main_window_size_allocate_cb        (GtkWidget        *widget,
214
                                                 GtkAllocation        *allocation,
215
                                                 gpointer         data);
216
static void folder_window_size_allocate_cb        (GtkWidget        *widget,
217
                                                 GtkAllocation        *allocation,
218
                                                 gpointer         data);
219
static void message_window_size_allocate_cb        (GtkWidget        *widget,
220
                                                 GtkAllocation        *allocation,
221
                                                 gpointer         data);
222
223
static gboolean main_window_window_state_cb        (GtkWidget                *widget,
224
                                                 GdkEventWindowState        *event,
225
                                                 gpointer                 data);
226
static gboolean main_window_visibility_notify_cb(GtkWidget                *widget,
227
                                                 GdkEventVisibility        *event,
228
                                                 gpointer                 data);
229
230
static void new_folder_cb         (MainWindow        *mainwin,
231
                                  guint                 action,
232
                                  GtkWidget        *widget);
233
static void rename_folder_cb         (MainWindow        *mainwin,
234
                                  guint                 action,
235
                                  GtkWidget        *widget);
236
static void move_folder_cb         (MainWindow        *mainwin,
237
                                  guint                 action,
238
                                  GtkWidget        *widget);
239
static void delete_folder_cb         (MainWindow        *mainwin,
240
                                  guint                 action,
241
                                  GtkWidget        *widget);
242
static void update_folderview_cb (MainWindow        *mainwin,
243
                                  guint                 action,
244
                                  GtkWidget        *widget);
245
246
static void add_mailbox_cb         (MainWindow        *mainwin,
247
                                  guint                 action,
248
                                  GtkWidget        *widget);
249
static void remove_mailbox_cb         (MainWindow        *mainwin,
250
                                  guint                 action,
251
                                  GtkWidget        *widget);
252
static void rebuild_tree_cb         (MainWindow        *mainwin,
253
                                  guint                 action,
254
                                  GtkWidget        *widget);
255
256
static void import_mail_cb         (MainWindow        *mainwin,
257
                                  guint                 action,
258
                                  GtkWidget        *widget);
259
static void export_mail_cb         (MainWindow        *mainwin,
260
                                  guint                 action,
261
                                  GtkWidget        *widget);
262
static void empty_trash_cb         (MainWindow        *mainwin,
263
                                  guint                 action,
264
                                  GtkWidget        *widget);
265
266
static void save_as_cb                 (MainWindow        *mainwin,
267
                                  guint                 action,
268
                                  GtkWidget        *widget);
269
#if GTK_CHECK_VERSION(2, 10, 0)
270
static void page_setup_cb         (MainWindow        *mainwin,
271
                                  guint                 action,
272
                                  GtkWidget        *widget);
273
#endif
274
static void print_cb                 (MainWindow        *mainwin,
275
                                  guint                 action,
276
                                  GtkWidget        *widget);
277
static void toggle_offline_cb         (MainWindow        *mainwin,
278
                                  guint                 action,
279
                                  GtkWidget        *widget);
280
static void app_exit_cb                 (MainWindow        *mainwin,
281
                                  guint                 action,
282
                                  GtkWidget        *widget);
283
284
static void search_cb                 (MainWindow        *mainwin,
285
                                  guint                 action,
286
                                  GtkWidget        *widget);
287
288
static void toggle_folder_cb         (MainWindow        *mainwin,
289
                                  guint                 action,
290
                                  GtkWidget        *widget);
291
static void toggle_message_cb         (MainWindow        *mainwin,
292
                                  guint                 action,
293
                                  GtkWidget        *widget);
294
static void toggle_toolbar_cb         (MainWindow        *mainwin,
295
                                  guint                 action,
296
                                  GtkWidget        *widget);
297
static void toggle_searchbar_cb         (MainWindow        *mainwin,
298
                                  guint                 action,
299
                                  GtkWidget        *widget);
300
static void toggle_statusbar_cb         (MainWindow        *mainwin,
301
                                  guint                 action,
302
                                  GtkWidget        *widget);
303
static void toolbar_customize_cb (MainWindow        *mainwin,
304
                                  guint                 action,
305
                                  GtkWidget        *widget);
306
static void change_layout_cb         (MainWindow        *mainwin,
307
                                  guint                 action,
308
                                  GtkWidget        *widget);
309
static void separate_widget_cb         (MainWindow        *mainwin,
310
                                  guint                 action,
311
                                  GtkWidget        *widget);
312
313
static void addressbook_open_cb        (MainWindow        *mainwin,
314
                                 guint                 action,
315
                                 GtkWidget        *widget);
316
static void log_window_show_cb        (MainWindow        *mainwin,
317
                                 guint                 action,
318
                                 GtkWidget        *widget);
319
320
static void inc_mail_cb                        (MainWindow        *mainwin,
321
                                         guint                 action,
322
                                         GtkWidget        *widget);
323
static void inc_all_account_mail_cb        (MainWindow        *mainwin,
324
                                         guint                 action,
325
                                         GtkWidget        *widget);
326
static void inc_stop_cb                        (MainWindow        *mainwin,
327
                                         guint                 action,
328
                                         GtkWidget        *widget);
329
330
static void rpop3_cb                        (MainWindow        *mainwin,
331
                                         guint                 action,
332
                                         GtkWidget        *widget);
333
334
static void send_queue_cb                (MainWindow        *mainwin,
335
                                         guint                 action,
336
                                         GtkWidget        *widget);
337
338
static void compose_cb                        (MainWindow        *mainwin,
339
                                         guint                 action,
340
                                         GtkWidget        *widget);
341
static void reply_cb                        (MainWindow        *mainwin,
342
                                         guint                 action,
343
                                         GtkWidget        *widget);
344
345
static void open_msg_cb                        (MainWindow        *mainwin,
346
                                         guint                 action,
347
                                         GtkWidget        *widget);
348
349
static void view_source_cb                (MainWindow        *mainwin,
350
                                         guint                 action,
351
                                         GtkWidget        *widget);
352
353
static void show_all_header_cb                (MainWindow        *mainwin,
354
                                         guint                 action,
355
                                         GtkWidget        *widget);
356
357
static void move_to_cb                        (MainWindow        *mainwin,
358
                                         guint                 action,
359
                                         GtkWidget        *widget);
360
static void copy_to_cb                        (MainWindow        *mainwin,
361
                                         guint                 action,
362
                                         GtkWidget        *widget);
363
static void delete_cb                        (MainWindow        *mainwin,
364
                                         guint                 action,
365
                                         GtkWidget        *widget);
366
367
static void mark_cb                        (MainWindow        *mainwin,
368
                                         guint                 action,
369
                                         GtkWidget        *widget);
370
static void unmark_cb                        (MainWindow        *mainwin,
371
                                         guint                 action,
372
                                         GtkWidget        *widget);
373
374
static void mark_as_unread_cb                (MainWindow        *mainwin,
375
                                         guint                 action,
376
                                         GtkWidget        *widget);
377
static void mark_as_read_cb                (MainWindow        *mainwin,
378
                                         guint                 action,
379
                                         GtkWidget        *widget);
380
static void mark_thread_as_read_cb        (MainWindow        *mainwin,
381
                                         guint                 action,
382
                                         GtkWidget        *widget);
383
static void mark_all_read_cb                (MainWindow        *mainwin,
384
                                         guint                 action,
385
                                         GtkWidget        *widget);
386
387
static void junk_cb                        (MainWindow        *mainwin,
388
                                         guint                 action,
389
                                         GtkWidget        *widget);
390
391
static void reedit_cb                        (MainWindow        *mainwin,
392
                                         guint                 action,
393
                                         GtkWidget        *widget);
394
395
static void add_address_cb                (MainWindow        *mainwin,
396
                                         guint                 action,
397
                                         GtkWidget        *widget);
398
399
static void set_charset_cb                (MainWindow        *mainwin,
400
                                         guint                 action,
401
                                         GtkWidget        *widget);
402
403
static void thread_cb                 (MainWindow        *mainwin,
404
                                  guint                 action,
405
                                  GtkWidget        *widget);
406
static void expand_threads_cb         (MainWindow        *mainwin,
407
                                  guint                 action,
408
                                  GtkWidget        *widget);
409
static void collapse_threads_cb         (MainWindow        *mainwin,
410
                                  guint                 action,
411
                                  GtkWidget        *widget);
412
413
static void set_display_item_cb         (MainWindow        *mainwin,
414
                                  guint                 action,
415
                                  GtkWidget        *widget);
416
static void sort_summary_cb         (MainWindow        *mainwin,
417
                                  guint                 action,
418
                                  GtkWidget        *widget);
419
static void sort_summary_type_cb (MainWindow        *mainwin,
420
                                  guint                 action,
421
                                  GtkWidget        *widget);
422
static void attract_by_subject_cb(MainWindow        *mainwin,
423
                                  guint                 action,
424
                                  GtkWidget        *widget);
425
426
static void delete_duplicated_cb (MainWindow        *mainwin,
427
                                  guint                 action,
428
                                  GtkWidget        *widget);
429
static void concat_partial_cb         (MainWindow        *mainwin,
430
                                  guint                 action,
431
                                  GtkWidget        *widget);
432
static void filter_cb                 (MainWindow        *mainwin,
433
                                  guint                 action,
434
                                  GtkWidget        *widget);
435
static void filter_junk_cb         (MainWindow        *mainwin,
436
                                  guint                 action,
437
                                  GtkWidget        *widget);
438
static void execute_summary_cb         (MainWindow        *mainwin,
439
                                  guint                 action,
440
                                  GtkWidget        *widget);
441
static void update_summary_cb         (MainWindow        *mainwin,
442
                                  guint                 action,
443
                                  GtkWidget        *widget);
444
445
static void prev_cb                 (MainWindow        *mainwin,
446
                                  guint                 action,
447
                                  GtkWidget        *widget);
448
static void next_cb                 (MainWindow        *mainwin,
449
                                  guint                 action,
450
                                  GtkWidget        *widget);
451
452
static void prev_unread_cb         (MainWindow        *mainwin,
453
                                  guint                 action,
454
                                  GtkWidget        *widget);
455
static void next_unread_cb         (MainWindow        *mainwin,
456
                                  guint                 action,
457
                                  GtkWidget        *widget);
458
static void prev_new_cb                 (MainWindow        *mainwin,
459
                                  guint                 action,
460
                                  GtkWidget        *widget);
461
static void next_new_cb                 (MainWindow        *mainwin,
462
                                  guint                 action,
463
                                  GtkWidget        *widget);
464
static void prev_marked_cb         (MainWindow        *mainwin,
465
                                  guint                 action,
466
                                  GtkWidget        *widget);
467
static void next_marked_cb         (MainWindow        *mainwin,
468
                                  guint                 action,
469
                                  GtkWidget        *widget);
470
static void prev_labeled_cb         (MainWindow        *mainwin,
471
                                  guint                 action,
472
                                  GtkWidget        *widget);
473
static void next_labeled_cb         (MainWindow        *mainwin,
474
                                  guint                 action,
475
                                  GtkWidget        *widget);
476
477
static void goto_folder_cb         (MainWindow        *mainwin,
478
                                  guint                 action,
479
                                  GtkWidget        *widget);
480
481
static void copy_cb                 (MainWindow        *mainwin,
482
                                  guint                 action,
483
                                  GtkWidget        *widget);
484
static void allsel_cb                 (MainWindow        *mainwin,
485
                                  guint                 action,
486
                                  GtkWidget        *widget);
487
static void select_thread_cb         (MainWindow        *mainwin,
488
                                  guint                 action,
489
                                  GtkWidget        *widget);
490
491
static void create_filter_cb         (MainWindow        *mainwin,
492
                                  guint                 action,
493
                                  GtkWidget        *widget);
494
495
static void prefs_common_open_cb        (MainWindow        *mainwin,
496
                                         guint                 action,
497
                                         GtkWidget        *widget);
498
static void prefs_filter_open_cb        (MainWindow        *mainwin,
499
                                         guint                 action,
500
                                         GtkWidget        *widget);
501
static void prefs_template_open_cb        (MainWindow        *mainwin,
502
                                         guint                 action,
503
                                         GtkWidget        *widget);
504
static void plugin_manager_open_cb        (MainWindow        *mainwin,
505
                                         guint                 action,
506
                                         GtkWidget        *widget);
507
#ifndef G_OS_WIN32
508
static void prefs_actions_open_cb        (MainWindow        *mainwin,
509
                                         guint                 action,
510
                                         GtkWidget        *widget);
511
#endif
512
static void prefs_account_open_cb        (MainWindow        *mainwin,
513
                                         guint                 action,
514
                                         GtkWidget        *widget);
515
516
static void new_account_cb         (MainWindow        *mainwin,
517
                                  guint                 action,
518
                                  GtkWidget        *widget);
519
520
static void account_selector_menu_cb         (GtkMenuItem        *menuitem,
521
                                          gpointer         data);
522
static void account_receive_menu_cb         (GtkMenuItem        *menuitem,
523
                                          gpointer         data);
524
525
static void manual_open_cb         (MainWindow        *mainwin,
526
                                  guint                 action,
527
                                  GtkWidget        *widget);
528
static void faq_open_cb                 (MainWindow        *mainwin,
529
                                  guint                 action,
530
                                  GtkWidget        *widget);
531
static void help_cmdline_cb         (MainWindow        *mainwin,
532
                                  guint                 action,
533
                                  GtkWidget        *widget);
534
#if USE_UPDATE_CHECK
535
static void update_check_cb         (MainWindow        *mainwin,
536
                                  guint                 action,
537
                                  GtkWidget        *widget);
538
#ifdef USE_UPDATE_CHECK_PLUGIN
539
static void update_check_plugin_cb(MainWindow *mainwin, guint action,
540
                                   GtkWidget *widget);
541
#endif
542
#endif
543
544
static void scan_tree_func         (Folder        *folder,
545
                                  FolderItem        *item,
546
                                  gpointer         data);
547
548
static GtkItemFactoryEntry mainwin_entries[] =
549
{
550
        {N_("/_File"),                                NULL, NULL, 0, "<Branch>"},
551
        {N_("/_File/_Folder"),                        NULL, NULL, 0, "<Branch>"},
552
        {N_("/_File/_Folder/Create _new folder..."),
553
                                                NULL, new_folder_cb, 0, NULL},
554
        {N_("/_File/_Folder/_Rename folder..."),NULL, rename_folder_cb, 0, NULL},
555
        {N_("/_File/_Folder/_Move folder..."),  NULL, move_folder_cb, 0, NULL},
556
        {N_("/_File/_Folder/_Delete folder"),        NULL, delete_folder_cb, 0, NULL},
557
        {N_("/_File/_Mailbox"),                        NULL, NULL, 0, "<Branch>"},
558
        {N_("/_File/_Mailbox/Add _mailbox..."),        NULL, add_mailbox_cb, 0, NULL},
559
        {N_("/_File/_Mailbox/_Remove mailbox"),        NULL, remove_mailbox_cb, 0, NULL},
560
        {N_("/_File/_Mailbox/---"),                NULL, NULL, 0, "<Separator>"},
561
        {N_("/_File/_Mailbox/_Check for new messages"),
562
                                                NULL, update_folderview_cb, 0, NULL},
563
        {N_("/_File/_Mailbox/Check for new messages in _all mailboxes"),
564
                                                NULL, update_folderview_cb, 1, NULL},
565
        {N_("/_File/_Mailbox/---"),                NULL, NULL, 0, "<Separator>"},
566
        {N_("/_File/_Mailbox/R_ebuild folder tree"),
567
                                                NULL, rebuild_tree_cb, 0, NULL},
568
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
569
        {N_("/_File/_Import mail data..."),        NULL, import_mail_cb, 0, NULL},
570
        {N_("/_File/_Export mail data..."),        NULL, export_mail_cb, 0, NULL},
571
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
572
        {N_("/_File/Empty all _trash"),                NULL, empty_trash_cb, 0, NULL},
573
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
574
        {N_("/_File/_Save as..."),                "<control>S", save_as_cb, 0, NULL},
575
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
576
#if GTK_CHECK_VERSION(2, 10, 0)
577
        {N_("/_File/Page set_up..."),                NULL, page_setup_cb, 0, NULL},
578
#endif
579
        {N_("/_File/_Print..."),                NULL, print_cb, 0, NULL},
580
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
581
        {N_("/_File/_Work offline"),                NULL, toggle_offline_cb, 0, "<ToggleItem>"},
582
        {N_("/_File/---"),                        NULL, NULL, 0, "<Separator>"},
583
        /* {N_("/_File/_Close"),                "<alt>W", app_exit_cb, 0, NULL}, */
584
        {N_("/_File/E_xit"),                        "<control>Q", app_exit_cb, 0, NULL},
585
586
        {N_("/_Edit"),                                NULL, NULL, 0, "<Branch>"},
587
        {N_("/_Edit/_Copy"),                        "<control>C", copy_cb, 0, NULL},
588
        {N_("/_Edit/Select _all"),                "<control>A", allsel_cb, 0, NULL},
589
        {N_("/_Edit/Select _thread"),                NULL, select_thread_cb, 0, NULL},
590
        {N_("/_Edit/---"),                        NULL, NULL, 0, "<Separator>"},
591
        {N_("/_Edit/_Find in current message..."),
592
                                                "<control>F", search_cb, 0, NULL},
593
        {N_("/_Edit/_Search messages..."),        "<shift><control>F", search_cb, 1, NULL},
594
        {N_("/_Edit/_Quick search"),                "<shift><control>S", search_cb, 2, NULL},
595
596
        {N_("/_View"),                                NULL, NULL, 0, "<Branch>"},
597
        {N_("/_View/Show or hi_de"),                NULL, NULL, 0, "<Branch>"},
598
        {N_("/_View/Show or hi_de/_Folder tree"),
599
                                                NULL, toggle_folder_cb, 0, "<ToggleItem>"},
600
        {N_("/_View/Show or hi_de/_Message view"),
601
                                                "V", toggle_message_cb, 0, "<ToggleItem>"},
602
        {N_("/_View/Show or hi_de/_Toolbar"),
603
                                                NULL, NULL, 0, "<Branch>"},
604
        {N_("/_View/Show or hi_de/_Toolbar/Icon _and text"),
605
                                                NULL, toggle_toolbar_cb, TOOLBAR_BOTH, "<RadioItem>"},
606
        {N_("/_View/Show or hi_de/_Toolbar/Text at the _right of icon"),
607
                                                NULL, toggle_toolbar_cb, TOOLBAR_BOTH_HORIZ, "/View/Show or hide/Toolbar/Icon and text"},
608
        {N_("/_View/Show or hi_de/_Toolbar/_Icon"),
609
                                                NULL, toggle_toolbar_cb, TOOLBAR_ICON, "/View/Show or hide/Toolbar/Icon and text"},
610
        {N_("/_View/Show or hi_de/_Toolbar/_Text"),
611
                                                NULL, toggle_toolbar_cb, TOOLBAR_TEXT, "/View/Show or hide/Toolbar/Icon and text"},
612
        {N_("/_View/Show or hi_de/_Toolbar/_None"),
613
                                                NULL, toggle_toolbar_cb, TOOLBAR_NONE, "/View/Show or hide/Toolbar/Icon and text"},
614
        {N_("/_View/Show or hi_de/_Search bar"),
615
                                                NULL, toggle_searchbar_cb, 0, "<ToggleItem>"},
616
        {N_("/_View/Show or hi_de/Status _bar"),
617
                                                NULL, toggle_statusbar_cb, 0, "<ToggleItem>"},
618
        {N_("/_View/_Customize toolbar..."),        NULL, toolbar_customize_cb, 0, NULL},
619
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
620
        {N_("/_View/Layou_t"),                        NULL, NULL, 0, "<Branch>"},
621
        {N_("/_View/Layou_t/_Normal"),                NULL, change_layout_cb, LAYOUT_NORMAL, "<RadioItem>"},
622
        {N_("/_View/Layou_t/_Vertical"),        NULL, change_layout_cb, LAYOUT_VERTICAL, "/View/Layout/Normal"},
623
        {N_("/_View/Separate f_older tree"),        NULL, separate_widget_cb, SEPARATE_FOLDER, "<ToggleItem>"},
624
        {N_("/_View/Separate _message view"),        NULL, separate_widget_cb, SEPARATE_MESSAGE, "<ToggleItem>"},
625
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
626
        {N_("/_View/_Sort"),                        NULL, NULL, 0, "<Branch>"},
627
        {N_("/_View/_Sort/by _number"),                NULL, sort_summary_cb, SORT_BY_NUMBER, "<RadioItem>"},
628
        {N_("/_View/_Sort/by s_ize"),                NULL, sort_summary_cb, SORT_BY_SIZE, "/View/Sort/by number"},
629
        {N_("/_View/_Sort/by _date"),                NULL, sort_summary_cb, SORT_BY_DATE, "/View/Sort/by number"},
630
        {N_("/_View/_Sort/by t_hread date"),        NULL, sort_summary_cb, SORT_BY_TDATE, "/View/Sort/by number"},
631
        {N_("/_View/_Sort/by _from"),                NULL, sort_summary_cb, SORT_BY_FROM, "/View/Sort/by number"},
632
        {N_("/_View/_Sort/by _recipient"),        NULL, sort_summary_cb, SORT_BY_TO, "/View/Sort/by number"},
633
        {N_("/_View/_Sort/by _subject"),        NULL, sort_summary_cb, SORT_BY_SUBJECT, "/View/Sort/by number"},
634
        {N_("/_View/_Sort/by _color label"),
635
                                                NULL, sort_summary_cb, SORT_BY_LABEL, "/View/Sort/by number"},
636
        {N_("/_View/_Sort/by _mark"),                NULL, sort_summary_cb, SORT_BY_MARK, "/View/Sort/by number"},
637
        {N_("/_View/_Sort/by _unread"),                NULL, sort_summary_cb, SORT_BY_UNREAD, "/View/Sort/by number"},
638
        {N_("/_View/_Sort/by a_ttachment"),
639
                                                NULL, sort_summary_cb, SORT_BY_MIME, "/View/Sort/by number"},
640
        {N_("/_View/_Sort/D_on't sort"),        NULL, sort_summary_cb, SORT_BY_NONE, "/View/Sort/by number"},
641
        {N_("/_View/_Sort/---"),                NULL, NULL, 0, "<Separator>"},
642
        {N_("/_View/_Sort/Ascending"),                NULL, sort_summary_type_cb, SORT_ASCENDING, "<RadioItem>"},
643
        {N_("/_View/_Sort/Descending"),                NULL, sort_summary_type_cb, SORT_DESCENDING, "/View/Sort/Ascending"},
644
        {N_("/_View/_Sort/---"),                NULL, NULL, 0, "<Separator>"},
645
        {N_("/_View/_Sort/_Attract by subject"),
646
                                                NULL, attract_by_subject_cb, 0, NULL},
647
        {N_("/_View/Th_read view"),                "<control>T", thread_cb, 0, "<ToggleItem>"},
648
        {N_("/_View/E_xpand all threads"),        NULL, expand_threads_cb, 0, NULL},
649
        {N_("/_View/Co_llapse all threads"),        NULL, collapse_threads_cb, 0, NULL},
650
        {N_("/_View/Set display _item..."),        NULL, set_display_item_cb, 0, NULL},
651
652
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
653
        {N_("/_View/_Go to"),                        NULL, NULL, 0, "<Branch>"},
654
        {N_("/_View/_Go to/_Prev message"),        "P", prev_cb, 0, NULL},
655
        {N_("/_View/_Go to/_Next message"),        "N", next_cb, 0, NULL},
656
        {N_("/_View/_Go to/---"),                NULL, NULL, 0, "<Separator>"},
657
        {N_("/_View/_Go to/P_rev unread message"),
658
                                                "<shift>P", prev_unread_cb, 0, NULL},
659
        {N_("/_View/_Go to/N_ext unread message"),
660
                                                "<shift>N", next_unread_cb, 0, NULL},
661
        {N_("/_View/_Go to/---"),                NULL, NULL, 0, "<Separator>"},
662
        {N_("/_View/_Go to/Prev ne_w message"),        NULL, prev_new_cb, 0, NULL},
663
        {N_("/_View/_Go to/Ne_xt new message"),        NULL, next_new_cb, 0, NULL},
664
        {N_("/_View/_Go to/---"),                NULL, NULL, 0, "<Separator>"},
665
        {N_("/_View/_Go to/Prev _marked message"),
666
                                                NULL, prev_marked_cb, 0, NULL},
667
        {N_("/_View/_Go to/Next m_arked message"),
668
                                                NULL, next_marked_cb, 0, NULL},
669
        {N_("/_View/_Go to/---"),                NULL, NULL, 0, "<Separator>"},
670
        {N_("/_View/_Go to/Prev _labeled message"),
671
                                                NULL, prev_labeled_cb, 0, NULL},
672
        {N_("/_View/_Go to/Next la_beled message"),
673
                                                NULL, next_labeled_cb, 0, NULL},
674
        {N_("/_View/_Go to/---"),                NULL, NULL, 0, "<Separator>"},
675
        {N_("/_View/_Go to/Other _folder..."),        "G", goto_folder_cb, 0, NULL},
676
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
677
678
#define ENC_SEPARATOR \
679
        {N_("/_View/Character _encoding/---"),                NULL, NULL, 0, "<Separator>"}
680
#define ENC_ACTION(action) \
681
         NULL, set_charset_cb, action, "/View/Character encoding/Auto detect"
682
683
        {N_("/_View/Character _encoding"),                NULL, NULL, 0, "<Branch>"},
684
        {N_("/_View/Character _encoding/_Auto detect"),
685
         NULL, set_charset_cb, C_AUTO, "<RadioItem>"},
686
        {N_("/_View/Character _encoding/---"),                NULL, NULL, 0, "<Separator>"},
687
        {N_("/_View/Character _encoding/7bit ascii (US-ASC_II)"),
688
         ENC_ACTION(C_US_ASCII)},
689
        {N_("/_View/Character _encoding/Unicode (_UTF-8)"),
690
         ENC_ACTION(C_UTF_8)},
691
        ENC_SEPARATOR,
692
693
        {N_("/_View/Character _encoding/Western European (ISO-8859-_1)"),
694
         ENC_ACTION(C_ISO_8859_1)},
695
        {N_("/_View/Character _encoding/Western European (ISO-8859-15)"),
696
         ENC_ACTION(C_ISO_8859_15)},
697
        {N_("/_View/Character _encoding/Western European (Windows-1252)"),
698
         ENC_ACTION(C_WINDOWS_1252)},
699
        ENC_SEPARATOR,
700
701
        {N_("/_View/Character _encoding/Central European (ISO-8859-_2)"),
702
         ENC_ACTION(C_ISO_8859_2)},
703
        ENC_SEPARATOR,
704
705
        {N_("/_View/Character _encoding/_Baltic (ISO-8859-13)"),
706
         ENC_ACTION(C_ISO_8859_13)},
707
        {N_("/_View/Character _encoding/Baltic (ISO-8859-_4)"),
708
         ENC_ACTION(C_ISO_8859_4)},
709
        {N_("/_View/Character _encoding/Baltic (Windows-1257)"),
710
         ENC_ACTION(C_WINDOWS_1257)},
711
        ENC_SEPARATOR,
712
713
        {N_("/_View/Character _encoding/Greek (ISO-8859-_7)"),
714
         ENC_ACTION(C_ISO_8859_7)},
715
        ENC_SEPARATOR,
716
717
        {N_("/_View/Character _encoding/Arabic (ISO-8859-_6)"),
718
         ENC_ACTION(C_ISO_8859_6)},
719
        {N_("/_View/Character _encoding/Arabic (Windows-1256)"),
720
         ENC_ACTION(C_CP1256)},
721
        ENC_SEPARATOR,
722
723
        {N_("/_View/Character _encoding/Hebrew (ISO-8859-_8)"),
724
         ENC_ACTION(C_ISO_8859_8)},
725
        {N_("/_View/Character _encoding/Hebrew (Windows-1255)"),
726
         ENC_ACTION(C_CP1255)},
727
        ENC_SEPARATOR,
728
729
        {N_("/_View/Character _encoding/Turkish (ISO-8859-_9)"),
730
         ENC_ACTION(C_ISO_8859_9)},
731
        ENC_SEPARATOR,
732
733
        {N_("/_View/Character _encoding/Cyrillic (ISO-8859-_5)"),
734
         ENC_ACTION(C_ISO_8859_5)},
735
        {N_("/_View/Character _encoding/Cyrillic (KOI8-_R)"),
736
         ENC_ACTION(C_KOI8_R)},
737
        {N_("/_View/Character _encoding/Cyrillic (KOI8-U)"),
738
         ENC_ACTION(C_KOI8_U)},
739
        {N_("/_View/Character _encoding/Cyrillic (Windows-1251)"),
740
         ENC_ACTION(C_CP1251)},
741
        ENC_SEPARATOR,
742
743
        {N_("/_View/Character _encoding/Japanese (ISO-2022-_JP)"),
744
         ENC_ACTION(C_ISO_2022_JP)},
745
        {N_("/_View/Character _encoding/Japanese (ISO-2022-JP-2)"),
746
         ENC_ACTION(C_ISO_2022_JP_2)},
747
        {N_("/_View/Character _encoding/Japanese (_EUC-JP)"),
748
         ENC_ACTION(C_EUC_JP)},
749
        {N_("/_View/Character _encoding/Japanese (_Shift__JIS)"),
750
         ENC_ACTION(C_SHIFT_JIS)},
751
        ENC_SEPARATOR,
752
753
        {N_("/_View/Character _encoding/Simplified Chinese (_GB2312)"),
754
         ENC_ACTION(C_GB2312)},
755
        {N_("/_View/Character _encoding/Simplified Chinese (GBK)"),
756
         ENC_ACTION(C_GBK)},
757
        {N_("/_View/Character _encoding/Traditional Chinese (_Big5)"),
758
         ENC_ACTION(C_BIG5)},
759
        {N_("/_View/Character _encoding/Traditional Chinese (EUC-_TW)"),
760
         ENC_ACTION(C_EUC_TW)},
761
        {N_("/_View/Character _encoding/Chinese (ISO-2022-_CN)"),
762
         ENC_ACTION(C_ISO_2022_CN)},
763
        ENC_SEPARATOR,
764
765
        {N_("/_View/Character _encoding/Korean (EUC-_KR)"),
766
         ENC_ACTION(C_EUC_KR)},
767
        {N_("/_View/Character _encoding/Korean (ISO-2022-KR)"),
768
         ENC_ACTION(C_ISO_2022_KR)},
769
        ENC_SEPARATOR,
770
771
        {N_("/_View/Character _encoding/Thai (TIS-620)"),
772
         ENC_ACTION(C_TIS_620)},
773
        {N_("/_View/Character _encoding/Thai (Windows-874)"),
774
         ENC_ACTION(C_WINDOWS_874)},
775
776
#undef CODESET_SEPARATOR
777
#undef CODESET_ACTION
778
779
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
780
        {N_("/_View/Open in new _window"),        "<control><alt>N", open_msg_cb, 0, NULL},
781
        {N_("/_View/Mess_age source"),                "<control>U", view_source_cb, 0, NULL},
782
        {N_("/_View/All _headers"),        "<control>H", show_all_header_cb, 0, "<ToggleItem>"},
783
        {N_("/_View/---"),                        NULL, NULL, 0, "<Separator>"},
784
        {N_("/_View/_Update summary"),                "<control><alt>U", update_summary_cb,  0, NULL},
785
786
        {N_("/_Message"),                        NULL, NULL, 0, "<Branch>"},
787
        {N_("/_Message/Recei_ve"),                NULL, NULL, 0, "<Branch>"},
788
        {N_("/_Message/Recei_ve/Get from _current account"),
789
                                                "<control>I",        inc_mail_cb, 0, NULL},
790
        {N_("/_Message/Recei_ve/Get from _all accounts"),
791
                                                "<shift><control>I", inc_all_account_mail_cb, 0, NULL},
792
        {N_("/_Message/Recei_ve/Stop receivin_g"),
793
                                                NULL, inc_stop_cb, 0, NULL},
794
        {N_("/_Message/Recei_ve/_Remote mailbox..."),
795
                                                NULL, rpop3_cb, 0, NULL},
796
        {N_("/_Message/Recei_ve/---"),                NULL, NULL, 0, "<Separator>"},
797
        {N_("/_Message/_Send queued messages"), NULL, send_queue_cb, 0, NULL},
798
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
799
        {N_("/_Message/Compose _new message"),        "<control>M",        compose_cb, 0, NULL},
800
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
801
        {N_("/_Message/_Reply"),                "<control>R",         reply_cb, COMPOSE_REPLY, NULL},
802
        {N_("/_Message/Repl_y to"),                NULL, NULL, 0, "<Branch>"},
803
        {N_("/_Message/Repl_y to/_all"),        "<shift><control>R", reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
804
        {N_("/_Message/Repl_y to/_sender"),        NULL, reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
805
        {N_("/_Message/Repl_y to/mailing _list"),
806
                                                "<control>L", reply_cb, COMPOSE_REPLY_TO_LIST, NULL},
807
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
808
        {N_("/_Message/_Forward"),                "<control><alt>F", reply_cb, COMPOSE_FORWARD, NULL},
809
        {N_("/_Message/For_ward as attachment"),
810
                                                "<shift><control><alt>F", reply_cb, COMPOSE_FORWARD_AS_ATTACH, NULL},
811
        {N_("/_Message/Redirec_t"),                NULL, reply_cb, COMPOSE_REDIRECT, NULL},
812
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
813
        {N_("/_Message/M_ove..."),                "<control>O", move_to_cb, 0, NULL},
814
        {N_("/_Message/_Copy..."),                "<shift><control>O", copy_to_cb, 0, NULL},
815
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
816
        {N_("/_Message/_Mark"),                        NULL, NULL, 0, "<Branch>"},
817
        {N_("/_Message/_Mark/Set _flag"),        "<shift>asterisk", mark_cb, 0, NULL},
818
        {N_("/_Message/_Mark/_Unset flag"),        "U", unmark_cb, 0, NULL},
819
        {N_("/_Message/_Mark/---"),                NULL, NULL, 0, "<Separator>"},
820
        {N_("/_Message/_Mark/Mark as unr_ead"),        "<shift>exclam", mark_as_unread_cb, 0, NULL},
821
        {N_("/_Message/_Mark/Mark as rea_d"),
822
                                                NULL, mark_as_read_cb, 0, NULL},
823
        {N_("/_Message/_Mark/Mark _thread as read"),
824
                                                NULL, mark_thread_as_read_cb, 0, NULL},
825
        {N_("/_Message/_Mark/Mark all _read"),        NULL, mark_all_read_cb, 0, NULL},
826
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
827
        {N_("/_Message/_Delete"),                "<control>D", delete_cb, 0, NULL},
828
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
829
        {N_("/_Message/Set as _junk mail"),        "<control>J", junk_cb, 0, NULL},
830
        {N_("/_Message/Set as not j_unk mail"),        "<shift><control>J", junk_cb, 1, NULL},
831
        {N_("/_Message/---"),                        NULL, NULL, 0, "<Separator>"},
832
        {N_("/_Message/Re-_edit"),                NULL, reedit_cb, 0, NULL},
833
834
        {N_("/_Tools"),                                NULL, NULL, 0, "<Branch>"},
835
        {N_("/_Tools/_Address book"),                "<shift><control>A", addressbook_open_cb, 0, NULL},
836
        {N_("/_Tools/Add sender to address boo_k..."),
837
                                                NULL, add_address_cb, 0, NULL},
838
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
839
        {N_("/_Tools/_Filter all messages in folder"),
840
                                                NULL, filter_cb, 0, NULL},
841
        {N_("/_Tools/Filter _selected messages"),
842
                                                NULL, filter_cb, 1, NULL},
843
        {N_("/_Tools/_Create filter rule"),        NULL, NULL, 0, "<Branch>"},
844
        {N_("/_Tools/_Create filter rule/_Automatically"),
845
                                                NULL, create_filter_cb, FLT_BY_AUTO, NULL},
846
        {N_("/_Tools/_Create filter rule/by _From"),
847
                                                NULL, create_filter_cb, FLT_BY_FROM, NULL},
848
        {N_("/_Tools/_Create filter rule/by _To"),
849
                                                NULL, create_filter_cb, FLT_BY_TO, NULL},
850
        {N_("/_Tools/_Create filter rule/by _Subject"),
851
                                                NULL, create_filter_cb, FLT_BY_SUBJECT, NULL},
852
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
853
        {N_("/_Tools/Filter _junk mails in folder"),
854
                                                NULL, filter_junk_cb, 0, NULL},
855
        {N_("/_Tools/Filter junk _mails in selected messages"),
856
                                                NULL, filter_junk_cb, 1, NULL},
857
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
858
#ifndef G_OS_WIN32
859
        {N_("/_Tools/Actio_ns"),                NULL, NULL, 0, "<Branch>"},
860
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
861
#endif
862
        {N_("/_Tools/Delete du_plicated messages"),
863
                                                NULL, delete_duplicated_cb,   0, NULL},
864
        {N_("/_Tools/C_oncatenate separated messages"),
865
                                                NULL, concat_partial_cb, 0, NULL},
866
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
867
        {N_("/_Tools/E_xecute marked process"),        "X", execute_summary_cb, 0, NULL},
868
        {N_("/_Tools/---"),                        NULL, NULL, 0, "<Separator>"},
869
        {N_("/_Tools/_Log window"),                "<shift><control>L", log_window_show_cb, 0, NULL},
870
871
        {N_("/_Configuration"),                        NULL, NULL, 0, "<Branch>"},
872
        {N_("/_Configuration/_Common preferences..."),
873
                                                NULL, prefs_common_open_cb, 0, NULL},
874
        {N_("/_Configuration/_Filter settings..."),
875
                                                NULL, prefs_filter_open_cb, 0, NULL},
876
        {N_("/_Configuration/_Template..."),        NULL, prefs_template_open_cb, 0, NULL},
877
#ifndef G_OS_WIN32
878
        {N_("/_Configuration/_Actions..."),        NULL, prefs_actions_open_cb, 0, NULL},
879
#endif
880
        {N_("/_Configuration/Plug-in _manager..."),
881
                                                NULL, plugin_manager_open_cb, 0, NULL},
882
        {N_("/_Configuration/---"),                NULL, NULL, 0, "<Separator>"},
883
        {N_("/_Configuration/_Preferences for current account..."),
884
                                                NULL, prefs_account_open_cb, 0, NULL},
885
        {N_("/_Configuration/Create _new account..."),
886
                                                NULL, new_account_cb, 0, NULL},
887
        {N_("/_Configuration/_Edit accounts..."),
888
                                                NULL, account_edit_open, 0, NULL},
889
        {N_("/_Configuration/C_hange current account"),
890
                                                NULL, NULL, 0, "<Branch>"},
891
892
        {N_("/_Help"),                                NULL, NULL, 0, "<Branch>"},
893
        {N_("/_Help/_Manual"),                        NULL, NULL, 0, "<Branch>"},
894
        {N_("/_Help/_Manual/_English"),                NULL, manual_open_cb, MANUAL_LANG_EN, NULL},
895
        {N_("/_Help/_Manual/_Japanese"),        NULL, manual_open_cb, MANUAL_LANG_JA, NULL},
896
        {N_("/_Help/_FAQ"),                        NULL, NULL, 0, "<Branch>"},
897
        {N_("/_Help/_FAQ/_English"),                NULL, faq_open_cb, MANUAL_LANG_EN, NULL},
898
        {N_("/_Help/_FAQ/_German"),                NULL, faq_open_cb, MANUAL_LANG_DE, NULL},
899
        {N_("/_Help/_FAQ/_Spanish"),                NULL, faq_open_cb, MANUAL_LANG_ES, NULL},
900
        {N_("/_Help/_FAQ/_French"),                NULL, faq_open_cb, MANUAL_LANG_FR, NULL},
901
        {N_("/_Help/_FAQ/_Italian"),                NULL, faq_open_cb, MANUAL_LANG_IT, NULL},
902
        {N_("/_Help/_Command line options"),        NULL, help_cmdline_cb, 0, NULL},
903
#if USE_UPDATE_CHECK
904
        {N_("/_Help/---"),                        NULL, NULL, 0, "<Separator>"},
905
        {N_("/_Help/_Update check..."),                NULL, update_check_cb, 0, NULL},
906
#ifdef USE_UPDATE_CHECK_PLUGIN
907
        {N_("/_Help/Update check of _plug-ins..."),
908
                                                NULL, update_check_plugin_cb, 0, NULL},
909
#endif
910
#endif
911
        {N_("/_Help/---"),                        NULL, NULL, 0, "<Separator>"},
912
        {N_("/_Help/_About"),                        NULL, about_show, 0, NULL}
913
};
914
915
MainWindow *main_window_create(SeparateType type)
916
{
917
        MainWindow *mainwin;
918
        GtkWidget *window;
919
        GtkWidget *vbox;
920
        GtkWidget *menubar;
921
        GtkWidget *toolbar;
922
        GtkWidget *hbox_spc;
923
        GtkWidget *vbox_body;
924
        GtkWidget *statusbar;
925
        GtkWidget *progressbar;
926
        GtkWidget *statuslabel;
927
        GtkWidget *online_hbox;
928
        GtkWidget *online_switch;
929
        GtkWidget *online_pixmap;
930
        GtkWidget *offline_pixmap;
931
        GtkTooltips *online_tip;
932
#if !GTK_CHECK_VERSION(2, 6, 0)
933
        GtkWidget *spacer_hbox;
934
#endif
935
        GtkWidget *ac_button;
936
        GtkWidget *ac_label;
937
938
        TrayIcon *tray_icon;
939
940
        FolderView *folderview;
941
        SummaryView *summaryview;
942
        MessageView *messageview;
943
        GdkColormap *colormap;
944
        GdkColor color[3];
945
        gboolean success[3];
946
        guint n_menu_entries;
947
        GtkItemFactory *ifactory;
948
        GtkWidget *ac_menu;
949
        GtkWidget *menuitem;
950
        gint i;
951
952
        static GdkGeometry geometry;
953
954
        debug_print(_("Creating main window...\n"));
955
        mainwin = g_new0(MainWindow, 1);
956
957
        /* main window */
958
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
959
        gtk_window_set_title(GTK_WINDOW(window), PROG_VERSION);
960
        gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, FALSE);
961
        gtk_window_set_wmclass(GTK_WINDOW(window), "main_window", "Sylpheed");
962
        gtk_widget_add_events(window, GDK_VISIBILITY_NOTIFY_MASK);
963
        g_signal_connect(G_OBJECT(window), "key_press_event",
964
                         G_CALLBACK(main_window_key_pressed), mainwin);
965
966
        if (!geometry.min_height) {
967
                geometry.min_width = 320;
968
                geometry.min_height = 200;
969
        }
970
        gtk_window_set_geometry_hints(GTK_WINDOW(window), NULL, &geometry,
971
                                      GDK_HINT_MIN_SIZE);
972
973
        g_signal_connect(G_OBJECT(window), "delete_event",
974
                         G_CALLBACK(main_window_close_cb), mainwin);
975
        MANAGE_WINDOW_SIGNALS_CONNECT(window);
976
        gtk_widget_realize(window);
977
978
        vbox = gtk_vbox_new(FALSE, 0);
979
        gtk_widget_show(vbox);
980
        gtk_container_add(GTK_CONTAINER(window), vbox);
981
982
        /* menu bar */
983
        n_menu_entries = sizeof(mainwin_entries) / sizeof(mainwin_entries[0]);
984
        menubar = menubar_create(window, mainwin_entries, 
985
                                 n_menu_entries, "<Main>", mainwin);
986
        gtk_widget_show(menubar);
987
        gtk_widget_set_size_request(menubar, 300, -1);
988
        gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, TRUE, 0);
989
        ifactory = gtk_item_factory_from_widget(menubar);
990
991
        toolbar = main_window_toolbar_create(mainwin);
992
        gtk_widget_set_size_request(toolbar, 300, -1);
993
        gtk_box_pack_start(GTK_BOX(vbox), toolbar, FALSE, FALSE, 0);
994
995
        hbox_spc = gtk_hbox_new(FALSE, 0);
996
        gtk_widget_show(hbox_spc);
997
        gtk_widget_set_size_request(hbox_spc, -1, BORDER_WIDTH);
998
        gtk_box_pack_start(GTK_BOX(vbox), hbox_spc, FALSE, FALSE, 0);
999
1000
        /* vbox that contains body */
1001
        vbox_body = gtk_vbox_new(FALSE, BORDER_WIDTH);
1002
        gtk_widget_show(vbox_body);
1003
        gtk_container_set_border_width(GTK_CONTAINER(vbox_body), 0);
1004
        gtk_box_pack_start(GTK_BOX(vbox), vbox_body, TRUE, TRUE, 0);
1005
1006
        statusbar = statusbar_create();
1007
        gtk_box_pack_end(GTK_BOX(vbox_body), statusbar, FALSE, FALSE, 0);
1008
1009
        progressbar = gtk_progress_bar_new();
1010
        gtk_widget_set_size_request(progressbar, 120, 1);
1011
        gtk_box_pack_start(GTK_BOX(statusbar), progressbar, FALSE, FALSE, 0);
1012
1013
        statuslabel = gtk_label_new("");
1014
        gtk_box_pack_start(GTK_BOX(statusbar), statuslabel, FALSE, FALSE, 0);
1015
1016
        online_hbox = gtk_hbox_new(FALSE, 0);
1017
1018
        online_pixmap = stock_pixbuf_widget(statusbar, STOCK_PIXMAP_ONLINE);
1019
        offline_pixmap = stock_pixbuf_widget(statusbar, STOCK_PIXMAP_OFFLINE);
1020
        gtk_box_pack_start(GTK_BOX(online_hbox), online_pixmap,
1021
                           FALSE, FALSE, 0);
1022
        gtk_box_pack_start(GTK_BOX(online_hbox), offline_pixmap,
1023
                           FALSE, FALSE, 0);
1024
1025
        online_switch = gtk_button_new();
1026
        gtk_button_set_relief(GTK_BUTTON(online_switch), GTK_RELIEF_NONE);
1027
        GTK_WIDGET_UNSET_FLAGS(online_switch, GTK_CAN_FOCUS);
1028
#ifdef G_OS_WIN32
1029
        gtk_widget_set_size_request(online_switch, 34, 20);
1030
#else
1031
        gtk_widget_set_size_request(online_switch, 34, 24);
1032
#endif
1033
        gtk_container_add(GTK_CONTAINER(online_switch), online_hbox);
1034
        g_signal_connect(G_OBJECT(online_switch), "clicked",
1035
                         G_CALLBACK(online_switch_clicked), mainwin);
1036
        gtk_box_pack_start(GTK_BOX(statusbar), online_switch, FALSE, FALSE, 0);
1037
1038
        online_tip = gtk_tooltips_new();
1039
1040
#if !GTK_CHECK_VERSION(2, 6, 0)
1041
        spacer_hbox = gtk_hbox_new(FALSE, 0);
1042
        gtk_box_pack_end(GTK_BOX(statusbar), spacer_hbox, FALSE, FALSE, 0);
1043
#endif
1044
1045
        ac_button = gtk_button_new();
1046
        gtk_button_set_relief(GTK_BUTTON(ac_button), GTK_RELIEF_NONE);
1047
        GTK_WIDGET_UNSET_FLAGS(ac_button, GTK_CAN_FOCUS);
1048
        gtk_widget_set_size_request(ac_button, -1, 1);
1049
        gtk_box_pack_end(GTK_BOX(statusbar), ac_button, FALSE, FALSE, 0);
1050
        g_signal_connect(G_OBJECT(ac_button), "button_press_event",
1051
                         G_CALLBACK(ac_label_button_pressed), mainwin);
1052
1053
        ac_label = gtk_label_new("");
1054
        gtk_container_add(GTK_CONTAINER(ac_button), ac_label);
1055
1056
        gtk_widget_show_all(statusbar);
1057
1058
        tray_icon = trayicon_create(mainwin);
1059
        if (tray_icon && prefs_common.show_trayicon)
1060
                trayicon_show(tray_icon);
1061
1062
        /* create views */
1063
        mainwin->folderview  = folderview  = folderview_create();
1064
        mainwin->summaryview = summaryview = summary_create();
1065
        mainwin->messageview = messageview = messageview_create();
1066
        mainwin->logwin      = log_window_create();
1067
1068
        quick_search_create(summaryview);
1069
1070
        folderview->mainwin      = mainwin;
1071
        folderview->summaryview  = summaryview;
1072
1073
        summaryview->mainwin     = mainwin;
1074
        summaryview->folderview  = folderview;
1075
        summaryview->messageview = messageview;
1076
        summaryview->window      = window;
1077
1078
        messageview->statusbar   = statusbar;
1079
        messageview->mainwin     = mainwin;
1080
1081
        mainwin->window         = window;
1082
        mainwin->vbox           = vbox;
1083
        mainwin->menubar        = menubar;
1084
        mainwin->menu_factory   = ifactory;
1085
        mainwin->toolbar        = toolbar;
1086
        mainwin->vbox_body      = vbox_body;
1087
        mainwin->statusbar      = statusbar;
1088
        mainwin->progressbar    = progressbar;
1089
        mainwin->statuslabel    = statuslabel;
1090
        mainwin->online_switch  = online_switch;
1091
        mainwin->online_pixmap  = online_pixmap;
1092
        mainwin->offline_pixmap = offline_pixmap;
1093
        mainwin->online_tip     = online_tip;
1094
        mainwin->ac_button      = ac_button;
1095
        mainwin->ac_label       = ac_label;
1096
1097
        mainwin->tray_icon      = tray_icon;
1098
1099
        /* set context IDs for status bar */
1100
        mainwin->mainwin_cid = gtk_statusbar_get_context_id
1101
                (GTK_STATUSBAR(statusbar), "Main Window");
1102
        mainwin->folderview_cid = gtk_statusbar_get_context_id
1103
                (GTK_STATUSBAR(statusbar), "Folder View");
1104
        mainwin->summaryview_cid = gtk_statusbar_get_context_id
1105
                (GTK_STATUSBAR(statusbar), "Summary View");
1106
        mainwin->messageview_cid = gtk_statusbar_get_context_id
1107
                (GTK_STATUSBAR(statusbar), "Message View");
1108
1109
        messageview->statusbar_cid = mainwin->messageview_cid;
1110
1111
        /* allocate colors for summary view and folder view */
1112
        summaryview->color_marked.red = summaryview->color_marked.green = 0;
1113
        summaryview->color_marked.blue = (guint16)65535;
1114
1115
        summaryview->color_dim.red = summaryview->color_dim.green =
1116
                summaryview->color_dim.blue = COLOR_DIM;
1117
1118
        folderview->color_new.red = (guint16)55000;
1119
        folderview->color_new.green = folderview->color_new.blue = 15000;
1120
1121
        folderview->color_noselect.red = folderview->color_noselect.green =
1122
                folderview->color_noselect.blue = COLOR_DIM;
1123
1124
        color[0] = summaryview->color_marked;
1125
        color[1] = summaryview->color_dim;
1126
        color[2] = folderview->color_new;
1127
1128
        colormap = gdk_window_get_colormap(window->window);
1129
        gdk_colormap_alloc_colors(colormap, color, 3, FALSE, TRUE, success);
1130
        for (i = 0; i < 3; i++) {
1131
                if (success[i] == FALSE)
1132
                        g_warning(_("MainWindow: color allocation %d failed\n"), i);
1133
        }
1134
1135
        if (prefs_common.layout_type == LAYOUT_VERTICAL)
1136
                messageview->visible = TRUE;
1137
        else
1138
                messageview->visible = prefs_common.msgview_visible;
1139
1140
        main_window_set_widgets(mainwin, prefs_common.layout_type, type);
1141
1142
        if (prefs_common.mainwin_maximized)
1143
                gtk_window_maximize(GTK_WINDOW(window));
1144
1145
        g_signal_connect(G_OBJECT(window), "size_allocate",
1146
                         G_CALLBACK(main_window_size_allocate_cb), mainwin);
1147
        g_signal_connect(G_OBJECT(window), "window_state_event",
1148
                         G_CALLBACK(main_window_window_state_cb), mainwin);
1149
        g_signal_connect(G_OBJECT(window), "visibility_notify_event",
1150
                         G_CALLBACK(main_window_visibility_notify_cb), mainwin);
1151
1152
        /* set menu items */
1153
        menuitem = gtk_item_factory_get_item
1154
                (ifactory, "/View/Character encoding/Auto detect");
1155
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE);
1156
1157
        main_window_toolbar_toggle_menu_set_active
1158
                (mainwin, prefs_common.toolbar_style);
1159
1160
        gtk_widget_hide(GTK_WIDGET_PTR(summaryview->qsearch));
1161
        menuitem = gtk_item_factory_get_item
1162
                (ifactory, "/View/Show or hide/Search bar");
1163
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
1164
                                       prefs_common.show_searchbar);
1165
1166
        gtk_widget_hide(mainwin->statusbar);
1167
        menuitem = gtk_item_factory_get_item
1168
                (ifactory, "/View/Show or hide/Status bar");
1169
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
1170
                                       prefs_common.show_statusbar);
1171
1172
        /* set account selection menu */
1173
        ac_menu = gtk_item_factory_get_widget
1174
                (ifactory, "/Configuration/Change current account");
1175
        g_signal_connect(G_OBJECT(ac_menu), "selection_done",
1176
                         G_CALLBACK(ac_menu_popup_closed), mainwin);
1177
        mainwin->ac_menu = ac_menu;
1178
1179
        main_window_set_toolbar_sensitive(mainwin);
1180
        main_window_set_toolbar_button_visibility(mainwin);
1181
1182
        /* create actions menu */
1183
#ifndef G_OS_WIN32
1184
        action_update_mainwin_menu(ifactory, mainwin);
1185
#endif
1186
1187
        /* initialize online switch */
1188
        prefs_common.online_mode = !prefs_common.online_mode;
1189
        online_switch_clicked(online_switch, mainwin);
1190
1191
        /* show main window */
1192
        gtk_widget_show(mainwin->window);
1193
1194
#if !GTK_CHECK_VERSION(2, 6, 0)
1195
        {
1196
                gint w, h;
1197
                gdk_drawable_get_size
1198
                        (GDK_DRAWABLE(GTK_STATUSBAR(statusbar)->grip_window),
1199
                         &w, &h);
1200
                gtk_widget_set_size_request(spacer_hbox, w, -1);
1201
        }
1202
#endif
1203
1204
        /* initialize views */
1205
        folderview_init(folderview);
1206
        summary_init(summaryview);
1207
        messageview_init(messageview);
1208
        log_window_init(mainwin->logwin);
1209
1210
        mainwin->lock_count = 0;
1211
        mainwin->menu_lock_count = 0;
1212
        mainwin->cursor_count = 0;
1213
1214
        mainwin->window_hidden = FALSE;
1215
        mainwin->window_obscured = FALSE;
1216
1217
        if (!watch_cursor)
1218
                watch_cursor = gdk_cursor_new(GDK_WATCH);
1219
1220
        mainwin_list = g_list_append(mainwin_list, mainwin);
1221
1222
        debug_print(_("done.\n"));
1223
1224
        return mainwin;
1225
}
1226
1227
void main_window_cursor_wait(MainWindow *mainwin)
1228
{
1229
1230
        if (mainwin->cursor_count == 0)
1231
                gdk_window_set_cursor(mainwin->window->window, watch_cursor);
1232
1233
        mainwin->cursor_count++;
1234
1235
        gdk_flush();
1236
}
1237
1238
void main_window_cursor_normal(MainWindow *mainwin)
1239
{
1240
        if (mainwin->cursor_count)
1241
                mainwin->cursor_count--;
1242
1243
        if (mainwin->cursor_count == 0)
1244
                gdk_window_set_cursor(mainwin->window->window, NULL);
1245
1246
        gdk_flush();
1247
}
1248
1249
/* lock / unlock the user-interface */
1250
void main_window_lock(MainWindow *mainwin)
1251
{
1252
        if (mainwin->lock_count == 0)
1253
                gtk_widget_set_sensitive(mainwin->ac_button, FALSE);
1254
1255
        mainwin->lock_count++;
1256
1257
        main_window_set_menu_sensitive(mainwin);
1258
        main_window_set_toolbar_sensitive(mainwin);
1259
}
1260
1261
void main_window_unlock(MainWindow *mainwin)
1262
{
1263
        if (mainwin->lock_count)
1264
                mainwin->lock_count--;
1265
1266
        main_window_set_menu_sensitive(mainwin);
1267
        main_window_set_toolbar_sensitive(mainwin);
1268
1269
        if (mainwin->lock_count == 0)
1270
                gtk_widget_set_sensitive(mainwin->ac_button, TRUE);
1271
}
1272
1273
static void main_window_menu_callback_block(MainWindow *mainwin)
1274
{
1275
        mainwin->menu_lock_count++;
1276
}
1277
1278
static void main_window_menu_callback_unblock(MainWindow *mainwin)
1279
{
1280
        if (mainwin->menu_lock_count)
1281
                mainwin->menu_lock_count--;
1282
}
1283
1284
void main_window_reflect_prefs_all(void)
1285
{
1286
        MainWindow *mainwin;
1287
1288
        mainwin = main_window_get();
1289
1290
        main_window_show_cur_account(mainwin);
1291
        main_window_set_menu_sensitive(mainwin);
1292
        main_window_set_toolbar_sensitive(mainwin);
1293
        main_window_set_toolbar_button_visibility(mainwin);
1294
1295
        if (mainwin->tray_icon) {
1296
                if (prefs_common.show_trayicon)
1297
                        trayicon_show(mainwin->tray_icon);
1298
                else {
1299
                        /* trayicon is automatically replaced by new one */
1300
                        trayicon_hide(mainwin->tray_icon);
1301
                }
1302
        }
1303
1304
        folderview_reflect_prefs(mainwin->folderview);
1305
1306
        messageview_reflect_prefs(mainwin->messageview);
1307
1308
        headerview_set_visibility(mainwin->messageview->headerview,
1309
                                  prefs_common.display_header_pane);
1310
1311
        textview_reflect_prefs(mainwin->messageview->textview);
1312
        textview_reflect_prefs(mainwin->messageview->mimeview->textview);
1313
1314
        summary_redisplay_msg(mainwin->summaryview);
1315
}
1316
1317
void main_window_set_summary_column(void)
1318
{
1319
        summary_set_column_order(main_window_get()->summaryview);
1320
}
1321
1322
static void main_window_set_account_selector_menu(MainWindow *mainwin,
1323
                                                  GList *account_list)
1324
{
1325
        GList *cur_ac, *cur_item;
1326
        GtkWidget *menuitem;
1327
        PrefsAccount *ac_prefs;
1328
1329
        /* destroy all previous menu item */
1330
        cur_item = GTK_MENU_SHELL(mainwin->ac_menu)->children;
1331
        while (cur_item != NULL) {
1332
                GList *next = cur_item->next;
1333
                gtk_widget_destroy(GTK_WIDGET(cur_item->data));
1334
                cur_item = next;
1335
        }
1336
1337
        for (cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) {
1338
                ac_prefs = (PrefsAccount *)cur_ac->data;
1339
1340
                menuitem = gtk_menu_item_new_with_label
1341
                        (ac_prefs->account_name
1342
                         ? ac_prefs->account_name : _("Untitled"));
1343
                gtk_widget_show(menuitem);
1344
                gtk_menu_append(GTK_MENU(mainwin->ac_menu), menuitem);
1345
                g_signal_connect(G_OBJECT(menuitem), "activate",
1346
                                 G_CALLBACK(account_selector_menu_cb),
1347
                                 ac_prefs);
1348
        }
1349
}
1350
1351
static void main_window_set_account_receive_menu(MainWindow *mainwin,
1352
                                                 GList *account_list)
1353
{
1354
        GList *cur_ac, *cur_item;
1355
        GtkWidget *menu;
1356
        GtkWidget *menuitem;
1357
        PrefsAccount *ac_prefs;
1358
1359
        menu = gtk_item_factory_get_widget(mainwin->menu_factory,
1360
                                           "/Message/Receive");
1361
1362
        /* search for separator */
1363
        for (cur_item = GTK_MENU_SHELL(menu)->children; cur_item != NULL;
1364
             cur_item = cur_item->next) {
1365
                if (GTK_BIN(cur_item->data)->child == NULL) {
1366
                        cur_item = cur_item->next;
1367
                        break;
1368
                }
1369
        }
1370
1371
        /* destroy all previous menu item */
1372
        while (cur_item != NULL) {
1373
                GList *next = cur_item->next;
1374
                gtk_widget_destroy(GTK_WIDGET(cur_item->data));
1375
                cur_item = next;
1376
        }
1377
1378
        for (cur_ac = account_list; cur_ac != NULL; cur_ac = cur_ac->next) {
1379
                ac_prefs = (PrefsAccount *)cur_ac->data;
1380
1381
                menuitem = gtk_menu_item_new_with_label
1382
                        (ac_prefs->account_name ? ac_prefs->account_name
1383
                         : _("Untitled"));
1384
                gtk_widget_show(menuitem);
1385
                gtk_menu_append(GTK_MENU(menu), menuitem);
1386
                g_signal_connect(G_OBJECT(menuitem), "activate",
1387
                                 G_CALLBACK(account_receive_menu_cb),
1388
                                 ac_prefs);
1389
        }
1390
}
1391
1392
void main_window_set_account_menu(GList *account_list)
1393
{
1394
        MainWindow *mainwin;
1395
1396
        mainwin = main_window_get();
1397
        main_window_set_account_selector_menu(mainwin, account_list);
1398
        main_window_set_account_receive_menu(mainwin, account_list);
1399
}
1400
1401
static void main_window_show_cur_account(MainWindow *mainwin)
1402
{
1403
        gchar *buf;
1404
        gchar *ac_name;
1405
1406
        ac_name = g_strdup(cur_account
1407
                           ? (cur_account->account_name
1408
                              ? cur_account->account_name : _("Untitled"))
1409
                           : _("none"));
1410
1411
        if (cur_account)
1412
                buf = g_strdup_printf("%s - %s", ac_name, PROG_VERSION);
1413
        else
1414
                buf = g_strdup(PROG_VERSION);
1415
        gtk_window_set_title(GTK_WINDOW(mainwin->window), buf);
1416
        g_free(buf);
1417
1418
        gtk_label_set_text(GTK_LABEL(mainwin->ac_label), ac_name);
1419
        gtk_widget_queue_resize(mainwin->ac_button);
1420
1421
        g_free(ac_name);
1422
}
1423
1424
void main_window_change_cur_account(void)
1425
{
1426
        MainWindow *mainwin;
1427
1428
        mainwin = main_window_get();
1429
        main_window_show_cur_account(mainwin);
1430
        main_window_set_menu_sensitive(mainwin);
1431
        main_window_set_toolbar_sensitive(mainwin);
1432
}
1433
1434
MainWindow *main_window_get(void)
1435
{
1436
        if (mainwin_list)
1437
                return (MainWindow *)mainwin_list->data;
1438
        else
1439
                return NULL;
1440
}
1441
1442
GtkWidget *main_window_get_folder_window(MainWindow *mainwin)
1443
{
1444
        switch (mainwin->type) {
1445
        case SEPARATE_FOLDER:
1446
                return mainwin->win.sep_folder.folderwin;
1447
        case SEPARATE_BOTH:
1448
                return mainwin->win.sep_both.folderwin;
1449
        default:
1450
                return NULL;
1451
        }
1452
}
1453
1454
GtkWidget *main_window_get_message_window(MainWindow *mainwin)
1455
{
1456
        switch (mainwin->type) {
1457
        case SEPARATE_MESSAGE:
1458
                return mainwin->win.sep_message.messagewin;
1459
        case SEPARATE_BOTH:
1460
                return mainwin->win.sep_both.messagewin;
1461
        default:
1462
                return NULL;
1463
        }
1464
}
1465
1466
void main_window_hide(MainWindow *mainwin)
1467
{
1468
        GtkWidget *folder_wid  = GTK_WIDGET_PTR(mainwin->folderview);
1469
        GtkWidget *summary_wid = GTK_WIDGET_PTR(mainwin->summaryview);
1470
        GtkWidget *message_wid = GTK_WIDGET_PTR(mainwin->messageview);
1471
        GtkWidget *qsearch_wid = GTK_WIDGET_PTR(mainwin->summaryview->qsearch);
1472
        GtkWidget *vbox_summary = qsearch_wid->parent;
1473
1474
        /* remove widgets from those containers */
1475
        gtkut_container_remove
1476
                (GTK_CONTAINER(folder_wid->parent), folder_wid);
1477
        gtkut_container_remove
1478
                (GTK_CONTAINER(summary_wid->parent), summary_wid);
1479
        gtkut_container_remove
1480
                (GTK_CONTAINER(message_wid->parent), message_wid);
1481
        gtkut_container_remove
1482
                (GTK_CONTAINER(qsearch_wid->parent), qsearch_wid);
1483
1484
        /* clean containers */
1485
        switch (mainwin->type) {
1486
        case SEPARATE_NONE:
1487
                if (!mainwin->win.sep_none.vpaned->parent)
1488
                        gtk_widget_destroy(mainwin->win.sep_none.vpaned);
1489
                gtk_widget_destroy(mainwin->win.sep_none.hpaned);
1490
                mainwin->win.sep_none.hpaned = NULL;
1491
                mainwin->win.sep_none.vpaned = NULL;
1492
                break;
1493
        case SEPARATE_FOLDER:
1494
                gtk_widget_destroy(mainwin->win.sep_folder.folderwin);
1495
                if (!mainwin->win.sep_folder.vpaned->parent)
1496
                        gtk_widget_destroy(mainwin->win.sep_folder.vpaned);
1497
                gtk_widget_destroy(vbox_summary);
1498
                mainwin->win.sep_folder.folderwin = NULL;
1499
                mainwin->win.sep_folder.vpaned = NULL;
1500
                break;
1501
        case SEPARATE_MESSAGE:
1502
                gtk_widget_destroy(mainwin->win.sep_message.messagewin);
1503
                gtk_widget_destroy(mainwin->win.sep_message.hpaned);
1504
                mainwin->win.sep_message.messagewin = NULL;
1505
                mainwin->win.sep_message.hpaned = NULL;
1506
                break;
1507
        case SEPARATE_BOTH:
1508
                gtk_widget_destroy(vbox_summary);
1509
                gtk_widget_destroy(mainwin->win.sep_both.folderwin);
1510
                gtk_widget_destroy(mainwin->win.sep_both.messagewin);
1511
                mainwin->win.sep_both.folderwin = NULL;
1512
                mainwin->win.sep_both.messagewin = NULL;
1513
                break;
1514
        }
1515
1516
        gtk_widget_hide(mainwin->window);
1517
}
1518
1519
void main_window_change_layout(MainWindow *mainwin, LayoutType layout,
1520
                               SeparateType type)
1521
{
1522
        GtkWidget *folder_wid  = GTK_WIDGET_PTR(mainwin->folderview);
1523
        GtkWidget *summary_wid = GTK_WIDGET_PTR(mainwin->summaryview);
1524
        GtkWidget *message_wid = GTK_WIDGET_PTR(mainwin->messageview);
1525
        GtkWidget *qsearch_wid = GTK_WIDGET_PTR(mainwin->summaryview->qsearch);
1526
        GtkWidget *focus_widget;
1527
1528
        debug_print("Changing window layout type (layout: %d -> %d, separation: %d -> %d)\n", prefs_common.layout_type, layout, mainwin->type, type);
1529
1530
        if (prefs_common.layout_type == layout && mainwin->type == type)
1531
                return;
1532
1533
        /* keep previous focus */
1534
        focus_widget = gtk_window_get_focus(GTK_WINDOW(mainwin->window));
1535
1536
        gtk_widget_ref(folder_wid);
1537
        gtk_widget_ref(summary_wid);
1538
        gtk_widget_ref(message_wid);
1539
        gtk_widget_ref(qsearch_wid);
1540
1541
        main_window_hide(mainwin);
1542
        main_window_set_widgets(mainwin, layout, type);
1543
        gtk_widget_show(mainwin->window);
1544
        if (focus_widget)
1545
                gtk_widget_grab_focus(focus_widget);
1546
1547
        gtk_widget_unref(folder_wid);
1548
        gtk_widget_unref(summary_wid);
1549
        gtk_widget_unref(message_wid);
1550
        gtk_widget_unref(qsearch_wid);
1551
}
1552
1553
void main_window_toggle_message_view(MainWindow *mainwin)
1554
{
1555
        SummaryView *summaryview = mainwin->summaryview;
1556
        union CompositeWin *cwin = &mainwin->win;
1557
        GtkWidget *vpaned = NULL;
1558
        GtkWidget *container = NULL;
1559
        GtkWidget *msgwin = NULL;
1560
        gboolean use_vlayout = (prefs_common.layout_type == LAYOUT_VERTICAL);
1561
1562
        switch (mainwin->type) {
1563
        case SEPARATE_NONE:
1564
                vpaned = cwin->sep_none.vpaned;
1565
                container = GTK_WIDGET_PTR(summaryview->qsearch)->parent;
1566
                break;
1567
        case SEPARATE_FOLDER:
1568
                vpaned = cwin->sep_folder.vpaned;
1569
                container = GTK_WIDGET_PTR(summaryview->qsearch)->parent;
1570
                break;
1571
        case SEPARATE_MESSAGE:
1572
                msgwin = mainwin->win.sep_message.messagewin;
1573
                break;
1574
        case SEPARATE_BOTH:
1575
                msgwin = mainwin->win.sep_both.messagewin;
1576
                break;
1577
        }
1578
1579
        if (msgwin) {
1580
                /* separate message view */
1581
                if (GTK_WIDGET_VISIBLE(msgwin)) {
1582
                        gtk_widget_hide(msgwin);
1583
                        mainwin->messageview->visible = FALSE;
1584
                        summaryview->displayed = NULL;
1585
                } else {
1586
                        gtk_widget_show(msgwin);
1587
                        mainwin->messageview->visible = TRUE;
1588
                }
1589
        } else if (vpaned->parent != NULL) {
1590
                /* hide message view */
1591
                mainwin->messageview->visible = FALSE;
1592
                summaryview->displayed = NULL;
1593
                gtk_widget_ref(vpaned);
1594
                gtkut_container_remove(GTK_CONTAINER(container), vpaned);
1595
                gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), container);
1596
                if (!use_vlayout)
1597
                        gtk_widget_hide(summaryview->hseparator);
1598
        } else {
1599
                /* show message view */
1600
                mainwin->messageview->visible = TRUE;
1601
                gtk_widget_reparent(GTK_WIDGET_PTR(summaryview), vpaned);
1602
                gtk_container_add(GTK_CONTAINER(container), vpaned);
1603
                gtk_widget_unref(vpaned);
1604
                if (!use_vlayout)
1605
                        gtk_widget_show(summaryview->hseparator);
1606
        }
1607
1608
        if (messageview_is_visible(mainwin->messageview))
1609
                gtk_arrow_set(GTK_ARROW(mainwin->summaryview->toggle_arrow),
1610
                              use_vlayout ? GTK_ARROW_RIGHT : GTK_ARROW_DOWN,
1611
                              GTK_SHADOW_OUT);
1612
        else
1613
                gtk_arrow_set(GTK_ARROW(mainwin->summaryview->toggle_arrow),
1614
                              use_vlayout ? GTK_ARROW_LEFT : GTK_ARROW_UP,
1615
                              GTK_SHADOW_OUT);
1616
1617
        if (mainwin->messageview->visible == FALSE)
1618
                messageview_clear(mainwin->messageview);
1619
1620
        main_window_set_menu_sensitive(mainwin);
1621
1622
        prefs_common.msgview_visible = mainwin->messageview->visible;
1623
1624
        gtk_widget_grab_focus(summaryview->treeview);
1625
}
1626
1627
void main_window_get_size(MainWindow *mainwin)
1628
{
1629
        GtkAllocation *allocation;
1630
        gboolean vlayout = (prefs_common.layout_type == LAYOUT_VERTICAL);
1631
1632
        allocation = &(GTK_WIDGET_PTR(mainwin->summaryview)->allocation);
1633
        if (allocation->width > 1 && allocation->height > 1) {
1634
                if (vlayout) {
1635
                        if (!(mainwin->type & SEPARATE_MESSAGE) &&
1636
                            messageview_is_visible(mainwin->messageview))
1637
                                prefs_common.summaryview_vwidth = allocation->width;
1638
                        prefs_common.summaryview_vheight = allocation->height;
1639
                } else {
1640
                        if (!prefs_common.mainwin_maximized) {
1641
                                prefs_common.summaryview_width = allocation->width;
1642
                                prefs_common.mainview_width = allocation->width;
1643
                        }
1644
                        if ((mainwin->type == SEPARATE_NONE ||
1645
                             mainwin->type == SEPARATE_FOLDER) &&
1646
                            messageview_is_visible(mainwin->messageview))
1647
                                prefs_common.summaryview_height = allocation->height;
1648
                }
1649
        }
1650
1651
        if (prefs_common.mainwin_maximized) {
1652
                allocation = &(GTK_WIDGET_PTR(mainwin->folderview)->allocation);
1653
                if (allocation->width > 1 && allocation->height > 1)
1654
                        prefs_common.folderview_width  = allocation->width;
1655
                return;
1656
        }
1657
1658
        allocation = &mainwin->window->allocation;
1659
        if (allocation->width > 1 && allocation->height > 1) {
1660
                prefs_common.mainview_height = allocation->height;
1661
                prefs_common.mainwin_width   = allocation->width;
1662
                prefs_common.mainwin_height  = allocation->height;
1663
        }
1664
1665
        allocation = &(GTK_WIDGET_PTR(mainwin->folderview)->allocation);
1666
        if (allocation->width > 1 && allocation->height > 1) {
1667
                prefs_common.folderview_width  = allocation->width;
1668
                prefs_common.folderview_height = allocation->height;
1669
        }
1670
1671
        allocation = &(GTK_WIDGET_PTR(mainwin->messageview)->allocation);
1672
        if (allocation->width > 1 && allocation->height > 1) {
1673
                if (vlayout) {
1674
                        prefs_common.msgview_vwidth = allocation->width;
1675
                        prefs_common.msgview_vheight = allocation->height;
1676
                } else {
1677
                        prefs_common.msgview_width = allocation->width;
1678
                        prefs_common.msgview_height = allocation->height;
1679
                }
1680
        }
1681
1682
#if 0
1683
        debug_print("summaryview size: %d x %d\n",
1684
                    prefs_common.summaryview_width,
1685
                    prefs_common.summaryview_height);
1686
        debug_print("mainwin size: %d x %d\n",
1687
                    prefs_common.mainwin_width,
1688
                    prefs_common.mainwin_height);
1689
        debug_print("folderview size: %d x %d\n",
1690
                    prefs_common.folderview_width,
1691
                    prefs_common.folderview_height);
1692
        debug_print("messageview size: %d x %d\n",
1693
                    prefs_common.msgview_width,
1694
                    prefs_common.msgview_height);
1695
#endif
1696
}
1697
1698
void main_window_get_position(MainWindow *mainwin)
1699
{
1700
        gint x, y;
1701
        GtkWidget *window;
1702
1703
        if (prefs_common.mainwin_maximized || mainwin->window_hidden)
1704
                return;
1705
1706
        gtkut_widget_get_uposition(mainwin->window, &x, &y);
1707
1708
        prefs_common.mainview_x = x;
1709
        prefs_common.mainview_y = y;
1710
        prefs_common.mainwin_x = x;
1711
        prefs_common.mainwin_y = y;
1712
1713
        debug_print("main window position: %d, %d\n", x, y);
1714
1715
        window = main_window_get_folder_window(mainwin);
1716
        if (window) {
1717
                gtkut_widget_get_uposition(window, &x, &y);
1718
                prefs_common.folderwin_x = x;
1719
                prefs_common.folderwin_y = y;
1720
                debug_print("folder window position: %d, %d\n", x, y);
1721
        }
1722
        window = main_window_get_message_window(mainwin);
1723
        if (window) {
1724
                gtkut_widget_get_uposition(window, &x, &y);
1725
                prefs_common.main_msgwin_x = x;
1726
                prefs_common.main_msgwin_y = y;
1727
                debug_print("message window position: %d, %d\n", x, y);
1728
        }
1729
}
1730
1731
void main_window_progress_on(MainWindow *mainwin)
1732
{
1733
        gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), TRUE);
1734
        gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
1735
}
1736
1737
void main_window_progress_off(MainWindow *mainwin)
1738
{
1739
        gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar), FALSE);
1740
        gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar), 0.0);
1741
        gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), "");
1742
}
1743
1744
void main_window_progress_set(MainWindow *mainwin, gint cur, gint total)
1745
{
1746
        gchar buf[32];
1747
1748
        g_snprintf(buf, sizeof(buf), "%d / %d", cur, total);
1749
        gtk_progress_set_format_string(GTK_PROGRESS(mainwin->progressbar), buf);
1750
        gtk_progress_bar_update(GTK_PROGRESS_BAR(mainwin->progressbar),
1751
                                (cur == 0 && total == 0) ? 0 :
1752
                                (gfloat)cur / (gfloat)total);
1753
}
1754
1755
void main_window_progress_show(gint cur, gint total)
1756
{
1757
        MainWindow *mainwin;
1758
1759
        mainwin = main_window_get();
1760
1761
        if (total > 0) {
1762
                gtk_progress_set_show_text(GTK_PROGRESS(mainwin->progressbar),
1763
                                           TRUE);
1764
                main_window_progress_set(mainwin, cur, total);
1765
        } else
1766
                main_window_progress_off(mainwin);
1767
}
1768
1769
void main_window_toggle_online(MainWindow *mainwin, gboolean online)
1770
{
1771
        if (prefs_common.online_mode != online)
1772
                online_switch_clicked(mainwin->online_switch, mainwin);
1773
}
1774
1775
gboolean main_window_toggle_online_if_offline(MainWindow *mainwin)
1776
{
1777
        if (!prefs_common.online_mode) {
1778
                if (alertpanel(_("Offline"),
1779
                               _("You are offline. Go online?"),
1780
                               GTK_STOCK_YES, GTK_STOCK_NO, NULL)
1781
                    == G_ALERTDEFAULT)
1782
                        main_window_toggle_online(mainwin, TRUE);
1783
        }
1784
1785
        return prefs_common.online_mode;
1786
}
1787
1788
void main_window_empty_trash(MainWindow *mainwin, gboolean confirm)
1789
{
1790
        GList *list;
1791
1792
        if (!procmsg_trash_messages_exist())
1793
                return;
1794
1795
        if (confirm) {
1796
                if (alertpanel(_("Empty all trash"),
1797
                               _("Delete all messages in trash folders?"),
1798
                               GTK_STOCK_YES, GTK_STOCK_NO, NULL)
1799
                    != G_ALERTDEFAULT)
1800
                        return;
1801
                manage_window_focus_in(mainwin->window, NULL, NULL);
1802
        }
1803
1804
        procmsg_empty_all_trash();
1805
        statusbar_pop_all();
1806
        trayicon_set_tooltip(NULL);
1807
        trayicon_set_notify(FALSE);
1808
1809
        for (list = folder_get_list(); list != NULL; list = list->next) {
1810
                Folder *folder;
1811
1812
                folder = list->data;
1813
                if (folder->trash)
1814
                        folderview_update_item(folder->trash, TRUE);
1815
        }
1816
1817
        if (mainwin->summaryview->folder_item &&
1818
            mainwin->summaryview->folder_item->stype == F_TRASH)
1819
                gtk_widget_grab_focus(mainwin->folderview->treeview);
1820
}
1821
1822
void main_window_add_mailbox(MainWindow *mainwin)
1823
{
1824
        gchar *path;
1825
        Folder *folder;
1826
1827
        path = input_dialog_with_filesel
1828
                (_("Add mailbox"),
1829
                 _("Specify the location of mailbox.\n"
1830
                   "If the existing mailbox is specified, it will be\n"
1831
                   "scanned automatically."),
1832
                 "Mail", GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
1833
        if (!path) return;
1834
        if (folder_find_from_path(path)) {
1835
                alertpanel_error(_("The mailbox `%s' already exists."), path);
1836
                g_free(path);
1837
                return;
1838
        }
1839
        if (!strcmp(path, "Mail"))
1840
                folder = folder_new(F_MH, _("Mailbox"), path);
1841
        else
1842
                folder = folder_new(F_MH, g_basename(path), path);
1843
        g_free(path);
1844
1845
        if (folder->klass->create_tree(folder) < 0) {
1846
                alertpanel_error(_("Creation of the mailbox failed.\n"
1847
                                   "Maybe some files already exist, or you don't have the permission to write there."));
1848
                folder_destroy(folder);
1849
                return;
1850
        }
1851
1852
        folder_add(folder);
1853
        folder_set_ui_func(folder, scan_tree_func, mainwin);
1854
        folder->klass->scan_tree(folder);
1855
        folder_set_ui_func(folder, NULL, NULL);
1856
1857
        folderview_set(mainwin->folderview);
1858
}
1859
1860
void main_window_send_queue(MainWindow *mainwin)
1861
{
1862
        GList *list;
1863
1864
        if (inc_is_active())
1865
                return;
1866
        if (!main_window_toggle_online_if_offline(mainwin))
1867
                return;
1868
1869
        for (list = folder_get_list(); list != NULL; list = list->next) {
1870
                Folder *folder = list->data;
1871
1872
                if (folder->queue) {
1873
                        gint ret;
1874
1875
                        ret = send_message_queue_all(folder->queue,
1876
                                                     prefs_common.savemsg,
1877
                                                     prefs_common.filter_sent);
1878
                        statusbar_pop_all();
1879
                        if (ret > 0)
1880
                                folder_item_scan(folder->queue);
1881
                }
1882
        }
1883
1884
        folderview_update_all_updated(TRUE);
1885
        main_window_set_menu_sensitive(mainwin);
1886
        main_window_set_toolbar_sensitive(mainwin);
1887
}
1888
1889
typedef enum
1890
{
1891
        M_UNLOCKED            = 1 << 0,
1892
        M_MSG_EXIST           = 1 << 1,
1893
        M_TARGET_EXIST        = 1 << 2,
1894
        M_SINGLE_TARGET_EXIST = 1 << 3,
1895
        M_EXEC                = 1 << 4,
1896
        M_ALLOW_REEDIT        = 1 << 5,
1897
        M_HAVE_ACCOUNT        = 1 << 6,
1898
        M_THREADED              = 1 << 7,
1899
        M_UNTHREADED              = 1 << 8,
1900
        M_ALLOW_DELETE              = 1 << 9,
1901
        M_INC_ACTIVE              = 1 << 10,
1902
        M_ENABLE_JUNK              = 1 << 11,
1903
        M_HAVE_QUEUED_MSG     = 1 << 12,
1904
        M_POP3_ACCOUNT              = 1 << 13,
1905
1906
        M_FOLDER_NEWOK              = 1 << 17,
1907
        M_FOLDER_RENOK              = 1 << 18,
1908
        M_FOLDER_MOVEOK              = 1 << 19,
1909
        M_FOLDER_DELOK              = 1 << 20,
1910
        M_MBOX_ADDOK              = 1 << 21,
1911
        M_MBOX_RMOK              = 1 << 22,
1912
        M_MBOX_CHKOK              = 1 << 23,
1913
        M_MBOX_CHKALLOK              = 1 << 24,
1914
        M_MBOX_REBUILDOK      = 1 << 25
1915
} SensitiveCond;
1916
1917
static SensitiveCond main_window_get_current_state(MainWindow *mainwin)
1918
{
1919
        SensitiveCond state = 0;
1920
        SummarySelection selection;
1921
        GList *list;
1922
        FolderItem *item = mainwin->summaryview->folder_item;
1923
1924
        selection = summary_get_selection_type(mainwin->summaryview);
1925
1926
        if (mainwin->lock_count == 0)
1927
                state |= M_UNLOCKED;
1928
        if (selection != SUMMARY_NONE)
1929
                state |= M_MSG_EXIST;
1930
        if (item && item->path && item->parent && !item->no_select) {
1931
                state |= M_EXEC;
1932
                if (item->threaded)
1933
                        state |= M_THREADED;
1934
                else
1935
                        state |= M_UNTHREADED;        
1936
                if (FOLDER_TYPE(item->folder) != F_NEWS)
1937
                        state |= M_ALLOW_DELETE;
1938
        }
1939
        if (selection == SUMMARY_SELECTED_SINGLE ||
1940
            selection == SUMMARY_SELECTED_MULTIPLE)
1941
                state |= M_TARGET_EXIST;
1942
        if (selection == SUMMARY_SELECTED_SINGLE)
1943
                state |= M_SINGLE_TARGET_EXIST;
1944
        if (selection == SUMMARY_SELECTED_SINGLE &&
1945
            FOLDER_ITEM_IS_SENT_FOLDER(item))
1946
                state |= M_ALLOW_REEDIT;
1947
        if (cur_account) {
1948
                state |= M_HAVE_ACCOUNT;
1949
                if (cur_account->protocol == A_POP3)
1950
                        state |= M_POP3_ACCOUNT;
1951
        }
1952
1953
        if (inc_is_active())
1954
                state |= M_INC_ACTIVE;
1955
1956
        if (prefs_common.enable_junk)
1957
                state |= M_ENABLE_JUNK;
1958
1959
        for (list = folder_get_list(); list != NULL; list = list->next) {
1960
                Folder *folder = list->data;
1961
                if (folder->queue && folder->queue->total > 0) {
1962
                        state |= M_HAVE_QUEUED_MSG;
1963
                        break;
1964
                }
1965
        }
1966
1967
        item = folderview_get_selected_item(mainwin->folderview);
1968
        if (item) {
1969
                state |= M_FOLDER_NEWOK;
1970
                if (item->parent == NULL) {
1971
                        state |= M_MBOX_RMOK;
1972
                        state |= M_MBOX_CHKOK;
1973
                }
1974
                if (FOLDER_IS_LOCAL(item->folder) ||
1975
                    FOLDER_TYPE(item->folder) == F_IMAP) {
1976
                        if (item->parent == NULL)
1977
                                state |= M_MBOX_REBUILDOK;
1978
                        else if (item->stype == F_NORMAL) {
1979
                                state |= M_FOLDER_RENOK;
1980
                                state |= M_FOLDER_DELOK;
1981
                                if (item->folder->klass->move_folder)
1982
                                        state |= M_FOLDER_MOVEOK;
1983
                        }
1984
                } else if (FOLDER_TYPE(item->folder) == F_NEWS) {
1985
                        if (item->parent != NULL)
1986
                                state |= M_FOLDER_DELOK;
1987
                }
1988
        }
1989
        state |= M_MBOX_ADDOK;
1990
        state |= M_MBOX_CHKALLOK;
1991
1992
        return state;
1993
}
1994
1995
void main_window_set_toolbar_sensitive(MainWindow *mainwin)
1996
{
1997
        SensitiveCond state;
1998
        gboolean sensitive, prev_sensitive;
1999
        gint n;
2000
        gint i = 0;
2001
2002
        struct {
2003
                GtkWidget *widget;
2004
                SensitiveCond cond;
2005
        } entry[20];
2006
2007
#define SET_WIDGET_COND(w, c)        \
2008
{                                \
2009
        entry[i].widget = w;        \
2010
        entry[i].cond = c;        \
2011
        i++;                        \
2012
}
2013
2014
        SET_WIDGET_COND(mainwin->get_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
2015
        SET_WIDGET_COND(mainwin->getall_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
2016
        SET_WIDGET_COND(mainwin->rpop3_btn,
2017
                        M_HAVE_ACCOUNT|M_UNLOCKED|M_POP3_ACCOUNT);
2018
        SET_WIDGET_COND(mainwin->send_btn,
2019
                        M_HAVE_ACCOUNT|M_UNLOCKED|M_HAVE_QUEUED_MSG);
2020
        SET_WIDGET_COND(mainwin->compose_btn, M_HAVE_ACCOUNT);
2021
        SET_WIDGET_COND(mainwin->reply_btn,
2022
                        M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
2023
        SET_WIDGET_COND(mainwin->reply_combo ?
2024
                        GTK_WIDGET_PTR(mainwin->reply_combo) : NULL,
2025
                        M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
2026
        SET_WIDGET_COND(mainwin->replyall_btn,
2027
                        M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST);
2028
        SET_WIDGET_COND(mainwin->fwd_btn, M_HAVE_ACCOUNT|M_TARGET_EXIST);
2029
        SET_WIDGET_COND(mainwin->fwd_combo ? GTK_WIDGET_PTR(mainwin->fwd_combo)
2030
                        : NULL,
2031
                        M_HAVE_ACCOUNT|M_TARGET_EXIST);
2032
        SET_WIDGET_COND(mainwin->delete_btn,
2033
                        M_TARGET_EXIST|M_ALLOW_DELETE);
2034
        SET_WIDGET_COND(mainwin->junk_btn,
2035
                        M_TARGET_EXIST|M_ALLOW_DELETE|M_ENABLE_JUNK);
2036
        SET_WIDGET_COND(mainwin->notjunk_btn,
2037
                        M_TARGET_EXIST|M_ALLOW_DELETE|M_ENABLE_JUNK);
2038
        SET_WIDGET_COND(mainwin->exec_btn, M_MSG_EXIST|M_EXEC);
2039
        SET_WIDGET_COND(mainwin->next_btn, M_MSG_EXIST);
2040
        SET_WIDGET_COND(mainwin->prev_btn, M_MSG_EXIST);
2041
        SET_WIDGET_COND(mainwin->print_btn, M_TARGET_EXIST);
2042
        SET_WIDGET_COND(mainwin->stop_btn, M_INC_ACTIVE);
2043
        SET_WIDGET_COND(mainwin->prefs_common_btn, M_UNLOCKED);
2044
        SET_WIDGET_COND(mainwin->prefs_account_btn, M_HAVE_ACCOUNT|M_UNLOCKED);
2045
2046
#undef SET_WIDGET_COND
2047
2048
        state = main_window_get_current_state(mainwin);
2049
2050
        n = sizeof(entry) / sizeof(entry[0]);
2051
        for (i = 0; i < n; i++) {
2052
                if (entry[i].widget) {
2053
                        prev_sensitive =
2054
                                GTK_WIDGET_IS_SENSITIVE(entry[i].widget);
2055
                        sensitive = ((entry[i].cond & state) == entry[i].cond);
2056
                        if (prev_sensitive != sensitive) {
2057
                                /* workaround for GTK+ bug (#56070) */
2058
                                if (!prev_sensitive)
2059
                                        gtk_widget_hide(entry[i].widget);
2060
                                gtk_widget_set_sensitive(entry[i].widget,
2061
                                                         sensitive);
2062
                                if (!prev_sensitive)
2063
                                        gtk_widget_show(entry[i].widget);
2064
                        }
2065
                }
2066
        }
2067
}
2068
2069
static void main_window_set_toolbar_button_visibility(MainWindow *mainwin)
2070
{
2071
        GtkToolbarStyle style = GTK_TOOLBAR_BOTH_HORIZ;
2072
2073
        if (prefs_common.toolbar_style == TOOLBAR_NONE)
2074
                style = -1;
2075
        else if (prefs_common.toolbar_style == TOOLBAR_ICON)
2076
                style = GTK_TOOLBAR_ICONS;
2077
        else if (prefs_common.toolbar_style == TOOLBAR_TEXT)
2078
                style = GTK_TOOLBAR_TEXT;
2079
        else if (prefs_common.toolbar_style == TOOLBAR_BOTH)
2080
                style = GTK_TOOLBAR_BOTH;
2081
        else if (prefs_common.toolbar_style == TOOLBAR_BOTH_HORIZ)
2082
                style = GTK_TOOLBAR_BOTH_HORIZ;
2083
2084
        if (style != -1) {
2085
                gtk_toolbar_set_style(GTK_TOOLBAR(mainwin->toolbar), style);
2086
                gtk_widget_show(mainwin->toolbar);
2087
                gtk_widget_queue_resize(mainwin->toolbar);
2088
        } else
2089
                gtk_widget_hide(mainwin->toolbar);
2090
2091
#if 0
2092
        if (mainwin->junk_btn) {
2093
                if (prefs_common.enable_junk)
2094
                        gtk_widget_show(mainwin->junk_btn);
2095
                else
2096
                        gtk_widget_hide(mainwin->junk_btn);
2097
        }
2098
2099
        if (mainwin->exec_btn) {
2100
                if (prefs_common.immediate_exec)
2101
                        gtk_widget_hide(mainwin->exec_btn);
2102
                else
2103
                        gtk_widget_show(mainwin->exec_btn);
2104
        }
2105
#endif
2106
}
2107
2108
void main_window_set_menu_sensitive(MainWindow *mainwin)
2109
{
2110
        GtkItemFactory *ifactory = mainwin->menu_factory;
2111
        SensitiveCond state;
2112
        gboolean sensitive;
2113
        GtkWidget *menu;
2114
        GtkWidget *menuitem;
2115
        FolderItem *item;
2116
        gchar *menu_path;
2117
        gint i;
2118
        GList *cur_item;
2119
2120
        static const struct {
2121
                gchar *const entry;
2122
                SensitiveCond cond;
2123
        } entry[] = {
2124
                {"/File/Folder/Create new folder...", M_UNLOCKED|M_FOLDER_NEWOK},
2125
                {"/File/Folder/Rename folder..."    , M_UNLOCKED|M_FOLDER_RENOK},
2126
                {"/File/Folder/Move folder..."      , M_UNLOCKED|M_FOLDER_MOVEOK},
2127
                {"/File/Folder/Delete folder"       , M_UNLOCKED|M_FOLDER_DELOK},
2128
                {"/File/Mailbox/Add mailbox..."     , M_UNLOCKED|M_MBOX_ADDOK},
2129
                {"/File/Mailbox/Remove mailbox"     , M_UNLOCKED|M_MBOX_RMOK},
2130
                {"/File/Mailbox/Check for new messages"
2131
                                                    , M_UNLOCKED|M_MBOX_CHKOK},
2132
                {"/File/Mailbox/Check for new messages in all mailboxes"
2133
                                                    , M_UNLOCKED|M_MBOX_CHKALLOK},
2134
                {"/File/Mailbox/Rebuild folder tree", M_UNLOCKED|M_MBOX_REBUILDOK},
2135
                {"/File/Import mail data..."        , M_UNLOCKED},
2136
                {"/File/Export mail data..."        , M_UNLOCKED},
2137
                {"/File/Empty all trash"            , M_UNLOCKED},
2138
2139
                {"/File/Save as..."  , M_SINGLE_TARGET_EXIST},
2140
                {"/File/Print..."    , M_TARGET_EXIST},
2141
                {"/File/Work offline", M_UNLOCKED},
2142
                /* {"/File/Close"    , M_UNLOCKED}, */
2143
                {"/File/Exit"        , M_UNLOCKED},
2144
2145
                {"/Edit/Select thread"             , M_SINGLE_TARGET_EXIST},
2146
2147
                {"/View/Sort"                      , M_EXEC},
2148
                {"/View/Thread view"               , M_EXEC},
2149
                {"/View/Expand all threads"        , M_MSG_EXIST},
2150
                {"/View/Collapse all threads"      , M_MSG_EXIST},
2151
                {"/View/Go to/Prev message"        , M_MSG_EXIST},
2152
                {"/View/Go to/Next message"        , M_MSG_EXIST},
2153
                {"/View/Go to/Prev unread message" , M_MSG_EXIST},
2154
                {"/View/Go to/Next unread message" , M_MSG_EXIST},
2155
                {"/View/Go to/Prev new message"    , M_MSG_EXIST},
2156
                {"/View/Go to/Next new message"    , M_MSG_EXIST},
2157
                {"/View/Go to/Prev marked message" , M_MSG_EXIST},
2158
                {"/View/Go to/Next marked message" , M_MSG_EXIST},
2159
                {"/View/Go to/Prev labeled message", M_MSG_EXIST},
2160
                {"/View/Go to/Next labeled message", M_MSG_EXIST},
2161
                {"/View/Open in new window"        , M_SINGLE_TARGET_EXIST},
2162
                {"/View/All headers"          , M_SINGLE_TARGET_EXIST},
2163
                {"/View/Message source"            , M_SINGLE_TARGET_EXIST},
2164
2165
                {"/Message/Receive/Get from current account"
2166
                                                 , M_HAVE_ACCOUNT|M_UNLOCKED},
2167
                {"/Message/Receive/Get from all accounts"
2168
                                                 , M_HAVE_ACCOUNT|M_UNLOCKED},
2169
                {"/Message/Receive/Stop receiving"
2170
                                                 , M_INC_ACTIVE},
2171
                {"/Message/Receive/Remote mailbox..."
2172
                                                 , M_HAVE_ACCOUNT|M_UNLOCKED|M_POP3_ACCOUNT},
2173
                {"/Message/Send queued messages" , M_HAVE_ACCOUNT|M_UNLOCKED|M_HAVE_QUEUED_MSG},
2174
2175
                {"/Message/Compose new message"  , M_HAVE_ACCOUNT},
2176
                {"/Message/Reply"                , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
2177
                {"/Message/Reply to"             , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
2178
                {"/Message/Forward"              , M_HAVE_ACCOUNT|M_TARGET_EXIST},
2179
                {"/Message/Forward as attachment", M_HAVE_ACCOUNT|M_TARGET_EXIST},
2180
                {"/Message/Redirect"             , M_HAVE_ACCOUNT|M_SINGLE_TARGET_EXIST},
2181
                {"/Message/Move..."              , M_TARGET_EXIST|M_ALLOW_DELETE},
2182
                {"/Message/Copy..."              , M_TARGET_EXIST|M_EXEC},
2183
                {"/Message/Delete"               , M_TARGET_EXIST|M_ALLOW_DELETE},
2184
                {"/Message/Mark"                 , M_TARGET_EXIST},
2185
                {"/Message/Set as junk mail"     , M_TARGET_EXIST|M_ALLOW_DELETE|M_ENABLE_JUNK},
2186
                {"/Message/Set as not junk mail" , M_TARGET_EXIST|M_ALLOW_DELETE|M_ENABLE_JUNK},
2187
                {"/Message/Re-edit"              , M_HAVE_ACCOUNT|M_ALLOW_REEDIT},
2188
2189
                {"/Tools/Add sender to address book...", M_SINGLE_TARGET_EXIST},
2190
                {"/Tools/Filter all messages in folder", M_MSG_EXIST|M_EXEC},
2191
                {"/Tools/Filter selected messages"     , M_TARGET_EXIST|M_EXEC},
2192
                {"/Tools/Create filter rule"           , M_SINGLE_TARGET_EXIST|M_UNLOCKED},
2193
                {"/Tools/Filter junk mails in folder"  , M_MSG_EXIST|M_EXEC|M_ENABLE_JUNK},
2194
                {"/Tools/Filter junk mails in selected messages", M_TARGET_EXIST|M_EXEC|M_ENABLE_JUNK},
2195
#ifndef G_OS_WIN32
2196
                {"/Tools/Actions"                      , M_TARGET_EXIST|M_UNLOCKED},
2197
#endif
2198
                {"/Tools/Execute marked process"       , M_MSG_EXIST|M_EXEC},
2199
                {"/Tools/Delete duplicated messages"   , M_MSG_EXIST|M_ALLOW_DELETE},
2200
                {"/Tools/Concatenate separated messages"
2201
                                                       , M_TARGET_EXIST|M_UNLOCKED|M_ALLOW_DELETE},
2202
2203
                {"/Configuration/Common preferences...", M_UNLOCKED},
2204
                {"/Configuration/Filter settings...", M_UNLOCKED},
2205
                {"/Configuration/Preferences for current account...", M_UNLOCKED},
2206
                {"/Configuration/Create new account...", M_UNLOCKED},
2207
                {"/Configuration/Edit accounts...", M_UNLOCKED},
2208
                {"/Configuration/Change current account", M_UNLOCKED},
2209
2210
                {NULL, 0}
2211
        };
2212
2213
        state = main_window_get_current_state(mainwin);
2214
2215
        for (i = 0; entry[i].entry != NULL; i++) {
2216
                sensitive = ((entry[i].cond & state) == entry[i].cond);
2217
                menu_set_sensitive(ifactory, entry[i].entry, sensitive);
2218
        }
2219
2220
        menu = gtk_item_factory_get_widget(ifactory, "/Message/Receive");
2221
2222
        /* search for separator */
2223
        for (cur_item = GTK_MENU_SHELL(menu)->children; cur_item != NULL;
2224
             cur_item = cur_item->next) {
2225
                if (GTK_BIN(cur_item->data)->child == NULL) {
2226
                        cur_item = cur_item->next;
2227
                        break;
2228
                }
2229
        }
2230
2231
        for (; cur_item != NULL; cur_item = cur_item->next) {
2232
                gtk_widget_set_sensitive(GTK_WIDGET(cur_item->data),
2233
                                         (M_UNLOCKED & state) != 0);
2234
        }
2235
2236
        main_window_menu_callback_block(mainwin);
2237
2238
#define SET_CHECK_MENU_ACTIVE(path, active) \
2239
{ \
2240
        menuitem = gtk_item_factory_get_widget(ifactory, path); \
2241
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), active); \
2242
}
2243
2244
        SET_CHECK_MENU_ACTIVE("/View/Show or hide/Message view",
2245
                              messageview_is_visible(mainwin->messageview));
2246
2247
        item = mainwin->summaryview->folder_item;
2248
        menu_path = "/View/Sort/Don't sort";
2249
        if (item) {
2250
                switch (item->sort_key) {
2251
                case SORT_BY_NUMBER:
2252
                        menu_path = "/View/Sort/by number"; break;
2253
                case SORT_BY_SIZE:
2254
                        menu_path = "/View/Sort/by size"; break;
2255
                case SORT_BY_DATE:
2256
                        menu_path = "/View/Sort/by date"; break;
2257
                case SORT_BY_TDATE:
2258
                        menu_path = "/View/Sort/by thread date"; break;
2259
                case SORT_BY_FROM:
2260
                        menu_path = "/View/Sort/by from"; break;
2261
                case SORT_BY_TO:
2262
                        menu_path = "/View/Sort/by recipient"; break;
2263
                case SORT_BY_SUBJECT:
2264
                        menu_path = "/View/Sort/by subject"; break;
2265
                case SORT_BY_LABEL:
2266
                        menu_path = "/View/Sort/by color label"; break;
2267
                case SORT_BY_MARK:
2268
                        menu_path = "/View/Sort/by mark"; break;
2269
                case SORT_BY_UNREAD:
2270
                        menu_path = "/View/Sort/by unread"; break;
2271
                case SORT_BY_MIME:
2272
                        menu_path = "/View/Sort/by attachment"; break;
2273
                case SORT_BY_NONE:
2274
                default:
2275
                        menu_path = "/View/Sort/Don't sort"; break;
2276
                }
2277
        }
2278
        SET_CHECK_MENU_ACTIVE(menu_path, TRUE);
2279
2280
        if (!item || item->sort_type == SORT_ASCENDING) {
2281
                SET_CHECK_MENU_ACTIVE("/View/Sort/Ascending", TRUE);
2282
        } else {
2283
                SET_CHECK_MENU_ACTIVE("/View/Sort/Descending", TRUE);
2284
        }
2285
2286
        if (item && item->sort_key != SORT_BY_NONE) {
2287
                menu_set_sensitive(ifactory, "/View/Sort/Ascending", TRUE);
2288
                menu_set_sensitive(ifactory, "/View/Sort/Descending", TRUE);
2289
                menu_set_sensitive(ifactory, "/View/Sort/Attract by subject",
2290
                                   FALSE);
2291
        } else {
2292
                menu_set_sensitive(ifactory, "/View/Sort/Ascending", FALSE);
2293
                menu_set_sensitive(ifactory, "/View/Sort/Descending", FALSE);
2294
                menu_set_sensitive(ifactory, "/View/Sort/Attract by subject",
2295
                                   (item != NULL));
2296
        }
2297
2298
        SET_CHECK_MENU_ACTIVE("/View/All headers",
2299
                              mainwin->messageview->textview->show_all_headers);
2300
        SET_CHECK_MENU_ACTIVE("/View/Thread view", (state & M_THREADED) != 0);
2301
2302
#undef SET_CHECK_MENU_ACTIVE
2303
2304
        main_window_menu_callback_unblock(mainwin);
2305
}
2306
2307
void main_window_popup(MainWindow *mainwin)
2308
{
2309
        gtkut_window_popup(mainwin->window);
2310
2311
        switch (mainwin->type) {
2312
        case SEPARATE_FOLDER:
2313
                if (prefs_common.folderview_visible)
2314
                        gtkut_window_popup(mainwin->win.sep_folder.folderwin);
2315
                break;
2316
        case SEPARATE_MESSAGE:
2317
                if (messageview_is_visible(mainwin->messageview))
2318
                        gtkut_window_popup(mainwin->win.sep_message.messagewin);
2319
                break;
2320
        case SEPARATE_BOTH:
2321
                if (prefs_common.folderview_visible)
2322
                        gtkut_window_popup(mainwin->win.sep_both.folderwin);
2323
                if (messageview_is_visible(mainwin->messageview))
2324
                        gtkut_window_popup(mainwin->win.sep_both.messagewin);
2325
                break;
2326
        default:
2327
                break;
2328
        }
2329
}
2330
2331
static void main_window_set_widgets(MainWindow *mainwin, LayoutType layout,
2332
                                    SeparateType type)
2333
{
2334
        GtkWidget *folderwin = NULL;
2335
        GtkWidget *messagewin = NULL;
2336
        GtkWidget *hpaned;
2337
        GtkWidget *vpaned;
2338
        GtkWidget *vbox_body = mainwin->vbox_body;
2339
        GtkWidget *vbox_summary;
2340
        GtkItemFactory *ifactory = mainwin->menu_factory;
2341
        GtkWidget *menuitem;
2342
        gboolean use_vlayout = (layout == LAYOUT_VERTICAL);
2343
2344
        debug_print("Setting main window widgets...\n");
2345
2346
        gtk_widget_set_size_request(GTK_WIDGET_PTR(mainwin->folderview),
2347
                                    prefs_common.folderview_width,
2348
                                    prefs_common.folderview_height);
2349
        if (use_vlayout) {
2350
                gtk_widget_set_size_request
2351
                        (GTK_WIDGET_PTR(mainwin->summaryview),
2352
                         prefs_common.summaryview_vwidth,
2353
                         prefs_common.summaryview_vheight);
2354
                gtk_widget_set_size_request
2355
                        (GTK_WIDGET_PTR(mainwin->messageview),
2356
                         prefs_common.msgview_vwidth,
2357
                         prefs_common.msgview_vheight);
2358
        } else {
2359
                gtk_widget_set_size_request
2360
                        (GTK_WIDGET_PTR(mainwin->summaryview),
2361
                         prefs_common.summaryview_width,
2362
                         prefs_common.summaryview_height);
2363
                gtk_widget_set_size_request
2364
                        (GTK_WIDGET_PTR(mainwin->messageview),
2365
                         prefs_common.msgview_width,
2366
                         prefs_common.msgview_height);
2367
        }
2368
2369
        /* create separated window(s) if needed */
2370
        if (type & SEPARATE_FOLDER) {
2371
                folderwin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2372
                gtk_window_set_title(GTK_WINDOW(folderwin),
2373
                                     _("Sylpheed - Folder View"));
2374
                gtk_window_set_wmclass(GTK_WINDOW(folderwin),
2375
                                       "folder_view", "Sylpheed");
2376
                gtk_window_set_policy(GTK_WINDOW(folderwin),
2377
                                      TRUE, TRUE, FALSE);
2378
                gtkut_window_move(GTK_WINDOW(folderwin),
2379
                                  prefs_common.folderwin_x,
2380
                                  prefs_common.folderwin_y);
2381
                gtk_container_set_border_width(GTK_CONTAINER(folderwin), 0);
2382
                g_signal_connect(G_OBJECT(folderwin), "delete_event",
2383
                                 G_CALLBACK(folder_window_close_cb), mainwin);
2384
                gtk_container_add(GTK_CONTAINER(folderwin),
2385
                                  GTK_WIDGET_PTR(mainwin->folderview));
2386
                gtk_widget_realize(folderwin);
2387
                if (prefs_common.folderview_visible)
2388
                        gtk_widget_show(folderwin);
2389
        }
2390
        if (type & SEPARATE_MESSAGE) {
2391
                messagewin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
2392
                gtk_window_set_title(GTK_WINDOW(messagewin),
2393
                                     _("Sylpheed - Message View"));
2394
                gtk_window_set_wmclass(GTK_WINDOW(messagewin),
2395
                                       "message_view", "Sylpheed");
2396
                gtk_window_set_policy(GTK_WINDOW(messagewin),
2397
                                      TRUE, TRUE, FALSE);
2398
                gtkut_window_move(GTK_WINDOW(messagewin),
2399
                                  prefs_common.main_msgwin_x,
2400
                                  prefs_common.main_msgwin_y);
2401
                gtk_container_set_border_width(GTK_CONTAINER(messagewin), 0);
2402
                g_signal_connect(G_OBJECT(messagewin), "delete_event",
2403
                                 G_CALLBACK(message_window_close_cb), mainwin);
2404
                gtk_container_add(GTK_CONTAINER(messagewin),
2405
                                  GTK_WIDGET_PTR(mainwin->messageview));
2406
                gtk_widget_realize(messagewin);
2407
                if (messageview_is_visible(mainwin->messageview))
2408
                        gtk_widget_show(messagewin);
2409
        }
2410
2411
        vbox_summary = gtk_vbox_new(FALSE, 1);
2412
        gtk_box_pack_start(GTK_BOX(vbox_summary),
2413
                           GTK_WIDGET_PTR(mainwin->summaryview->qsearch),
2414
                           FALSE, FALSE, 0);
2415
        gtk_widget_show(vbox_summary);
2416
2417
        switch (type) {
2418
        case SEPARATE_NONE:
2419
                hpaned = gtk_hpaned_new();
2420
                gtk_box_pack_start(GTK_BOX(vbox_body), hpaned, TRUE, TRUE, 0);
2421
                gtk_paned_add1(GTK_PANED(hpaned),
2422
                               GTK_WIDGET_PTR(mainwin->folderview));
2423
                gtk_paned_add2(GTK_PANED(hpaned), vbox_summary);
2424
                gtk_widget_show(hpaned);
2425
                gtk_widget_queue_resize(hpaned);
2426
2427
                if (use_vlayout) {
2428
                        vpaned = gtk_hpaned_new();
2429
                        gtk_widget_hide(mainwin->summaryview->hseparator);
2430
                } else
2431
                        vpaned = gtk_vpaned_new();
2432
                if (messageview_is_visible(mainwin->messageview)) {
2433
                        gtk_paned_add1(GTK_PANED(vpaned),
2434
                                       GTK_WIDGET_PTR(mainwin->summaryview));
2435
                        gtk_box_pack_start(GTK_BOX(vbox_summary), vpaned,
2436
                                           TRUE, TRUE, 0);
2437
                        if (!use_vlayout)
2438
                                gtk_widget_show
2439
                                        (mainwin->summaryview->hseparator);
2440
                } else {
2441
                        gtk_box_pack_start(GTK_BOX(vbox_summary),
2442
                                           GTK_WIDGET_PTR(mainwin->summaryview),
2443
                                           TRUE, TRUE, 0);
2444
                        gtk_widget_ref(vpaned);
2445
                        gtk_widget_hide(mainwin->summaryview->hseparator);
2446
                }
2447
                gtk_paned_add2(GTK_PANED(vpaned),
2448
                               GTK_WIDGET_PTR(mainwin->messageview));
2449
                gtk_widget_show(vpaned);
2450
                gtk_widget_queue_resize(vpaned);
2451
2452
                mainwin->win.sep_none.hpaned = hpaned;
2453
                mainwin->win.sep_none.vpaned = vpaned;
2454
2455
                break;
2456
        case SEPARATE_FOLDER:
2457
                gtk_box_pack_start(GTK_BOX(vbox_body), vbox_summary,
2458
                                   TRUE, TRUE, 0);
2459
2460
                if (use_vlayout) {
2461
                        vpaned = gtk_hpaned_new();
2462
                        gtk_widget_hide(mainwin->summaryview->hseparator);
2463
                } else
2464
                        vpaned = gtk_vpaned_new();
2465
                if (messageview_is_visible(mainwin->messageview)) {
2466
                        gtk_paned_add1(GTK_PANED(vpaned),
2467
                                       GTK_WIDGET_PTR(mainwin->summaryview));
2468
                        gtk_box_pack_start(GTK_BOX(vbox_summary), vpaned,
2469
                                           TRUE, TRUE, 0);
2470
                        if (!use_vlayout)
2471
                                gtk_widget_show
2472
                                        (mainwin->summaryview->hseparator);
2473
                } else {
2474
                        gtk_box_pack_start(GTK_BOX(vbox_summary),
2475
                                           GTK_WIDGET_PTR(mainwin->summaryview),
2476
                                           TRUE, TRUE, 0);
2477
                        gtk_widget_ref(vpaned);
2478
                        gtk_widget_hide(mainwin->summaryview->hseparator);
2479
                }
2480
                gtk_paned_add2(GTK_PANED(vpaned),
2481
                               GTK_WIDGET_PTR(mainwin->messageview));
2482
                gtk_widget_show(vpaned);
2483
                gtk_widget_queue_resize(vpaned);
2484
2485
                mainwin->win.sep_folder.folderwin = folderwin;
2486
                mainwin->win.sep_folder.vpaned    = vpaned;
2487
2488
                break;
2489
        case SEPARATE_MESSAGE:
2490
                hpaned = gtk_hpaned_new();
2491
                gtk_box_pack_start(GTK_BOX(vbox_body), hpaned, TRUE, TRUE, 0);
2492
                gtk_paned_add1(GTK_PANED(hpaned),
2493
                               GTK_WIDGET_PTR(mainwin->folderview));
2494
                gtk_paned_add2(GTK_PANED(hpaned), vbox_summary);
2495
                gtk_box_pack_start(GTK_BOX(vbox_summary),
2496
                                   GTK_WIDGET_PTR(mainwin->summaryview),
2497
                                   TRUE, TRUE, 0);
2498
                gtk_widget_hide(mainwin->summaryview->hseparator);
2499
                gtk_widget_show(hpaned);
2500
                gtk_widget_queue_resize(hpaned);
2501
2502
                mainwin->win.sep_message.messagewin = messagewin;
2503
                mainwin->win.sep_message.hpaned     = hpaned;
2504
2505
                break;
2506
        case SEPARATE_BOTH:
2507
                gtk_box_pack_start(GTK_BOX(vbox_body), vbox_summary,
2508
                                   TRUE, TRUE, 0);
2509
                gtk_box_pack_start(GTK_BOX(vbox_summary),
2510
                                   GTK_WIDGET_PTR(mainwin->summaryview),
2511
                                   TRUE, TRUE, 0);
2512
                gtk_widget_hide(mainwin->summaryview->hseparator);
2513
2514
                mainwin->win.sep_both.folderwin = folderwin;
2515
                mainwin->win.sep_both.messagewin = messagewin;
2516
2517
                break;
2518
        }
2519
2520
        if (messageview_is_visible(mainwin->messageview))
2521
                gtk_arrow_set(GTK_ARROW(mainwin->summaryview->toggle_arrow),
2522
                              use_vlayout ? GTK_ARROW_RIGHT : GTK_ARROW_DOWN,
2523
                              GTK_SHADOW_OUT);
2524
        else
2525
                gtk_arrow_set(GTK_ARROW(mainwin->summaryview->toggle_arrow),
2526
                              use_vlayout ? GTK_ARROW_LEFT : GTK_ARROW_UP,
2527
                              GTK_SHADOW_OUT);
2528
2529
        gtkut_window_move(GTK_WINDOW(mainwin->window), 
2530
                          prefs_common.mainwin_x, prefs_common.mainwin_y);
2531
2532
        gtk_widget_queue_resize(vbox_body);
2533
        gtk_widget_queue_resize(mainwin->vbox);
2534
        gtk_widget_queue_resize(mainwin->window);
2535
2536
        mainwin->type = type;
2537
        prefs_common.layout_type = layout;
2538
2539
        /* toggle menu state */
2540
        menuitem = gtk_item_factory_get_item
2541
                (ifactory, "/View/Show or hide/Folder tree");
2542
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2543
                                       (type & SEPARATE_FOLDER) == 0 ? TRUE :
2544
                                       prefs_common.folderview_visible);
2545
        gtk_widget_set_sensitive(menuitem, ((type & SEPARATE_FOLDER) != 0));
2546
        menuitem = gtk_item_factory_get_item
2547
                (ifactory, "/View/Show or hide/Message view");
2548
        gtk_check_menu_item_set_active
2549
                (GTK_CHECK_MENU_ITEM(menuitem),
2550
                 messageview_is_visible(mainwin->messageview));
2551
2552
        if (layout == LAYOUT_NORMAL) {
2553
                menuitem = gtk_item_factory_get_item
2554
                        (ifactory, "/View/Layout/Normal");
2555
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2556
                                               TRUE);
2557
        } else if (layout == LAYOUT_VERTICAL) {
2558
                menuitem = gtk_item_factory_get_item
2559
                        (ifactory, "/View/Layout/Vertical");
2560
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2561
                                               TRUE);
2562
        }
2563
2564
        menuitem = gtk_item_factory_get_item
2565
                (ifactory, "/View/Separate folder tree");
2566
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2567
                                       ((type & SEPARATE_FOLDER) != 0));
2568
        menuitem = gtk_item_factory_get_item
2569
                (ifactory, "/View/Separate message view");
2570
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2571
                                       ((type & SEPARATE_MESSAGE) != 0));
2572
2573
        if (folderwin) {
2574
                g_signal_connect
2575
                        (G_OBJECT(folderwin), "size_allocate",
2576
                         G_CALLBACK(folder_window_size_allocate_cb), mainwin);
2577
        }
2578
        if (messagewin) {
2579
                g_signal_connect
2580
                        (G_OBJECT(messagewin), "size_allocate",
2581
                         G_CALLBACK(message_window_size_allocate_cb), mainwin);
2582
        }
2583
2584
        debug_print("done.\n");
2585
}
2586
2587
static GtkItemFactoryEntry reply_entries[] =
2588
{
2589
        {N_("/_Reply"),                        NULL, reply_cb, COMPOSE_REPLY, NULL},
2590
        {N_("/Reply to _all"),                NULL, reply_cb, COMPOSE_REPLY_TO_ALL, NULL},
2591
        {N_("/Reply to _sender"),        NULL, reply_cb, COMPOSE_REPLY_TO_SENDER, NULL},
2592
        {N_("/Reply to mailing _list"),        NULL, reply_cb, COMPOSE_REPLY_TO_LIST, NULL}
2593
};
2594
2595
static GtkItemFactoryEntry forward_entries[] =
2596
{
2597
        {N_("/_Forward"),                NULL, reply_cb, COMPOSE_FORWARD, NULL},
2598
        {N_("/For_ward as attachment"), NULL, reply_cb, COMPOSE_FORWARD_AS_ATTACH, NULL},
2599
        {N_("/Redirec_t"),                NULL, reply_cb, COMPOSE_REDIRECT, NULL}
2600
};
2601
2602
static PrefsToolbarItem items[] =
2603
{
2604
        {T_GET,                        TRUE,        toolbar_inc_cb},
2605
        {T_GET_ALL,                TRUE,        toolbar_inc_all_cb},
2606
        {T_SEND_QUEUE,                TRUE,        toolbar_send_cb},
2607
        {T_COMPOSE,                TRUE,        toolbar_compose_cb},
2608
        {T_REPLY,                TRUE,        toolbar_reply_cb},
2609
        {T_REPLY_ALL,                TRUE,        toolbar_reply_to_all_cb},
2610
        {T_FORWARD,                TRUE,        toolbar_forward_cb},
2611
        {T_DELETE,                FALSE,        toolbar_delete_cb},
2612
        {T_JUNK,                TRUE,        toolbar_junk_cb},
2613
        {T_NOTJUNK,                FALSE,        toolbar_notjunk_cb},
2614
        {T_NEXT,                FALSE,        toolbar_next_unread_cb},
2615
        {T_PREV,                FALSE,        toolbar_prev_unread_cb},
2616
        {T_SEARCH,                FALSE,        toolbar_search_cb},
2617
        {T_PRINT,                FALSE,        toolbar_print_cb},
2618
        {T_STOP,                FALSE,        toolbar_stop_cb},
2619
        {T_ADDRESS_BOOK,        FALSE,        toolbar_address_cb},
2620
        {T_EXECUTE,                FALSE,        toolbar_exec_cb},
2621
        {T_COMMON_PREFS,        FALSE,        toolbar_prefs_common_cb},
2622
        {T_ACCOUNT_PREFS,        FALSE,        toolbar_prefs_account_cb},
2623
        {T_REMOTE_MAILBOX,        FALSE,        toolbar_rpop3_cb},
2624
2625
        {-1, FALSE, NULL}
2626
};
2627
2628
static GtkWidget *main_window_toolbar_create(MainWindow *mainwin)
2629
{
2630
        GtkWidget *toolbar;
2631
        const gchar *setting;
2632
        GList *item_list;
2633
2634
        if (prefs_common.main_toolbar_setting &&
2635
            *prefs_common.main_toolbar_setting != '\0')
2636
                setting = prefs_common.main_toolbar_setting;
2637
        else
2638
                setting = prefs_toolbar_get_default_main_setting_name_list();
2639
2640
        item_list = prefs_toolbar_get_item_list_from_name_list(setting);
2641
        toolbar = main_window_toolbar_create_from_list(mainwin, item_list);
2642
        g_list_free(item_list);
2643
2644
        return toolbar;
2645
}
2646
2647
static GtkWidget *main_window_toolbar_create_from_list(MainWindow *mainwin,
2648
                                                       GList *item_list)
2649
{
2650
        GtkWidget *toolbar;
2651
        GtkWidget *icon_wid;
2652
        GtkToolItem *toolitem;
2653
        GtkToolItem *comboitem;
2654
        ComboButton *combo;
2655
        gint n_entries;
2656
        gint i;
2657
        GList *cur;
2658
2659
        toolbar = gtk_toolbar_new();
2660
        gtk_toolbar_set_orientation(GTK_TOOLBAR(toolbar),
2661
                                    GTK_ORIENTATION_HORIZONTAL);
2662
        gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_BOTH);
2663
        g_signal_connect(G_OBJECT(toolbar), "button_press_event",
2664
                         G_CALLBACK(toolbar_button_pressed), mainwin);
2665
2666
        items[0].data = &mainwin->get_btn;
2667
        items[1].data = &mainwin->getall_btn;
2668
        items[2].data = &mainwin->send_btn;
2669
        items[3].data = &mainwin->compose_btn;
2670
        items[4].data = &mainwin->reply_btn;
2671
        items[5].data = &mainwin->replyall_btn;
2672
        items[6].data = &mainwin->fwd_btn;
2673
        items[7].data = &mainwin->delete_btn;
2674
        items[8].data = &mainwin->junk_btn;
2675
        items[9].data = &mainwin->notjunk_btn;
2676
        items[10].data = &mainwin->next_btn;
2677
        items[11].data = &mainwin->prev_btn;
2678
        items[12].data = &mainwin->search_btn;
2679
        items[13].data = &mainwin->print_btn;
2680
        items[14].data = &mainwin->stop_btn;
2681
        items[15].data = &mainwin->address_btn;
2682
        items[16].data = &mainwin->exec_btn;
2683
        items[17].data = &mainwin->prefs_common_btn;
2684
        items[18].data = &mainwin->prefs_account_btn;
2685
        items[19].data = &mainwin->rpop3_btn;
2686
        for (i = 0; i <= 19; i++)
2687
                *(GtkWidget **)items[i].data = NULL;
2688
        mainwin->reply_combo = NULL;
2689
        mainwin->fwd_combo = NULL;
2690
2691
        for (cur = item_list; cur != NULL; cur = cur->next) {
2692
                const PrefsDisplayItem *ditem = cur->data;
2693
                PrefsToolbarItem *item;
2694
                GtkTooltips *tips;
2695
                gint width;
2696
2697
                if (ditem->id == T_SEPARATOR) {
2698
                        toolitem = gtk_separator_tool_item_new();
2699
                        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2700
                        continue;
2701
                }
2702
2703
                for (item = items; item->id != -1; item++) {
2704
                        if (ditem->id == item->id)
2705
                                break;
2706
                }
2707
                if (item->id == -1)
2708
                        continue;
2709
2710
                if (ditem->stock_id) {
2711
                        icon_wid = gtk_image_new_from_stock
2712
                                (ditem->stock_id, GTK_ICON_SIZE_LARGE_TOOLBAR);
2713
                } else
2714
                        icon_wid = stock_pixbuf_widget(NULL, ditem->icon);
2715
2716
                toolitem = gtk_tool_button_new(icon_wid, gettext(ditem->label));
2717
                if (ditem->description) {
2718
                        tips = gtk_tooltips_new();
2719
                        gtk_tool_item_set_tooltip(toolitem, tips,
2720
                                                  gettext(ditem->description),
2721
                                                  ditem->name);
2722
                }
2723
2724
                gtkut_get_str_size(GTK_WIDGET(toolitem), gettext(ditem->label),
2725
                                   &width, NULL);
2726
                gtk_tool_item_set_homogeneous
2727
                        (toolitem, width < 52 ? TRUE : FALSE);
2728
                gtk_tool_item_set_is_important(toolitem, item->is_important);
2729
2730
                gtk_toolbar_insert(GTK_TOOLBAR(toolbar), toolitem, -1);
2731
2732
                g_signal_connect(G_OBJECT(toolitem), "clicked",
2733
                                 G_CALLBACK(item->callback), mainwin);
2734
                g_signal_connect(G_OBJECT(GTK_BIN(toolitem)->child),
2735
                                 "button_press_event",
2736
                                 G_CALLBACK(toolbar_button_pressed), mainwin);
2737
2738
                if (ditem->id == T_REPLY) {
2739
                        n_entries = sizeof(reply_entries) /
2740
                                sizeof(reply_entries[0]);
2741
                        combo = gtkut_combo_button_create
2742
                                (GTK_WIDGET(toolitem),
2743
                                 reply_entries, n_entries, "<Reply>", mainwin);
2744
                        gtk_button_set_relief(GTK_BUTTON(combo->arrow),
2745
                                              GTK_RELIEF_NONE);
2746
2747
                        comboitem = gtk_tool_item_new();
2748
                        gtk_tool_item_set_homogeneous(comboitem, FALSE);
2749
                        gtk_container_add(GTK_CONTAINER(comboitem),
2750
                                          GTK_WIDGET_PTR(combo));
2751
                        if (ditem->description) {
2752
                                tips = gtk_tooltips_new();
2753
                                gtk_tool_item_set_tooltip
2754
                                        (comboitem, tips,
2755
                                         gettext(ditem->description),
2756
                                         ditem->name);
2757
                        }
2758
2759
                        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), comboitem, -1);
2760
2761
                        mainwin->reply_combo = combo;
2762
                } else if (ditem->id == T_FORWARD) {
2763
                        n_entries = sizeof(forward_entries) /
2764
                                sizeof(forward_entries[0]);
2765
                        combo = gtkut_combo_button_create
2766
                                (GTK_WIDGET(toolitem),
2767
                                 forward_entries, n_entries, "<Forward>",
2768
                                 mainwin);
2769
                        gtk_button_set_relief(GTK_BUTTON(combo->arrow),
2770
                                              GTK_RELIEF_NONE);
2771
2772
                        comboitem = gtk_tool_item_new();
2773
                        gtk_tool_item_set_homogeneous(comboitem, FALSE);
2774
                        gtk_container_add(GTK_CONTAINER(comboitem),
2775
                                          GTK_WIDGET_PTR(combo));
2776
                        if (ditem->description) {
2777
                                tips = gtk_tooltips_new();
2778
                                gtk_tool_item_set_tooltip
2779
                                        (comboitem, tips,
2780
                                         gettext(ditem->description),
2781
                                         ditem->name);
2782
                        }
2783
2784
                        gtk_toolbar_insert(GTK_TOOLBAR(toolbar), comboitem, -1);
2785
2786
                        mainwin->fwd_combo = combo;
2787
                }
2788
2789
                *(GtkWidget **)item->data = GTK_WIDGET(toolitem);
2790
        }
2791
2792
        gtk_widget_show_all(toolbar);
2793
2794
        return toolbar;
2795
}
2796
2797
static void main_window_toolbar_toggle_menu_set_active(MainWindow *mainwin,
2798
                                                       ToolbarStyle style)
2799
{
2800
        GtkWidget *menuitem = NULL;
2801
        GtkItemFactory *ifactory = mainwin->menu_factory;
2802
2803
        switch (style) {
2804
        case TOOLBAR_NONE:
2805
                menuitem = gtk_item_factory_get_item
2806
                        (ifactory, "/View/Show or hide/Toolbar/None");
2807
                break;
2808
        case TOOLBAR_ICON:
2809
                menuitem = gtk_item_factory_get_item
2810
                        (ifactory, "/View/Show or hide/Toolbar/Icon");
2811
                break;
2812
        case TOOLBAR_TEXT:
2813
                menuitem = gtk_item_factory_get_item
2814
                        (ifactory, "/View/Show or hide/Toolbar/Text");
2815
                break;
2816
        case TOOLBAR_BOTH:
2817
                menuitem = gtk_item_factory_get_item
2818
                        (ifactory, "/View/Show or hide/Toolbar/Icon and text");
2819
                break;
2820
        case TOOLBAR_BOTH_HORIZ:
2821
                menuitem = gtk_item_factory_get_item
2822
                        (ifactory, "/View/Show or hide/Toolbar/Text at the right of icon");
2823
                break;
2824
        }
2825
2826
        if (menuitem)
2827
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
2828
                                               TRUE);
2829
}
2830
2831
/* callback functions */
2832
2833
static void toolbar_inc_cb        (GtkWidget        *widget,
2834
                                 gpointer         data)
2835
{
2836
        MainWindow *mainwin = (MainWindow *)data;
2837
2838
        inc_mail_cb(mainwin, 0, NULL);
2839
}
2840
2841
static void toolbar_inc_all_cb        (GtkWidget        *widget,
2842
                                 gpointer         data)
2843
{
2844
        MainWindow *mainwin = (MainWindow *)data;
2845
2846
        inc_all_account_mail_cb(mainwin, 0, NULL);
2847
}
2848
2849
static void toolbar_rpop3_cb        (GtkWidget        *widget,
2850
                                 gpointer         data)
2851
{
2852
        MainWindow *mainwin = (MainWindow *)data;
2853
2854
        rpop3_cb(mainwin, 0, NULL);
2855
}
2856
2857
static void toolbar_send_cb        (GtkWidget        *widget,
2858
                                 gpointer         data)
2859
{
2860
        MainWindow *mainwin = (MainWindow *)data;
2861
2862
        send_queue_cb(mainwin, 0, NULL);
2863
}
2864
2865
static void toolbar_compose_cb        (GtkWidget        *widget,
2866
                                 gpointer         data)
2867
{
2868
        MainWindow *mainwin = (MainWindow *)data;
2869
2870
        compose_cb(mainwin, 0, NULL);
2871
}
2872
2873
static void toolbar_reply_cb        (GtkWidget        *widget,
2874
                                 gpointer         data)
2875
{
2876
        MainWindow *mainwin = (MainWindow *)data;
2877
2878
        if (prefs_common.default_reply_list)
2879
                reply_cb(mainwin, COMPOSE_REPLY_TO_LIST, NULL);
2880
        else
2881
                reply_cb(mainwin, COMPOSE_REPLY, NULL);
2882
}
2883
2884
static void toolbar_reply_to_all_cb        (GtkWidget        *widget,
2885
                                         gpointer         data)
2886
{
2887
        MainWindow *mainwin = (MainWindow *)data;
2888
2889
        reply_cb(mainwin, COMPOSE_REPLY_TO_ALL, NULL);
2890
}
2891
2892
static void toolbar_forward_cb        (GtkWidget        *widget,
2893
                                 gpointer         data)
2894
{
2895
        MainWindow *mainwin = (MainWindow *)data;
2896
2897
        reply_cb(mainwin, COMPOSE_FORWARD, NULL);
2898
}
2899
2900
static void toolbar_delete_cb        (GtkWidget        *widget,
2901
                                 gpointer         data)
2902
{
2903
        MainWindow *mainwin = (MainWindow *)data;
2904
2905
        summary_delete(mainwin->summaryview);
2906
}
2907
2908
static void toolbar_junk_cb        (GtkWidget        *widget,
2909
                                 gpointer         data)
2910
{
2911
        MainWindow *mainwin = (MainWindow *)data;
2912
2913
        summary_junk(mainwin->summaryview);
2914
}
2915
2916
static void toolbar_notjunk_cb        (GtkWidget        *widget,
2917
                                 gpointer         data)
2918
{
2919
        MainWindow *mainwin = (MainWindow *)data;
2920
2921
        summary_not_junk(mainwin->summaryview);
2922
}
2923
2924
static void toolbar_exec_cb        (GtkWidget        *widget,
2925
                                 gpointer         data)
2926
{
2927
        MainWindow *mainwin = (MainWindow *)data;
2928
2929
        summary_execute(mainwin->summaryview);
2930
}
2931
2932
static void toolbar_next_unread_cb        (GtkWidget        *widget,
2933
                                         gpointer         data)
2934
{
2935
        MainWindow *mainwin = (MainWindow *)data;
2936
2937
        next_unread_cb(mainwin, 0, NULL);
2938
}
2939
2940
static void toolbar_prev_unread_cb(GtkWidget *widget, gpointer data)
2941
{
2942
        MainWindow *mainwin = (MainWindow *)data;
2943
2944
        prev_unread_cb(mainwin, 0, NULL);
2945
}
2946
2947
static void toolbar_address_cb(GtkWidget *widget, gpointer data)
2948
{
2949
        MainWindow *mainwin = (MainWindow *)data;
2950
2951
        addressbook_open_cb(mainwin, 0, NULL);
2952
}
2953
2954
static void toolbar_search_cb(GtkWidget *widget, gpointer data)
2955
{
2956
        MainWindow *mainwin = (MainWindow *)data;
2957
2958
        search_cb(mainwin, 1, NULL);
2959
}
2960
2961
static void toolbar_print_cb(GtkWidget *widget, gpointer data)
2962
{
2963
        MainWindow *mainwin = (MainWindow *)data;
2964
2965
        print_cb(mainwin, 0, NULL);
2966
}
2967
2968
static void toolbar_stop_cb(GtkWidget *widget, gpointer data)
2969
{
2970
        MainWindow *mainwin = (MainWindow *)data;
2971
2972
        inc_stop_cb(mainwin, 0, NULL);
2973
}
2974
2975
static void toolbar_prefs_common_cb(GtkWidget *widget, gpointer data)
2976
{
2977
        MainWindow *mainwin = (MainWindow *)data;
2978
2979
        prefs_common_open_cb(mainwin, 0, NULL);
2980
}
2981
2982
static void toolbar_prefs_account_cb(GtkWidget *widget, gpointer data)
2983
{
2984
        MainWindow *mainwin = (MainWindow *)data;
2985
2986
        prefs_account_open_cb(mainwin, 0, NULL);
2987
}
2988
2989
static void toolbar_toggle(GtkWidget *widget, gpointer data)
2990
{
2991
        MainWindow *mainwin = (MainWindow *)data;
2992
        ToolbarStyle style;
2993
2994
        if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
2995
                return;
2996
2997
        style = (ToolbarStyle)g_object_get_data(G_OBJECT(widget), MENU_VAL_ID);
2998
        main_window_toolbar_toggle_menu_set_active(mainwin, style);
2999
}
3000
3001
static void toolbar_customize(GtkWidget *widget, gpointer data)
3002
{
3003
        MainWindow *mainwin = (MainWindow *)data;
3004
        gint *visible_items;
3005
        GList *item_list = NULL;
3006
        GtkWidget *toolbar;
3007
        gint ret;
3008
        const gchar *setting;
3009
3010
        if (prefs_common.main_toolbar_setting &&
3011
            *prefs_common.main_toolbar_setting != '\0')
3012
                setting = prefs_common.main_toolbar_setting;
3013
        else
3014
                setting = prefs_toolbar_get_default_main_setting_name_list();
3015
        visible_items = prefs_toolbar_get_id_list_from_name_list(setting);
3016
        ret = prefs_toolbar_open(TOOLBAR_MAIN, visible_items, &item_list);
3017
        g_free(visible_items);
3018
3019
        if (ret == 0) {
3020
                gtk_widget_destroy(mainwin->toolbar);
3021
                toolbar = main_window_toolbar_create_from_list(mainwin,
3022
                                                               item_list);
3023
                gtk_widget_set_size_request(toolbar, 300, -1);
3024
                gtk_box_pack_start(GTK_BOX(mainwin->vbox), toolbar,
3025
                                   FALSE, FALSE, 0);
3026
                gtk_box_reorder_child(GTK_BOX(mainwin->vbox), toolbar, 1);
3027
                mainwin->toolbar = toolbar;
3028
                main_window_set_toolbar_sensitive(mainwin);
3029
                main_window_set_toolbar_button_visibility(mainwin);
3030
                g_free(prefs_common.main_toolbar_setting);
3031
                prefs_common.main_toolbar_setting =
3032
                        prefs_toolbar_get_name_list_from_item_list(item_list);
3033
                g_list_free(item_list);
3034
                prefs_common_write_config();
3035
        }
3036
}
3037
3038
static gboolean toolbar_button_pressed(GtkWidget *widget, GdkEventButton *event,
3039
                                       gpointer data)
3040
{
3041
        MainWindow *mainwin = (MainWindow *)data;
3042
        GtkWidget *menu;
3043
        GtkWidget *menuitem;
3044
3045
        if (!event) return FALSE;
3046
        if (event->button != 3) return FALSE;
3047
3048
        menu = gtk_menu_new();
3049
        gtk_widget_show(menu);
3050
3051
#define SET_TOOLBAR_MENU(text, style, widget)                                \
3052
{                                                                        \
3053
        MENUITEM_ADD_RADIO(menu, menuitem, widget, text, style);        \
3054
        if (prefs_common.toolbar_style == style)                        \
3055
                gtk_check_menu_item_set_active                                \
3056
                        (GTK_CHECK_MENU_ITEM(menuitem), TRUE);                \
3057
        g_signal_connect(G_OBJECT(menuitem), "activate",                \
3058
                         G_CALLBACK(toolbar_toggle), mainwin);                \
3059
}
3060
3061
        SET_TOOLBAR_MENU(_("Icon _and text"), TOOLBAR_BOTH, NULL);
3062
        SET_TOOLBAR_MENU(_("Text at the _right of icon"), TOOLBAR_BOTH_HORIZ,
3063
                         menuitem);
3064
        SET_TOOLBAR_MENU(_("_Icon"), TOOLBAR_ICON, menuitem);
3065
        SET_TOOLBAR_MENU(_("_Text"), TOOLBAR_TEXT, menuitem);
3066
        SET_TOOLBAR_MENU(_("_None"), TOOLBAR_NONE, menuitem);
3067
        MENUITEM_ADD(menu, menuitem, NULL, NULL);
3068
        MENUITEM_ADD_WITH_MNEMONIC(menu, menuitem, _("_Customize toolbar..."),
3069
                                   0);
3070
        g_signal_connect(G_OBJECT(menuitem), "activate",
3071
                         G_CALLBACK(toolbar_customize), mainwin);
3072
3073
        g_signal_connect(G_OBJECT(menu), "selection_done",
3074
                         G_CALLBACK(gtk_widget_destroy), NULL);
3075
3076
        gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
3077
                       event->button, event->time);
3078
3079
        return TRUE;
3080
}
3081
3082
static void online_switch_clicked(GtkWidget *widget, gpointer data)
3083
{
3084
        MainWindow *mainwin = (MainWindow *)data;
3085
        GtkWidget *menuitem;
3086
3087
        debug_print("Toggle online mode: %d -> %d\n", prefs_common.online_mode,
3088
                    !prefs_common.online_mode);
3089
3090
        menuitem = gtk_item_factory_get_item(mainwin->menu_factory,
3091
                                             "/File/Work offline");
3092
3093
        if (prefs_common.online_mode == TRUE) {
3094
                if (folder_remote_folder_active_session_exist()) {
3095
                        debug_print("Active session exist. Cancelling online switch.\n");
3096
                        return;
3097
                }
3098
3099
                prefs_common.online_mode = FALSE;
3100
                gtk_widget_hide(mainwin->online_pixmap);
3101
                gtk_widget_show(mainwin->offline_pixmap);
3102
                gtk_tooltips_set_tip
3103
                        (mainwin->online_tip, mainwin->online_switch,
3104
                         _("You are offline. Click the icon to go online."),
3105
                         NULL);
3106
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
3107
                                               TRUE);
3108
                inc_autocheck_timer_remove();
3109
                folder_remote_folder_destroy_all_sessions();
3110
        } else {
3111
                prefs_common.online_mode = TRUE;
3112
                gtk_widget_hide(mainwin->offline_pixmap);
3113
                gtk_widget_show(mainwin->online_pixmap);
3114
                gtk_tooltips_set_tip
3115
                        (mainwin->online_tip, mainwin->online_switch,
3116
                         _("You are online. Click the icon to go offline."),
3117
                         NULL);
3118
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem),
3119
                                               FALSE);
3120
                inc_autocheck_timer_set();
3121
        }
3122
}
3123
3124
static gboolean ac_label_button_pressed(GtkWidget *widget,
3125
                                        GdkEventButton *event, gpointer data)
3126
{
3127
        MainWindow *mainwin = (MainWindow *)data;
3128
3129
        if (!event) return FALSE;
3130
3131
        gtk_button_set_relief(GTK_BUTTON(widget), GTK_RELIEF_NORMAL);
3132
        g_object_set_data(G_OBJECT(mainwin->ac_menu), "menu_button", widget);
3133
3134
        gtk_menu_popup(GTK_MENU(mainwin->ac_menu), NULL, NULL,
3135
                       menu_button_position, widget,
3136
                       event->button, event->time);
3137
3138
        return TRUE;
3139
}
3140
3141
static void ac_menu_popup_closed(GtkMenuShell *menu_shell, gpointer data)
3142
{
3143
        MainWindow *mainwin = (MainWindow *)data;
3144
        GtkWidget *button;
3145
3146
        button = g_object_get_data(G_OBJECT(menu_shell), "menu_button");
3147
        if (!button) return;
3148
        gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
3149
        g_object_set_data(G_OBJECT(mainwin->ac_menu), "menu_button", NULL);
3150
        manage_window_focus_in(mainwin->window, NULL, NULL);
3151
}
3152
3153
static gboolean main_window_key_pressed(GtkWidget *widget, GdkEventKey *event,
3154
                                        gpointer data)
3155
{
3156
        MainWindow *mainwin = (MainWindow *)data;
3157
3158
        if (!mainwin)
3159
                return FALSE;
3160
3161
        if (!GTK_WIDGET_HAS_FOCUS(mainwin->summaryview->qsearch->entry))
3162
                return FALSE;
3163
3164
        /* g_print("keyval: %d, state: %d\n", event->keyval, event->state); */
3165
        if ((event->state & (GDK_MOD1_MASK|GDK_CONTROL_MASK)) != 0)
3166
                return FALSE;
3167
        if (event->keyval == GDK_Tab || event->keyval == GDK_KP_Tab ||
3168
            event->keyval == GDK_ISO_Left_Tab)
3169
                return FALSE;
3170
3171
        gtk_window_propagate_key_event(GTK_WINDOW(widget), event);
3172
3173
        return TRUE;
3174
}
3175
3176
static gint main_window_close_cb(GtkWidget *widget, GdkEventAny *event,
3177
                                 gpointer data)
3178
{
3179
        MainWindow *mainwin = (MainWindow *)data;
3180
3181
        if (mainwin->lock_count == 0)
3182
                app_exit_cb(data, 0, widget);
3183
3184
        return TRUE;
3185
}
3186
3187
static gint folder_window_close_cb(GtkWidget *widget, GdkEventAny *event,
3188
                                   gpointer data)
3189
{
3190
        MainWindow *mainwin = (MainWindow *)data;
3191
        GtkWidget *menuitem;
3192
3193
        menuitem = gtk_item_factory_get_item
3194
                (mainwin->menu_factory, "/View/Show or hide/Folder tree");
3195
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE);
3196
3197
        return TRUE;
3198
}
3199
3200
static gint message_window_close_cb(GtkWidget *widget, GdkEventAny *event,
3201
                                    gpointer data)
3202
{
3203
        MainWindow *mainwin = (MainWindow *)data;
3204
        GtkWidget *menuitem;
3205
3206
        menuitem = gtk_item_factory_get_item
3207
                (mainwin->menu_factory, "/View/Show or hide/Message view");
3208
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), FALSE);
3209
3210
        return TRUE;
3211
}
3212
3213
static void main_window_size_allocate_cb(GtkWidget *widget,
3214
                                         GtkAllocation *allocation,
3215
                                         gpointer data)
3216
{
3217
        MainWindow *mainwin = (MainWindow *)data;
3218
3219
        main_window_get_size(mainwin);
3220
}
3221
3222
static void folder_window_size_allocate_cb(GtkWidget *widget,
3223
                                           GtkAllocation *allocation,
3224
                                           gpointer data)
3225
{
3226
        MainWindow *mainwin = (MainWindow *)data;
3227
3228
        main_window_get_size(mainwin);
3229
}
3230
3231
static void message_window_size_allocate_cb(GtkWidget *widget,
3232
                                            GtkAllocation *allocation,
3233
                                            gpointer data)
3234
{
3235
        MainWindow *mainwin = (MainWindow *)data;
3236
3237
        main_window_get_size(mainwin);
3238
}
3239
3240
static gboolean main_window_window_state_cb(GtkWidget *widget,
3241
                                            GdkEventWindowState *event,
3242
                                            gpointer data)
3243
{
3244
        MainWindow *mainwin = (MainWindow *)data;
3245
3246
        if ((event->changed_mask & GDK_WINDOW_STATE_MAXIMIZED) != 0) {
3247
                if ((event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) != 0)
3248
                        prefs_common.mainwin_maximized = TRUE;
3249
                else
3250
                        prefs_common.mainwin_maximized = FALSE;
3251
        }
3252
        if ((event->changed_mask & GDK_WINDOW_STATE_ICONIFIED) != 0) {
3253
                if ((event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) != 0)
3254
                        mainwin->window_hidden = TRUE;
3255
                else
3256
                        mainwin->window_hidden = FALSE;
3257
        }
3258
        if ((event->changed_mask & GDK_WINDOW_STATE_WITHDRAWN) != 0) {
3259
                if ((event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) != 0)
3260
                        mainwin->window_hidden = TRUE;
3261
                else
3262
                        mainwin->window_hidden = FALSE;
3263
        }
3264
3265
        if (mainwin->window_hidden &&
3266
            prefs_common.show_trayicon && prefs_common.minimize_to_tray)
3267
                gtk_window_set_skip_taskbar_hint(GTK_WINDOW(widget), TRUE);
3268
        else if (!mainwin->window_hidden)
3269
                gtk_window_set_skip_taskbar_hint(GTK_WINDOW(widget), FALSE);
3270
3271
        return FALSE;
3272
}
3273
3274
static gboolean main_window_visibility_notify_cb(GtkWidget *widget,
3275
                                                 GdkEventVisibility *event,
3276
                                                 gpointer data)
3277
{
3278
        MainWindow *mainwin = (MainWindow *)data;
3279
3280
        mainwin->window_obscured =
3281
                (event->state == GDK_VISIBILITY_FULLY_OBSCURED ||
3282
                 event->state == GDK_VISIBILITY_PARTIAL) ? TRUE : FALSE;
3283
3284
        return FALSE;
3285
}
3286
3287
static void new_folder_cb(MainWindow *mainwin, guint action,
3288
                          GtkWidget *widget)
3289
{
3290
        folderview_new_folder(mainwin->folderview);
3291
}
3292
3293
static void rename_folder_cb(MainWindow *mainwin, guint action,
3294
                             GtkWidget *widget)
3295
{
3296
        folderview_rename_folder(mainwin->folderview);
3297
}
3298
3299
static void move_folder_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3300
{
3301
        folderview_move_folder(mainwin->folderview);
3302
}
3303
3304
static void delete_folder_cb(MainWindow *mainwin, guint action,
3305
                             GtkWidget *widget)
3306
{
3307
        folderview_delete_folder(mainwin->folderview);
3308
}
3309
3310
static void add_mailbox_cb(MainWindow *mainwin, guint action,
3311
                           GtkWidget *widget)
3312
{
3313
        main_window_add_mailbox(mainwin);
3314
}
3315
3316
static void remove_mailbox_cb(MainWindow *mainwin, guint action,
3317
                              GtkWidget *widget)
3318
{
3319
        folderview_remove_mailbox(mainwin->folderview);
3320
}
3321
3322
static void update_folderview_cb(MainWindow *mainwin, guint action,
3323
                                 GtkWidget *widget)
3324
{
3325
        if (action == 0)
3326
                folderview_check_new_selected(mainwin->folderview);
3327
        else
3328
                folderview_check_new_all();
3329
}
3330
3331
static void rebuild_tree_cb(MainWindow *mainwin, guint action,
3332
                            GtkWidget *widget)
3333
{
3334
        folderview_rebuild_tree(mainwin->folderview);
3335
}
3336
3337
static void import_mail_cb(MainWindow *mainwin, guint action,
3338
                           GtkWidget *widget)
3339
{
3340
        import_mail(mainwin->summaryview->folder_item);
3341
        main_window_popup(mainwin);
3342
}
3343
3344
static void export_mail_cb(MainWindow *mainwin, guint action,
3345
                           GtkWidget *widget)
3346
{
3347
        export_mail(mainwin->summaryview->folder_item);
3348
        main_window_popup(mainwin);
3349
}
3350
3351
static void empty_trash_cb(MainWindow *mainwin, guint action,
3352
                           GtkWidget *widget)
3353
{
3354
        main_window_empty_trash(mainwin, TRUE);
3355
}
3356
3357
static void save_as_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3358
{
3359
        MessageView *messageview = mainwin->messageview;
3360
3361
        if (messageview_get_selected_mime_part(messageview) &&
3362
            GTK_WIDGET_HAS_FOCUS(messageview->mimeview->treeview))
3363
                mimeview_save_as(messageview->mimeview);
3364
        else
3365
                summary_save_as(mainwin->summaryview);
3366
}
3367
3368
#if GTK_CHECK_VERSION(2, 10, 0)
3369
static void page_setup_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3370
{
3371
        printing_page_setup_gtk();
3372
}
3373
#endif
3374
3375
static void print_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3376
{
3377
        summary_print(mainwin->summaryview);
3378
}
3379
3380
static void toggle_offline_cb(MainWindow *mainwin, guint action,
3381
                              GtkWidget *widget)
3382
{
3383
        if (GTK_CHECK_MENU_ITEM(widget)->active &&
3384
            folder_remote_folder_active_session_exist()) {
3385
                debug_print("Active session exist. Cancelling online switch.\n");
3386
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget),
3387
                                               FALSE);
3388
                return;
3389
        }
3390
3391
        main_window_toggle_online
3392
                (mainwin, !GTK_CHECK_MENU_ITEM(widget)->active);
3393
}
3394
3395
static void app_exit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3396
{
3397
        if (prefs_common.confirm_on_exit) {
3398
                if (alertpanel(_("Exit"), _("Exit this program?"),
3399
                               GTK_STOCK_OK, GTK_STOCK_CANCEL, NULL)
3400
                    != G_ALERTDEFAULT)
3401
                        return;
3402
                manage_window_focus_in(mainwin->window, NULL, NULL);
3403
        }
3404
3405
        app_will_exit(FALSE);
3406
}
3407
3408
static void search_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3409
{
3410
        if (action == 1) {
3411
                FolderItem *item;
3412
3413
                item = folderview_get_selected_item(mainwin->folderview);
3414
                if (item && item->stype == F_VIRTUAL)
3415
                        prefs_search_folder_open(item);
3416
                else
3417
                        query_search(item);
3418
        } else if (action == 2) {
3419
                if (!prefs_common.show_searchbar) {
3420
                        GtkWidget *menuitem;
3421
3422
                        menuitem = gtk_item_factory_get_item
3423
                                (mainwin->menu_factory,
3424
                                 "/View/Show or hide/Search bar");
3425
                        gtk_check_menu_item_set_active
3426
                                (GTK_CHECK_MENU_ITEM(menuitem), TRUE);
3427
                }
3428
                gtk_widget_grab_focus(mainwin->summaryview->qsearch->entry);
3429
        } else
3430
                message_search(mainwin->messageview);
3431
}
3432
3433
static void toggle_folder_cb(MainWindow *mainwin, guint action,
3434
                             GtkWidget *widget)
3435
{
3436
        gboolean active;
3437
3438
        active = GTK_CHECK_MENU_ITEM(widget)->active;
3439
3440
        switch (mainwin->type) {
3441
        case SEPARATE_NONE:
3442
        case SEPARATE_MESSAGE:
3443
#if 0
3444
                if (active)
3445
                        gtk_widget_show(GTK_WIDGET_PTR(mainwin->folderview));
3446
                else
3447
                        gtk_widget_hide(GTK_WIDGET_PTR(mainwin->folderview));
3448
#endif
3449
                break;
3450
        case SEPARATE_FOLDER:
3451
                if (active)
3452
                        gtk_widget_show(mainwin->win.sep_folder.folderwin);
3453
                else
3454
                        gtk_widget_hide(mainwin->win.sep_folder.folderwin);
3455
                break;
3456
        case SEPARATE_BOTH:
3457
                if (active)
3458
                        gtk_widget_show(mainwin->win.sep_both.folderwin);
3459
                else
3460
                        gtk_widget_hide(mainwin->win.sep_both.folderwin);
3461
                break;
3462
        }
3463
3464
        prefs_common.folderview_visible = active;
3465
}
3466
3467
static void toggle_message_cb(MainWindow *mainwin, guint action,
3468
                              GtkWidget *widget)
3469
{
3470
        gboolean active;
3471
3472
        active = GTK_CHECK_MENU_ITEM(widget)->active;
3473
3474
        if (active != messageview_is_visible(mainwin->messageview))
3475
                summary_toggle_view(mainwin->summaryview);
3476
}
3477
3478
static void toggle_toolbar_cb(MainWindow *mainwin, guint action,
3479
                              GtkWidget *widget)
3480
{
3481
        mainwin->toolbar_style = (ToolbarStyle)action;
3482
        prefs_common.toolbar_style = (ToolbarStyle)action;
3483
3484
        main_window_set_toolbar_button_visibility(mainwin);
3485
}
3486
3487
static void toggle_searchbar_cb(MainWindow *mainwin, guint action,
3488
                                GtkWidget *widget)
3489
{
3490
        if (GTK_CHECK_MENU_ITEM(widget)->active) {
3491
                gtk_widget_show(mainwin->summaryview->qsearch->hbox);
3492
                prefs_common.show_searchbar = TRUE;
3493
        } else {
3494
                gtk_widget_hide(mainwin->summaryview->qsearch->hbox);
3495
                summary_qsearch_reset(mainwin->summaryview);
3496
                prefs_common.show_searchbar = FALSE;
3497
        }
3498
}
3499
3500
static void toggle_statusbar_cb(MainWindow *mainwin, guint action,
3501
                                GtkWidget *widget)
3502
{
3503
        if (GTK_CHECK_MENU_ITEM(widget)->active) {
3504
                gtk_widget_show(mainwin->statusbar);
3505
                prefs_common.show_statusbar = TRUE;
3506
        } else {
3507
                gtk_widget_hide(mainwin->statusbar);
3508
                prefs_common.show_statusbar = FALSE;
3509
        }
3510
}
3511
3512
static void toolbar_customize_cb(MainWindow *mainwin, guint action,
3513
                                 GtkWidget *widget)
3514
{
3515
        toolbar_customize(widget, mainwin);
3516
}
3517
3518
static void change_layout_cb(MainWindow *mainwin, guint action,
3519
                             GtkWidget *widget)
3520
{
3521
        LayoutType type = action;
3522
3523
        if (GTK_CHECK_MENU_ITEM(widget)->active)
3524
                main_window_change_layout(mainwin, type, mainwin->type);
3525
}
3526
3527
static void separate_widget_cb(MainWindow *mainwin, guint action,
3528
                               GtkWidget *widget)
3529
{
3530
        SeparateType type;
3531
3532
        if (GTK_CHECK_MENU_ITEM(widget)->active)
3533
                type = mainwin->type | action;
3534
        else
3535
                type = mainwin->type & ~action;
3536
3537
        main_window_change_layout(mainwin, prefs_common.layout_type, type);
3538
3539
        prefs_common.sep_folder = (type & SEPARATE_FOLDER)  != 0;
3540
        prefs_common.sep_msg    = (type & SEPARATE_MESSAGE) != 0;
3541
}
3542
3543
static void addressbook_open_cb(MainWindow *mainwin, guint action,
3544
                                GtkWidget *widget)
3545
{
3546
        addressbook_open(NULL);
3547
}
3548
3549
static void log_window_show_cb(MainWindow *mainwin, guint action,
3550
                               GtkWidget *widget)
3551
{
3552
        log_window_show(mainwin->logwin);
3553
}
3554
3555
static void inc_mail_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3556
{
3557
        inc_mail(mainwin);
3558
}
3559
3560
static void inc_all_account_mail_cb(MainWindow *mainwin, guint action,
3561
                                    GtkWidget *widget)
3562
{
3563
        inc_all_account_mail(mainwin, FALSE);
3564
}
3565
3566
static void inc_stop_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3567
{
3568
        inc_cancel_all();
3569
}
3570
3571
static void rpop3_cb(MainWindow        *mainwin, guint action, GtkWidget *widget)
3572
{
3573
        rpop3_account(cur_account);
3574
}
3575
3576
static void send_queue_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3577
{
3578
        main_window_send_queue(mainwin);
3579
}
3580
3581
static void compose_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3582
{
3583
        PrefsAccount *ac = NULL;
3584
        FolderItem *item = mainwin->summaryview->folder_item;
3585
3586
        if (item) {
3587
                ac = account_find_from_item(item);
3588
                if (ac && ac->protocol == A_NNTP &&
3589
                    FOLDER_TYPE(item->folder) == F_NEWS) {
3590
                        compose_new(ac, item, item->path, NULL);
3591
                        return;
3592
                }
3593
        }
3594
3595
        compose_new(ac, item, NULL, NULL);
3596
}
3597
3598
static void reply_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3599
{
3600
        summary_reply(mainwin->summaryview, (ComposeMode)action);
3601
}
3602
3603
static void move_to_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3604
{
3605
        summary_move_to(mainwin->summaryview);
3606
}
3607
3608
static void copy_to_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3609
{
3610
        summary_copy_to(mainwin->summaryview);
3611
}
3612
3613
static void delete_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3614
{
3615
        summary_delete(mainwin->summaryview);
3616
}
3617
3618
static void open_msg_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3619
{
3620
        summary_open_msg(mainwin->summaryview);
3621
}
3622
3623
static void view_source_cb(MainWindow *mainwin, guint action,
3624
                           GtkWidget *widget)
3625
{
3626
        summary_view_source(mainwin->summaryview);
3627
}
3628
3629
static void show_all_header_cb(MainWindow *mainwin, guint action,
3630
                               GtkWidget *widget)
3631
{
3632
        if (mainwin->menu_lock_count) return;
3633
        summary_display_msg_selected(mainwin->summaryview, FALSE,
3634
                                     GTK_CHECK_MENU_ITEM(widget)->active);
3635
}
3636
3637
static void mark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3638
{
3639
        summary_mark(mainwin->summaryview);
3640
}
3641
3642
static void unmark_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3643
{
3644
        summary_unmark(mainwin->summaryview);
3645
}
3646
3647
static void mark_as_unread_cb(MainWindow *mainwin, guint action,
3648
                              GtkWidget *widget)
3649
{
3650
        summary_mark_as_unread(mainwin->summaryview);
3651
}
3652
3653
static void mark_as_read_cb(MainWindow *mainwin, guint action,
3654
                            GtkWidget *widget)
3655
{
3656
        summary_mark_as_read(mainwin->summaryview);
3657
}
3658
3659
static void mark_thread_as_read_cb(MainWindow *mainwin, guint action,
3660
                                   GtkWidget *widget)
3661
{
3662
        summary_mark_thread_as_read(mainwin->summaryview);
3663
}
3664
3665
static void mark_all_read_cb(MainWindow *mainwin, guint action,
3666
                             GtkWidget *widget)
3667
{
3668
        summary_mark_all_read(mainwin->summaryview);
3669
}
3670
3671
static void junk_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3672
{
3673
        if (action == 0)
3674
                summary_junk(mainwin->summaryview);
3675
        else
3676
                summary_not_junk(mainwin->summaryview);
3677
}
3678
3679
static void reedit_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3680
{
3681
        summary_reedit(mainwin->summaryview);
3682
}
3683
3684
static void add_address_cb(MainWindow *mainwin, guint action,
3685
                           GtkWidget *widget)
3686
{
3687
        summary_add_address(mainwin->summaryview);
3688
}
3689
3690
static void set_charset_cb(MainWindow *mainwin, guint action,
3691
                           GtkWidget *widget)
3692
{
3693
        const gchar *str;
3694
3695
        if (GTK_CHECK_MENU_ITEM(widget)->active) {
3696
                str = conv_get_charset_str((CharSet)action);
3697
                g_free(prefs_common.force_charset);
3698
                prefs_common.force_charset = str ? g_strdup(str) : NULL;
3699
3700
                summary_redisplay_msg(mainwin->summaryview);
3701
3702
                debug_print("forced charset: %s\n",
3703
                            str ? str : "Auto-Detect");
3704
        }
3705
}
3706
3707
static void thread_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3708
{
3709
        if (mainwin->menu_lock_count) return;
3710
        if (!mainwin->summaryview->folder_item) return;
3711
3712
        if (GTK_CHECK_MENU_ITEM(widget)->active)
3713
                summary_thread_build(mainwin->summaryview);
3714
        else
3715
                summary_unthread(mainwin->summaryview);
3716
}
3717
3718
static void expand_threads_cb(MainWindow *mainwin, guint action,
3719
                              GtkWidget *widget)
3720
{
3721
        summary_expand_threads(mainwin->summaryview);
3722
}
3723
3724
static void collapse_threads_cb(MainWindow *mainwin, guint action,
3725
                                GtkWidget *widget)
3726
{
3727
        summary_collapse_threads(mainwin->summaryview);
3728
}
3729
3730
static void set_display_item_cb(MainWindow *mainwin, guint action,
3731
                                GtkWidget *widget)
3732
{
3733
        prefs_summary_column_open
3734
                (FOLDER_ITEM_IS_SENT_FOLDER(mainwin->summaryview->folder_item));
3735
}
3736
3737
static void sort_summary_cb(MainWindow *mainwin, guint action,
3738
                            GtkWidget *widget)
3739
{
3740
        FolderItem *item = mainwin->summaryview->folder_item;
3741
        GtkWidget *menuitem;
3742
3743
        if (mainwin->menu_lock_count) return;
3744
3745
        if (GTK_CHECK_MENU_ITEM(widget)->active && item) {
3746
                menuitem = gtk_item_factory_get_item
3747
                        (mainwin->menu_factory, "/View/Sort/Ascending");
3748
                summary_sort(mainwin->summaryview, (FolderSortKey)action,
3749
                             GTK_CHECK_MENU_ITEM(menuitem)->active
3750
                             ? SORT_ASCENDING : SORT_DESCENDING);
3751
        }
3752
}
3753
3754
static void sort_summary_type_cb(MainWindow *mainwin, guint action,
3755
                                 GtkWidget *widget)
3756
{
3757
        FolderItem *item = mainwin->summaryview->folder_item;
3758
3759
        if (mainwin->menu_lock_count) return;
3760
3761
        if (GTK_CHECK_MENU_ITEM(widget)->active && item)
3762
                summary_sort(mainwin->summaryview,
3763
                             item->sort_key, (FolderSortType)action);
3764
}
3765
3766
static void attract_by_subject_cb(MainWindow *mainwin, guint action,
3767
                                  GtkWidget *widget)
3768
{
3769
        summary_attract_by_subject(mainwin->summaryview);
3770
}
3771
3772
static void delete_duplicated_cb(MainWindow *mainwin, guint action,
3773
                                 GtkWidget *widget)
3774
{
3775
        summary_delete_duplicated(mainwin->summaryview);
3776
}
3777
3778
static void concat_partial_cb(MainWindow *mainwin, guint action,
3779
                              GtkWidget *widget)
3780
{
3781
        GSList *mlist;
3782
        gchar *file;
3783
        FolderItem *item;
3784
3785
        if (summary_is_locked(mainwin->summaryview))
3786
                return;
3787
3788
        item = mainwin->summaryview->folder_item;
3789
        if (!item)
3790
                return;
3791
        mlist = summary_get_selected_msg_list(mainwin->summaryview);
3792
        if (!mlist)
3793
                return;
3794
3795
        file = get_tmp_file();
3796
        if (procmsg_concat_partial_messages(mlist, file) == 0) {
3797
                folder_item_add_msg(item, file, NULL, TRUE);
3798
                summary_show_queued_msgs(mainwin->summaryview);
3799
        } else {
3800
                alertpanel_error
3801
                        (_("The selected messages could not be combined."));
3802
        }
3803
        g_free(file);
3804
3805
        g_slist_free(mlist);
3806
}
3807
3808
static void filter_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3809
{
3810
        summary_filter(mainwin->summaryview, (gboolean)action);
3811
}
3812
3813
static void filter_junk_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3814
{
3815
        summary_filter_junk(mainwin->summaryview, (gboolean)action);
3816
}
3817
3818
static void execute_summary_cb(MainWindow *mainwin, guint action,
3819
                               GtkWidget *widget)
3820
{
3821
        summary_execute(mainwin->summaryview);
3822
}
3823
3824
static void update_summary_cb(MainWindow *mainwin, guint action,
3825
                              GtkWidget *widget)
3826
{
3827
        if (!mainwin->summaryview->folder_item) return;
3828
3829
        summary_show(mainwin->summaryview, mainwin->summaryview->folder_item,
3830
                     TRUE);
3831
}
3832
3833
static void prev_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3834
{
3835
        MessageView *messageview = mainwin->messageview;
3836
3837
        if (messageview_get_selected_mime_part(messageview) &&
3838
            GTK_WIDGET_HAS_FOCUS(messageview->mimeview->treeview) &&
3839
            mimeview_step(messageview->mimeview, GTK_SCROLL_STEP_BACKWARD))
3840
                return;
3841
3842
        if (summary_step(mainwin->summaryview, GTK_SCROLL_STEP_BACKWARD))
3843
                summary_mark_displayed_read(mainwin->summaryview, NULL);
3844
}
3845
3846
static void next_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3847
{
3848
        MessageView *messageview = mainwin->messageview;
3849
3850
        if (messageview_get_selected_mime_part(messageview) &&
3851
            GTK_WIDGET_HAS_FOCUS(messageview->mimeview->treeview) &&
3852
            mimeview_step(messageview->mimeview, GTK_SCROLL_STEP_FORWARD))
3853
                return;
3854
3855
        if (summary_step(mainwin->summaryview, GTK_SCROLL_STEP_FORWARD))
3856
                summary_mark_displayed_read(mainwin->summaryview, NULL);
3857
}
3858
3859
static void prev_unread_cb(MainWindow *mainwin, guint action,
3860
                           GtkWidget *widget)
3861
{
3862
        summary_select_prev_unread(mainwin->summaryview);
3863
}
3864
3865
static void next_unread_cb(MainWindow *mainwin, guint action,
3866
                           GtkWidget *widget)
3867
{
3868
        summary_select_next_unread(mainwin->summaryview);
3869
}
3870
3871
static void prev_new_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3872
{
3873
        summary_select_prev_new(mainwin->summaryview);
3874
}
3875
3876
static void next_new_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3877
{
3878
        summary_select_next_new(mainwin->summaryview);
3879
}
3880
3881
static void prev_marked_cb(MainWindow *mainwin, guint action,
3882
                           GtkWidget *widget)
3883
{
3884
        summary_select_prev_marked(mainwin->summaryview);
3885
}
3886
3887
static void next_marked_cb(MainWindow *mainwin, guint action,
3888
                           GtkWidget *widget)
3889
{
3890
        summary_select_next_marked(mainwin->summaryview);
3891
}
3892
3893
static void prev_labeled_cb(MainWindow *mainwin, guint action,
3894
                            GtkWidget *widget)
3895
{
3896
        summary_select_prev_labeled(mainwin->summaryview);
3897
}
3898
3899
static void next_labeled_cb(MainWindow *mainwin, guint action,
3900
                            GtkWidget *widget)
3901
{
3902
        summary_select_next_labeled(mainwin->summaryview);
3903
}
3904
3905
static void goto_folder_cb(MainWindow *mainwin, guint action,
3906
                           GtkWidget *widget)
3907
{
3908
        FolderItem *to_folder;
3909
3910
        to_folder = foldersel_folder_sel_full(NULL, FOLDER_SEL_ALL, NULL,
3911
                                              _("Select folder to open"));
3912
3913
        if (to_folder)
3914
                folderview_select(mainwin->folderview, to_folder);
3915
}
3916
3917
static void copy_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3918
{
3919
        messageview_copy_clipboard(mainwin->messageview);
3920
}
3921
3922
static void allsel_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
3923
{
3924
        MessageView *msgview = mainwin->messageview;
3925
3926
        if (GTK_WIDGET_HAS_FOCUS(mainwin->summaryview->treeview))
3927
                summary_select_all(mainwin->summaryview);
3928
        else if (GTK_WIDGET_HAS_FOCUS(mainwin->summaryview->qsearch->entry))
3929
                gtk_editable_select_region
3930
                        (GTK_EDITABLE(mainwin->summaryview->qsearch->entry),
3931
                         0, -1);
3932
        else if (messageview_is_visible(msgview) &&
3933
                 (GTK_WIDGET_HAS_FOCUS(msgview->textview->text) ||
3934
                  GTK_WIDGET_HAS_FOCUS(msgview->mimeview->textview->text)))
3935
                messageview_select_all(msgview);
3936
}
3937
3938
static void select_thread_cb(MainWindow *mainwin, guint action,
3939
                             GtkWidget *widget)
3940
{
3941
        summary_select_thread(mainwin->summaryview);
3942
}
3943
3944
static void create_filter_cb(MainWindow *mainwin, guint action,
3945
                             GtkWidget *widget)
3946
{
3947
        summary_filter_open(mainwin->summaryview, (FilterCreateType)action);
3948
}
3949
3950
static void prefs_common_open_cb(MainWindow *mainwin, guint action,
3951
                                 GtkWidget *widget)
3952
{
3953
        prefs_common_open();
3954
}
3955
3956
static void prefs_filter_open_cb(MainWindow *mainwin, guint action,
3957
                                 GtkWidget *widget)
3958
{
3959
        prefs_filter_open(NULL, NULL, NULL);
3960
}
3961
3962
static void prefs_template_open_cb(MainWindow *mainwin, guint action,
3963
                                   GtkWidget *widget)
3964
{
3965
        prefs_template_open();
3966
}
3967
3968
static void plugin_manager_open_cb(MainWindow *mainwin, guint action,
3969
                                   GtkWidget *widget)
3970
{
3971
        plugin_manager_open();
3972
}
3973
3974
#ifndef G_OS_WIN32
3975
static void prefs_actions_open_cb(MainWindow *mainwin, guint action,
3976
                                  GtkWidget *widget)
3977
{
3978
        prefs_actions_open(mainwin);
3979
}
3980
#endif
3981
3982
static void prefs_account_open_cb(MainWindow *mainwin, guint action,
3983
                                  GtkWidget *widget)
3984
{
3985
        if (!cur_account) {
3986
                new_account_cb(mainwin, 0, widget);
3987
        } else {
3988
                account_open(cur_account);
3989
        }
3990
}
3991
3992
static void new_account_cb(MainWindow *mainwin, guint action,
3993
                           GtkWidget *widget)
3994
{
3995
        PrefsAccount *ac;
3996
3997
        if (compose_get_compose_list()) {
3998
                alertpanel_notice(_("Some composing windows are open.\n"
3999
                                    "Please close all the composing windows before editing the accounts."));
4000
                return;
4001
        }
4002
4003
        if ((ac = setup_account())) {
4004
                account_set_menu();
4005
                main_window_reflect_prefs_all();
4006
                account_set_missing_folder();
4007
                folderview_set(mainwin->folderview);
4008
                if (ac->folder)
4009
                        folder_write_list();
4010
        }
4011
}
4012
4013
static void account_selector_menu_cb(GtkMenuItem *menuitem, gpointer data)
4014
{
4015
        cur_account = (PrefsAccount *)data;
4016
        main_window_change_cur_account();
4017
}
4018
4019
static void account_receive_menu_cb(GtkMenuItem *menuitem, gpointer data)
4020
{
4021
        PrefsAccount *account = (PrefsAccount *)data;
4022
4023
        inc_account_mail(main_window_get(), account);
4024
}
4025
4026
static void manual_open_cb(MainWindow *mainwin, guint action,
4027
                           GtkWidget *widget)
4028
{
4029
        manual_open((ManualLang)action);
4030
}
4031
4032
static void faq_open_cb(MainWindow *mainwin, guint action, GtkWidget *widget)
4033
{
4034
        faq_open((ManualLang)action);
4035
}
4036
4037
static GtkWidget *help_cmdline_window;
4038
4039
static void help_cmdline_ok(GtkWidget *button)
4040
{
4041
        gtk_widget_destroy(gtk_widget_get_toplevel(button));
4042
}
4043
4044
static gboolean help_cmdline_key_pressed(GtkWidget *widget, GdkEventKey *event,
4045
                                         gpointer data)
4046
{
4047
        if (event && event->keyval == GDK_Escape) {
4048
                gtk_widget_destroy(widget);
4049
                return TRUE;
4050
        }
4051
        return FALSE;
4052
}
4053
4054
static gboolean help_cmdline_deleted(GtkWidget *widget, GdkEventAny *event,
4055
                                     gpointer data)
4056
{
4057
        return FALSE;
4058
}
4059
4060
static void help_cmdline_destroyed(GtkWidget *widget, gpointer data)
4061
{
4062
        help_cmdline_window = NULL;
4063
}
4064
4065
static void help_command_line_show(void)
4066
{
4067
        GtkWidget *window;
4068
        GtkWidget *vbox;
4069
        GtkWidget *vbox2;
4070
        GtkWidget *hbox;
4071
        GtkWidget *label;
4072
        GtkWidget *hbbox;
4073
        GtkWidget *ok_btn;
4074
4075
        if (help_cmdline_window) {
4076
                gtk_window_present(GTK_WINDOW(help_cmdline_window));
4077
                return;
4078
        }
4079
4080
        window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
4081
        gtk_window_set_title(GTK_WINDOW(window), _("Command line options"));
4082
        gtk_container_set_border_width(GTK_CONTAINER(window), 8);
4083
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
4084
        gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
4085
        help_cmdline_window = window;
4086
4087
        vbox = gtk_vbox_new(FALSE, 8);
4088
        gtk_container_add(GTK_CONTAINER(window), vbox);
4089
4090
        vbox2 = gtk_vbox_new(FALSE, 8);
4091
        gtk_container_set_border_width(GTK_CONTAINER(vbox2), 8);
4092
        gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0);
4093
4094
        label = gtk_label_new(_("Usage: sylpheed [OPTION]..."));
4095
        gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0);
4096
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4097
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4098
4099
        hbox = gtk_hbox_new(FALSE, 16);
4100
        gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
4101
4102
        label = gtk_label_new(_("--compose [address]\n"
4103
                                "--attach file1 [file2]...\n"
4104
                                "--receive\n"
4105
                                "--receive-all\n"
4106
                                "--send\n"
4107
                                "--status [folder]...\n"
4108
                                "--status-full [folder]...\n"
4109
                                "--open folderid/msgnum\n"
4110
                                "--configdir dirname\n"
4111
                                "--exit\n"
4112
                                "--debug\n"
4113
                                "--help\n"
4114
                                "--version"));
4115
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4116
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4117
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4118
4119
        label = gtk_label_new(_("open composition window\n"
4120
                                "open composition window with specified files attached\n"
4121
                                "receive new messages\n"
4122
                                "receive new messages of all accounts\n"
4123
                                "send all queued messages\n"
4124
                                "show the total number of messages\n"
4125
                                "show the status of each folder\n"
4126
                                "open message in new window\n"
4127
                                "specify directory which stores configuration files\n"
4128
                                "exit Sylpheed\n"
4129
                                "debug mode\n"
4130
                                "display this help and exit\n"
4131
                                "output version information and exit"));
4132
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4133
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4134
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4135
4136
#ifdef G_OS_WIN32
4137
        label = gtk_label_new(_("Windows-only option:"));
4138
        gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 0);
4139
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4140
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4141
4142
        hbox = gtk_hbox_new(FALSE, 32);
4143
        gtk_box_pack_start(GTK_BOX(vbox2), hbox, FALSE, FALSE, 0);
4144
4145
        label = gtk_label_new(_("--ipcport portnum"));
4146
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4147
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4148
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4149
4150
        label = gtk_label_new(_("specify port for IPC remote commands"));
4151
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
4152
        gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
4153
        gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
4154
#endif
4155
4156
        gtkut_stock_button_set_create(&hbbox, &ok_btn, GTK_STOCK_OK,
4157
                                      NULL, NULL, NULL, NULL);
4158
        gtk_box_pack_end(GTK_BOX(vbox), hbbox, FALSE, FALSE, 0);
4159
        gtk_widget_grab_default(ok_btn);
4160
4161
        g_signal_connect(G_OBJECT(ok_btn), "clicked",
4162
                         G_CALLBACK(help_cmdline_ok), NULL);
4163
        g_signal_connect(G_OBJECT(window), "key_press_event",
4164
                         G_CALLBACK(help_cmdline_key_pressed), NULL);
4165
        g_signal_connect(G_OBJECT(window), "delete_event",
4166
                         G_CALLBACK(help_cmdline_deleted), NULL);
4167
        g_signal_connect(G_OBJECT(window), "destroy",
4168
                         G_CALLBACK(help_cmdline_destroyed), NULL);
4169
4170
        gtk_widget_show_all(window);
4171
}
4172
4173
static void help_cmdline_cb(MainWindow *mainwin, guint action,
4174
                            GtkWidget *widget)
4175
{
4176
        help_command_line_show();
4177
}
4178
4179
#if USE_UPDATE_CHECK
4180
static void update_check_cb(MainWindow *mainwin, guint action,
4181
                            GtkWidget *widget)
4182
{
4183
        update_check(TRUE);
4184
}
4185
4186
#ifdef USE_UPDATE_CHECK_PLUGIN
4187
static void update_check_plugin_cb(MainWindow *mainwin, guint action,
4188
                                   GtkWidget *widget)
4189
{
4190
        update_check_plugin(TRUE);
4191
}
4192
#endif
4193
#endif
4194
4195
static void scan_tree_func(Folder *folder, FolderItem *item, gpointer data)
4196
{
4197
        MainWindow *mainwin = (MainWindow *)data;
4198
        gchar *str;
4199
4200
        if (item->path)
4201
                str = g_strdup_printf(_("Scanning folder %s%c%s ..."),
4202
                                      LOCAL_FOLDER(folder)->rootpath,
4203
                                      G_DIR_SEPARATOR,
4204
                                      item->path);
4205
        else
4206
                str = g_strdup_printf(_("Scanning folder %s ..."),
4207
                                      LOCAL_FOLDER(folder)->rootpath);
4208
4209
        STATUSBAR_PUSH(mainwin, str);
4210
        STATUSBAR_POP(mainwin);
4211
        g_free(str);
4212
}