1 /* Copyright (c) 2006, Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include <glib/gi18n.h>
31 #include <gtk/gtktreeviewcolumn.h>
32 #include <tny-account-store-view.h>
33 #include <tny-simple-list.h>
35 #include <tny-iterator.h>
36 #include <tny-maemo-conic-device.h>
37 #include "modest-hildon-includes.h"
38 #include "modest-defs.h"
41 #include "widgets/modest-main-window.h"
42 #include "widgets/modest-msg-edit-window.h"
43 #include "widgets/modest-account-view-window.h"
44 #include "modest-runtime.h"
45 #include "modest-account-mgr-helpers.h"
46 #include "modest-platform.h"
47 #include "modest-widget-memory.h"
48 #include "modest-window-priv.h"
49 #include "modest-main-window-ui.h"
50 #include "modest-main-window-ui-dimming.h"
51 #include "modest-account-mgr.h"
52 #include "modest-tny-account.h"
53 #include "modest-tny-folder.h"
54 #include "modest-conf.h"
55 #include <modest-maemo-utils.h>
56 #include "modest-tny-platform-factory.h"
57 #include "modest-tny-msg.h"
58 #include "modest-mail-operation.h"
59 #include "modest-icon-names.h"
60 #include "modest-progress-bar-widget.h"
61 #include "modest-text-utils.h"
62 #include "modest-ui-dimming-manager.h"
63 #include "maemo/modest-osso-state-saving.h"
65 #ifdef MODEST_HAVE_HILDON0_WIDGETS
66 #include <hildon-widgets/hildon-program.h>
68 #include <hildon/hildon-program.h>
69 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
71 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
78 /* 'private'/'protected' functions */
79 static void modest_main_window_class_init (ModestMainWindowClass *klass);
80 static void modest_main_window_init (ModestMainWindow *obj);
81 static void modest_main_window_finalize (GObject *obj);
82 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
83 GdkEventWindowState *event,
86 static void connect_signals (ModestMainWindow *self);
88 static void restore_settings (ModestMainWindow *self, gboolean do_folder_view_too);
89 static void save_state (ModestWindow *self);
91 static void modest_main_window_show_toolbar (ModestWindow *window,
92 gboolean show_toolbar);
94 static void cancel_progressbar (GtkToolButton *toolbutton,
95 ModestMainWindow *self);
97 static void on_queue_changed (ModestMailOperationQueue *queue,
98 ModestMailOperation *mail_op,
99 ModestMailOperationQueueNotification type,
100 ModestMainWindow *self);
102 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
104 static void on_account_update (TnyAccountStore *account_store,
105 const gchar *account_name,
108 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
112 static void on_configuration_key_changed (ModestConf* conf,
114 ModestConfEvent event,
115 ModestMainWindow *self);
117 static void set_toolbar_mode (ModestMainWindow *self,
118 ModestToolBarModes mode);
120 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
122 static void on_show_account_action_activated (GtkAction *action,
125 static void on_refresh_account_action_activated (GtkAction *action,
128 static void on_send_receive_csm_activated (GtkMenuItem *item,
132 _on_msg_count_changed (ModestHeaderView *header_view,
134 TnyFolderChange *change,
135 ModestMainWindow *main_window);
138 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
141 static GtkWidget * create_empty_view (void);
144 on_folder_view_focus_in (GtkWidget *widget,
145 GdkEventFocus *event,
148 on_header_view_focus_in (GtkWidget *widget,
149 GdkEventFocus *event,
152 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
153 TnyFolderStore *folder_store,
155 ModestMainWindow *main_window);
157 /* list my signals */
164 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
165 struct _ModestMainWindowPrivate {
166 GtkWidget *msg_paned;
167 GtkWidget *main_paned;
168 GtkWidget *main_vbox;
169 GtkWidget *contents_widget;
170 GtkWidget *empty_view;
172 /* Progress observers */
173 GtkWidget *progress_bar;
174 GSList *progress_widgets;
177 GtkWidget *progress_toolitem;
178 GtkWidget *cancel_toolitem;
179 GtkWidget *sort_toolitem;
180 GtkWidget *refresh_toolitem;
181 ModestToolBarModes current_toolbar_mode;
183 /* Merge ids used to add/remove accounts to the ViewMenu*/
184 GByteArray *merge_ids;
186 /* On-demand widgets */
187 GtkWidget *accounts_popup;
188 GtkWidget *details_widget;
190 /* Optimized view enabled */
191 gboolean optimized_view;
193 /* Optimized view enabled */
194 gboolean send_receive_in_progress;
196 ModestHeaderView *header_view;
197 ModestFolderView *folder_view;
199 ModestMainWindowStyle style;
200 ModestMainWindowContentsStyle contents_style;
202 guint progress_bar_timeout;
204 /* Signal handler UIDs */
205 gint queue_changed_handler_uid;
206 GList *queue_err_signals;
208 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
209 MODEST_TYPE_MAIN_WINDOW, \
210 ModestMainWindowPrivate))
212 typedef struct _GetMsgAsyncHelper {
213 ModestMainWindowPrivate *main_window_private;
215 ModestTnyMsgReplyType reply_type;
216 ModestTnyMsgForwardType forward_type;
223 static GtkWindowClass *parent_class = NULL;
226 /* Private actions */
227 /* This is the context sensitive menu: */
228 static const GtkActionEntry modest_folder_view_action_entries [] = {
230 /* Folder View CSM actions */
231 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
232 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
233 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
234 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
235 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
236 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
239 static const GtkActionEntry modest_header_view_action_entries [] = {
241 /* Header View CSM actions */
242 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
243 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
244 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
245 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
246 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
247 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
248 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
249 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) },
250 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, NULL },
251 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
254 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
255 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
258 /************************************************************************/
261 modest_main_window_get_type (void)
263 static GType my_type = 0;
265 static const GTypeInfo my_info = {
266 sizeof(ModestMainWindowClass),
267 NULL, /* base init */
268 NULL, /* base finalize */
269 (GClassInitFunc) modest_main_window_class_init,
270 NULL, /* class finalize */
271 NULL, /* class data */
272 sizeof(ModestMainWindow),
274 (GInstanceInitFunc) modest_main_window_init,
277 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
285 modest_main_window_class_init (ModestMainWindowClass *klass)
287 GObjectClass *gobject_class;
288 gobject_class = (GObjectClass*) klass;
289 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
291 parent_class = g_type_class_peek_parent (klass);
292 gobject_class->finalize = modest_main_window_finalize;
294 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
296 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
297 modest_window_class->save_state_func = save_state;
298 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
299 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
303 modest_main_window_init (ModestMainWindow *obj)
305 ModestMainWindowPrivate *priv;
307 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
309 priv->queue_err_signals = NULL;
310 priv->msg_paned = NULL;
311 priv->main_paned = NULL;
312 priv->main_vbox = NULL;
313 priv->header_view = NULL;
314 priv->folder_view = NULL;
315 priv->contents_widget = NULL;
316 priv->accounts_popup = NULL;
317 priv->details_widget = NULL;
318 priv->empty_view = NULL;
319 priv->progress_widgets = NULL;
320 priv->progress_bar = NULL;
321 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
322 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
323 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
324 priv->merge_ids = NULL;
325 priv->optimized_view = FALSE;
326 priv->send_receive_in_progress = FALSE;
327 priv->progress_bar_timeout = 0;
328 priv->queue_changed_handler_uid = 0;
332 modest_main_window_finalize (GObject *obj)
334 ModestMainWindowPrivate *priv;
336 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
338 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
340 g_slist_free (priv->progress_widgets);
342 g_byte_array_free (priv->merge_ids, TRUE);
344 if (priv->progress_bar_timeout > 0) {
345 g_source_remove (priv->progress_bar_timeout);
346 priv->progress_bar_timeout = 0;
349 /* Disconnect signal handlers */
350 if (priv->queue_changed_handler_uid)
351 g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
352 priv->queue_changed_handler_uid);
354 G_OBJECT_CLASS(parent_class)->finalize (obj);
358 modest_main_window_get_child_widget (ModestMainWindow *self,
359 ModestWidgetType widget_type)
361 ModestMainWindowPrivate *priv;
364 g_return_val_if_fail (self, NULL);
365 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
368 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
370 switch (widget_type) {
371 case MODEST_WIDGET_TYPE_HEADER_VIEW:
372 widget = (GtkWidget*)priv->header_view; break;
373 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
374 widget = (GtkWidget*)priv->folder_view; break;
379 return widget ? GTK_WIDGET(widget) : NULL;
384 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
387 ModestMainWindowPrivate *priv;
389 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
391 conf = modest_runtime_get_conf ();
393 modest_widget_memory_restore (conf, G_OBJECT(self),
394 MODEST_CONF_MAIN_WINDOW_KEY);
396 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
397 MODEST_CONF_HEADER_VIEW_KEY);
399 if (do_folder_view_too)
400 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
401 MODEST_CONF_FOLDER_VIEW_KEY);
403 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
404 MODEST_CONF_MAIN_PANED_KEY);
406 /* We need to force a redraw here in order to get the right
407 position of the horizontal paned separator */
408 gtk_widget_show (GTK_WIDGET (self));
413 save_state (ModestWindow *window)
416 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
417 ModestMainWindowPrivate *priv;
419 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
420 conf = modest_runtime_get_conf ();
422 modest_widget_memory_save (conf,G_OBJECT(self),
423 MODEST_CONF_MAIN_WINDOW_KEY);
424 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
425 MODEST_CONF_MAIN_PANED_KEY);
426 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
427 // MODEST_CONF_HEADER_VIEW_KEY);
428 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
429 MODEST_CONF_FOLDER_VIEW_KEY);
433 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
435 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
436 gtk_scrolled_window_add_with_viewport
437 (GTK_SCROLLED_WINDOW(win), widget);
439 gtk_container_add (GTK_CONTAINER(win),
445 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
447 modest_window_save_state (MODEST_WINDOW(self));
453 ModestMainWindow *self;
459 on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
461 OnResponseInfo *info = (OnResponseInfo *) user_data;
462 ModestMainWindow *self = info->self;
463 TnyHeader *header = info->header;
464 TnySendQueue *queue = info->queue;
466 if (arg1 == GTK_RESPONSE_YES) {
467 TnyFolder *outbox = tny_send_queue_get_outbox (queue);
468 tny_folder_remove_msg (outbox, header, NULL);
469 tny_folder_sync (outbox, TRUE, NULL);
470 g_object_unref (outbox);
473 g_object_unref (queue);
474 g_object_unref (header);
475 g_object_unref (self);
477 gtk_widget_destroy (GTK_WIDGET (dialog));
478 g_slice_free (OnResponseInfo, info);
483 on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
486 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
487 err->message, tny_header_get_subject (header));
488 OnResponseInfo *info = g_slice_new (OnResponseInfo);
489 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
490 GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
492 info->queue = g_object_ref (self);
493 info->self = g_object_ref (user_data);
494 info->header = g_object_ref (header);
495 g_signal_connect (G_OBJECT (dialog), "response",
496 G_CALLBACK (on_response), info);
497 gtk_widget_show_all (dialog);
507 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
509 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
511 GList *oerrsignals = priv->queue_err_signals;
512 while (oerrsignals) {
513 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
514 g_signal_handler_disconnect (esignal->queue, esignal->signal);
515 g_slice_free (QueueErrorSignal, esignal);
516 oerrsignals = g_list_next (oerrsignals);
518 g_list_free (priv->queue_err_signals);
519 priv->queue_err_signals = NULL;
523 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
525 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
527 /* When going online, do the equivalent of pressing the send/receive button,
528 * as per the specification:
529 * (without the check for >0 accounts, though that is not specified): */
531 TnyDevice *device = tny_account_store_get_device (store);
533 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
535 /* Check that we are really online.
536 * This signal should not be emitted when we are not connected,
537 * but it seems to happen sometimes: */
538 if (!tny_device_is_online (device))
541 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
542 printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
544 /* Stop the existing send queues: */
545 modest_runtime_remove_all_send_queues ();
547 /* Create the send queues again, using the appropriate transport accounts
548 * for this new connection.
549 * This could be the first time that they are created if this is the first
551 /* TODO: Does this really destroy the TnySendQueues and their threads
552 * We do not want 2 TnySendQueues to exist with the same underlying
553 * outbox directory. */
555 modest_main_window_cleanup_queue_error_signals (self);
557 GSList *account_names = modest_account_mgr_account_names (
558 modest_runtime_get_account_mgr(),
559 TRUE /* enabled accounts only */);
560 GSList *iter = account_names;
562 const gchar *account_name = (const gchar*)(iter->data);
564 TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
565 modest_tny_account_store_get_transport_account_for_open_connection
566 (modest_runtime_get_account_store(), account_name));
568 /* Q: Is this the first location where the send-queues are requested? */
569 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
570 printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name,
571 tny_account_get_id(TNY_ACCOUNT(account)));
572 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
573 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
574 G_CALLBACK (on_sendqueue_error_happened), self);
575 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
579 iter = g_slist_next (iter);
582 modest_account_mgr_free_account_names (account_names);
583 account_names = NULL;
585 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
589 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
591 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
594 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
598 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
600 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
602 /* Update visibility */
605 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
609 connect_signals (ModestMainWindow *self)
611 ModestWindowPrivate *parent_priv;
612 ModestMainWindowPrivate *priv;
615 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
616 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
619 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
620 G_CALLBACK(on_inner_widgets_key_pressed), self);
621 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
622 G_CALLBACK(modest_main_window_on_folder_selection_changed), self);
623 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
624 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
625 g_signal_connect (G_OBJECT (priv->folder_view), "focus-in-event",
626 G_CALLBACK (on_folder_view_focus_in), self);
628 /* Folder view CSM */
629 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
630 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
631 g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
632 G_CALLBACK(_folder_view_csm_menu_activated),
635 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
636 G_CALLBACK(modest_ui_actions_on_header_selected), self);
637 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
638 G_CALLBACK(modest_ui_actions_on_header_activated), self);
639 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
640 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
641 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
642 G_CALLBACK(on_inner_widgets_key_pressed), self);
643 g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
644 G_CALLBACK(_on_msg_count_changed), self);
645 g_signal_connect (G_OBJECT (priv->header_view), "focus-in-event",
646 G_CALLBACK (on_header_view_focus_in), self);
648 /* Header view CSM */
649 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
650 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
651 g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
652 G_CALLBACK(_header_view_csm_menu_activated),
656 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
657 g_signal_connect (G_OBJECT (self), "window-state-event",
658 G_CALLBACK (modest_main_window_window_state_event),
661 /* Mail Operation Queue */
662 priv->queue_changed_handler_uid =
663 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
664 "queue-changed", G_CALLBACK (on_queue_changed), self);
666 /* Track changes in the device name */
667 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
668 "key_changed", G_CALLBACK (on_configuration_key_changed),
671 /* Track account changes. We need to refresh the toolbar */
672 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
673 "account_update", G_CALLBACK (on_account_update),
677 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()),
678 "password_requested",
679 G_CALLBACK (modest_ui_actions_on_password_requested), self);
682 g_signal_connect (G_OBJECT(modest_runtime_get_account_store()),
683 "connecting-finished",
684 G_CALLBACK(on_account_store_connecting_finished), self);
688 /** Idle handler, to send/receive at startup .*/
690 sync_accounts_cb (ModestMainWindow *win)
692 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
693 return FALSE; /* Do not call this idle handler again. */
697 static void on_hildon_program_is_topmost_notify(GObject *self,
698 GParamSpec *propert_param, gpointer user_data)
700 HildonProgram *app = HILDON_PROGRAM (self);
703 ModestWindow* self = MODEST_WINDOW(user_data);
706 /* Note that use of hildon_program_set_can_hibernate()
707 * is generally referred to as "setting the killable flag",
708 * though hibernation does not seem equal to death.
711 if (hildon_program_get_is_topmost (app)) {
712 /* Prevent hibernation when the progam comes to the foreground,
713 * because hibernation should only happen when the application
714 * is in the background: */
715 hildon_program_set_can_hibernate (app, FALSE);
717 /* Allow hibernation if the program has gone to the background: */
719 /* However, prevent hibernation while the settings are being changed: */
720 const gboolean hibernation_prevented =
721 modest_window_mgr_get_hibernation_is_prevented (
722 modest_runtime_get_window_mgr ());
724 if (hibernation_prevented)
725 hildon_program_set_can_hibernate (app, FALSE);
727 /* Allow hibernation, after saving the state: */
728 modest_osso_save_state();
729 hildon_program_set_can_hibernate (app, TRUE);
736 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
738 GtkWidget *folder_win = (GtkWidget *) user_data;
739 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
741 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
742 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
743 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
745 gtk_widget_show (GTK_WIDGET (priv->folder_view));
747 /* Connect signals */
748 connect_signals ((ModestMainWindow*)self);
750 /* Set account store */
751 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
752 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
754 /* Load previous osso state, for instance if we are being restored from
756 modest_osso_load_state ();
758 /* Restore window & widget settings */
760 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
762 /* Check if accounts exist and show the account wizard if not */
763 gboolean accounts_exist =
764 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
766 if (!accounts_exist) {
767 /* This is necessary to have the main window shown behind the dialog
768 It's an ugly hack... jschmid */
769 gtk_widget_show_all(GTK_WIDGET(self));
770 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
773 GtkAction *send_receive_all;
774 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
775 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
776 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
777 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
778 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
779 modest_account_mgr_free_account_names (accounts);
786 modest_main_window_new (void)
788 ModestMainWindow *self = NULL;
789 ModestMainWindowPrivate *priv = NULL;
790 ModestWindowPrivate *parent_priv = NULL;
791 GtkWidget *folder_win = NULL;
792 ModestDimmingRulesGroup *menu_rules_group = NULL;
793 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
794 GtkActionGroup *action_group = NULL;
795 GError *error = NULL;
796 ModestConf *conf = NULL;
797 GtkAction *action = NULL;
799 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
800 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
801 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
803 parent_priv->ui_manager = gtk_ui_manager_new();
804 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
806 action_group = gtk_action_group_new ("ModestMainWindowActions");
807 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
809 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
810 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
812 /* Add common actions */
813 gtk_action_group_add_actions (action_group,
814 modest_action_entries,
815 G_N_ELEMENTS (modest_action_entries),
818 gtk_action_group_add_actions (action_group,
819 modest_folder_view_action_entries,
820 G_N_ELEMENTS (modest_folder_view_action_entries),
823 gtk_action_group_add_actions (action_group,
824 modest_header_view_action_entries,
825 G_N_ELEMENTS (modest_header_view_action_entries),
828 gtk_action_group_add_toggle_actions (action_group,
829 modest_toggle_action_entries,
830 G_N_ELEMENTS (modest_toggle_action_entries),
833 gtk_action_group_add_toggle_actions (action_group,
834 modest_main_window_toggle_action_entries,
835 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
838 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
839 g_object_unref (action_group);
841 /* Load the UI definition */
842 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
843 MODEST_UIDIR "modest-main-window-ui.xml", &error);
845 g_warning ("Could not merge modest-ui.xml: %s", error->message);
846 g_error_free (error);
850 /* Add common dimming rules */
851 modest_dimming_rules_group_add_rules (menu_rules_group,
852 modest_main_window_menu_dimming_entries,
853 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
855 modest_dimming_rules_group_add_rules (toolbar_rules_group,
856 modest_main_window_toolbar_dimming_entries,
857 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
860 /* Insert dimming rules group for this window */
861 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
862 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
863 g_object_unref (menu_rules_group);
864 g_object_unref (toolbar_rules_group);
866 /* Add accelerators */
867 gtk_window_add_accel_group (GTK_WINDOW (self),
868 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
870 /* Menubar. Update the state of some toggles */
871 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
872 conf = modest_runtime_get_conf ();
873 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
874 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
875 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
876 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
877 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
878 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
879 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
880 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
881 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
883 /* Get device name */
884 modest_maemo_utils_get_device_name ();
888 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
889 if (!priv->header_view)
890 g_printerr ("modest: cannot instantiate header view\n");
891 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
892 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
893 MODEST_CONF_HEADER_VIEW_KEY);
896 priv->empty_view = create_empty_view ();
898 /* Create scrolled windows */
899 folder_win = gtk_scrolled_window_new (NULL, NULL);
900 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
901 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
903 GTK_POLICY_AUTOMATIC);
904 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
906 GTK_POLICY_AUTOMATIC);
909 priv->main_paned = gtk_hpaned_new ();
910 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
911 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
912 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
914 /* putting it all together... */
915 priv->main_vbox = gtk_vbox_new (FALSE, 6);
916 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
918 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
920 HildonProgram *app = hildon_program_get_instance ();
921 hildon_program_add_window (app, HILDON_WINDOW (self));
923 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
924 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
926 g_signal_connect (G_OBJECT(self), "show",
927 G_CALLBACK (modest_main_window_on_show), folder_win);
930 restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
932 return MODEST_WINDOW(self);
936 modest_main_window_close_all (ModestMainWindow *self)
939 GtkResponseType response;
941 /* Create the confirmation dialog MSG-NOT308 */
942 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
943 _("emev_nc_close_windows"),
944 _("mcen_bd_yes"), GTK_RESPONSE_YES,
945 _("mcen_bd_no"), GTK_RESPONSE_NO,
948 response = gtk_dialog_run (GTK_DIALOG (note));
949 gtk_widget_destroy (GTK_WIDGET (note));
951 if (response == GTK_RESPONSE_YES)
959 modest_main_window_set_style (ModestMainWindow *self,
960 ModestMainWindowStyle style)
962 ModestMainWindowPrivate *priv;
963 ModestWindowPrivate *parent_priv;
966 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
968 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
969 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
971 /* no change -> nothing to do */
972 if (priv->style == style)
975 /* Get toggle button */
976 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
980 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
981 /* Remove main paned */
982 g_object_ref (priv->main_paned);
983 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
985 /* Reparent the contents widget to the main vbox */
986 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
988 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
989 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
990 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
992 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
993 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
994 TnyIterator *iterator = tny_list_create_iterator (selection);
996 tny_iterator_first (iterator);
997 header = TNY_HEADER (tny_iterator_get_current (iterator));
998 if (tny_header_get_subject (header))
999 gtk_window_set_title (GTK_WINDOW(self), tny_header_get_subject (header));
1001 gtk_window_set_title (GTK_WINDOW (self), _("mail_va_no_subject"));
1002 g_object_unref (header);
1003 g_object_unref (iterator);
1004 g_object_unref (selection);
1008 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1009 /* Remove header view */
1010 g_object_ref (priv->contents_widget);
1011 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1013 /* Reparent the main paned */
1014 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1015 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1017 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1018 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1019 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1023 g_return_if_reached ();
1026 /* Let header view grab the focus if it's being shown */
1027 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1028 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1030 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1033 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1036 ModestMainWindowStyle
1037 modest_main_window_get_style (ModestMainWindow *self)
1039 ModestMainWindowPrivate *priv;
1041 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1043 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1050 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1052 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1053 ModestWindowPrivate *parent_priv;
1054 ModestWindowMgr *mgr;
1055 gboolean is_fullscreen;
1056 GtkAction *fs_toggle_action;
1059 mgr = modest_runtime_get_window_mgr ();
1061 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1063 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1065 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1066 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1067 if (is_fullscreen != active) {
1068 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1077 set_homogeneous (GtkWidget *widget,
1080 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1081 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1085 modest_main_window_show_toolbar (ModestWindow *self,
1086 gboolean show_toolbar)
1088 ModestMainWindowPrivate *priv = NULL;
1089 ModestWindowPrivate *parent_priv = NULL;
1090 GtkWidget *reply_button = NULL, *menu = NULL;
1091 GtkWidget *placeholder = NULL;
1094 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1095 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1096 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1098 /* Set optimized view status */
1099 priv->optimized_view = !show_toolbar;
1101 if (!parent_priv->toolbar) {
1102 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1105 /* Set homogeneous toolbar */
1106 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1107 set_homogeneous, NULL);
1109 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1110 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1111 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1112 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1113 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1114 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1115 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1116 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1118 /* Add ProgressBar (Transfer toolbar) */
1119 priv->progress_bar = modest_progress_bar_widget_new ();
1120 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1121 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1122 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1123 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1124 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1126 /* Connect cancel 'clicked' signal to abort progress mode */
1127 g_signal_connect(priv->cancel_toolitem, "clicked",
1128 G_CALLBACK(cancel_progressbar),
1131 /* Add it to the observers list */
1132 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1135 hildon_window_add_toolbar (HILDON_WINDOW (self),
1136 GTK_TOOLBAR (parent_priv->toolbar));
1138 /* Set reply button tap and hold menu */
1139 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1140 "/ToolBar/ToolbarMessageReply");
1141 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1142 "/ToolbarReplyCSM");
1143 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1145 /* Set send & receive button tap and hold menu */
1146 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1151 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1152 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1153 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1155 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1156 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1158 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1163 compare_display_names (ModestAccountData *a,
1164 ModestAccountData *b)
1166 return strcmp (a->display_name, b->display_name);
1170 on_account_update (TnyAccountStore *account_store,
1171 const gchar *account_name,
1174 GSList *account_names, *iter, *accounts;
1175 ModestMainWindow *self;
1176 ModestMainWindowPrivate *priv;
1177 ModestWindowPrivate *parent_priv;
1178 ModestAccountMgr *mgr;
1179 gint i, num_accounts;
1180 GtkActionGroup *action_group;
1182 gchar *default_account;
1183 GtkWidget *send_receive_button, *item;
1184 GtkAction *send_receive_all = NULL;
1186 self = MODEST_MAIN_WINDOW (user_data);
1187 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1188 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1190 /* Get enabled account IDs */
1191 mgr = modest_runtime_get_account_mgr ();
1192 account_names = modest_account_mgr_account_names (mgr, TRUE);
1193 iter = account_names;
1197 ModestAccountData *account_data =
1198 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1199 accounts = g_slist_prepend (accounts, account_data);
1203 modest_account_mgr_free_account_names (account_names);
1204 account_names = NULL;
1206 /* Order the list of accounts by its display name */
1207 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1208 num_accounts = g_slist_length (accounts);
1210 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1211 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1212 gtk_action_set_visible (send_receive_all, num_accounts > 1);
1214 /* Delete old send&receive popup items. We can not just do a
1215 menu_detach because it does not work well with
1217 if (priv->accounts_popup)
1218 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
1219 (GtkCallback) gtk_widget_destroy, NULL);
1221 /* Delete old entries in the View menu. Do not free groups, it
1223 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1225 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1226 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1227 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
1228 GTK_ACTION_GROUP (groups->data));
1231 if (priv->merge_ids) {
1232 for (i = 0; i < priv->merge_ids->len; i++)
1233 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1234 g_byte_array_free (priv->merge_ids, TRUE);
1236 /* We need to call this in order to ensure
1237 that the new actions are added in the right
1238 order (alphabetical */
1239 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1241 groups = g_list_next (groups);
1243 priv->merge_ids = g_byte_array_sized_new (num_accounts);
1245 /* Get send receive button */
1246 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1247 "/ToolBar/ToolbarSendReceive");
1249 /* Create the menu */
1250 if (num_accounts > 1) {
1251 if (!priv->accounts_popup)
1252 priv->accounts_popup = gtk_menu_new ();
1253 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1254 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1255 g_signal_connect (G_OBJECT (item),
1257 G_CALLBACK (on_send_receive_csm_activated),
1259 item = gtk_separator_menu_item_new ();
1260 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1263 /* Create a new action group */
1264 default_account = modest_account_mgr_get_default_account (mgr);
1265 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1266 for (i = 0; i < num_accounts; i++) {
1267 gchar *display_name = NULL;
1269 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1271 /* Create display name. The default account is shown differently */
1272 if (default_account && account_data->account_name &&
1273 !(strcmp (default_account, account_data->account_name) == 0)) {
1274 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
1275 account_data->display_name);
1278 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
1279 account_data->display_name);
1282 /* Create action and add it to the action group. The
1283 action name must be the account name, this way we
1284 could know in the handlers the account to show */
1285 if(account_data->account_name) {
1286 gchar* item_name, *refresh_action_name;
1288 GtkAction *view_account_action, *refresh_account_action;
1290 view_account_action = gtk_action_new (account_data->account_name,
1291 display_name, NULL, NULL);
1292 gtk_action_group_add_action (action_group, view_account_action);
1294 /* Add ui from account data. We allow 2^9-1 account
1295 changes in a single execution because we're
1296 downcasting the guint to a guint8 in order to use a
1297 GByteArray, it should be enough */
1298 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1299 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1300 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1301 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1303 "/MenuBar/ViewMenu/ViewMenuAdditions",
1305 account_data->account_name,
1306 GTK_UI_MANAGER_MENUITEM,
1309 /* Connect the action signal "activate" */
1310 g_signal_connect (G_OBJECT (view_account_action),
1312 G_CALLBACK (on_show_account_action_activated),
1315 /* Create the items for the Tools->Send&Receive submenu */
1316 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1317 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
1318 display_name, NULL, NULL);
1319 gtk_action_group_add_action (action_group, refresh_account_action);
1321 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1322 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1323 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1325 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1327 refresh_action_name,
1328 GTK_UI_MANAGER_MENUITEM,
1330 g_free (refresh_action_name);
1332 g_signal_connect_data (G_OBJECT (refresh_account_action),
1334 G_CALLBACK (on_refresh_account_action_activated),
1335 g_strdup (account_data->account_name),
1336 (GClosureNotify) g_free,
1339 /* Create item and add it to the send&receive
1340 CSM. If there is only one account then
1342 if (priv->accounts_popup) {
1343 item = gtk_menu_item_new_with_label (display_name);
1344 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1345 g_signal_connect_data (G_OBJECT (item),
1347 G_CALLBACK (on_send_receive_csm_activated),
1348 g_strdup (account_data->account_name),
1349 (GClosureNotify) g_free,
1356 g_free (display_name);
1357 modest_account_mgr_free_account_data (mgr, account_data);
1359 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1361 if (priv->accounts_popup) {
1362 /* Mandatory in order to view the menu contents */
1363 gtk_widget_show_all (priv->accounts_popup);
1365 /* Setup tap_and_hold just if was not done before*/
1366 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1367 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1371 g_slist_free (accounts);
1372 g_free (default_account);
1376 * This function manages the key events used to navigate between
1377 * header and folder views (when the window is in split view)
1380 * -------------------------------------------------
1381 * HeaderView GDK_Left Move focus to folder view
1382 * FolderView GDK_Right Move focus to header view
1384 * There is no need to scroll to selected row, the widgets will be the
1385 * responsibles of doing that (probably managing the focus-in event
1388 on_inner_widgets_key_pressed (GtkWidget *widget,
1392 ModestMainWindowPrivate *priv;
1394 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1396 /* Do nothing if we're in SIMPLE style */
1397 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1400 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1401 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1402 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1403 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1409 set_alignment (GtkWidget *widget,
1412 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1413 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1417 create_empty_view (void)
1419 GtkLabel *label = NULL;
1420 GtkWidget *align = NULL;
1422 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1423 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1424 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1425 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1427 return GTK_WIDGET(align);
1431 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1433 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1438 gchar *gray_color_markup;
1440 vbox = gtk_vbox_new (FALSE, 0);
1442 /* Obtain the secondary text color. We need a realized widget, that's why
1443 we get styled_widget from outside */
1444 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1446 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1447 gray_color_markup = modest_text_utils_get_color_string (&color);
1449 // gray_color_markup is freed below
1450 gray_color_markup = g_strdup ("#BBBBBB");
1452 /* Account description: */
1454 if (modest_tny_account_is_virtual_local_folders (account)
1455 || (modest_tny_account_is_memory_card_account (account))) {
1457 /* Local folders: */
1459 /* Get device name */
1460 gchar *device_name = NULL;
1461 if (modest_tny_account_is_virtual_local_folders (account))
1462 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1463 MODEST_CONF_DEVICE_NAME, NULL);
1465 device_name = g_strdup (tny_account_get_name (account));
1467 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1468 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1469 gray_color_markup, tmp, device_name);
1471 label_w = gtk_label_new (NULL);
1472 gtk_label_set_markup (GTK_LABEL (label_w), label);
1473 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1474 g_free (device_name);
1477 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1478 gtk_box_pack_start (GTK_BOX (vbox),
1479 gtk_label_new (tny_account_get_name (account)),
1482 /* Other accounts, such as IMAP and POP: */
1487 /* Put proto in uppercase */
1488 proto = g_string_new (tny_account_get_proto (account));
1489 proto = g_string_ascii_up (proto);
1491 /* note: mcen_fi_localroot_description is something like "%s account"
1492 * however, we should display "%s account: %s"... therefore, ugly tmp */
1493 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1494 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1495 gray_color_markup, tmp, tny_account_get_name (account));
1498 label_w = gtk_label_new (NULL);
1499 gtk_label_set_markup (GTK_LABEL (label_w), label);
1500 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1501 g_string_free (proto, TRUE);
1507 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1508 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1509 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1510 modest_tny_folder_store_get_message_count (folder_store));
1511 label_w = gtk_label_new (NULL);
1512 gtk_label_set_markup (GTK_LABEL (label_w), label);
1513 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1517 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1519 _("mcen_fi_rootfolder_folders"),
1520 modest_tny_folder_store_get_folder_count (folder_store));
1521 label_w = gtk_label_new (NULL);
1522 gtk_label_set_markup (GTK_LABEL (label_w), label);
1523 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1527 if (modest_tny_account_is_virtual_local_folders (account)
1528 || modest_tny_account_is_memory_card_account (account)) {
1529 /* FIXME: format size */
1530 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1531 gray_color_markup, _("mcen_fi_rootfolder_size"),
1532 modest_tny_folder_store_get_local_size (folder_store));
1533 label_w = gtk_label_new (NULL);
1534 gtk_label_set_markup (GTK_LABEL (label_w), label);
1535 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1537 } else if (TNY_IS_ACCOUNT(folder_store)) {
1538 TnyAccount *account = TNY_ACCOUNT(folder_store);
1540 time_t last_updated;
1541 gchar *last_updated_string;
1542 /* Get last updated from configuration */
1543 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1544 tny_account_get_id (account),
1545 MODEST_ACCOUNT_LAST_UPDATED,
1547 if (last_updated > 0)
1548 last_updated_string = modest_text_utils_get_display_date(last_updated);
1550 last_updated_string = g_strdup (_("mcen_va_never"));
1552 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1553 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1554 label_w = gtk_label_new (NULL);
1555 gtk_label_set_markup (GTK_LABEL (label_w), label);
1556 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1557 g_free (last_updated_string);
1561 g_free (gray_color_markup);
1564 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1570 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1572 ModestMainWindowPrivate *priv = NULL;
1574 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1576 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1578 return priv->send_receive_in_progress;
1582 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1584 GtkAction *action = NULL;
1585 GtkWidget *widget = NULL;
1586 ModestMainWindowPrivate *priv = NULL;
1588 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1589 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1591 priv->send_receive_in_progress = TRUE;
1593 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1594 gtk_action_set_sensitive (action, FALSE);
1595 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1596 /* gtk_action_set_sensitive (action, FALSE); */
1597 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1598 gtk_widget_set_sensitive (widget, FALSE);
1602 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1604 GtkAction *action = NULL;
1605 GtkWidget *widget = NULL;
1606 ModestMainWindowPrivate *priv = NULL;
1608 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1609 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1611 priv->send_receive_in_progress = FALSE;
1613 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1614 gtk_action_set_sensitive (action, TRUE);
1615 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1616 /* gtk_action_set_sensitive (action, TRUE); */
1617 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1618 gtk_widget_set_sensitive (widget, TRUE);
1623 _on_msg_count_changed (ModestHeaderView *header_view,
1625 TnyFolderChange *change,
1626 ModestMainWindow *main_window)
1628 printf ("DEBUG: %s\n", __FUNCTION__);
1629 gboolean folder_empty = FALSE;
1630 TnyFolderChangeChanged changed;
1632 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1633 g_return_if_fail (TNY_IS_FOLDER(folder));
1634 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1636 changed = tny_folder_change_get_changed (change);
1638 /* If something changes */
1639 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1640 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1642 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1644 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1646 /* Set contents style of headers view */
1648 modest_main_window_set_contents_style (main_window,
1649 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1652 modest_main_window_set_contents_style (main_window,
1653 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1658 modest_main_window_set_contents_style (ModestMainWindow *self,
1659 ModestMainWindowContentsStyle style)
1661 ModestMainWindowPrivate *priv;
1663 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1665 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1667 /* We allow to set the same content style than the previously
1668 set if there are details, because it could happen when we're
1669 selecting different accounts consecutively */
1670 if ((priv->contents_style == style) &&
1671 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1674 /* Remove previous child. Delete it if it was an account
1676 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1678 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1679 g_object_ref (content);
1680 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1681 g_object_ref (priv->empty_view);
1682 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1685 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1688 priv->contents_style = style;
1690 switch (priv->contents_style) {
1691 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1692 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1694 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1696 TnyFolderStore *selected_folderstore =
1697 modest_folder_view_get_selected (priv->folder_view);
1698 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1699 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1700 TNY_ACCOUNT (selected_folderstore));
1702 wrap_in_scrolled_window (priv->contents_widget,
1703 priv->details_widget);
1705 g_object_unref (selected_folderstore);
1708 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1709 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1712 g_return_if_reached ();
1716 gtk_widget_show_all (priv->contents_widget);
1719 ModestMainWindowContentsStyle
1720 modest_main_window_get_contents_style (ModestMainWindow *self)
1722 ModestMainWindowPrivate *priv;
1724 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1726 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1727 return priv->contents_style;
1732 on_configuration_key_changed (ModestConf* conf,
1734 ModestConfEvent event,
1735 ModestMainWindow *self)
1737 ModestMainWindowPrivate *priv;
1738 TnyAccount *account;
1740 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1743 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1745 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1748 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1749 if (TNY_IS_ACCOUNT (account) &&
1750 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1753 const gchar *device_name;
1757 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1758 label = GTK_LABEL (children->data);
1760 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1761 MODEST_CONF_DEVICE_NAME, NULL);
1763 new_text = g_strdup_printf ("%s: %s",
1764 _("mcen_fi_localroot_description"),
1767 gtk_label_set_text (label, new_text);
1768 gtk_widget_show (GTK_WIDGET (label));
1771 g_list_free (children);
1773 g_object_unref (account);
1777 set_toolbar_transfer_mode (ModestMainWindow *self)
1779 ModestMainWindowPrivate *priv = NULL;
1781 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1783 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1785 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1787 if (priv->progress_bar_timeout > 0) {
1788 g_source_remove (priv->progress_bar_timeout);
1789 priv->progress_bar_timeout = 0;
1796 set_toolbar_mode (ModestMainWindow *self,
1797 ModestToolBarModes mode)
1799 ModestWindowPrivate *parent_priv = NULL;
1800 ModestMainWindowPrivate *priv = NULL;
1801 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1803 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1805 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1806 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1808 /* In case this was called before the toolbar exists: */
1809 if (!(parent_priv->toolbar))
1812 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1814 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1815 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1816 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1818 /* Sets current toolbar mode */
1819 priv->current_toolbar_mode = mode;
1821 /* Show and hide toolbar items */
1823 case TOOLBAR_MODE_NORMAL:
1825 gtk_action_set_visible (sort_action, TRUE);
1827 gtk_action_set_visible (refresh_action, TRUE);
1828 if (priv->progress_toolitem) {
1829 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1830 gtk_widget_hide (priv->progress_toolitem);
1832 if (priv->progress_bar)
1833 gtk_widget_hide (priv->progress_bar);
1836 gtk_action_set_visible (cancel_action, FALSE);
1837 /* if (priv->sort_toolitem) */
1838 /* gtk_widget_show (priv->sort_toolitem); */
1840 /* if (priv->refresh_toolitem) */
1841 /* gtk_widget_show (priv->refresh_toolitem); */
1843 /* if (priv->progress_toolitem) */
1844 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1845 /* if (priv->progress_bar) */
1846 /* gtk_widget_hide (priv->progress_bar); */
1848 /* if (priv->cancel_toolitem) */
1849 /* gtk_widget_hide (priv->cancel_toolitem); */
1851 /* Hide toolbar if optimized view is enabled */
1852 if (priv->optimized_view)
1853 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1855 case TOOLBAR_MODE_TRANSFER:
1857 gtk_action_set_visible (sort_action, FALSE);
1859 gtk_action_set_visible (refresh_action, FALSE);
1861 gtk_action_set_visible (cancel_action, TRUE);
1862 if (priv->progress_toolitem) {
1863 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1864 gtk_widget_show (priv->progress_toolitem);
1866 if (priv->progress_bar)
1867 gtk_widget_show (priv->progress_bar);
1869 /* if (priv->sort_toolitem) */
1870 /* gtk_widget_hide (priv->sort_toolitem); */
1872 /* if (priv->refresh_toolitem) */
1873 /* gtk_widget_hide (priv->refresh_toolitem); */
1875 /* if (priv->progress_toolitem) */
1876 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1877 /* if (priv->progress_bar) */
1878 /* gtk_widget_show (priv->progress_bar); */
1880 /* if (priv->cancel_toolitem) */
1881 /* gtk_widget_show (priv->cancel_toolitem); */
1883 /* Show toolbar if it's hiden (optimized view ) */
1884 if (priv->optimized_view)
1885 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1888 g_return_if_reached ();
1893 cancel_progressbar (GtkToolButton *toolbutton,
1894 ModestMainWindow *self)
1897 ModestMainWindowPrivate *priv;
1899 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1901 /* Get operation observers and cancel its current operation */
1902 tmp = priv->progress_widgets;
1904 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1905 tmp=g_slist_next(tmp);
1910 observers_empty (ModestMainWindow *self)
1913 ModestMainWindowPrivate *priv;
1914 gboolean is_empty = TRUE;
1915 guint pending_ops = 0;
1917 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1918 tmp = priv->progress_widgets;
1920 /* Check all observers */
1921 while (tmp && is_empty) {
1922 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1923 is_empty = pending_ops == 0;
1925 tmp = g_slist_next(tmp);
1932 on_queue_changed (ModestMailOperationQueue *queue,
1933 ModestMailOperation *mail_op,
1934 ModestMailOperationQueueNotification type,
1935 ModestMainWindow *self)
1937 ModestMainWindowPrivate *priv;
1938 ModestMailOperationTypeOperation op_type;
1939 ModestToolBarModes mode;
1941 gboolean mode_changed = FALSE;
1942 /* ModestMailOperationStatus status; */
1944 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1945 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1947 /* Get toolbar mode from operation id*/
1948 op_type = modest_mail_operation_get_type_operation (mail_op);
1950 case MODEST_MAIL_OPERATION_TYPE_SEND:
1951 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1952 case MODEST_MAIL_OPERATION_TYPE_OPEN:
1953 mode = TOOLBAR_MODE_TRANSFER;
1954 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1955 mode_changed = TRUE;
1958 mode = TOOLBAR_MODE_NORMAL;
1963 /* Add operation observers and change toolbar if neccessary*/
1964 tmp = priv->progress_widgets;
1966 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1967 if (mode == TOOLBAR_MODE_TRANSFER) {
1969 set_toolbar_transfer_mode(self);
1971 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1973 tmp = g_slist_next (tmp);
1977 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1978 /* Change toolbar mode */
1979 if (mode == TOOLBAR_MODE_TRANSFER) {
1981 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1983 tmp = g_slist_next (tmp);
1986 /* If no more operations are being observed, NORMAL mode is enabled again */
1987 if (observers_empty (self)) {
1988 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1999 on_show_account_action_activated (GtkAction *action,
2002 ModestAccountData *acc_data;
2003 ModestMainWindow *self;
2004 ModestMainWindowPrivate *priv;
2005 ModestAccountMgr *mgr;
2006 const gchar *acc_name;
2008 self = MODEST_MAIN_WINDOW (user_data);
2009 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2011 /* Get account data */
2012 acc_name = gtk_action_get_name (action);
2013 mgr = modest_runtime_get_account_mgr ();
2014 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2016 /* Set the new visible & active account */
2017 if (acc_data->store_account) {
2018 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2019 acc_data->store_account->account_name);
2020 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2024 modest_account_mgr_free_account_data (mgr, acc_data);
2028 refresh_account (const gchar *account_name)
2032 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2034 /* If account_name == NULL, we must update all (option All) */
2036 modest_ui_actions_do_send_receive_all (win);
2038 modest_ui_actions_do_send_receive (account_name, win);
2043 on_refresh_account_action_activated (GtkAction *action,
2046 refresh_account ((const gchar*) user_data);
2050 on_send_receive_csm_activated (GtkMenuItem *item,
2053 refresh_account ((const gchar*) user_data);
2057 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2059 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2061 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2067 on_folder_view_focus_in (GtkWidget *widget,
2068 GdkEventFocus *event,
2075 on_header_view_focus_in (GtkWidget *widget,
2076 GdkEventFocus *event,
2079 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (userdata);
2080 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2082 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
2083 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
2084 TnyIterator *iterator = tny_list_create_iterator (selection);
2087 tny_iterator_first (iterator);
2088 header = TNY_HEADER (tny_iterator_get_current (iterator));
2090 if (tny_header_get_subject (header))
2091 gtk_window_set_title (GTK_WINDOW(main_window), tny_header_get_subject (header));
2093 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
2095 g_object_unref (header);
2096 g_object_unref (iterator);
2097 g_object_unref (selection);
2103 modest_main_window_on_folder_selection_changed (ModestFolderView *folder_view,
2104 TnyFolderStore *folder_store,
2106 ModestMainWindow *main_window)
2108 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (main_window);
2109 GtkAction *action = NULL;
2110 gboolean show_reply = TRUE;
2111 gboolean show_forward = TRUE;
2112 gboolean show_cancel_send = FALSE;
2113 gboolean show_clipboard = TRUE;
2114 gboolean show_delete = TRUE;
2117 if (TNY_IS_ACCOUNT (folder_store)) {
2118 show_reply = show_forward = show_cancel_send = show_clipboard = show_delete = FALSE;
2119 } else if (TNY_IS_FOLDER (folder_store)) {
2120 if (modest_tny_folder_is_local_folder (TNY_FOLDER (folder_store))) {
2121 TnyFolderType folder_type = modest_tny_folder_get_local_folder_type (
2122 TNY_FOLDER (folder_store));
2123 switch (folder_type) {
2124 case TNY_FOLDER_TYPE_DRAFTS:
2125 show_clipboard = show_delete = TRUE;
2126 show_reply = show_forward = show_cancel_send = FALSE;
2128 case TNY_FOLDER_TYPE_SENT:
2129 show_forward = show_clipboard = show_delete = TRUE;
2130 show_reply = show_cancel_send = FALSE;
2132 case TNY_FOLDER_TYPE_OUTBOX:
2133 show_clipboard = show_delete = show_cancel_send = TRUE;
2134 show_reply = show_forward = FALSE;
2137 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2138 show_cancel_send = FALSE;
2141 show_reply = show_forward = show_clipboard = show_delete = TRUE;
2142 show_cancel_send = FALSE;
2147 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReply");
2148 gtk_action_set_visible (action, show_reply);
2149 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMReplyAll");
2150 gtk_action_set_visible (action, show_reply);
2151 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMForward");
2152 gtk_action_set_visible (action, show_forward);
2153 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCancelSending");
2154 gtk_action_set_visible (action, show_cancel_send);
2155 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCut");
2156 gtk_action_set_visible (action, show_clipboard);
2157 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMCopy");
2158 gtk_action_set_visible (action, show_clipboard);
2159 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMPaste");
2160 gtk_action_set_visible (action, show_clipboard);
2161 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/HeaderViewCSM/HeaderViewCSMDelete");
2162 gtk_action_set_visible (action, show_delete);
2164 /* We finally call to the ui actions handler, after updating properly
2165 * the header view CSM */
2166 modest_ui_actions_on_folder_selection_changed (folder_view, folder_store, selected, main_window);