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-conf.h"
54 #include <modest-maemo-utils.h>
55 #include "modest-tny-platform-factory.h"
56 #include "modest-tny-msg.h"
57 #include "modest-mail-operation.h"
58 #include "modest-icon-names.h"
59 #include "modest-progress-bar-widget.h"
60 #include "modest-text-utils.h"
61 #include "modest-ui-dimming-manager.h"
62 #include "maemo/modest-osso-state-saving.h"
64 #ifdef MODEST_HAVE_HILDON0_WIDGETS
65 #include <hildon-widgets/hildon-program.h>
67 #include <hildon/hildon-program.h>
68 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
70 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
77 /* 'private'/'protected' functions */
78 static void modest_main_window_class_init (ModestMainWindowClass *klass);
79 static void modest_main_window_init (ModestMainWindow *obj);
80 static void modest_main_window_finalize (GObject *obj);
81 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
82 GdkEventWindowState *event,
85 static void connect_signals (ModestMainWindow *self);
87 static void restore_settings (ModestMainWindow *self, gboolean do_folder_view_too);
88 static void save_state (ModestWindow *self);
90 static void modest_main_window_show_toolbar (ModestWindow *window,
91 gboolean show_toolbar);
93 static void cancel_progressbar (GtkToolButton *toolbutton,
94 ModestMainWindow *self);
96 static void on_queue_changed (ModestMailOperationQueue *queue,
97 ModestMailOperation *mail_op,
98 ModestMailOperationQueueNotification type,
99 ModestMainWindow *self);
101 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
103 static void on_account_update (TnyAccountStore *account_store,
104 const gchar *account_name,
107 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
111 static void on_configuration_key_changed (ModestConf* conf,
113 ModestConfEvent event,
114 ModestMainWindow *self);
116 static void set_toolbar_mode (ModestMainWindow *self,
117 ModestToolBarModes mode);
119 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
121 static void on_show_account_action_activated (GtkAction *action,
124 static void on_refresh_account_action_activated (GtkAction *action,
127 static void on_send_receive_csm_activated (GtkMenuItem *item,
131 _on_msg_count_changed (ModestHeaderView *header_view,
133 TnyFolderChange *change,
134 ModestMainWindow *main_window);
137 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
140 static GtkWidget * create_empty_view (void);
143 /* list my signals */
150 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
151 struct _ModestMainWindowPrivate {
152 GtkWidget *msg_paned;
153 GtkWidget *main_paned;
154 GtkWidget *main_vbox;
155 GtkWidget *contents_widget;
156 GtkWidget *empty_view;
158 /* Progress observers */
159 GtkWidget *progress_bar;
160 GSList *progress_widgets;
163 GtkWidget *progress_toolitem;
164 GtkWidget *cancel_toolitem;
165 GtkWidget *sort_toolitem;
166 GtkWidget *refresh_toolitem;
167 ModestToolBarModes current_toolbar_mode;
169 /* Merge ids used to add/remove accounts to the ViewMenu*/
170 GByteArray *merge_ids;
172 /* On-demand widgets */
173 GtkWidget *accounts_popup;
174 GtkWidget *details_widget;
176 /* Optimized view enabled */
177 gboolean optimized_view;
179 /* Optimized view enabled */
180 gboolean send_receive_in_progress;
182 ModestHeaderView *header_view;
183 ModestFolderView *folder_view;
185 ModestMainWindowStyle style;
186 ModestMainWindowContentsStyle contents_style;
188 guint progress_bar_timeout;
190 /* Signal handler UIDs */
191 gint queue_changed_handler_uid;
192 GList *queue_err_signals;
194 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
195 MODEST_TYPE_MAIN_WINDOW, \
196 ModestMainWindowPrivate))
198 typedef struct _GetMsgAsyncHelper {
199 ModestMainWindowPrivate *main_window_private;
201 ModestTnyMsgReplyType reply_type;
202 ModestTnyMsgForwardType forward_type;
209 static GtkWindowClass *parent_class = NULL;
212 /* Private actions */
213 /* This is the context sensitive menu: */
214 static const GtkActionEntry modest_folder_view_action_entries [] = {
216 /* Folder View CSM actions */
217 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
218 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
219 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
220 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
221 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
222 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
225 static const GtkActionEntry modest_header_view_action_entries [] = {
227 /* Header View CSM actions */
228 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
229 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
230 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
231 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
232 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
233 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
234 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
235 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) },
236 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, NULL },
237 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
240 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
241 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
244 /************************************************************************/
247 modest_main_window_get_type (void)
249 static GType my_type = 0;
251 static const GTypeInfo my_info = {
252 sizeof(ModestMainWindowClass),
253 NULL, /* base init */
254 NULL, /* base finalize */
255 (GClassInitFunc) modest_main_window_class_init,
256 NULL, /* class finalize */
257 NULL, /* class data */
258 sizeof(ModestMainWindow),
260 (GInstanceInitFunc) modest_main_window_init,
263 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
271 modest_main_window_class_init (ModestMainWindowClass *klass)
273 GObjectClass *gobject_class;
274 gobject_class = (GObjectClass*) klass;
275 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
277 parent_class = g_type_class_peek_parent (klass);
278 gobject_class->finalize = modest_main_window_finalize;
280 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
282 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
283 modest_window_class->save_state_func = save_state;
284 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
285 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
289 modest_main_window_init (ModestMainWindow *obj)
291 ModestMainWindowPrivate *priv;
293 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
295 priv->queue_err_signals = NULL;
296 priv->msg_paned = NULL;
297 priv->main_paned = NULL;
298 priv->main_vbox = NULL;
299 priv->header_view = NULL;
300 priv->folder_view = NULL;
301 priv->contents_widget = NULL;
302 priv->accounts_popup = NULL;
303 priv->details_widget = NULL;
304 priv->empty_view = NULL;
305 priv->progress_widgets = NULL;
306 priv->progress_bar = NULL;
307 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
308 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
309 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
310 priv->merge_ids = NULL;
311 priv->optimized_view = FALSE;
312 priv->send_receive_in_progress = FALSE;
313 priv->progress_bar_timeout = 0;
314 priv->queue_changed_handler_uid = 0;
318 modest_main_window_finalize (GObject *obj)
320 ModestMainWindowPrivate *priv;
322 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
324 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
326 g_slist_free (priv->progress_widgets);
328 g_byte_array_free (priv->merge_ids, TRUE);
330 if (priv->progress_bar_timeout > 0) {
331 g_source_remove (priv->progress_bar_timeout);
332 priv->progress_bar_timeout = 0;
335 /* Disconnect signal handlers */
336 if (priv->queue_changed_handler_uid)
337 g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
338 priv->queue_changed_handler_uid);
340 G_OBJECT_CLASS(parent_class)->finalize (obj);
344 modest_main_window_get_child_widget (ModestMainWindow *self,
345 ModestWidgetType widget_type)
347 ModestMainWindowPrivate *priv;
350 g_return_val_if_fail (self, NULL);
351 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
354 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
356 switch (widget_type) {
357 case MODEST_WIDGET_TYPE_HEADER_VIEW:
358 widget = (GtkWidget*)priv->header_view; break;
359 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
360 widget = (GtkWidget*)priv->folder_view; break;
365 return widget ? GTK_WIDGET(widget) : NULL;
370 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
373 ModestMainWindowPrivate *priv;
375 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
377 conf = modest_runtime_get_conf ();
379 modest_widget_memory_restore (conf, G_OBJECT(self),
380 MODEST_CONF_MAIN_WINDOW_KEY);
382 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
383 MODEST_CONF_HEADER_VIEW_KEY);
385 if (do_folder_view_too)
386 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
387 MODEST_CONF_FOLDER_VIEW_KEY);
389 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
390 MODEST_CONF_MAIN_PANED_KEY);
392 /* We need to force a redraw here in order to get the right
393 position of the horizontal paned separator */
394 gtk_widget_show (GTK_WIDGET (self));
399 save_state (ModestWindow *window)
402 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
403 ModestMainWindowPrivate *priv;
405 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
406 conf = modest_runtime_get_conf ();
408 modest_widget_memory_save (conf,G_OBJECT(self),
409 MODEST_CONF_MAIN_WINDOW_KEY);
410 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
411 MODEST_CONF_MAIN_PANED_KEY);
412 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
413 // MODEST_CONF_HEADER_VIEW_KEY);
414 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
415 MODEST_CONF_FOLDER_VIEW_KEY);
419 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
421 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
422 gtk_scrolled_window_add_with_viewport
423 (GTK_SCROLLED_WINDOW(win), widget);
425 gtk_container_add (GTK_CONTAINER(win),
431 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
433 modest_window_save_state (MODEST_WINDOW(self));
439 ModestMainWindow *self;
445 on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
447 OnResponseInfo *info = (OnResponseInfo *) user_data;
448 ModestMainWindow *self = info->self;
449 TnyHeader *header = info->header;
450 TnySendQueue *queue = info->queue;
452 if (arg1 == GTK_RESPONSE_YES) {
453 TnyFolder *outbox = tny_send_queue_get_outbox (queue);
454 tny_folder_remove_msg (outbox, header, NULL);
455 tny_folder_sync (outbox, TRUE, NULL);
456 g_object_unref (outbox);
459 g_object_unref (queue);
460 g_object_unref (header);
461 g_object_unref (self);
463 gtk_widget_destroy (GTK_WIDGET (dialog));
464 g_slice_free (OnResponseInfo, info);
469 on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
472 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
473 err->message, tny_header_get_subject (header));
474 OnResponseInfo *info = g_slice_new (OnResponseInfo);
475 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
476 GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
478 info->queue = g_object_ref (self);
479 info->self = g_object_ref (user_data);
480 info->header = g_object_ref (header);
481 g_signal_connect (G_OBJECT (dialog), "response",
482 G_CALLBACK (on_response), info);
483 gtk_widget_show_all (dialog);
493 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
495 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
497 GList *oerrsignals = priv->queue_err_signals;
498 while (oerrsignals) {
499 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
500 g_signal_handler_disconnect (esignal->queue, esignal->signal);
501 g_slice_free (QueueErrorSignal, esignal);
502 oerrsignals = g_list_next (oerrsignals);
504 g_list_free (priv->queue_err_signals);
505 priv->queue_err_signals = NULL;
509 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
511 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
513 /* When going online, do the equivalent of pressing the send/receive button,
514 * as per the specification:
515 * (without the check for >0 accounts, though that is not specified): */
517 TnyDevice *device = tny_account_store_get_device (store);
519 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
521 /* Check that we are really online.
522 * This signal should not be emitted when we are not connected,
523 * but it seems to happen sometimes: */
524 if (!tny_device_is_online (device))
527 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
528 printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
530 /* Stop the existing send queues: */
531 modest_runtime_remove_all_send_queues ();
533 /* Create the send queues again, using the appropriate transport accounts
534 * for this new connection.
535 * This could be the first time that they are created if this is the first
537 /* TODO: Does this really destroy the TnySendQueues and their threads
538 * We do not want 2 TnySendQueues to exist with the same underlying
539 * outbox directory. */
541 modest_main_window_cleanup_queue_error_signals (self);
543 GSList *account_names = modest_account_mgr_account_names (
544 modest_runtime_get_account_mgr(),
545 TRUE /* enabled accounts only */);
546 GSList *iter = account_names;
548 const gchar *account_name = (const gchar*)(iter->data);
550 TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
551 modest_tny_account_store_get_transport_account_for_open_connection
552 (modest_runtime_get_account_store(), account_name));
554 /* Q: Is this the first location where the send-queues are requested? */
555 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
556 printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name,
557 tny_account_get_id(TNY_ACCOUNT(account)));
558 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
559 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
560 G_CALLBACK (on_sendqueue_error_happened), self);
561 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
565 iter = g_slist_next (iter);
568 modest_account_mgr_free_account_names (account_names);
569 account_names = NULL;
571 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
575 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
577 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
580 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
584 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
586 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
588 /* Update visibility */
591 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
595 connect_signals (ModestMainWindow *self)
597 ModestWindowPrivate *parent_priv;
598 ModestMainWindowPrivate *priv;
601 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
602 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
605 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
606 G_CALLBACK(on_inner_widgets_key_pressed), self);
607 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
608 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
609 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
610 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
612 /* Folder view CSM */
613 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
614 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
615 g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
616 G_CALLBACK(_folder_view_csm_menu_activated),
619 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
620 G_CALLBACK(modest_ui_actions_on_header_selected), self);
621 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
622 G_CALLBACK(modest_ui_actions_on_header_activated), self);
623 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
624 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
625 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
626 G_CALLBACK(on_inner_widgets_key_pressed), self);
627 g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
628 G_CALLBACK(_on_msg_count_changed), self);
630 /* Header view CSM */
631 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
632 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
633 g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
634 G_CALLBACK(_header_view_csm_menu_activated),
638 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
639 g_signal_connect (G_OBJECT (self), "window-state-event",
640 G_CALLBACK (modest_main_window_window_state_event),
643 /* Mail Operation Queue */
644 priv->queue_changed_handler_uid =
645 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
646 "queue-changed", G_CALLBACK (on_queue_changed), self);
648 /* Track changes in the device name */
649 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
650 "key_changed", G_CALLBACK (on_configuration_key_changed),
653 /* Track account changes. We need to refresh the toolbar */
654 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
655 "account_update", G_CALLBACK (on_account_update),
659 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()),
660 "password_requested",
661 G_CALLBACK (modest_ui_actions_on_password_requested), self);
664 g_signal_connect (G_OBJECT(modest_runtime_get_account_store()),
665 "connecting-finished",
666 G_CALLBACK(on_account_store_connecting_finished), self);
670 /** Idle handler, to send/receive at startup .*/
672 sync_accounts_cb (ModestMainWindow *win)
674 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
675 return FALSE; /* Do not call this idle handler again. */
679 static void on_hildon_program_is_topmost_notify(GObject *self,
680 GParamSpec *propert_param, gpointer user_data)
682 HildonProgram *app = HILDON_PROGRAM (self);
685 ModestWindow* self = MODEST_WINDOW(user_data);
688 /* Note that use of hildon_program_set_can_hibernate()
689 * is generally referred to as "setting the killable flag",
690 * though hibernation does not seem equal to death.
693 if (hildon_program_get_is_topmost (app)) {
694 /* Prevent hibernation when the progam comes to the foreground,
695 * because hibernation should only happen when the application
696 * is in the background: */
697 hildon_program_set_can_hibernate (app, FALSE);
699 /* Allow hibernation if the program has gone to the background: */
701 /* However, prevent hibernation while the settings are being changed: */
702 const gboolean hibernation_prevented =
703 modest_window_mgr_get_hibernation_is_prevented (
704 modest_runtime_get_window_mgr ());
706 if (hibernation_prevented)
707 hildon_program_set_can_hibernate (app, FALSE);
709 /* Allow hibernation, after saving the state: */
710 modest_osso_save_state();
711 hildon_program_set_can_hibernate (app, TRUE);
718 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
720 GtkWidget *folder_win = (GtkWidget *) user_data;
721 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
723 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
724 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
725 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
727 gtk_widget_show (GTK_WIDGET (priv->folder_view));
729 /* Connect signals */
730 connect_signals ((ModestMainWindow*)self);
732 /* Set account store */
733 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
734 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
736 /* Load previous osso state, for instance if we are being restored from
738 modest_osso_load_state ();
740 /* Restore window & widget settings */
742 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
744 /* Check if accounts exist and show the account wizard if not */
745 gboolean accounts_exist =
746 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
748 if (!accounts_exist) {
749 /* This is necessary to have the main window shown behind the dialog
750 It's an ugly hack... jschmid */
751 gtk_widget_show_all(GTK_WIDGET(self));
752 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
755 GtkAction *send_receive_all;
756 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
757 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
758 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
759 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
760 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
761 modest_account_mgr_free_account_names (accounts);
768 modest_main_window_new (void)
770 ModestMainWindow *self = NULL;
771 ModestMainWindowPrivate *priv = NULL;
772 ModestWindowPrivate *parent_priv = NULL;
773 GtkWidget *folder_win = NULL;
774 ModestDimmingRulesGroup *menu_rules_group = NULL;
775 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
776 GtkActionGroup *action_group = NULL;
777 GError *error = NULL;
778 ModestConf *conf = NULL;
779 GtkAction *action = NULL;
781 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
782 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
783 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
785 parent_priv->ui_manager = gtk_ui_manager_new();
786 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
788 action_group = gtk_action_group_new ("ModestMainWindowActions");
789 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
791 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
792 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
794 /* Add common actions */
795 gtk_action_group_add_actions (action_group,
796 modest_action_entries,
797 G_N_ELEMENTS (modest_action_entries),
800 gtk_action_group_add_actions (action_group,
801 modest_folder_view_action_entries,
802 G_N_ELEMENTS (modest_folder_view_action_entries),
805 gtk_action_group_add_actions (action_group,
806 modest_header_view_action_entries,
807 G_N_ELEMENTS (modest_header_view_action_entries),
810 gtk_action_group_add_toggle_actions (action_group,
811 modest_toggle_action_entries,
812 G_N_ELEMENTS (modest_toggle_action_entries),
815 gtk_action_group_add_toggle_actions (action_group,
816 modest_main_window_toggle_action_entries,
817 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
820 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
821 g_object_unref (action_group);
823 /* Load the UI definition */
824 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
825 MODEST_UIDIR "modest-main-window-ui.xml", &error);
827 g_warning ("Could not merge modest-ui.xml: %s", error->message);
828 g_error_free (error);
832 /* Add common dimming rules */
833 modest_dimming_rules_group_add_rules (menu_rules_group,
834 modest_main_window_menu_dimming_entries,
835 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
837 modest_dimming_rules_group_add_rules (toolbar_rules_group,
838 modest_main_window_toolbar_dimming_entries,
839 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
842 /* Insert dimming rules group for this window */
843 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
844 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
845 g_object_unref (menu_rules_group);
846 g_object_unref (toolbar_rules_group);
848 /* Add accelerators */
849 gtk_window_add_accel_group (GTK_WINDOW (self),
850 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
852 /* Menubar. Update the state of some toggles */
853 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
854 conf = modest_runtime_get_conf ();
855 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
856 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
857 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
858 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
859 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
860 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
861 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
862 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
863 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
865 /* Get device name */
866 modest_maemo_utils_get_device_name ();
870 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
871 if (!priv->header_view)
872 g_printerr ("modest: cannot instantiate header view\n");
873 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
874 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
875 MODEST_CONF_HEADER_VIEW_KEY);
878 priv->empty_view = create_empty_view ();
880 /* Create scrolled windows */
881 folder_win = gtk_scrolled_window_new (NULL, NULL);
882 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
883 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
885 GTK_POLICY_AUTOMATIC);
886 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
888 GTK_POLICY_AUTOMATIC);
891 priv->main_paned = gtk_hpaned_new ();
892 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
893 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
894 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
896 /* putting it all together... */
897 priv->main_vbox = gtk_vbox_new (FALSE, 6);
898 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
900 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
902 HildonProgram *app = hildon_program_get_instance ();
903 hildon_program_add_window (app, HILDON_WINDOW (self));
905 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
906 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
908 g_signal_connect (G_OBJECT(self), "show",
909 G_CALLBACK (modest_main_window_on_show), folder_win);
912 restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
914 return MODEST_WINDOW(self);
918 modest_main_window_close_all (ModestMainWindow *self)
921 GtkResponseType response;
923 /* Create the confirmation dialog MSG-NOT308 */
924 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
925 _("emev_nc_close_windows"),
926 _("mcen_bd_yes"), GTK_RESPONSE_YES,
927 _("mcen_bd_no"), GTK_RESPONSE_NO,
930 response = gtk_dialog_run (GTK_DIALOG (note));
931 gtk_widget_destroy (GTK_WIDGET (note));
933 if (response == GTK_RESPONSE_YES)
941 modest_main_window_set_style (ModestMainWindow *self,
942 ModestMainWindowStyle style)
944 ModestMainWindowPrivate *priv;
945 ModestWindowPrivate *parent_priv;
948 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
950 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
951 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
953 /* no change -> nothing to do */
954 if (priv->style == style)
957 /* Get toggle button */
958 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
962 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
963 /* Remove main paned */
964 g_object_ref (priv->main_paned);
965 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
967 /* Reparent the contents widget to the main vbox */
968 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
970 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
971 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
972 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
974 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
975 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
976 TnyIterator *iterator = tny_list_create_iterator (selection);
978 tny_iterator_first (iterator);
979 header = TNY_HEADER (tny_iterator_get_current (iterator));
980 if (tny_header_get_subject (header))
981 gtk_window_set_title (GTK_WINDOW(self), tny_header_get_subject (header));
983 gtk_window_set_title (GTK_WINDOW (self), _("mail_va_no_subject"));
984 g_object_unref (header);
985 g_object_unref (iterator);
986 g_object_unref (selection);
990 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
991 /* Remove header view */
992 g_object_ref (priv->contents_widget);
993 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
995 /* Reparent the main paned */
996 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
997 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
999 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1000 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1001 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1005 g_return_if_reached ();
1008 /* Let header view grab the focus if it's being shown */
1009 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1010 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1012 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1015 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1018 ModestMainWindowStyle
1019 modest_main_window_get_style (ModestMainWindow *self)
1021 ModestMainWindowPrivate *priv;
1023 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1025 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1032 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1034 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1035 ModestWindowPrivate *parent_priv;
1036 ModestWindowMgr *mgr;
1037 gboolean is_fullscreen;
1038 GtkAction *fs_toggle_action;
1041 mgr = modest_runtime_get_window_mgr ();
1043 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1045 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1047 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1048 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1049 if (is_fullscreen != active) {
1050 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1059 set_homogeneous (GtkWidget *widget,
1062 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1063 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1067 modest_main_window_show_toolbar (ModestWindow *self,
1068 gboolean show_toolbar)
1070 ModestMainWindowPrivate *priv = NULL;
1071 ModestWindowPrivate *parent_priv = NULL;
1072 GtkWidget *reply_button = NULL, *menu = NULL;
1073 GtkWidget *placeholder = NULL;
1076 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1077 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1078 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1080 /* Set optimized view status */
1081 priv->optimized_view = !show_toolbar;
1083 if (!parent_priv->toolbar) {
1084 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1087 /* Set homogeneous toolbar */
1088 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1089 set_homogeneous, NULL);
1091 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1092 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1093 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1094 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1095 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1096 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1097 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1098 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1100 /* Add ProgressBar (Transfer toolbar) */
1101 priv->progress_bar = modest_progress_bar_widget_new ();
1102 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1103 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1104 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1105 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1106 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1108 /* Connect cancel 'clicked' signal to abort progress mode */
1109 g_signal_connect(priv->cancel_toolitem, "clicked",
1110 G_CALLBACK(cancel_progressbar),
1113 /* Add it to the observers list */
1114 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1117 hildon_window_add_toolbar (HILDON_WINDOW (self),
1118 GTK_TOOLBAR (parent_priv->toolbar));
1120 /* Set reply button tap and hold menu */
1121 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1122 "/ToolBar/ToolbarMessageReply");
1123 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1124 "/ToolbarReplyCSM");
1125 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1127 /* Set send & receive button tap and hold menu */
1128 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1133 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1134 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1135 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1137 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1138 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1140 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1145 compare_display_names (ModestAccountData *a,
1146 ModestAccountData *b)
1148 return strcmp (a->display_name, b->display_name);
1152 on_account_update (TnyAccountStore *account_store,
1153 const gchar *account_name,
1156 GSList *account_names, *iter, *accounts;
1157 ModestMainWindow *self;
1158 ModestMainWindowPrivate *priv;
1159 ModestWindowPrivate *parent_priv;
1160 ModestAccountMgr *mgr;
1161 gint i, num_accounts;
1162 GtkActionGroup *action_group;
1164 gchar *default_account;
1165 GtkWidget *send_receive_button, *item;
1166 GtkAction *send_receive_all = NULL;
1168 self = MODEST_MAIN_WINDOW (user_data);
1169 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1170 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1172 /* Get enabled account IDs */
1173 mgr = modest_runtime_get_account_mgr ();
1174 account_names = modest_account_mgr_account_names (mgr, TRUE);
1175 iter = account_names;
1179 ModestAccountData *account_data =
1180 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1181 accounts = g_slist_prepend (accounts, account_data);
1185 modest_account_mgr_free_account_names (account_names);
1186 account_names = NULL;
1188 /* Order the list of accounts by its display name */
1189 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1190 num_accounts = g_slist_length (accounts);
1192 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1193 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1194 gtk_action_set_visible (send_receive_all, num_accounts > 1);
1196 /* Delete old send&receive popup items. We can not just do a
1197 menu_detach because it does not work well with
1199 if (priv->accounts_popup)
1200 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
1201 (GtkCallback) gtk_widget_destroy, NULL);
1203 /* Delete old entries in the View menu. Do not free groups, it
1205 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1207 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1208 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1209 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
1210 GTK_ACTION_GROUP (groups->data));
1213 if (priv->merge_ids) {
1214 for (i = 0; i < priv->merge_ids->len; i++)
1215 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1216 g_byte_array_free (priv->merge_ids, TRUE);
1218 /* We need to call this in order to ensure
1219 that the new actions are added in the right
1220 order (alphabetical */
1221 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1223 groups = g_list_next (groups);
1225 priv->merge_ids = g_byte_array_sized_new (num_accounts);
1227 /* Get send receive button */
1228 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1229 "/ToolBar/ToolbarSendReceive");
1231 /* Create the menu */
1232 if (num_accounts > 1) {
1233 if (!priv->accounts_popup)
1234 priv->accounts_popup = gtk_menu_new ();
1235 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1236 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1237 g_signal_connect (G_OBJECT (item),
1239 G_CALLBACK (on_send_receive_csm_activated),
1241 item = gtk_separator_menu_item_new ();
1242 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1245 /* Create a new action group */
1246 default_account = modest_account_mgr_get_default_account (mgr);
1247 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1248 for (i = 0; i < num_accounts; i++) {
1249 gchar *display_name = NULL;
1251 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1253 /* Create display name. The default account is shown differently */
1254 if (default_account && account_data->account_name &&
1255 !(strcmp (default_account, account_data->account_name) == 0)) {
1256 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
1257 account_data->display_name);
1260 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
1261 account_data->display_name);
1264 /* Create action and add it to the action group. The
1265 action name must be the account name, this way we
1266 could know in the handlers the account to show */
1267 if(account_data->account_name) {
1268 gchar* item_name, *refresh_action_name;
1270 GtkAction *view_account_action, *refresh_account_action;
1272 view_account_action = gtk_action_new (account_data->account_name,
1273 display_name, NULL, NULL);
1274 gtk_action_group_add_action (action_group, view_account_action);
1276 /* Add ui from account data. We allow 2^9-1 account
1277 changes in a single execution because we're
1278 downcasting the guint to a guint8 in order to use a
1279 GByteArray, it should be enough */
1280 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1281 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1282 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1283 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1285 "/MenuBar/ViewMenu/ViewMenuAdditions",
1287 account_data->account_name,
1288 GTK_UI_MANAGER_MENUITEM,
1291 /* Connect the action signal "activate" */
1292 g_signal_connect (G_OBJECT (view_account_action),
1294 G_CALLBACK (on_show_account_action_activated),
1297 /* Create the items for the Tools->Send&Receive submenu */
1298 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1299 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
1300 display_name, NULL, NULL);
1301 gtk_action_group_add_action (action_group, refresh_account_action);
1303 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1304 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1305 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1307 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1309 refresh_action_name,
1310 GTK_UI_MANAGER_MENUITEM,
1312 g_free (refresh_action_name);
1314 g_signal_connect_data (G_OBJECT (refresh_account_action),
1316 G_CALLBACK (on_refresh_account_action_activated),
1317 g_strdup (account_data->account_name),
1318 (GClosureNotify) g_free,
1321 /* Create item and add it to the send&receive
1322 CSM. If there is only one account then
1324 if (priv->accounts_popup) {
1325 item = gtk_menu_item_new_with_label (display_name);
1326 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1327 g_signal_connect_data (G_OBJECT (item),
1329 G_CALLBACK (on_send_receive_csm_activated),
1330 g_strdup (account_data->account_name),
1331 (GClosureNotify) g_free,
1338 g_free (display_name);
1339 modest_account_mgr_free_account_data (mgr, account_data);
1341 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1343 if (priv->accounts_popup) {
1344 /* Mandatory in order to view the menu contents */
1345 gtk_widget_show_all (priv->accounts_popup);
1347 /* Setup tap_and_hold just if was not done before*/
1348 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1349 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1353 g_slist_free (accounts);
1354 g_free (default_account);
1358 * This function manages the key events used to navigate between
1359 * header and folder views (when the window is in split view)
1362 * -------------------------------------------------
1363 * HeaderView GDK_Left Move focus to folder view
1364 * FolderView GDK_Right Move focus to header view
1366 * There is no need to scroll to selected row, the widgets will be the
1367 * responsibles of doing that (probably managing the focus-in event
1370 on_inner_widgets_key_pressed (GtkWidget *widget,
1374 ModestMainWindowPrivate *priv;
1376 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1378 /* Do nothing if we're in SIMPLE style */
1379 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1382 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1383 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1384 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1385 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1391 set_alignment (GtkWidget *widget,
1394 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1395 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1399 create_empty_view (void)
1401 GtkLabel *label = NULL;
1402 GtkWidget *align = NULL;
1404 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1405 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1406 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1407 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1409 return GTK_WIDGET(align);
1413 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1415 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1420 gchar *gray_color_markup;
1422 vbox = gtk_vbox_new (FALSE, 0);
1424 /* Obtain the secondary text color. We need a realized widget, that's why
1425 we get styled_widget from outside */
1426 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1428 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1429 gray_color_markup = modest_text_utils_get_color_string (&color);
1431 // gray_color_markup is freed below
1432 gray_color_markup = g_strdup ("#BBBBBB");
1434 /* Account description: */
1436 if (modest_tny_account_is_virtual_local_folders (account)
1437 || (modest_tny_account_is_memory_card_account (account))) {
1439 /* Local folders: */
1441 /* Get device name */
1442 gchar *device_name = NULL;
1443 if (modest_tny_account_is_virtual_local_folders (account))
1444 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1445 MODEST_CONF_DEVICE_NAME, NULL);
1447 device_name = g_strdup (tny_account_get_name (account));
1449 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1450 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1451 gray_color_markup, tmp, device_name);
1453 label_w = gtk_label_new (NULL);
1454 gtk_label_set_markup (GTK_LABEL (label_w), label);
1455 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1456 g_free (device_name);
1459 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1460 gtk_box_pack_start (GTK_BOX (vbox),
1461 gtk_label_new (tny_account_get_name (account)),
1464 /* Other accounts, such as IMAP and POP: */
1469 /* Put proto in uppercase */
1470 proto = g_string_new (tny_account_get_proto (account));
1471 proto = g_string_ascii_up (proto);
1473 /* note: mcen_fi_localroot_description is something like "%s account"
1474 * however, we should display "%s account: %s"... therefore, ugly tmp */
1475 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1476 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1477 gray_color_markup, tmp, tny_account_get_name (account));
1480 label_w = gtk_label_new (NULL);
1481 gtk_label_set_markup (GTK_LABEL (label_w), label);
1482 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1483 g_string_free (proto, TRUE);
1489 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1490 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1491 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1492 modest_tny_folder_store_get_message_count (folder_store));
1493 label_w = gtk_label_new (NULL);
1494 gtk_label_set_markup (GTK_LABEL (label_w), label);
1495 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1499 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1501 _("mcen_fi_rootfolder_folders"),
1502 modest_tny_folder_store_get_folder_count (folder_store));
1503 label_w = gtk_label_new (NULL);
1504 gtk_label_set_markup (GTK_LABEL (label_w), label);
1505 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1509 if (modest_tny_account_is_virtual_local_folders (account)
1510 || modest_tny_account_is_memory_card_account (account)) {
1511 /* FIXME: format size */
1512 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1513 gray_color_markup, _("mcen_fi_rootfolder_size"),
1514 modest_tny_folder_store_get_local_size (folder_store));
1515 label_w = gtk_label_new (NULL);
1516 gtk_label_set_markup (GTK_LABEL (label_w), label);
1517 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1519 } else if (TNY_IS_ACCOUNT(folder_store)) {
1520 TnyAccount *account = TNY_ACCOUNT(folder_store);
1522 time_t last_updated;
1523 gchar *last_updated_string;
1524 /* Get last updated from configuration */
1525 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1526 tny_account_get_id (account),
1527 MODEST_ACCOUNT_LAST_UPDATED,
1529 if (last_updated > 0)
1530 last_updated_string = modest_text_utils_get_display_date(last_updated);
1532 last_updated_string = g_strdup (_("mcen_va_never"));
1534 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1535 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1536 label_w = gtk_label_new (NULL);
1537 gtk_label_set_markup (GTK_LABEL (label_w), label);
1538 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1539 g_free (last_updated_string);
1543 g_free (gray_color_markup);
1546 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1552 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1554 ModestMainWindowPrivate *priv = NULL;
1556 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1558 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1560 return priv->send_receive_in_progress;
1564 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1566 GtkAction *action = NULL;
1567 GtkWidget *widget = NULL;
1568 ModestMainWindowPrivate *priv = NULL;
1570 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1571 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1573 priv->send_receive_in_progress = TRUE;
1575 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1576 gtk_action_set_sensitive (action, FALSE);
1577 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1578 /* gtk_action_set_sensitive (action, FALSE); */
1579 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1580 gtk_widget_set_sensitive (widget, FALSE);
1584 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1586 GtkAction *action = NULL;
1587 GtkWidget *widget = NULL;
1588 ModestMainWindowPrivate *priv = NULL;
1590 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1591 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1593 priv->send_receive_in_progress = FALSE;
1595 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1596 gtk_action_set_sensitive (action, TRUE);
1597 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1598 /* gtk_action_set_sensitive (action, TRUE); */
1599 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1600 gtk_widget_set_sensitive (widget, TRUE);
1605 _on_msg_count_changed (ModestHeaderView *header_view,
1607 TnyFolderChange *change,
1608 ModestMainWindow *main_window)
1610 printf ("DEBUG: %s\n", __FUNCTION__);
1611 gboolean folder_empty = FALSE;
1612 TnyFolderChangeChanged changed;
1614 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1615 g_return_if_fail (TNY_IS_FOLDER(folder));
1616 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1618 changed = tny_folder_change_get_changed (change);
1620 /* If something changes */
1621 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1622 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1624 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1626 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1628 /* Set contents style of headers view */
1630 modest_main_window_set_contents_style (main_window,
1631 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1634 modest_main_window_set_contents_style (main_window,
1635 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1640 modest_main_window_set_contents_style (ModestMainWindow *self,
1641 ModestMainWindowContentsStyle style)
1643 ModestMainWindowPrivate *priv;
1645 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1647 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1649 /* We allow to set the same content style than the previously
1650 set if there are details, because it could happen when we're
1651 selecting different accounts consecutively */
1652 if ((priv->contents_style == style) &&
1653 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1656 /* Remove previous child. Delete it if it was an account
1658 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1660 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1661 g_object_ref (content);
1662 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1663 g_object_ref (priv->empty_view);
1664 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1667 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1670 priv->contents_style = style;
1672 switch (priv->contents_style) {
1673 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1674 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1676 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1678 TnyFolderStore *selected_folderstore =
1679 modest_folder_view_get_selected (priv->folder_view);
1680 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1681 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1682 TNY_ACCOUNT (selected_folderstore));
1684 wrap_in_scrolled_window (priv->contents_widget,
1685 priv->details_widget);
1687 g_object_unref (selected_folderstore);
1690 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1691 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1694 g_return_if_reached ();
1698 gtk_widget_show_all (priv->contents_widget);
1701 ModestMainWindowContentsStyle
1702 modest_main_window_get_contents_style (ModestMainWindow *self)
1704 ModestMainWindowPrivate *priv;
1706 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1708 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1709 return priv->contents_style;
1714 on_configuration_key_changed (ModestConf* conf,
1716 ModestConfEvent event,
1717 ModestMainWindow *self)
1719 ModestMainWindowPrivate *priv;
1720 TnyAccount *account;
1722 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1725 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1727 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1730 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1731 if (TNY_IS_ACCOUNT (account) &&
1732 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1735 const gchar *device_name;
1739 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1740 label = GTK_LABEL (children->data);
1742 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1743 MODEST_CONF_DEVICE_NAME, NULL);
1745 new_text = g_strdup_printf ("%s: %s",
1746 _("mcen_fi_localroot_description"),
1749 gtk_label_set_text (label, new_text);
1750 gtk_widget_show (GTK_WIDGET (label));
1753 g_list_free (children);
1755 g_object_unref (account);
1759 set_toolbar_transfer_mode (ModestMainWindow *self)
1761 ModestMainWindowPrivate *priv = NULL;
1763 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1765 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1767 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1769 if (priv->progress_bar_timeout > 0) {
1770 g_source_remove (priv->progress_bar_timeout);
1771 priv->progress_bar_timeout = 0;
1778 set_toolbar_mode (ModestMainWindow *self,
1779 ModestToolBarModes mode)
1781 ModestWindowPrivate *parent_priv = NULL;
1782 ModestMainWindowPrivate *priv = NULL;
1783 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1785 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1787 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1788 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1790 /* In case this was called before the toolbar exists: */
1791 if (!(parent_priv->toolbar))
1794 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1796 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1797 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1798 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1800 /* Sets current toolbar mode */
1801 priv->current_toolbar_mode = mode;
1803 /* Show and hide toolbar items */
1805 case TOOLBAR_MODE_NORMAL:
1807 gtk_action_set_visible (sort_action, TRUE);
1809 gtk_action_set_visible (refresh_action, TRUE);
1810 if (priv->progress_toolitem) {
1811 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1812 gtk_widget_hide (priv->progress_toolitem);
1814 if (priv->progress_bar)
1815 gtk_widget_hide (priv->progress_bar);
1818 gtk_action_set_visible (cancel_action, FALSE);
1819 /* if (priv->sort_toolitem) */
1820 /* gtk_widget_show (priv->sort_toolitem); */
1822 /* if (priv->refresh_toolitem) */
1823 /* gtk_widget_show (priv->refresh_toolitem); */
1825 /* if (priv->progress_toolitem) */
1826 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1827 /* if (priv->progress_bar) */
1828 /* gtk_widget_hide (priv->progress_bar); */
1830 /* if (priv->cancel_toolitem) */
1831 /* gtk_widget_hide (priv->cancel_toolitem); */
1833 /* Hide toolbar if optimized view is enabled */
1834 if (priv->optimized_view)
1835 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1837 case TOOLBAR_MODE_TRANSFER:
1839 gtk_action_set_visible (sort_action, FALSE);
1841 gtk_action_set_visible (refresh_action, FALSE);
1843 gtk_action_set_visible (cancel_action, TRUE);
1844 if (priv->progress_toolitem) {
1845 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1846 gtk_widget_show (priv->progress_toolitem);
1848 if (priv->progress_bar)
1849 gtk_widget_show (priv->progress_bar);
1851 /* if (priv->sort_toolitem) */
1852 /* gtk_widget_hide (priv->sort_toolitem); */
1854 /* if (priv->refresh_toolitem) */
1855 /* gtk_widget_hide (priv->refresh_toolitem); */
1857 /* if (priv->progress_toolitem) */
1858 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1859 /* if (priv->progress_bar) */
1860 /* gtk_widget_show (priv->progress_bar); */
1862 /* if (priv->cancel_toolitem) */
1863 /* gtk_widget_show (priv->cancel_toolitem); */
1865 /* Show toolbar if it's hiden (optimized view ) */
1866 if (priv->optimized_view)
1867 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1870 g_return_if_reached ();
1875 cancel_progressbar (GtkToolButton *toolbutton,
1876 ModestMainWindow *self)
1879 ModestMainWindowPrivate *priv;
1881 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1883 /* Get operation observers and cancel its current operation */
1884 tmp = priv->progress_widgets;
1886 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1887 tmp=g_slist_next(tmp);
1892 observers_empty (ModestMainWindow *self)
1895 ModestMainWindowPrivate *priv;
1896 gboolean is_empty = TRUE;
1897 guint pending_ops = 0;
1899 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1900 tmp = priv->progress_widgets;
1902 /* Check all observers */
1903 while (tmp && is_empty) {
1904 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1905 is_empty = pending_ops == 0;
1907 tmp = g_slist_next(tmp);
1914 on_queue_changed (ModestMailOperationQueue *queue,
1915 ModestMailOperation *mail_op,
1916 ModestMailOperationQueueNotification type,
1917 ModestMainWindow *self)
1919 ModestMainWindowPrivate *priv;
1920 ModestMailOperationTypeOperation op_type;
1921 ModestToolBarModes mode;
1923 gboolean mode_changed = FALSE;
1924 /* ModestMailOperationStatus status; */
1926 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1927 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1929 /* Get toolbar mode from operation id*/
1930 op_type = modest_mail_operation_get_type_operation (mail_op);
1932 case MODEST_MAIL_OPERATION_TYPE_SEND:
1933 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1934 case MODEST_MAIL_OPERATION_TYPE_OPEN:
1935 mode = TOOLBAR_MODE_TRANSFER;
1936 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1937 mode_changed = TRUE;
1940 mode = TOOLBAR_MODE_NORMAL;
1945 /* Add operation observers and change toolbar if neccessary*/
1946 tmp = priv->progress_widgets;
1948 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1949 if (mode == TOOLBAR_MODE_TRANSFER) {
1951 set_toolbar_transfer_mode(self);
1953 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1955 tmp = g_slist_next (tmp);
1959 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1960 /* Change toolbar mode */
1961 if (mode == TOOLBAR_MODE_TRANSFER) {
1963 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1965 tmp = g_slist_next (tmp);
1968 /* If no more operations are being observed, NORMAL mode is enabled again */
1969 if (observers_empty (self)) {
1970 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1981 on_show_account_action_activated (GtkAction *action,
1984 ModestAccountData *acc_data;
1985 ModestMainWindow *self;
1986 ModestMainWindowPrivate *priv;
1987 ModestAccountMgr *mgr;
1988 const gchar *acc_name;
1990 self = MODEST_MAIN_WINDOW (user_data);
1991 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1993 /* Get account data */
1994 acc_name = gtk_action_get_name (action);
1995 mgr = modest_runtime_get_account_mgr ();
1996 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1998 /* Set the new visible & active account */
1999 if (acc_data->store_account) {
2000 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2001 acc_data->store_account->account_name);
2002 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2006 modest_account_mgr_free_account_data (mgr, acc_data);
2010 refresh_account (const gchar *account_name)
2014 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2016 /* If account_name == NULL, we must update all (option All) */
2018 modest_ui_actions_do_send_receive_all (win);
2020 modest_ui_actions_do_send_receive (account_name, win);
2025 on_refresh_account_action_activated (GtkAction *action,
2028 refresh_account ((const gchar*) user_data);
2032 on_send_receive_csm_activated (GtkMenuItem *item,
2035 refresh_account ((const gchar*) user_data);
2039 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2041 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2043 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));