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>
34 #include <tny-maemo-conic-device.h>
35 #include "modest-hildon-includes.h"
36 #include "modest-defs.h"
39 #include "widgets/modest-main-window.h"
40 #include "widgets/modest-msg-edit-window.h"
41 #include "widgets/modest-account-view-window.h"
42 #include "modest-runtime.h"
43 #include "modest-account-mgr-helpers.h"
44 #include "modest-platform.h"
45 #include "modest-widget-memory.h"
46 #include "modest-window-priv.h"
47 #include "modest-main-window-ui.h"
48 #include "modest-main-window-ui-dimming.h"
49 #include "modest-account-mgr.h"
50 #include "modest-tny-account.h"
51 #include "modest-conf.h"
52 #include <modest-maemo-utils.h>
53 #include "modest-tny-platform-factory.h"
54 #include "modest-tny-msg.h"
55 #include "modest-mail-operation.h"
56 #include "modest-icon-names.h"
57 #include "modest-progress-bar-widget.h"
58 #include "modest-text-utils.h"
59 #include "modest-ui-dimming-manager.h"
60 #include "maemo/modest-osso-state-saving.h"
62 #ifdef MODEST_HAVE_HILDON0_WIDGETS
63 #include <hildon-widgets/hildon-program.h>
65 #include <hildon/hildon-program.h>
66 #endif /*MODEST_HAVE_HILDON0_WIDGETS*/
68 #define MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS "ModestMainWindowActionAdditions"
75 /* 'private'/'protected' functions */
76 static void modest_main_window_class_init (ModestMainWindowClass *klass);
77 static void modest_main_window_init (ModestMainWindow *obj);
78 static void modest_main_window_finalize (GObject *obj);
79 static gboolean modest_main_window_window_state_event (GtkWidget *widget,
80 GdkEventWindowState *event,
83 static void connect_signals (ModestMainWindow *self);
85 static void restore_settings (ModestMainWindow *self, gboolean do_folder_view_too);
86 static void save_state (ModestWindow *self);
88 static void modest_main_window_show_toolbar (ModestWindow *window,
89 gboolean show_toolbar);
91 static void cancel_progressbar (GtkToolButton *toolbutton,
92 ModestMainWindow *self);
94 static void on_queue_changed (ModestMailOperationQueue *queue,
95 ModestMailOperation *mail_op,
96 ModestMailOperationQueueNotification type,
97 ModestMainWindow *self);
99 static gboolean on_zoom_minus_plus_not_implemented (ModestWindow *window);
101 static void on_account_update (TnyAccountStore *account_store,
102 const gchar *account_name,
105 static gboolean on_inner_widgets_key_pressed (GtkWidget *widget,
109 static void on_configuration_key_changed (ModestConf* conf,
111 ModestConfEvent event,
112 ModestMainWindow *self);
114 static void set_toolbar_mode (ModestMainWindow *self,
115 ModestToolBarModes mode);
117 static gboolean set_toolbar_transfer_mode (ModestMainWindow *self);
119 static void on_show_account_action_activated (GtkAction *action,
122 static void on_refresh_account_action_activated (GtkAction *action,
125 static void on_send_receive_csm_activated (GtkMenuItem *item,
129 _on_msg_count_changed (ModestHeaderView *header_view,
131 TnyFolderChange *change,
132 ModestMainWindow *main_window);
135 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self);
138 static GtkWidget * create_empty_view (void);
141 /* list my signals */
148 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
149 struct _ModestMainWindowPrivate {
150 GtkWidget *msg_paned;
151 GtkWidget *main_paned;
152 GtkWidget *main_vbox;
153 GtkWidget *contents_widget;
154 GtkWidget *empty_view;
156 /* Progress observers */
157 GtkWidget *progress_bar;
158 GSList *progress_widgets;
161 GtkWidget *progress_toolitem;
162 GtkWidget *cancel_toolitem;
163 GtkWidget *sort_toolitem;
164 GtkWidget *refresh_toolitem;
165 ModestToolBarModes current_toolbar_mode;
167 /* Merge ids used to add/remove accounts to the ViewMenu*/
168 GByteArray *merge_ids;
170 /* On-demand widgets */
171 GtkWidget *accounts_popup;
172 GtkWidget *details_widget;
174 /* Optimized view enabled */
175 gboolean optimized_view;
177 /* Optimized view enabled */
178 gboolean send_receive_in_progress;
180 ModestHeaderView *header_view;
181 ModestFolderView *folder_view;
183 ModestMainWindowStyle style;
184 ModestMainWindowContentsStyle contents_style;
186 guint progress_bar_timeout;
188 /* Signal handler UIDs */
189 gint queue_changed_handler_uid;
190 GList *queue_err_signals;
192 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
193 MODEST_TYPE_MAIN_WINDOW, \
194 ModestMainWindowPrivate))
196 typedef struct _GetMsgAsyncHelper {
197 ModestMainWindowPrivate *main_window_private;
199 ModestTnyMsgReplyType reply_type;
200 ModestTnyMsgForwardType forward_type;
207 static GtkWindowClass *parent_class = NULL;
210 /* Private actions */
211 /* This is the context sensitive menu: */
212 static const GtkActionEntry modest_folder_view_action_entries [] = {
214 /* Folder View CSM actions */
215 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
216 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
217 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
218 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
219 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
220 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
223 static const GtkActionEntry modest_header_view_action_entries [] = {
225 /* Header View CSM actions */
226 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
227 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
228 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
229 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
230 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
231 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
232 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
233 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) },
234 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, NULL },
235 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
238 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
239 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
242 /************************************************************************/
245 modest_main_window_get_type (void)
247 static GType my_type = 0;
249 static const GTypeInfo my_info = {
250 sizeof(ModestMainWindowClass),
251 NULL, /* base init */
252 NULL, /* base finalize */
253 (GClassInitFunc) modest_main_window_class_init,
254 NULL, /* class finalize */
255 NULL, /* class data */
256 sizeof(ModestMainWindow),
258 (GInstanceInitFunc) modest_main_window_init,
261 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
269 modest_main_window_class_init (ModestMainWindowClass *klass)
271 GObjectClass *gobject_class;
272 gobject_class = (GObjectClass*) klass;
273 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
275 parent_class = g_type_class_peek_parent (klass);
276 gobject_class->finalize = modest_main_window_finalize;
278 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
280 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
281 modest_window_class->save_state_func = save_state;
282 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
283 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
287 modest_main_window_init (ModestMainWindow *obj)
289 ModestMainWindowPrivate *priv;
291 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
293 priv->queue_err_signals = NULL;
294 priv->msg_paned = NULL;
295 priv->main_paned = NULL;
296 priv->main_vbox = NULL;
297 priv->header_view = NULL;
298 priv->folder_view = NULL;
299 priv->contents_widget = NULL;
300 priv->accounts_popup = NULL;
301 priv->details_widget = NULL;
302 priv->empty_view = NULL;
303 priv->progress_widgets = NULL;
304 priv->progress_bar = NULL;
305 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
306 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
307 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
308 priv->merge_ids = NULL;
309 priv->optimized_view = FALSE;
310 priv->send_receive_in_progress = FALSE;
311 priv->progress_bar_timeout = 0;
312 priv->queue_changed_handler_uid = 0;
316 modest_main_window_finalize (GObject *obj)
318 ModestMainWindowPrivate *priv;
320 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
322 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
324 g_slist_free (priv->progress_widgets);
326 g_byte_array_free (priv->merge_ids, TRUE);
328 if (priv->progress_bar_timeout > 0) {
329 g_source_remove (priv->progress_bar_timeout);
330 priv->progress_bar_timeout = 0;
333 /* Disconnect signal handlers */
334 if (priv->queue_changed_handler_uid)
335 g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
336 priv->queue_changed_handler_uid);
338 G_OBJECT_CLASS(parent_class)->finalize (obj);
342 modest_main_window_get_child_widget (ModestMainWindow *self,
343 ModestWidgetType widget_type)
345 ModestMainWindowPrivate *priv;
348 g_return_val_if_fail (self, NULL);
349 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
352 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
354 switch (widget_type) {
355 case MODEST_WIDGET_TYPE_HEADER_VIEW:
356 widget = (GtkWidget*)priv->header_view; break;
357 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
358 widget = (GtkWidget*)priv->folder_view; break;
363 return widget ? GTK_WIDGET(widget) : NULL;
368 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
371 ModestMainWindowPrivate *priv;
373 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
375 conf = modest_runtime_get_conf ();
377 modest_widget_memory_restore (conf, G_OBJECT(self),
378 MODEST_CONF_MAIN_WINDOW_KEY);
380 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
381 MODEST_CONF_HEADER_VIEW_KEY);
383 if (do_folder_view_too)
384 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
385 MODEST_CONF_FOLDER_VIEW_KEY);
387 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
388 MODEST_CONF_MAIN_PANED_KEY);
390 /* We need to force a redraw here in order to get the right
391 position of the horizontal paned separator */
392 gtk_widget_show (GTK_WIDGET (self));
397 save_state (ModestWindow *window)
400 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
401 ModestMainWindowPrivate *priv;
403 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
404 conf = modest_runtime_get_conf ();
406 modest_widget_memory_save (conf,G_OBJECT(self),
407 MODEST_CONF_MAIN_WINDOW_KEY);
408 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
409 MODEST_CONF_MAIN_PANED_KEY);
410 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
411 // MODEST_CONF_HEADER_VIEW_KEY);
412 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
413 MODEST_CONF_FOLDER_VIEW_KEY);
417 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
419 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
420 gtk_scrolled_window_add_with_viewport
421 (GTK_SCROLLED_WINDOW(win), widget);
423 gtk_container_add (GTK_CONTAINER(win),
429 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
431 modest_window_save_state (MODEST_WINDOW(self));
437 ModestMainWindow *self;
443 on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
445 OnResponseInfo *info = (OnResponseInfo *) user_data;
446 ModestMainWindow *self = info->self;
447 TnyHeader *header = info->header;
448 TnySendQueue *queue = info->queue;
450 if (arg1 == GTK_RESPONSE_YES) {
451 TnyFolder *outbox = tny_send_queue_get_outbox (queue);
452 tny_folder_remove_msg (outbox, header, NULL);
453 tny_folder_sync (outbox, TRUE, NULL);
454 g_object_unref (outbox);
457 g_object_unref (queue);
458 g_object_unref (header);
459 g_object_unref (self);
461 gtk_widget_destroy (GTK_WIDGET (dialog));
462 g_slice_free (OnResponseInfo, info);
467 on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
470 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
471 err->message, tny_header_get_subject (header));
472 OnResponseInfo *info = g_slice_new (OnResponseInfo);
473 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
474 GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
476 info->queue = g_object_ref (self);
477 info->self = g_object_ref (user_data);
478 info->header = g_object_ref (header);
479 g_signal_connect (G_OBJECT (dialog), "response",
480 G_CALLBACK (on_response), info);
481 gtk_widget_show_all (dialog);
491 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
493 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
495 GList *oerrsignals = priv->queue_err_signals;
496 while (oerrsignals) {
497 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
498 g_signal_handler_disconnect (esignal->queue, esignal->signal);
499 g_slice_free (QueueErrorSignal, esignal);
500 oerrsignals = g_list_next (oerrsignals);
502 g_list_free (priv->queue_err_signals);
503 priv->queue_err_signals = NULL;
507 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
509 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
511 /* When going online, do the equivalent of pressing the send/receive button,
512 * as per the specification:
513 * (without the check for >0 accounts, though that is not specified): */
515 TnyDevice *device = tny_account_store_get_device (store);
517 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
519 /* Check that we are really online.
520 * This signal should not be emitted when we are not connected,
521 * but it seems to happen sometimes: */
522 if (!tny_device_is_online (device))
525 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
526 printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
528 /* Stop the existing send queues: */
529 modest_runtime_remove_all_send_queues ();
531 /* Create the send queues again, using the appropriate transport accounts
532 * for this new connection.
533 * This could be the first time that they are created if this is the first
535 /* TODO: Does this really destroy the TnySendQueues and their threads
536 * We do not want 2 TnySendQueues to exist with the same underlying
537 * outbox directory. */
539 modest_main_window_cleanup_queue_error_signals (self);
541 GSList *account_names = modest_account_mgr_account_names (
542 modest_runtime_get_account_mgr(),
543 TRUE /* enabled accounts only */);
544 GSList *iter = account_names;
546 const gchar *account_name = (const gchar*)(iter->data);
548 TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
549 modest_tny_account_store_get_transport_account_for_open_connection
550 (modest_runtime_get_account_store(), account_name));
552 /* Q: Is this the first location where the send-queues are requested? */
553 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
554 printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name,
555 tny_account_get_id(TNY_ACCOUNT(account)));
556 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
557 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
558 G_CALLBACK (on_sendqueue_error_happened), self);
559 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
563 iter = g_slist_next (iter);
566 modest_account_mgr_free_account_names (account_names);
567 account_names = NULL;
569 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
573 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
575 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
578 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
582 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
584 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
586 /* Update visibility */
589 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
593 connect_signals (ModestMainWindow *self)
595 ModestWindowPrivate *parent_priv;
596 ModestMainWindowPrivate *priv;
599 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
600 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
603 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
604 G_CALLBACK(on_inner_widgets_key_pressed), self);
605 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
606 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
607 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
608 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
610 /* Folder view CSM */
611 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
612 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
613 g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
614 G_CALLBACK(_folder_view_csm_menu_activated),
617 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
618 G_CALLBACK(modest_ui_actions_on_header_selected), self);
619 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
620 G_CALLBACK(modest_ui_actions_on_header_activated), self);
621 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
622 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
623 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
624 G_CALLBACK(on_inner_widgets_key_pressed), self);
625 g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
626 G_CALLBACK(_on_msg_count_changed), self);
628 /* Header view CSM */
629 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
630 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
631 g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
632 G_CALLBACK(_header_view_csm_menu_activated),
636 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
637 g_signal_connect (G_OBJECT (self), "window-state-event",
638 G_CALLBACK (modest_main_window_window_state_event),
641 /* Mail Operation Queue */
642 priv->queue_changed_handler_uid =
643 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
644 "queue-changed", G_CALLBACK (on_queue_changed), self);
646 /* Track changes in the device name */
647 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
648 "key_changed", G_CALLBACK (on_configuration_key_changed),
651 /* Track account changes. We need to refresh the toolbar */
652 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
653 "account_update", G_CALLBACK (on_account_update),
657 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()),
658 "password_requested",
659 G_CALLBACK (modest_ui_actions_on_password_requested), self);
662 g_signal_connect (G_OBJECT(modest_runtime_get_account_store()),
663 "connecting-finished",
664 G_CALLBACK(on_account_store_connecting_finished), self);
668 /** Idle handler, to send/receive at startup .*/
670 sync_accounts_cb (ModestMainWindow *win)
672 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
673 return FALSE; /* Do not call this idle handler again. */
677 static void on_hildon_program_is_topmost_notify(GObject *self,
678 GParamSpec *propert_param, gpointer user_data)
680 HildonProgram *app = HILDON_PROGRAM (self);
683 ModestWindow* self = MODEST_WINDOW(user_data);
686 /* Note that use of hildon_program_set_can_hibernate()
687 * is generally referred to as "setting the killable flag",
688 * though hibernation does not seem equal to death.
691 if (hildon_program_get_is_topmost (app)) {
692 /* Prevent hibernation when the progam comes to the foreground,
693 * because hibernation should only happen when the application
694 * is in the background: */
695 hildon_program_set_can_hibernate (app, FALSE);
697 /* Allow hibernation if the program has gone to the background: */
699 /* However, prevent hibernation while the settings are being changed: */
700 const gboolean hibernation_prevented =
701 modest_window_mgr_get_hibernation_is_prevented (
702 modest_runtime_get_window_mgr ());
704 if (hibernation_prevented)
705 hildon_program_set_can_hibernate (app, FALSE);
707 /* Allow hibernation, after saving the state: */
708 modest_osso_save_state();
709 hildon_program_set_can_hibernate (app, TRUE);
716 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
718 GtkWidget *folder_win = (GtkWidget *) user_data;
719 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
721 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
722 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
723 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
725 gtk_widget_show (GTK_WIDGET (priv->folder_view));
727 /* Connect signals */
728 connect_signals ((ModestMainWindow*)self);
730 /* Set account store */
731 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
732 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
734 /* Load previous osso state, for instance if we are being restored from
736 modest_osso_load_state ();
738 /* Restore window & widget settings */
740 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
742 /* Check if accounts exist and show the account wizard if not */
743 gboolean accounts_exist =
744 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
746 if (!accounts_exist) {
747 /* This is necessary to have the main window shown behind the dialog
748 It's an ugly hack... jschmid */
749 gtk_widget_show_all(GTK_WIDGET(self));
750 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
753 GtkAction *send_receive_all;
754 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
755 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
756 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
757 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
758 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
759 modest_account_mgr_free_account_names (accounts);
766 modest_main_window_new (void)
768 ModestMainWindow *self = NULL;
769 ModestMainWindowPrivate *priv = NULL;
770 ModestWindowPrivate *parent_priv = NULL;
771 GtkWidget *folder_win = NULL;
772 ModestDimmingRulesGroup *menu_rules_group = NULL;
773 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
774 GtkActionGroup *action_group = NULL;
775 GError *error = NULL;
776 ModestConf *conf = NULL;
777 GtkAction *action = NULL;
779 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
780 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
781 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
783 parent_priv->ui_manager = gtk_ui_manager_new();
784 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
786 action_group = gtk_action_group_new ("ModestMainWindowActions");
787 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
789 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
790 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
792 /* Add common actions */
793 gtk_action_group_add_actions (action_group,
794 modest_action_entries,
795 G_N_ELEMENTS (modest_action_entries),
798 gtk_action_group_add_actions (action_group,
799 modest_folder_view_action_entries,
800 G_N_ELEMENTS (modest_folder_view_action_entries),
803 gtk_action_group_add_actions (action_group,
804 modest_header_view_action_entries,
805 G_N_ELEMENTS (modest_header_view_action_entries),
808 gtk_action_group_add_toggle_actions (action_group,
809 modest_toggle_action_entries,
810 G_N_ELEMENTS (modest_toggle_action_entries),
813 gtk_action_group_add_toggle_actions (action_group,
814 modest_main_window_toggle_action_entries,
815 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
818 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
819 g_object_unref (action_group);
821 /* Load the UI definition */
822 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
823 MODEST_UIDIR "modest-main-window-ui.xml", &error);
825 g_warning ("Could not merge modest-ui.xml: %s", error->message);
826 g_error_free (error);
830 /* Add common dimming rules */
831 modest_dimming_rules_group_add_rules (menu_rules_group,
832 modest_main_window_menu_dimming_entries,
833 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
835 modest_dimming_rules_group_add_rules (toolbar_rules_group,
836 modest_main_window_toolbar_dimming_entries,
837 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
840 /* Insert dimming rules group for this window */
841 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
842 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
843 g_object_unref (menu_rules_group);
844 g_object_unref (toolbar_rules_group);
846 /* Add accelerators */
847 gtk_window_add_accel_group (GTK_WINDOW (self),
848 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
850 /* Menubar. Update the state of some toggles */
851 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
852 conf = modest_runtime_get_conf ();
853 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
854 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
855 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
856 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
857 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
858 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
859 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
860 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
861 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
863 /* Get device name */
864 modest_maemo_utils_get_device_name ();
868 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
869 if (!priv->header_view)
870 g_printerr ("modest: cannot instantiate header view\n");
871 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
872 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
873 MODEST_CONF_HEADER_VIEW_KEY);
876 priv->empty_view = create_empty_view ();
878 /* Create scrolled windows */
879 folder_win = gtk_scrolled_window_new (NULL, NULL);
880 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
881 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
883 GTK_POLICY_AUTOMATIC);
884 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
886 GTK_POLICY_AUTOMATIC);
889 priv->main_paned = gtk_hpaned_new ();
890 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
891 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
892 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
894 /* putting it all together... */
895 priv->main_vbox = gtk_vbox_new (FALSE, 6);
896 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
898 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
900 HildonProgram *app = hildon_program_get_instance ();
901 hildon_program_add_window (app, HILDON_WINDOW (self));
903 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
904 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
906 g_signal_connect (G_OBJECT(self), "show",
907 G_CALLBACK (modest_main_window_on_show), folder_win);
910 restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
912 return MODEST_WINDOW(self);
916 modest_main_window_close_all (ModestMainWindow *self)
919 GtkResponseType response;
921 /* Create the confirmation dialog MSG-NOT308 */
922 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
923 _("emev_nc_close_windows"),
924 _("mcen_bd_yes"), GTK_RESPONSE_YES,
925 _("mcen_bd_no"), GTK_RESPONSE_NO,
928 response = gtk_dialog_run (GTK_DIALOG (note));
929 gtk_widget_destroy (GTK_WIDGET (note));
931 if (response == GTK_RESPONSE_YES)
939 modest_main_window_set_style (ModestMainWindow *self,
940 ModestMainWindowStyle style)
942 ModestMainWindowPrivate *priv;
943 ModestWindowPrivate *parent_priv;
946 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
948 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
949 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
951 /* no change -> nothing to do */
952 if (priv->style == style)
955 /* Get toggle button */
956 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
960 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
961 /* Remove main paned */
962 g_object_ref (priv->main_paned);
963 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
965 /* Reparent the contents widget to the main vbox */
966 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
968 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
969 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
970 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
973 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
974 /* Remove header view */
975 g_object_ref (priv->contents_widget);
976 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
978 /* Reparent the main paned */
979 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
980 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
982 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
983 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
984 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
988 g_return_if_reached ();
991 /* Let header view grab the focus if it's being shown */
992 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
993 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
995 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
998 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1001 ModestMainWindowStyle
1002 modest_main_window_get_style (ModestMainWindow *self)
1004 ModestMainWindowPrivate *priv;
1006 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1008 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1015 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1017 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1018 ModestWindowPrivate *parent_priv;
1019 ModestWindowMgr *mgr;
1020 gboolean is_fullscreen;
1021 GtkAction *fs_toggle_action;
1024 mgr = modest_runtime_get_window_mgr ();
1026 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1028 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1030 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1031 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1032 if (is_fullscreen != active) {
1033 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1042 set_homogeneous (GtkWidget *widget,
1045 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1046 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1050 modest_main_window_show_toolbar (ModestWindow *self,
1051 gboolean show_toolbar)
1053 ModestMainWindowPrivate *priv = NULL;
1054 ModestWindowPrivate *parent_priv = NULL;
1055 GtkWidget *reply_button = NULL, *menu = NULL;
1056 GtkWidget *placeholder = NULL;
1059 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1060 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1061 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1063 /* Set optimized view status */
1064 priv->optimized_view = !show_toolbar;
1066 if (!parent_priv->toolbar) {
1067 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1070 /* Set homogeneous toolbar */
1071 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1072 set_homogeneous, NULL);
1074 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1075 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1076 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1077 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1078 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1079 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1080 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1081 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1083 /* Add ProgressBar (Transfer toolbar) */
1084 priv->progress_bar = modest_progress_bar_widget_new ();
1085 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1086 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1087 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1088 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1089 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1091 /* Connect cancel 'clicked' signal to abort progress mode */
1092 g_signal_connect(priv->cancel_toolitem, "clicked",
1093 G_CALLBACK(cancel_progressbar),
1096 /* Add it to the observers list */
1097 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1100 hildon_window_add_toolbar (HILDON_WINDOW (self),
1101 GTK_TOOLBAR (parent_priv->toolbar));
1103 /* Set reply button tap and hold menu */
1104 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1105 "/ToolBar/ToolbarMessageReply");
1106 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1107 "/ToolbarReplyCSM");
1108 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1110 /* Set send & receive button tap and hold menu */
1111 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1116 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1117 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1118 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1120 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1121 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1123 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1128 compare_display_names (ModestAccountData *a,
1129 ModestAccountData *b)
1131 return strcmp (a->display_name, b->display_name);
1135 on_account_update (TnyAccountStore *account_store,
1136 const gchar *account_name,
1139 GSList *account_names, *iter, *accounts;
1140 ModestMainWindow *self;
1141 ModestMainWindowPrivate *priv;
1142 ModestWindowPrivate *parent_priv;
1143 ModestAccountMgr *mgr;
1144 gint i, num_accounts;
1145 GtkActionGroup *action_group;
1147 gchar *default_account;
1148 GtkWidget *send_receive_button, *item;
1149 GtkAction *send_receive_all = NULL;
1151 self = MODEST_MAIN_WINDOW (user_data);
1152 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1153 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1155 /* Get enabled account IDs */
1156 mgr = modest_runtime_get_account_mgr ();
1157 account_names = modest_account_mgr_account_names (mgr, TRUE);
1158 iter = account_names;
1162 ModestAccountData *account_data =
1163 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1164 accounts = g_slist_prepend (accounts, account_data);
1168 modest_account_mgr_free_account_names (account_names);
1169 account_names = NULL;
1171 /* Order the list of accounts by its display name */
1172 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1173 num_accounts = g_slist_length (accounts);
1175 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1176 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1177 gtk_action_set_visible (send_receive_all, num_accounts > 1);
1179 /* Delete old send&receive popup items. We can not just do a
1180 menu_detach because it does not work well with
1182 if (priv->accounts_popup)
1183 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
1184 (GtkCallback) gtk_widget_destroy, NULL);
1186 /* Delete old entries in the View menu. Do not free groups, it
1188 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1190 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1191 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1192 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
1193 GTK_ACTION_GROUP (groups->data));
1196 if (priv->merge_ids) {
1197 for (i = 0; i < priv->merge_ids->len; i++)
1198 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1199 g_byte_array_free (priv->merge_ids, TRUE);
1201 /* We need to call this in order to ensure
1202 that the new actions are added in the right
1203 order (alphabetical */
1204 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1206 groups = g_list_next (groups);
1208 priv->merge_ids = g_byte_array_sized_new (num_accounts);
1210 /* Get send receive button */
1211 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1212 "/ToolBar/ToolbarSendReceive");
1214 /* Create the menu */
1215 if (num_accounts > 1) {
1216 if (!priv->accounts_popup)
1217 priv->accounts_popup = gtk_menu_new ();
1218 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1219 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1220 g_signal_connect (G_OBJECT (item),
1222 G_CALLBACK (on_send_receive_csm_activated),
1224 item = gtk_separator_menu_item_new ();
1225 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1228 /* Create a new action group */
1229 default_account = modest_account_mgr_get_default_account (mgr);
1230 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1231 for (i = 0; i < num_accounts; i++) {
1232 gchar *display_name = NULL;
1234 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1236 /* Create display name. The default account is shown differently */
1237 if (default_account && account_data->account_name &&
1238 !(strcmp (default_account, account_data->account_name) == 0)) {
1239 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
1240 account_data->display_name);
1243 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
1244 account_data->display_name);
1247 /* Create action and add it to the action group. The
1248 action name must be the account name, this way we
1249 could know in the handlers the account to show */
1250 if(account_data->account_name) {
1251 gchar* item_name, *refresh_action_name;
1253 GtkAction *view_account_action, *refresh_account_action;
1255 view_account_action = gtk_action_new (account_data->account_name,
1256 display_name, NULL, NULL);
1257 gtk_action_group_add_action (action_group, view_account_action);
1259 /* Add ui from account data. We allow 2^9-1 account
1260 changes in a single execution because we're
1261 downcasting the guint to a guint8 in order to use a
1262 GByteArray, it should be enough */
1263 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1264 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1265 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1266 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1268 "/MenuBar/ViewMenu/ViewMenuAdditions",
1270 account_data->account_name,
1271 GTK_UI_MANAGER_MENUITEM,
1274 /* Connect the action signal "activate" */
1275 g_signal_connect (G_OBJECT (view_account_action),
1277 G_CALLBACK (on_show_account_action_activated),
1280 /* Create the items for the Tools->Send&Receive submenu */
1281 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1282 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
1283 display_name, NULL, NULL);
1284 gtk_action_group_add_action (action_group, refresh_account_action);
1286 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1287 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1288 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1290 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1292 refresh_action_name,
1293 GTK_UI_MANAGER_MENUITEM,
1295 g_free (refresh_action_name);
1297 g_signal_connect_data (G_OBJECT (refresh_account_action),
1299 G_CALLBACK (on_refresh_account_action_activated),
1300 g_strdup (account_data->account_name),
1301 (GClosureNotify) g_free,
1304 /* Create item and add it to the send&receive
1305 CSM. If there is only one account then
1307 if (priv->accounts_popup) {
1308 item = gtk_menu_item_new_with_label (display_name);
1309 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1310 g_signal_connect_data (G_OBJECT (item),
1312 G_CALLBACK (on_send_receive_csm_activated),
1313 g_strdup (account_data->account_name),
1314 (GClosureNotify) g_free,
1321 g_free (display_name);
1322 modest_account_mgr_free_account_data (mgr, account_data);
1324 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1326 if (priv->accounts_popup) {
1327 /* Mandatory in order to view the menu contents */
1328 gtk_widget_show_all (priv->accounts_popup);
1330 /* Setup tap_and_hold just if was not done before*/
1331 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1332 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1336 g_slist_free (accounts);
1337 g_free (default_account);
1341 * This function manages the key events used to navigate between
1342 * header and folder views (when the window is in split view)
1345 * -------------------------------------------------
1346 * HeaderView GDK_Left Move focus to folder view
1347 * FolderView GDK_Right Move focus to header view
1349 * There is no need to scroll to selected row, the widgets will be the
1350 * responsibles of doing that (probably managing the focus-in event
1353 on_inner_widgets_key_pressed (GtkWidget *widget,
1357 ModestMainWindowPrivate *priv;
1359 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1361 /* Do nothing if we're in SIMPLE style */
1362 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1365 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1366 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1367 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1368 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1374 set_alignment (GtkWidget *widget,
1377 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1378 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1382 create_empty_view (void)
1384 GtkLabel *label = NULL;
1385 GtkWidget *align = NULL;
1387 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1388 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1389 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1390 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1392 return GTK_WIDGET(align);
1396 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1398 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1403 gchar *gray_color_markup;
1405 vbox = gtk_vbox_new (FALSE, 0);
1407 /* Obtain the secondary text color. We need a realized widget, that's why
1408 we get styled_widget from outside */
1409 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1411 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1412 gray_color_markup = modest_text_utils_get_color_string (&color);
1414 // gray_color_markup is freed below
1415 gray_color_markup = g_strdup ("#BBBBBB");
1417 /* Account description: */
1419 if (modest_tny_account_is_virtual_local_folders (account)
1420 || (modest_tny_account_is_memory_card_account (account))) {
1422 /* Local folders: */
1424 /* Get device name */
1425 gchar *device_name = NULL;
1426 if (modest_tny_account_is_virtual_local_folders (account))
1427 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1428 MODEST_CONF_DEVICE_NAME, NULL);
1430 device_name = g_strdup (tny_account_get_name (account));
1432 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1433 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1434 gray_color_markup, tmp, device_name);
1436 label_w = gtk_label_new (NULL);
1437 gtk_label_set_markup (GTK_LABEL (label_w), label);
1438 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1439 g_free (device_name);
1442 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1443 gtk_box_pack_start (GTK_BOX (vbox),
1444 gtk_label_new (tny_account_get_name (account)),
1447 /* Other accounts, such as IMAP and POP: */
1452 /* Put proto in uppercase */
1453 proto = g_string_new (tny_account_get_proto (account));
1454 proto = g_string_ascii_up (proto);
1456 /* note: mcen_fi_localroot_description is something like "%s account"
1457 * however, we should display "%s account: %s"... therefore, ugly tmp */
1458 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1459 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1460 gray_color_markup, tmp, tny_account_get_name (account));
1463 label_w = gtk_label_new (NULL);
1464 gtk_label_set_markup (GTK_LABEL (label_w), label);
1465 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1466 g_string_free (proto, TRUE);
1472 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1473 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1474 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1475 modest_tny_folder_store_get_message_count (folder_store));
1476 label_w = gtk_label_new (NULL);
1477 gtk_label_set_markup (GTK_LABEL (label_w), label);
1478 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1482 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1484 _("mcen_fi_rootfolder_folders"),
1485 modest_tny_folder_store_get_folder_count (folder_store));
1486 label_w = gtk_label_new (NULL);
1487 gtk_label_set_markup (GTK_LABEL (label_w), label);
1488 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1492 if (modest_tny_account_is_virtual_local_folders (account)
1493 || modest_tny_account_is_memory_card_account (account)) {
1494 /* FIXME: format size */
1495 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1496 gray_color_markup, _("mcen_fi_rootfolder_size"),
1497 modest_tny_folder_store_get_local_size (folder_store));
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);
1502 } else if (TNY_IS_ACCOUNT(folder_store)) {
1503 TnyAccount *account = TNY_ACCOUNT(folder_store);
1505 time_t last_updated;
1506 gchar *last_updated_string;
1507 /* Get last updated from configuration */
1508 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1509 tny_account_get_id (account),
1510 MODEST_ACCOUNT_LAST_UPDATED,
1512 if (last_updated > 0)
1513 last_updated_string = modest_text_utils_get_display_date(last_updated);
1515 last_updated_string = g_strdup (_("mcen_va_never"));
1517 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1518 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1519 label_w = gtk_label_new (NULL);
1520 gtk_label_set_markup (GTK_LABEL (label_w), label);
1521 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1522 g_free (last_updated_string);
1526 g_free (gray_color_markup);
1529 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1535 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1537 ModestMainWindowPrivate *priv = NULL;
1539 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1541 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1543 return priv->send_receive_in_progress;
1547 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1549 GtkAction *action = NULL;
1550 GtkWidget *widget = NULL;
1551 ModestMainWindowPrivate *priv = NULL;
1553 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1554 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1556 priv->send_receive_in_progress = TRUE;
1558 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1559 gtk_action_set_sensitive (action, FALSE);
1560 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1561 /* gtk_action_set_sensitive (action, FALSE); */
1562 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1563 gtk_widget_set_sensitive (widget, FALSE);
1567 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1569 GtkAction *action = NULL;
1570 GtkWidget *widget = NULL;
1571 ModestMainWindowPrivate *priv = NULL;
1573 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1574 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1576 priv->send_receive_in_progress = FALSE;
1578 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1579 gtk_action_set_sensitive (action, TRUE);
1580 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1581 /* gtk_action_set_sensitive (action, TRUE); */
1582 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1583 gtk_widget_set_sensitive (widget, TRUE);
1588 _on_msg_count_changed (ModestHeaderView *header_view,
1590 TnyFolderChange *change,
1591 ModestMainWindow *main_window)
1593 printf ("DEBUG: %s\n", __FUNCTION__);
1594 gboolean folder_empty = FALSE;
1595 TnyFolderChangeChanged changed;
1597 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1598 g_return_if_fail (TNY_IS_FOLDER(folder));
1599 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1601 changed = tny_folder_change_get_changed (change);
1603 /* If something changes */
1604 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1605 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1607 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1609 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1611 /* Set contents style of headers view */
1613 modest_main_window_set_contents_style (main_window,
1614 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1617 modest_main_window_set_contents_style (main_window,
1618 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1623 modest_main_window_set_contents_style (ModestMainWindow *self,
1624 ModestMainWindowContentsStyle style)
1626 ModestMainWindowPrivate *priv;
1628 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1630 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1632 /* We allow to set the same content style than the previously
1633 set if there are details, because it could happen when we're
1634 selecting different accounts consecutively */
1635 if ((priv->contents_style == style) &&
1636 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1639 /* Remove previous child. Delete it if it was an account
1641 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1643 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1644 g_object_ref (content);
1645 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1646 g_object_ref (priv->empty_view);
1647 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1650 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1653 priv->contents_style = style;
1655 switch (priv->contents_style) {
1656 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1657 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1659 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1661 TnyFolderStore *selected_folderstore =
1662 modest_folder_view_get_selected (priv->folder_view);
1663 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1664 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1665 TNY_ACCOUNT (selected_folderstore));
1667 wrap_in_scrolled_window (priv->contents_widget,
1668 priv->details_widget);
1670 g_object_unref (selected_folderstore);
1673 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1674 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1677 g_return_if_reached ();
1681 gtk_widget_show_all (priv->contents_widget);
1684 ModestMainWindowContentsStyle
1685 modest_main_window_get_contents_style (ModestMainWindow *self)
1687 ModestMainWindowPrivate *priv;
1689 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1691 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1692 return priv->contents_style;
1697 on_configuration_key_changed (ModestConf* conf,
1699 ModestConfEvent event,
1700 ModestMainWindow *self)
1702 ModestMainWindowPrivate *priv;
1703 TnyAccount *account;
1705 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1708 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1710 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1713 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1714 if (TNY_IS_ACCOUNT (account) &&
1715 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1718 const gchar *device_name;
1722 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1723 label = GTK_LABEL (children->data);
1725 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1726 MODEST_CONF_DEVICE_NAME, NULL);
1728 new_text = g_strdup_printf ("%s: %s",
1729 _("mcen_fi_localroot_description"),
1732 gtk_label_set_text (label, new_text);
1733 gtk_widget_show (GTK_WIDGET (label));
1736 g_list_free (children);
1738 g_object_unref (account);
1742 set_toolbar_transfer_mode (ModestMainWindow *self)
1744 ModestMainWindowPrivate *priv = NULL;
1746 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1748 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1750 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1752 if (priv->progress_bar_timeout > 0) {
1753 g_source_remove (priv->progress_bar_timeout);
1754 priv->progress_bar_timeout = 0;
1761 set_toolbar_mode (ModestMainWindow *self,
1762 ModestToolBarModes mode)
1764 ModestWindowPrivate *parent_priv = NULL;
1765 ModestMainWindowPrivate *priv = NULL;
1766 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1768 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1770 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1771 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1773 /* In case this was called before the toolbar exists: */
1774 if (!(parent_priv->toolbar))
1777 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1779 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1780 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1781 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1783 /* Sets current toolbar mode */
1784 priv->current_toolbar_mode = mode;
1786 /* Show and hide toolbar items */
1788 case TOOLBAR_MODE_NORMAL:
1790 gtk_action_set_visible (sort_action, TRUE);
1792 gtk_action_set_visible (refresh_action, TRUE);
1793 if (priv->progress_toolitem) {
1794 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1795 gtk_widget_hide (priv->progress_toolitem);
1797 if (priv->progress_bar)
1798 gtk_widget_hide (priv->progress_bar);
1801 gtk_action_set_visible (cancel_action, FALSE);
1802 /* if (priv->sort_toolitem) */
1803 /* gtk_widget_show (priv->sort_toolitem); */
1805 /* if (priv->refresh_toolitem) */
1806 /* gtk_widget_show (priv->refresh_toolitem); */
1808 /* if (priv->progress_toolitem) */
1809 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1810 /* if (priv->progress_bar) */
1811 /* gtk_widget_hide (priv->progress_bar); */
1813 /* if (priv->cancel_toolitem) */
1814 /* gtk_widget_hide (priv->cancel_toolitem); */
1816 /* Hide toolbar if optimized view is enabled */
1817 if (priv->optimized_view)
1818 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1820 case TOOLBAR_MODE_TRANSFER:
1822 gtk_action_set_visible (sort_action, FALSE);
1824 gtk_action_set_visible (refresh_action, FALSE);
1826 gtk_action_set_visible (cancel_action, TRUE);
1827 if (priv->progress_toolitem) {
1828 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1829 gtk_widget_show (priv->progress_toolitem);
1831 if (priv->progress_bar)
1832 gtk_widget_show (priv->progress_bar);
1834 /* if (priv->sort_toolitem) */
1835 /* gtk_widget_hide (priv->sort_toolitem); */
1837 /* if (priv->refresh_toolitem) */
1838 /* gtk_widget_hide (priv->refresh_toolitem); */
1840 /* if (priv->progress_toolitem) */
1841 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1842 /* if (priv->progress_bar) */
1843 /* gtk_widget_show (priv->progress_bar); */
1845 /* if (priv->cancel_toolitem) */
1846 /* gtk_widget_show (priv->cancel_toolitem); */
1848 /* Show toolbar if it's hiden (optimized view ) */
1849 if (priv->optimized_view)
1850 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1853 g_return_if_reached ();
1858 cancel_progressbar (GtkToolButton *toolbutton,
1859 ModestMainWindow *self)
1862 ModestMainWindowPrivate *priv;
1864 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1866 /* Get operation observers and cancel its current operation */
1867 tmp = priv->progress_widgets;
1869 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1870 tmp=g_slist_next(tmp);
1875 observers_empty (ModestMainWindow *self)
1878 ModestMainWindowPrivate *priv;
1879 gboolean is_empty = TRUE;
1880 guint pending_ops = 0;
1882 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1883 tmp = priv->progress_widgets;
1885 /* Check all observers */
1886 while (tmp && is_empty) {
1887 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1888 is_empty = pending_ops == 0;
1890 tmp = g_slist_next(tmp);
1897 on_queue_changed (ModestMailOperationQueue *queue,
1898 ModestMailOperation *mail_op,
1899 ModestMailOperationQueueNotification type,
1900 ModestMainWindow *self)
1902 ModestMainWindowPrivate *priv;
1903 ModestMailOperationTypeOperation op_type;
1904 ModestToolBarModes mode;
1906 gboolean mode_changed = FALSE;
1907 /* ModestMailOperationStatus status; */
1909 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1910 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1912 /* Get toolbar mode from operation id*/
1913 op_type = modest_mail_operation_get_type_operation (mail_op);
1915 case MODEST_MAIL_OPERATION_TYPE_SEND:
1916 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1917 case MODEST_MAIL_OPERATION_TYPE_OPEN:
1918 mode = TOOLBAR_MODE_TRANSFER;
1919 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1920 mode_changed = TRUE;
1923 mode = TOOLBAR_MODE_NORMAL;
1928 /* Add operation observers and change toolbar if neccessary*/
1929 tmp = priv->progress_widgets;
1931 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1932 if (mode == TOOLBAR_MODE_TRANSFER) {
1934 set_toolbar_transfer_mode(self);
1936 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1938 tmp = g_slist_next (tmp);
1942 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1943 /* Change toolbar mode */
1944 if (mode == TOOLBAR_MODE_TRANSFER) {
1946 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1948 tmp = g_slist_next (tmp);
1951 /* If no more operations are being observed, NORMAL mode is enabled again */
1952 if (observers_empty (self)) {
1953 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1964 on_show_account_action_activated (GtkAction *action,
1967 ModestAccountData *acc_data;
1968 ModestMainWindow *self;
1969 ModestMainWindowPrivate *priv;
1970 ModestAccountMgr *mgr;
1971 const gchar *acc_name;
1973 self = MODEST_MAIN_WINDOW (user_data);
1974 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1976 /* Get account data */
1977 acc_name = gtk_action_get_name (action);
1978 mgr = modest_runtime_get_account_mgr ();
1979 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
1981 /* Set the new visible & active account */
1982 if (acc_data->store_account) {
1983 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
1984 acc_data->store_account->account_name);
1985 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
1989 modest_account_mgr_free_account_data (mgr, acc_data);
1993 refresh_account (const gchar *account_name)
1997 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
1999 /* If account_name == NULL, we must update all (option All) */
2001 modest_ui_actions_do_send_receive_all (win);
2003 modest_ui_actions_do_send_receive (account_name, win);
2008 on_refresh_account_action_activated (GtkAction *action,
2011 refresh_account ((const gchar*) user_data);
2015 on_send_receive_csm_activated (GtkMenuItem *item,
2018 refresh_account ((const gchar*) user_data);
2022 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2024 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2026 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));