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 on_folder_view_focus_in (GtkWidget *widget,
144 GdkEventFocus *event,
147 on_header_view_focus_in (GtkWidget *widget,
148 GdkEventFocus *event,
151 /* list my signals */
158 typedef struct _ModestMainWindowPrivate ModestMainWindowPrivate;
159 struct _ModestMainWindowPrivate {
160 GtkWidget *msg_paned;
161 GtkWidget *main_paned;
162 GtkWidget *main_vbox;
163 GtkWidget *contents_widget;
164 GtkWidget *empty_view;
166 /* Progress observers */
167 GtkWidget *progress_bar;
168 GSList *progress_widgets;
171 GtkWidget *progress_toolitem;
172 GtkWidget *cancel_toolitem;
173 GtkWidget *sort_toolitem;
174 GtkWidget *refresh_toolitem;
175 ModestToolBarModes current_toolbar_mode;
177 /* Merge ids used to add/remove accounts to the ViewMenu*/
178 GByteArray *merge_ids;
180 /* On-demand widgets */
181 GtkWidget *accounts_popup;
182 GtkWidget *details_widget;
184 /* Optimized view enabled */
185 gboolean optimized_view;
187 /* Optimized view enabled */
188 gboolean send_receive_in_progress;
190 ModestHeaderView *header_view;
191 ModestFolderView *folder_view;
193 ModestMainWindowStyle style;
194 ModestMainWindowContentsStyle contents_style;
196 guint progress_bar_timeout;
198 /* Signal handler UIDs */
199 gint queue_changed_handler_uid;
200 GList *queue_err_signals;
202 #define MODEST_MAIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
203 MODEST_TYPE_MAIN_WINDOW, \
204 ModestMainWindowPrivate))
206 typedef struct _GetMsgAsyncHelper {
207 ModestMainWindowPrivate *main_window_private;
209 ModestTnyMsgReplyType reply_type;
210 ModestTnyMsgForwardType forward_type;
217 static GtkWindowClass *parent_class = NULL;
220 /* Private actions */
221 /* This is the context sensitive menu: */
222 static const GtkActionEntry modest_folder_view_action_entries [] = {
224 /* Folder View CSM actions */
225 { "FolderViewCSMNewFolder", NULL, N_("mcen_ti_new_folder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_new_folder) },
226 { "FolderViewCSMRenameFolder", NULL, N_("mcen_me_user_renamefolder"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_rename_folder) },
227 { "FolderViewCSMPasteMsgs", NULL, N_("mcen_me_inbox_paste"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_paste)},
228 { "FolderViewCSMDeleteFolder", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete_folder) },
229 { "FolderViewCSMSearchMessages", NULL, N_("mcen_me_inbox_search"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_search_messages) },
230 { "FolderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
233 static const GtkActionEntry modest_header_view_action_entries [] = {
235 /* Header View CSM actions */
236 { "HeaderViewCSMOpen", NULL, N_("mcen_me_inbox_open"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_open) },
237 { "HeaderViewCSMReply", NULL, N_("mcen_me_inbox_reply"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply) },
238 { "HeaderViewCSMReplyAll", NULL, N_("mcen_me_inbox_replytoall"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_reply_all) },
239 { "HeaderViewCSMForward", NULL, N_("mcen_me_inbox_forward"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_forward) },
240 { "HeaderViewCSMCut", NULL, N_("mcen_me_inbox_cut"), "<CTRL>X", NULL, G_CALLBACK (modest_ui_actions_on_cut) },
241 { "HeaderViewCSMCopy", NULL, N_("mcen_me_inbox_copy"), "<CTRL>C", NULL, G_CALLBACK (modest_ui_actions_on_copy) },
242 { "HeaderViewCSMPaste", NULL, N_("mcen_me_inbox_paste"), "<CTRL>V", NULL, G_CALLBACK (modest_ui_actions_on_paste) },
243 { "HeaderViewCSMDelete", NULL, N_("mcen_me_inbox_delete"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_delete) },
244 { "HeaderViewCSMCancelSending", NULL, N_("mcen_me_outbox_cancelsend"), NULL, NULL, NULL },
245 { "HeaderViewCSMHelp", NULL, N_("mcen_me_inbox_help"), NULL, NULL, G_CALLBACK (modest_ui_actions_on_help) },
248 static const GtkToggleActionEntry modest_main_window_toggle_action_entries [] = {
249 { "ToolbarToggleView", MODEST_STOCK_SPLIT_VIEW, N_("gqn_toolb_rss_fldonoff"), "<CTRL>t", NULL, G_CALLBACK (modest_ui_actions_toggle_folders_view), FALSE },
252 /************************************************************************/
255 modest_main_window_get_type (void)
257 static GType my_type = 0;
259 static const GTypeInfo my_info = {
260 sizeof(ModestMainWindowClass),
261 NULL, /* base init */
262 NULL, /* base finalize */
263 (GClassInitFunc) modest_main_window_class_init,
264 NULL, /* class finalize */
265 NULL, /* class data */
266 sizeof(ModestMainWindow),
268 (GInstanceInitFunc) modest_main_window_init,
271 my_type = g_type_register_static (MODEST_TYPE_WINDOW,
279 modest_main_window_class_init (ModestMainWindowClass *klass)
281 GObjectClass *gobject_class;
282 gobject_class = (GObjectClass*) klass;
283 ModestWindowClass *modest_window_class = (ModestWindowClass *) klass;
285 parent_class = g_type_class_peek_parent (klass);
286 gobject_class->finalize = modest_main_window_finalize;
288 g_type_class_add_private (gobject_class, sizeof(ModestMainWindowPrivate));
290 modest_window_class->show_toolbar_func = modest_main_window_show_toolbar;
291 modest_window_class->save_state_func = save_state;
292 modest_window_class->zoom_minus_func = on_zoom_minus_plus_not_implemented;
293 modest_window_class->zoom_plus_func = on_zoom_minus_plus_not_implemented;
297 modest_main_window_init (ModestMainWindow *obj)
299 ModestMainWindowPrivate *priv;
301 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
303 priv->queue_err_signals = NULL;
304 priv->msg_paned = NULL;
305 priv->main_paned = NULL;
306 priv->main_vbox = NULL;
307 priv->header_view = NULL;
308 priv->folder_view = NULL;
309 priv->contents_widget = NULL;
310 priv->accounts_popup = NULL;
311 priv->details_widget = NULL;
312 priv->empty_view = NULL;
313 priv->progress_widgets = NULL;
314 priv->progress_bar = NULL;
315 priv->current_toolbar_mode = TOOLBAR_MODE_NORMAL;
316 priv->style = MODEST_MAIN_WINDOW_STYLE_SPLIT;
317 priv->contents_style = -1; /* invalid contents style. We need this to select it for the first time */
318 priv->merge_ids = NULL;
319 priv->optimized_view = FALSE;
320 priv->send_receive_in_progress = FALSE;
321 priv->progress_bar_timeout = 0;
322 priv->queue_changed_handler_uid = 0;
326 modest_main_window_finalize (GObject *obj)
328 ModestMainWindowPrivate *priv;
330 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(obj);
332 modest_main_window_cleanup_queue_error_signals ((ModestMainWindow *) obj);
334 g_slist_free (priv->progress_widgets);
336 g_byte_array_free (priv->merge_ids, TRUE);
338 if (priv->progress_bar_timeout > 0) {
339 g_source_remove (priv->progress_bar_timeout);
340 priv->progress_bar_timeout = 0;
343 /* Disconnect signal handlers */
344 if (priv->queue_changed_handler_uid)
345 g_signal_handler_disconnect (modest_runtime_get_mail_operation_queue (),
346 priv->queue_changed_handler_uid);
348 G_OBJECT_CLASS(parent_class)->finalize (obj);
352 modest_main_window_get_child_widget (ModestMainWindow *self,
353 ModestWidgetType widget_type)
355 ModestMainWindowPrivate *priv;
358 g_return_val_if_fail (self, NULL);
359 g_return_val_if_fail (widget_type >= 0 && widget_type < MODEST_WIDGET_TYPE_NUM,
362 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
364 switch (widget_type) {
365 case MODEST_WIDGET_TYPE_HEADER_VIEW:
366 widget = (GtkWidget*)priv->header_view; break;
367 case MODEST_WIDGET_TYPE_FOLDER_VIEW:
368 widget = (GtkWidget*)priv->folder_view; break;
373 return widget ? GTK_WIDGET(widget) : NULL;
378 restore_settings (ModestMainWindow *self, gboolean do_folder_view_too)
381 ModestMainWindowPrivate *priv;
383 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
385 conf = modest_runtime_get_conf ();
387 modest_widget_memory_restore (conf, G_OBJECT(self),
388 MODEST_CONF_MAIN_WINDOW_KEY);
390 modest_widget_memory_restore (conf, G_OBJECT(priv->header_view),
391 MODEST_CONF_HEADER_VIEW_KEY);
393 if (do_folder_view_too)
394 modest_widget_memory_restore (conf, G_OBJECT(priv->folder_view),
395 MODEST_CONF_FOLDER_VIEW_KEY);
397 modest_widget_memory_restore (conf, G_OBJECT(priv->main_paned),
398 MODEST_CONF_MAIN_PANED_KEY);
400 /* We need to force a redraw here in order to get the right
401 position of the horizontal paned separator */
402 gtk_widget_show (GTK_WIDGET (self));
407 save_state (ModestWindow *window)
410 ModestMainWindow* self = MODEST_MAIN_WINDOW(window);
411 ModestMainWindowPrivate *priv;
413 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
414 conf = modest_runtime_get_conf ();
416 modest_widget_memory_save (conf,G_OBJECT(self),
417 MODEST_CONF_MAIN_WINDOW_KEY);
418 modest_widget_memory_save (conf, G_OBJECT(priv->main_paned),
419 MODEST_CONF_MAIN_PANED_KEY);
420 // modest_widget_memory_save (conf, G_OBJECT(priv->header_view),
421 // MODEST_CONF_HEADER_VIEW_KEY);
422 modest_widget_memory_save (conf, G_OBJECT(priv->folder_view),
423 MODEST_CONF_FOLDER_VIEW_KEY);
427 wrap_in_scrolled_window (GtkWidget *win, GtkWidget *widget)
429 if (!gtk_widget_set_scroll_adjustments (widget, NULL, NULL))
430 gtk_scrolled_window_add_with_viewport
431 (GTK_SCROLLED_WINDOW(win), widget);
433 gtk_container_add (GTK_CONTAINER(win),
439 on_delete_event (GtkWidget *widget, GdkEvent *event, ModestMainWindow *self)
441 modest_window_save_state (MODEST_WINDOW(self));
447 ModestMainWindow *self;
453 on_response (GtkDialog *dialog, gint arg1, gpointer user_data)
455 OnResponseInfo *info = (OnResponseInfo *) user_data;
456 ModestMainWindow *self = info->self;
457 TnyHeader *header = info->header;
458 TnySendQueue *queue = info->queue;
460 if (arg1 == GTK_RESPONSE_YES) {
461 TnyFolder *outbox = tny_send_queue_get_outbox (queue);
462 tny_folder_remove_msg (outbox, header, NULL);
463 tny_folder_sync (outbox, TRUE, NULL);
464 g_object_unref (outbox);
467 g_object_unref (queue);
468 g_object_unref (header);
469 g_object_unref (self);
471 gtk_widget_destroy (GTK_WIDGET (dialog));
472 g_slice_free (OnResponseInfo, info);
477 on_sendqueue_error_happened (TnySendQueue *self, TnyHeader *header, TnyMsg *msg, GError *err, ModestMainWindow *user_data)
480 gchar *str = g_strdup_printf ("%s. Do you want to remove the message (%s)?",
481 err->message, tny_header_get_subject (header));
482 OnResponseInfo *info = g_slice_new (OnResponseInfo);
483 GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (user_data), 0,
484 GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, str);
486 info->queue = g_object_ref (self);
487 info->self = g_object_ref (user_data);
488 info->header = g_object_ref (header);
489 g_signal_connect (G_OBJECT (dialog), "response",
490 G_CALLBACK (on_response), info);
491 gtk_widget_show_all (dialog);
501 modest_main_window_cleanup_queue_error_signals (ModestMainWindow *self)
503 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
505 GList *oerrsignals = priv->queue_err_signals;
506 while (oerrsignals) {
507 QueueErrorSignal *esignal = (QueueErrorSignal *) oerrsignals->data;
508 g_signal_handler_disconnect (esignal->queue, esignal->signal);
509 g_slice_free (QueueErrorSignal, esignal);
510 oerrsignals = g_list_next (oerrsignals);
512 g_list_free (priv->queue_err_signals);
513 priv->queue_err_signals = NULL;
517 on_account_store_connecting_finished (TnyAccountStore *store, ModestMainWindow *self)
519 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
521 /* When going online, do the equivalent of pressing the send/receive button,
522 * as per the specification:
523 * (without the check for >0 accounts, though that is not specified): */
525 TnyDevice *device = tny_account_store_get_device (store);
527 /* modest_folder_view_update_model (MODEST_FOLDER_VIEW (priv->folder_view), store); */
529 /* Check that we are really online.
530 * This signal should not be emitted when we are not connected,
531 * but it seems to happen sometimes: */
532 if (!tny_device_is_online (device))
535 const gchar *iap_id = tny_maemo_conic_device_get_current_iap_id (TNY_MAEMO_CONIC_DEVICE (device));
536 printf ("DEBUG: %s: connection id=%s\n", __FUNCTION__, iap_id);
538 /* Stop the existing send queues: */
539 modest_runtime_remove_all_send_queues ();
541 /* Create the send queues again, using the appropriate transport accounts
542 * for this new connection.
543 * This could be the first time that they are created if this is the first
545 /* TODO: Does this really destroy the TnySendQueues and their threads
546 * We do not want 2 TnySendQueues to exist with the same underlying
547 * outbox directory. */
549 modest_main_window_cleanup_queue_error_signals (self);
551 GSList *account_names = modest_account_mgr_account_names (
552 modest_runtime_get_account_mgr(),
553 TRUE /* enabled accounts only */);
554 GSList *iter = account_names;
556 const gchar *account_name = (const gchar*)(iter->data);
558 TnyTransportAccount *account = TNY_TRANSPORT_ACCOUNT (
559 modest_tny_account_store_get_transport_account_for_open_connection
560 (modest_runtime_get_account_store(), account_name));
562 /* Q: Is this the first location where the send-queues are requested? */
563 QueueErrorSignal *esignal = g_slice_new (QueueErrorSignal);
564 printf ("debug: %s:\n Transport account for %s: %s\n", __FUNCTION__, account_name,
565 tny_account_get_id(TNY_ACCOUNT(account)));
566 esignal->queue = TNY_SEND_QUEUE (modest_runtime_get_send_queue (account));
567 esignal->signal = g_signal_connect (G_OBJECT (esignal->queue), "error-happened",
568 G_CALLBACK (on_sendqueue_error_happened), self);
569 priv->queue_err_signals = g_list_prepend (priv->queue_err_signals, esignal);
573 iter = g_slist_next (iter);
576 modest_account_mgr_free_account_names (account_names);
577 account_names = NULL;
579 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (self));
583 _folder_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
585 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
588 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
592 _header_view_csm_menu_activated (GtkWidget *widget, gpointer user_data)
594 g_return_if_fail (MODEST_IS_MAIN_WINDOW (user_data));
596 /* Update visibility */
599 modest_window_check_dimming_rules_group (MODEST_WINDOW (user_data), "ModestMenuDimmingRules");
603 connect_signals (ModestMainWindow *self)
605 ModestWindowPrivate *parent_priv;
606 ModestMainWindowPrivate *priv;
609 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
610 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
613 g_signal_connect (G_OBJECT(priv->folder_view), "key-press-event",
614 G_CALLBACK(on_inner_widgets_key_pressed), self);
615 g_signal_connect (G_OBJECT(priv->folder_view), "folder_selection_changed",
616 G_CALLBACK(modest_ui_actions_on_folder_selection_changed), self);
617 g_signal_connect (G_OBJECT(priv->folder_view), "folder-display-name-changed",
618 G_CALLBACK(modest_ui_actions_on_folder_display_name_changed), self);
619 g_signal_connect (G_OBJECT (priv->folder_view), "focus-in-event",
620 G_CALLBACK (on_folder_view_focus_in), self);
622 /* Folder view CSM */
623 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/FolderViewCSM");
624 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->folder_view), menu, NULL, 0);
625 g_signal_connect (G_OBJECT(priv->folder_view), "tap-and-hold",
626 G_CALLBACK(_folder_view_csm_menu_activated),
629 g_signal_connect (G_OBJECT(priv->header_view), "header_selected",
630 G_CALLBACK(modest_ui_actions_on_header_selected), self);
631 g_signal_connect (G_OBJECT(priv->header_view), "header_activated",
632 G_CALLBACK(modest_ui_actions_on_header_activated), self);
633 g_signal_connect (G_OBJECT(priv->header_view), "item_not_found",
634 G_CALLBACK(modest_ui_actions_on_item_not_found), self);
635 g_signal_connect (G_OBJECT(priv->header_view), "key-press-event",
636 G_CALLBACK(on_inner_widgets_key_pressed), self);
637 g_signal_connect (G_OBJECT(priv->header_view), "msg_count_changed",
638 G_CALLBACK(_on_msg_count_changed), self);
639 g_signal_connect (G_OBJECT (priv->header_view), "focus-in-event",
640 G_CALLBACK (on_header_view_focus_in), self);
642 /* Header view CSM */
643 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/HeaderViewCSM");
644 gtk_widget_tap_and_hold_setup (GTK_WIDGET (priv->header_view), menu, NULL, 0);
645 g_signal_connect (G_OBJECT(priv->header_view), "tap-and-hold",
646 G_CALLBACK(_header_view_csm_menu_activated),
650 g_signal_connect (G_OBJECT(self), "delete-event", G_CALLBACK(on_delete_event), self);
651 g_signal_connect (G_OBJECT (self), "window-state-event",
652 G_CALLBACK (modest_main_window_window_state_event),
655 /* Mail Operation Queue */
656 priv->queue_changed_handler_uid =
657 g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
658 "queue-changed", G_CALLBACK (on_queue_changed), self);
660 /* Track changes in the device name */
661 g_signal_connect (G_OBJECT(modest_runtime_get_conf ()),
662 "key_changed", G_CALLBACK (on_configuration_key_changed),
665 /* Track account changes. We need to refresh the toolbar */
666 g_signal_connect (G_OBJECT (modest_runtime_get_account_store ()),
667 "account_update", G_CALLBACK (on_account_update),
671 g_signal_connect (G_OBJECT (modest_runtime_get_account_store()),
672 "password_requested",
673 G_CALLBACK (modest_ui_actions_on_password_requested), self);
676 g_signal_connect (G_OBJECT(modest_runtime_get_account_store()),
677 "connecting-finished",
678 G_CALLBACK(on_account_store_connecting_finished), self);
682 /** Idle handler, to send/receive at startup .*/
684 sync_accounts_cb (ModestMainWindow *win)
686 modest_ui_actions_do_send_receive (NULL, MODEST_WINDOW (win));
687 return FALSE; /* Do not call this idle handler again. */
691 static void on_hildon_program_is_topmost_notify(GObject *self,
692 GParamSpec *propert_param, gpointer user_data)
694 HildonProgram *app = HILDON_PROGRAM (self);
697 ModestWindow* self = MODEST_WINDOW(user_data);
700 /* Note that use of hildon_program_set_can_hibernate()
701 * is generally referred to as "setting the killable flag",
702 * though hibernation does not seem equal to death.
705 if (hildon_program_get_is_topmost (app)) {
706 /* Prevent hibernation when the progam comes to the foreground,
707 * because hibernation should only happen when the application
708 * is in the background: */
709 hildon_program_set_can_hibernate (app, FALSE);
711 /* Allow hibernation if the program has gone to the background: */
713 /* However, prevent hibernation while the settings are being changed: */
714 const gboolean hibernation_prevented =
715 modest_window_mgr_get_hibernation_is_prevented (
716 modest_runtime_get_window_mgr ());
718 if (hibernation_prevented)
719 hildon_program_set_can_hibernate (app, FALSE);
721 /* Allow hibernation, after saving the state: */
722 modest_osso_save_state();
723 hildon_program_set_can_hibernate (app, TRUE);
730 modest_main_window_on_show (GtkWidget *self, gpointer user_data)
732 GtkWidget *folder_win = (GtkWidget *) user_data;
733 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
735 priv->folder_view = MODEST_FOLDER_VIEW (modest_platform_create_folder_view (NULL));
736 wrap_in_scrolled_window (folder_win, GTK_WIDGET(priv->folder_view));
737 /* wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET(priv->header_view)); */
739 gtk_widget_show (GTK_WIDGET (priv->folder_view));
741 /* Connect signals */
742 connect_signals ((ModestMainWindow*)self);
744 /* Set account store */
745 tny_account_store_view_set_account_store (TNY_ACCOUNT_STORE_VIEW (priv->folder_view),
746 TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()));
748 /* Load previous osso state, for instance if we are being restored from
750 modest_osso_load_state ();
752 /* Restore window & widget settings */
754 restore_settings (MODEST_MAIN_WINDOW(self), TRUE);
756 /* Check if accounts exist and show the account wizard if not */
757 gboolean accounts_exist =
758 modest_account_mgr_has_accounts(modest_runtime_get_account_mgr(), TRUE);
760 if (!accounts_exist) {
761 /* This is necessary to have the main window shown behind the dialog
762 It's an ugly hack... jschmid */
763 gtk_widget_show_all(GTK_WIDGET(self));
764 modest_ui_actions_on_accounts (NULL, MODEST_WINDOW(self));
767 GtkAction *send_receive_all;
768 ModestWindowPrivate *parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
769 accounts = modest_account_mgr_account_names (modest_runtime_get_account_mgr (), TRUE);
770 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
771 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
772 gtk_action_set_visible (send_receive_all, g_slist_length (accounts));
773 modest_account_mgr_free_account_names (accounts);
780 modest_main_window_new (void)
782 ModestMainWindow *self = NULL;
783 ModestMainWindowPrivate *priv = NULL;
784 ModestWindowPrivate *parent_priv = NULL;
785 GtkWidget *folder_win = NULL;
786 ModestDimmingRulesGroup *menu_rules_group = NULL;
787 ModestDimmingRulesGroup *toolbar_rules_group = NULL;
788 GtkActionGroup *action_group = NULL;
789 GError *error = NULL;
790 ModestConf *conf = NULL;
791 GtkAction *action = NULL;
793 self = MODEST_MAIN_WINDOW(g_object_new(MODEST_TYPE_MAIN_WINDOW, NULL));
794 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
795 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
797 parent_priv->ui_manager = gtk_ui_manager_new();
798 parent_priv->ui_dimming_manager = modest_ui_dimming_manager_new();
800 action_group = gtk_action_group_new ("ModestMainWindowActions");
801 gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
803 menu_rules_group = modest_dimming_rules_group_new ("ModestMenuDimmingRules");
804 toolbar_rules_group = modest_dimming_rules_group_new ("ModestToolbarDimmingRules");
806 /* Add common actions */
807 gtk_action_group_add_actions (action_group,
808 modest_action_entries,
809 G_N_ELEMENTS (modest_action_entries),
812 gtk_action_group_add_actions (action_group,
813 modest_folder_view_action_entries,
814 G_N_ELEMENTS (modest_folder_view_action_entries),
817 gtk_action_group_add_actions (action_group,
818 modest_header_view_action_entries,
819 G_N_ELEMENTS (modest_header_view_action_entries),
822 gtk_action_group_add_toggle_actions (action_group,
823 modest_toggle_action_entries,
824 G_N_ELEMENTS (modest_toggle_action_entries),
827 gtk_action_group_add_toggle_actions (action_group,
828 modest_main_window_toggle_action_entries,
829 G_N_ELEMENTS (modest_main_window_toggle_action_entries),
832 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 0);
833 g_object_unref (action_group);
835 /* Load the UI definition */
836 gtk_ui_manager_add_ui_from_file (parent_priv->ui_manager,
837 MODEST_UIDIR "modest-main-window-ui.xml", &error);
839 g_warning ("Could not merge modest-ui.xml: %s", error->message);
840 g_error_free (error);
844 /* Add common dimming rules */
845 modest_dimming_rules_group_add_rules (menu_rules_group,
846 modest_main_window_menu_dimming_entries,
847 G_N_ELEMENTS (modest_main_window_menu_dimming_entries),
849 modest_dimming_rules_group_add_rules (toolbar_rules_group,
850 modest_main_window_toolbar_dimming_entries,
851 G_N_ELEMENTS (modest_main_window_toolbar_dimming_entries),
854 /* Insert dimming rules group for this window */
855 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, menu_rules_group);
856 modest_ui_dimming_manager_insert_rules_group (parent_priv->ui_dimming_manager, toolbar_rules_group);
857 g_object_unref (menu_rules_group);
858 g_object_unref (toolbar_rules_group);
860 /* Add accelerators */
861 gtk_window_add_accel_group (GTK_WINDOW (self),
862 gtk_ui_manager_get_accel_group (parent_priv->ui_manager));
864 /* Menubar. Update the state of some toggles */
865 parent_priv->menubar = modest_maemo_utils_menubar_to_menu (parent_priv->ui_manager);
866 conf = modest_runtime_get_conf ();
867 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
868 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarNormalScreenMenu");
869 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
870 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL));
871 action = gtk_ui_manager_get_action (parent_priv->ui_manager,
872 "/MenuBar/ViewMenu/ViewShowToolbarMainMenu/ViewShowToolbarFullScreenMenu");
873 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
874 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL));
875 hildon_window_set_menu (HILDON_WINDOW (self), GTK_MENU (parent_priv->menubar));
877 /* Get device name */
878 modest_maemo_utils_get_device_name ();
882 MODEST_HEADER_VIEW (modest_header_view_new (NULL, MODEST_HEADER_VIEW_STYLE_DETAILS));
883 if (!priv->header_view)
884 g_printerr ("modest: cannot instantiate header view\n");
885 modest_header_view_set_style (priv->header_view, MODEST_HEADER_VIEW_STYLE_TWOLINES);
886 modest_widget_memory_restore (modest_runtime_get_conf (), G_OBJECT(priv->header_view),
887 MODEST_CONF_HEADER_VIEW_KEY);
890 priv->empty_view = create_empty_view ();
892 /* Create scrolled windows */
893 folder_win = gtk_scrolled_window_new (NULL, NULL);
894 priv->contents_widget = gtk_scrolled_window_new (NULL, NULL);
895 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (folder_win),
897 GTK_POLICY_AUTOMATIC);
898 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->contents_widget),
900 GTK_POLICY_AUTOMATIC);
903 priv->main_paned = gtk_hpaned_new ();
904 gtk_paned_pack1 (GTK_PANED(priv->main_paned), folder_win, TRUE, TRUE);
905 gtk_paned_pack2 (GTK_PANED(priv->main_paned), priv->contents_widget, TRUE, TRUE);
906 gtk_tree_view_columns_autosize (GTK_TREE_VIEW(priv->header_view));
908 /* putting it all together... */
909 priv->main_vbox = gtk_vbox_new (FALSE, 6);
910 gtk_box_pack_start (GTK_BOX(priv->main_vbox), priv->main_paned, TRUE, TRUE,0);
912 gtk_container_add (GTK_CONTAINER(self), priv->main_vbox);
914 HildonProgram *app = hildon_program_get_instance ();
915 hildon_program_add_window (app, HILDON_WINDOW (self));
917 g_signal_connect (G_OBJECT(app), "notify::is-topmost",
918 G_CALLBACK (on_hildon_program_is_topmost_notify), self);
920 g_signal_connect (G_OBJECT(self), "show",
921 G_CALLBACK (modest_main_window_on_show), folder_win);
924 restore_settings (MODEST_MAIN_WINDOW(self), FALSE);
926 return MODEST_WINDOW(self);
930 modest_main_window_close_all (ModestMainWindow *self)
933 GtkResponseType response;
935 /* Create the confirmation dialog MSG-NOT308 */
936 note = hildon_note_new_confirmation_add_buttons (GTK_WINDOW (self),
937 _("emev_nc_close_windows"),
938 _("mcen_bd_yes"), GTK_RESPONSE_YES,
939 _("mcen_bd_no"), GTK_RESPONSE_NO,
942 response = gtk_dialog_run (GTK_DIALOG (note));
943 gtk_widget_destroy (GTK_WIDGET (note));
945 if (response == GTK_RESPONSE_YES)
953 modest_main_window_set_style (ModestMainWindow *self,
954 ModestMainWindowStyle style)
956 ModestMainWindowPrivate *priv;
957 ModestWindowPrivate *parent_priv;
960 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
962 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
963 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
965 /* no change -> nothing to do */
966 if (priv->style == style)
969 /* Get toggle button */
970 action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarToggleView");
974 case MODEST_MAIN_WINDOW_STYLE_SIMPLE:
975 /* Remove main paned */
976 g_object_ref (priv->main_paned);
977 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
979 /* Reparent the contents widget to the main vbox */
980 gtk_widget_reparent (priv->contents_widget, priv->main_vbox);
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), TRUE);
984 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
986 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
987 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
988 TnyIterator *iterator = tny_list_create_iterator (selection);
990 tny_iterator_first (iterator);
991 header = TNY_HEADER (tny_iterator_get_current (iterator));
992 if (tny_header_get_subject (header))
993 gtk_window_set_title (GTK_WINDOW(self), tny_header_get_subject (header));
995 gtk_window_set_title (GTK_WINDOW (self), _("mail_va_no_subject"));
996 g_object_unref (header);
997 g_object_unref (iterator);
998 g_object_unref (selection);
1002 case MODEST_MAIN_WINDOW_STYLE_SPLIT:
1003 /* Remove header view */
1004 g_object_ref (priv->contents_widget);
1005 gtk_container_remove (GTK_CONTAINER (priv->main_vbox), priv->contents_widget);
1007 /* Reparent the main paned */
1008 gtk_paned_add2 (GTK_PANED (priv->main_paned), priv->contents_widget);
1009 gtk_container_add (GTK_CONTAINER (priv->main_vbox), priv->main_paned);
1011 g_signal_handlers_block_by_func (action, modest_ui_actions_toggle_folders_view, self);
1012 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
1013 g_signal_handlers_unblock_by_func (action, modest_ui_actions_toggle_folders_view, self);
1017 g_return_if_reached ();
1020 /* Let header view grab the focus if it's being shown */
1021 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1022 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1024 gtk_widget_grab_focus (GTK_WIDGET (priv->contents_widget));
1027 gtk_widget_show_all (GTK_WIDGET (priv->main_vbox));
1030 ModestMainWindowStyle
1031 modest_main_window_get_style (ModestMainWindow *self)
1033 ModestMainWindowPrivate *priv;
1035 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1037 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1044 modest_main_window_window_state_event (GtkWidget *widget, GdkEventWindowState *event, gpointer userdata)
1046 if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
1047 ModestWindowPrivate *parent_priv;
1048 ModestWindowMgr *mgr;
1049 gboolean is_fullscreen;
1050 GtkAction *fs_toggle_action;
1053 mgr = modest_runtime_get_window_mgr ();
1055 is_fullscreen = modest_window_mgr_get_fullscreen_mode (mgr);
1057 parent_priv = MODEST_WINDOW_GET_PRIVATE (widget);
1059 fs_toggle_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/MenuBar/ViewMenu/ViewToggleFullscreenMenu");
1060 active = (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (fs_toggle_action)))?1:0;
1061 if (is_fullscreen != active) {
1062 gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (fs_toggle_action), is_fullscreen);
1071 set_homogeneous (GtkWidget *widget,
1074 gtk_tool_item_set_expand (GTK_TOOL_ITEM (widget), TRUE);
1075 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (widget), TRUE);
1079 modest_main_window_show_toolbar (ModestWindow *self,
1080 gboolean show_toolbar)
1082 ModestMainWindowPrivate *priv = NULL;
1083 ModestWindowPrivate *parent_priv = NULL;
1084 GtkWidget *reply_button = NULL, *menu = NULL;
1085 GtkWidget *placeholder = NULL;
1088 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1089 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1090 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1092 /* Set optimized view status */
1093 priv->optimized_view = !show_toolbar;
1095 if (!parent_priv->toolbar) {
1096 parent_priv->toolbar = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1099 /* Set homogeneous toolbar */
1100 gtk_container_foreach (GTK_CONTAINER (parent_priv->toolbar),
1101 set_homogeneous, NULL);
1103 priv->progress_toolitem = GTK_WIDGET (gtk_tool_item_new ());
1104 priv->cancel_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1105 priv->refresh_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1106 priv->sort_toolitem = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1107 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1108 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1109 gtk_tool_item_set_homogeneous (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1110 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->cancel_toolitem), FALSE);
1112 /* Add ProgressBar (Transfer toolbar) */
1113 priv->progress_bar = modest_progress_bar_widget_new ();
1114 gtk_widget_set_no_show_all (priv->progress_bar, TRUE);
1115 placeholder = gtk_ui_manager_get_widget (parent_priv->ui_manager, "/ToolBar/ProgressBarView");
1116 insert_index = gtk_toolbar_get_item_index(GTK_TOOLBAR (parent_priv->toolbar), GTK_TOOL_ITEM(placeholder));
1117 gtk_container_add (GTK_CONTAINER (priv->progress_toolitem), priv->progress_bar);
1118 gtk_toolbar_insert(GTK_TOOLBAR(parent_priv->toolbar), GTK_TOOL_ITEM (priv->progress_toolitem), insert_index);
1120 /* Connect cancel 'clicked' signal to abort progress mode */
1121 g_signal_connect(priv->cancel_toolitem, "clicked",
1122 G_CALLBACK(cancel_progressbar),
1125 /* Add it to the observers list */
1126 priv->progress_widgets = g_slist_prepend(priv->progress_widgets, priv->progress_bar);
1129 hildon_window_add_toolbar (HILDON_WINDOW (self),
1130 GTK_TOOLBAR (parent_priv->toolbar));
1132 /* Set reply button tap and hold menu */
1133 reply_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1134 "/ToolBar/ToolbarMessageReply");
1135 menu = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1136 "/ToolbarReplyCSM");
1137 gtk_widget_tap_and_hold_setup (GTK_WIDGET (reply_button), menu, NULL, 0);
1139 /* Set send & receive button tap and hold menu */
1140 on_account_update (TNY_ACCOUNT_STORE (modest_runtime_get_account_store ()),
1145 /* Quick hack: this prevents toolbar icons "dance" when progress bar show status is changed */
1146 /* TODO: resize mode migth be GTK_RESIZE_QUEUE, in order to avoid unneccesary shows */
1147 gtk_container_set_resize_mode (GTK_CONTAINER(parent_priv->toolbar), GTK_RESIZE_IMMEDIATE);
1149 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1150 set_toolbar_mode (MODEST_MAIN_WINDOW(self), TOOLBAR_MODE_NORMAL);
1152 gtk_widget_hide (GTK_WIDGET (parent_priv->toolbar));
1157 compare_display_names (ModestAccountData *a,
1158 ModestAccountData *b)
1160 return strcmp (a->display_name, b->display_name);
1164 on_account_update (TnyAccountStore *account_store,
1165 const gchar *account_name,
1168 GSList *account_names, *iter, *accounts;
1169 ModestMainWindow *self;
1170 ModestMainWindowPrivate *priv;
1171 ModestWindowPrivate *parent_priv;
1172 ModestAccountMgr *mgr;
1173 gint i, num_accounts;
1174 GtkActionGroup *action_group;
1176 gchar *default_account;
1177 GtkWidget *send_receive_button, *item;
1178 GtkAction *send_receive_all = NULL;
1180 self = MODEST_MAIN_WINDOW (user_data);
1181 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (self);
1182 parent_priv = MODEST_WINDOW_GET_PRIVATE (self);
1184 /* Get enabled account IDs */
1185 mgr = modest_runtime_get_account_mgr ();
1186 account_names = modest_account_mgr_account_names (mgr, TRUE);
1187 iter = account_names;
1191 ModestAccountData *account_data =
1192 modest_account_mgr_get_account_data (mgr, (gchar*) iter->data);
1193 accounts = g_slist_prepend (accounts, account_data);
1197 modest_account_mgr_free_account_names (account_names);
1198 account_names = NULL;
1200 /* Order the list of accounts by its display name */
1201 accounts = g_slist_sort (accounts, (GCompareFunc) compare_display_names);
1202 num_accounts = g_slist_length (accounts);
1204 send_receive_all = gtk_ui_manager_get_action (parent_priv->ui_manager,
1205 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1206 gtk_action_set_visible (send_receive_all, num_accounts > 1);
1208 /* Delete old send&receive popup items. We can not just do a
1209 menu_detach because it does not work well with
1211 if (priv->accounts_popup)
1212 gtk_container_foreach (GTK_CONTAINER (priv->accounts_popup),
1213 (GtkCallback) gtk_widget_destroy, NULL);
1215 /* Delete old entries in the View menu. Do not free groups, it
1217 groups = gtk_ui_manager_get_action_groups (parent_priv->ui_manager);
1219 if (!strcmp (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS,
1220 gtk_action_group_get_name (GTK_ACTION_GROUP (groups->data)))) {
1221 gtk_ui_manager_remove_action_group (parent_priv->ui_manager,
1222 GTK_ACTION_GROUP (groups->data));
1225 if (priv->merge_ids) {
1226 for (i = 0; i < priv->merge_ids->len; i++)
1227 gtk_ui_manager_remove_ui (parent_priv->ui_manager, priv->merge_ids->data[i]);
1228 g_byte_array_free (priv->merge_ids, TRUE);
1230 /* We need to call this in order to ensure
1231 that the new actions are added in the right
1232 order (alphabetical */
1233 gtk_ui_manager_ensure_update (parent_priv->ui_manager);
1235 groups = g_list_next (groups);
1237 priv->merge_ids = g_byte_array_sized_new (num_accounts);
1239 /* Get send receive button */
1240 send_receive_button = gtk_ui_manager_get_widget (parent_priv->ui_manager,
1241 "/ToolBar/ToolbarSendReceive");
1243 /* Create the menu */
1244 if (num_accounts > 1) {
1245 if (!priv->accounts_popup)
1246 priv->accounts_popup = gtk_menu_new ();
1247 item = gtk_menu_item_new_with_label (_("mcen_me_toolbar_sendreceive_all"));
1248 gtk_menu_shell_append (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1249 g_signal_connect (G_OBJECT (item),
1251 G_CALLBACK (on_send_receive_csm_activated),
1253 item = gtk_separator_menu_item_new ();
1254 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1257 /* Create a new action group */
1258 default_account = modest_account_mgr_get_default_account (mgr);
1259 action_group = gtk_action_group_new (MODEST_MAIN_WINDOW_ACTION_GROUP_ADDITIONS);
1260 for (i = 0; i < num_accounts; i++) {
1261 gchar *display_name = NULL;
1263 ModestAccountData *account_data = (ModestAccountData *) g_slist_nth_data (accounts, i);
1265 /* Create display name. The default account is shown differently */
1266 if (default_account && account_data->account_name &&
1267 !(strcmp (default_account, account_data->account_name) == 0)) {
1268 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_default"),
1269 account_data->display_name);
1272 display_name = g_strdup_printf (_("mcen_me_toolbar_sendreceive_mailbox_n"),
1273 account_data->display_name);
1276 /* Create action and add it to the action group. The
1277 action name must be the account name, this way we
1278 could know in the handlers the account to show */
1279 if(account_data->account_name) {
1280 gchar* item_name, *refresh_action_name;
1282 GtkAction *view_account_action, *refresh_account_action;
1284 view_account_action = gtk_action_new (account_data->account_name,
1285 display_name, NULL, NULL);
1286 gtk_action_group_add_action (action_group, view_account_action);
1288 /* Add ui from account data. We allow 2^9-1 account
1289 changes in a single execution because we're
1290 downcasting the guint to a guint8 in order to use a
1291 GByteArray, it should be enough */
1292 item_name = g_strconcat (account_data->account_name, "Menu", NULL);
1293 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1294 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1295 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1297 "/MenuBar/ViewMenu/ViewMenuAdditions",
1299 account_data->account_name,
1300 GTK_UI_MANAGER_MENUITEM,
1303 /* Connect the action signal "activate" */
1304 g_signal_connect (G_OBJECT (view_account_action),
1306 G_CALLBACK (on_show_account_action_activated),
1309 /* Create the items for the Tools->Send&Receive submenu */
1310 refresh_action_name = g_strconcat ("SendReceive", account_data->account_name, NULL);
1311 refresh_account_action = gtk_action_new ((const gchar*) refresh_action_name,
1312 display_name, NULL, NULL);
1313 gtk_action_group_add_action (action_group, refresh_account_action);
1315 merge_id = (guint8) gtk_ui_manager_new_merge_id (parent_priv->ui_manager);
1316 priv->merge_ids = g_byte_array_append (priv->merge_ids, &merge_id, 1);
1317 gtk_ui_manager_add_ui (parent_priv->ui_manager,
1319 "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions",
1321 refresh_action_name,
1322 GTK_UI_MANAGER_MENUITEM,
1324 g_free (refresh_action_name);
1326 g_signal_connect_data (G_OBJECT (refresh_account_action),
1328 G_CALLBACK (on_refresh_account_action_activated),
1329 g_strdup (account_data->account_name),
1330 (GClosureNotify) g_free,
1333 /* Create item and add it to the send&receive
1334 CSM. If there is only one account then
1336 if (priv->accounts_popup) {
1337 item = gtk_menu_item_new_with_label (display_name);
1338 gtk_menu_shell_prepend (GTK_MENU_SHELL (priv->accounts_popup), GTK_WIDGET (item));
1339 g_signal_connect_data (G_OBJECT (item),
1341 G_CALLBACK (on_send_receive_csm_activated),
1342 g_strdup (account_data->account_name),
1343 (GClosureNotify) g_free,
1350 g_free (display_name);
1351 modest_account_mgr_free_account_data (mgr, account_data);
1353 gtk_ui_manager_insert_action_group (parent_priv->ui_manager, action_group, 1);
1355 if (priv->accounts_popup) {
1356 /* Mandatory in order to view the menu contents */
1357 gtk_widget_show_all (priv->accounts_popup);
1359 /* Setup tap_and_hold just if was not done before*/
1360 if (!gtk_menu_get_attach_widget (GTK_MENU (priv->accounts_popup)))
1361 gtk_widget_tap_and_hold_setup (send_receive_button, priv->accounts_popup, NULL, 0);
1365 g_slist_free (accounts);
1366 g_free (default_account);
1370 * This function manages the key events used to navigate between
1371 * header and folder views (when the window is in split view)
1374 * -------------------------------------------------
1375 * HeaderView GDK_Left Move focus to folder view
1376 * FolderView GDK_Right Move focus to header view
1378 * There is no need to scroll to selected row, the widgets will be the
1379 * responsibles of doing that (probably managing the focus-in event
1382 on_inner_widgets_key_pressed (GtkWidget *widget,
1386 ModestMainWindowPrivate *priv;
1388 priv = MODEST_MAIN_WINDOW_GET_PRIVATE (user_data);
1390 /* Do nothing if we're in SIMPLE style */
1391 if (priv->style == MODEST_MAIN_WINDOW_STYLE_SIMPLE)
1394 if (MODEST_IS_HEADER_VIEW (widget) && event->keyval == GDK_Left)
1395 gtk_widget_grab_focus (GTK_WIDGET (priv->folder_view));
1396 else if (MODEST_IS_FOLDER_VIEW (widget) && event->keyval == GDK_Right)
1397 gtk_widget_grab_focus (GTK_WIDGET (priv->header_view));
1403 set_alignment (GtkWidget *widget,
1406 gtk_misc_set_alignment (GTK_MISC (widget), 0.0, 0.0);
1407 gtk_misc_set_padding (GTK_MISC (widget), 0, 0);
1411 create_empty_view (void)
1413 GtkLabel *label = NULL;
1414 GtkWidget *align = NULL;
1416 align = gtk_alignment_new(XALIGN, YALIGN, XSPACE, YSPACE);
1417 label = GTK_LABEL(gtk_label_new (_("mcen_ia_nomessages")));
1418 gtk_label_set_justify (label, GTK_JUSTIFY_CENTER);
1419 gtk_container_add (GTK_CONTAINER (align), GTK_WIDGET(label));
1421 return GTK_WIDGET(align);
1425 create_details_widget (GtkWidget *styled_widget, TnyAccount *account)
1427 /* TODO: Clean up this function. It's a mess, with lots of copy/paste. murrayc. */
1432 gchar *gray_color_markup;
1434 vbox = gtk_vbox_new (FALSE, 0);
1436 /* Obtain the secondary text color. We need a realized widget, that's why
1437 we get styled_widget from outside */
1438 #ifndef MODEST_HAVE_HILDON0_WIDGETS
1440 gtk_style_lookup_color (styled_widget->style, "SecondaryTextColor", &color);
1441 gray_color_markup = modest_text_utils_get_color_string (&color);
1443 // gray_color_markup is freed below
1444 gray_color_markup = g_strdup ("#BBBBBB");
1446 /* Account description: */
1448 if (modest_tny_account_is_virtual_local_folders (account)
1449 || (modest_tny_account_is_memory_card_account (account))) {
1451 /* Local folders: */
1453 /* Get device name */
1454 gchar *device_name = NULL;
1455 if (modest_tny_account_is_virtual_local_folders (account))
1456 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1457 MODEST_CONF_DEVICE_NAME, NULL);
1459 device_name = g_strdup (tny_account_get_name (account));
1461 tmp = g_strdup_printf (_("mcen_fi_localroot_description"), ""); //TODO: Why the ""?
1462 label = g_markup_printf_escaped ("<span color='%s'>%s</span>%s",
1463 gray_color_markup, tmp, device_name);
1465 label_w = gtk_label_new (NULL);
1466 gtk_label_set_markup (GTK_LABEL (label_w), label);
1467 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1468 g_free (device_name);
1471 if(!strcmp (tny_account_get_id (account), MODEST_MMC_ACCOUNT_ID)) {
1472 gtk_box_pack_start (GTK_BOX (vbox),
1473 gtk_label_new (tny_account_get_name (account)),
1476 /* Other accounts, such as IMAP and POP: */
1481 /* Put proto in uppercase */
1482 proto = g_string_new (tny_account_get_proto (account));
1483 proto = g_string_ascii_up (proto);
1485 /* note: mcen_fi_localroot_description is something like "%s account"
1486 * however, we should display "%s account: %s"... therefore, ugly tmp */
1487 tmp = g_strdup_printf (_("mcen_fi_remoteroot_account"),proto->str);
1488 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1489 gray_color_markup, tmp, tny_account_get_name (account));
1492 label_w = gtk_label_new (NULL);
1493 gtk_label_set_markup (GTK_LABEL (label_w), label);
1494 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1495 g_string_free (proto, TRUE);
1501 TnyFolderStore *folder_store = TNY_FOLDER_STORE (account);
1502 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1503 gray_color_markup, _("mcen_fi_rootfolder_messages"),
1504 modest_tny_folder_store_get_message_count (folder_store));
1505 label_w = gtk_label_new (NULL);
1506 gtk_label_set_markup (GTK_LABEL (label_w), label);
1507 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1511 label = g_markup_printf_escaped ("<span color='%s'>%s</span>: %d",
1513 _("mcen_fi_rootfolder_folders"),
1514 modest_tny_folder_store_get_folder_count (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);
1521 if (modest_tny_account_is_virtual_local_folders (account)
1522 || modest_tny_account_is_memory_card_account (account)) {
1523 /* FIXME: format size */
1524 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %d",
1525 gray_color_markup, _("mcen_fi_rootfolder_size"),
1526 modest_tny_folder_store_get_local_size (folder_store));
1527 label_w = gtk_label_new (NULL);
1528 gtk_label_set_markup (GTK_LABEL (label_w), label);
1529 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1531 } else if (TNY_IS_ACCOUNT(folder_store)) {
1532 TnyAccount *account = TNY_ACCOUNT(folder_store);
1534 time_t last_updated;
1535 gchar *last_updated_string;
1536 /* Get last updated from configuration */
1537 last_updated = modest_account_mgr_get_int (modest_runtime_get_account_mgr (),
1538 tny_account_get_id (account),
1539 MODEST_ACCOUNT_LAST_UPDATED,
1541 if (last_updated > 0)
1542 last_updated_string = modest_text_utils_get_display_date(last_updated);
1544 last_updated_string = g_strdup (_("mcen_va_never"));
1546 label = g_markup_printf_escaped ("<span color='%s'>%s:</span> %s",
1547 gray_color_markup, _("mcen_ti_lastupdated"), last_updated_string);
1548 label_w = gtk_label_new (NULL);
1549 gtk_label_set_markup (GTK_LABEL (label_w), label);
1550 gtk_box_pack_start (GTK_BOX (vbox), label_w, FALSE, FALSE, 0);
1551 g_free (last_updated_string);
1555 g_free (gray_color_markup);
1558 gtk_container_foreach (GTK_CONTAINER (vbox), (GtkCallback) set_alignment, NULL);
1564 modest_main_window_send_receive_in_progress (ModestMainWindow *self)
1566 ModestMainWindowPrivate *priv = NULL;
1568 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1570 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1572 return priv->send_receive_in_progress;
1576 modest_main_window_notify_send_receive_initied (ModestMainWindow *self)
1578 GtkAction *action = NULL;
1579 GtkWidget *widget = NULL;
1580 ModestMainWindowPrivate *priv = NULL;
1582 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1583 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1585 priv->send_receive_in_progress = TRUE;
1587 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1588 gtk_action_set_sensitive (action, FALSE);
1589 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1590 /* gtk_action_set_sensitive (action, FALSE); */
1591 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1592 gtk_widget_set_sensitive (widget, FALSE);
1596 modest_main_window_notify_send_receive_completed (ModestMainWindow *self)
1598 GtkAction *action = NULL;
1599 GtkWidget *widget = NULL;
1600 ModestMainWindowPrivate *priv = NULL;
1602 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1603 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1605 priv->send_receive_in_progress = FALSE;
1607 action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveAllMenu");
1608 gtk_action_set_sensitive (action, TRUE);
1609 /* action = modest_window_get_action (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsSendReceiveCancelSendingMenu"); */
1610 /* gtk_action_set_sensitive (action, TRUE); */
1611 widget = modest_window_get_action_widget (MODEST_WINDOW(self), "/MenuBar/ToolsMenu/ToolsSendReceiveMainMenu/ToolsMenuAdditions");
1612 gtk_widget_set_sensitive (widget, TRUE);
1617 _on_msg_count_changed (ModestHeaderView *header_view,
1619 TnyFolderChange *change,
1620 ModestMainWindow *main_window)
1622 printf ("DEBUG: %s\n", __FUNCTION__);
1623 gboolean folder_empty = FALSE;
1624 TnyFolderChangeChanged changed;
1626 g_return_if_fail (MODEST_IS_MAIN_WINDOW (main_window));
1627 g_return_if_fail (TNY_IS_FOLDER(folder));
1628 g_return_if_fail (TNY_IS_FOLDER_CHANGE(change));
1630 changed = tny_folder_change_get_changed (change);
1632 /* If something changes */
1633 if ((changed) & TNY_FOLDER_CHANGE_CHANGED_ALL_COUNT)
1634 folder_empty = (tny_folder_change_get_new_all_count (change) == 0);
1636 folder_empty = (tny_folder_get_all_count (TNY_FOLDER (folder)) == 0);
1638 printf ("DEBUG: %s: folder_empty=%d\n", __FUNCTION__, folder_empty);
1640 /* Set contents style of headers view */
1642 modest_main_window_set_contents_style (main_window,
1643 MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY);
1646 modest_main_window_set_contents_style (main_window,
1647 MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS);
1652 modest_main_window_set_contents_style (ModestMainWindow *self,
1653 ModestMainWindowContentsStyle style)
1655 ModestMainWindowPrivate *priv;
1657 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1659 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1661 /* We allow to set the same content style than the previously
1662 set if there are details, because it could happen when we're
1663 selecting different accounts consecutively */
1664 if ((priv->contents_style == style) &&
1665 (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS))
1668 /* Remove previous child. Delete it if it was an account
1670 GtkWidget *content = gtk_bin_get_child (GTK_BIN (priv->contents_widget));
1672 if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS)
1673 g_object_ref (content);
1674 else if (priv->contents_style == MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY) {
1675 g_object_ref (priv->empty_view);
1676 gtk_container_remove (GTK_CONTAINER (content), priv->empty_view);
1679 gtk_container_remove (GTK_CONTAINER (priv->contents_widget), content);
1682 priv->contents_style = style;
1684 switch (priv->contents_style) {
1685 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_HEADERS:
1686 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->header_view));
1688 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS:
1690 TnyFolderStore *selected_folderstore =
1691 modest_folder_view_get_selected (priv->folder_view);
1692 if (TNY_IS_ACCOUNT (selected_folderstore)) {
1693 priv->details_widget = create_details_widget (GTK_WIDGET (self),
1694 TNY_ACCOUNT (selected_folderstore));
1696 wrap_in_scrolled_window (priv->contents_widget,
1697 priv->details_widget);
1699 g_object_unref (selected_folderstore);
1702 case MODEST_MAIN_WINDOW_CONTENTS_STYLE_EMPTY:
1703 wrap_in_scrolled_window (priv->contents_widget, GTK_WIDGET (priv->empty_view));
1706 g_return_if_reached ();
1710 gtk_widget_show_all (priv->contents_widget);
1713 ModestMainWindowContentsStyle
1714 modest_main_window_get_contents_style (ModestMainWindow *self)
1716 ModestMainWindowPrivate *priv;
1718 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), -1);
1720 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1721 return priv->contents_style;
1726 on_configuration_key_changed (ModestConf* conf,
1728 ModestConfEvent event,
1729 ModestMainWindow *self)
1731 ModestMainWindowPrivate *priv;
1732 TnyAccount *account;
1734 if (!key || strcmp (key, MODEST_CONF_DEVICE_NAME))
1737 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1739 if (priv->contents_style != MODEST_MAIN_WINDOW_CONTENTS_STYLE_DETAILS)
1742 account = (TnyAccount *) modest_folder_view_get_selected (priv->folder_view);
1743 if (TNY_IS_ACCOUNT (account) &&
1744 !strcmp (tny_account_get_id (account), MODEST_LOCAL_FOLDERS_ACCOUNT_ID)) {
1747 const gchar *device_name;
1751 children = gtk_container_get_children (GTK_CONTAINER (priv->details_widget));
1752 label = GTK_LABEL (children->data);
1754 device_name = modest_conf_get_string (modest_runtime_get_conf(),
1755 MODEST_CONF_DEVICE_NAME, NULL);
1757 new_text = g_strdup_printf ("%s: %s",
1758 _("mcen_fi_localroot_description"),
1761 gtk_label_set_text (label, new_text);
1762 gtk_widget_show (GTK_WIDGET (label));
1765 g_list_free (children);
1767 g_object_unref (account);
1771 set_toolbar_transfer_mode (ModestMainWindow *self)
1773 ModestMainWindowPrivate *priv = NULL;
1775 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (self), FALSE);
1777 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1779 set_toolbar_mode (self, TOOLBAR_MODE_TRANSFER);
1781 if (priv->progress_bar_timeout > 0) {
1782 g_source_remove (priv->progress_bar_timeout);
1783 priv->progress_bar_timeout = 0;
1790 set_toolbar_mode (ModestMainWindow *self,
1791 ModestToolBarModes mode)
1793 ModestWindowPrivate *parent_priv = NULL;
1794 ModestMainWindowPrivate *priv = NULL;
1795 GtkAction *sort_action = NULL, *refresh_action = NULL, *cancel_action = NULL;
1797 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1799 parent_priv = MODEST_WINDOW_GET_PRIVATE(self);
1800 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1802 /* In case this was called before the toolbar exists: */
1803 if (!(parent_priv->toolbar))
1806 g_return_if_fail (GTK_IS_TOOLBAR(parent_priv->toolbar));
1808 sort_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSort");
1809 refresh_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarSendReceive");
1810 cancel_action = gtk_ui_manager_get_action (parent_priv->ui_manager, "/ToolBar/ToolbarCancel");
1812 /* Sets current toolbar mode */
1813 priv->current_toolbar_mode = mode;
1815 /* Show and hide toolbar items */
1817 case TOOLBAR_MODE_NORMAL:
1819 gtk_action_set_visible (sort_action, TRUE);
1821 gtk_action_set_visible (refresh_action, TRUE);
1822 if (priv->progress_toolitem) {
1823 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE);
1824 gtk_widget_hide (priv->progress_toolitem);
1826 if (priv->progress_bar)
1827 gtk_widget_hide (priv->progress_bar);
1830 gtk_action_set_visible (cancel_action, FALSE);
1831 /* if (priv->sort_toolitem) */
1832 /* gtk_widget_show (priv->sort_toolitem); */
1834 /* if (priv->refresh_toolitem) */
1835 /* gtk_widget_show (priv->refresh_toolitem); */
1837 /* if (priv->progress_toolitem) */
1838 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), FALSE); */
1839 /* if (priv->progress_bar) */
1840 /* gtk_widget_hide (priv->progress_bar); */
1842 /* if (priv->cancel_toolitem) */
1843 /* gtk_widget_hide (priv->cancel_toolitem); */
1845 /* Hide toolbar if optimized view is enabled */
1846 if (priv->optimized_view)
1847 gtk_widget_hide (GTK_WIDGET(parent_priv->toolbar));
1849 case TOOLBAR_MODE_TRANSFER:
1851 gtk_action_set_visible (sort_action, FALSE);
1853 gtk_action_set_visible (refresh_action, FALSE);
1855 gtk_action_set_visible (cancel_action, TRUE);
1856 if (priv->progress_toolitem) {
1857 gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE);
1858 gtk_widget_show (priv->progress_toolitem);
1860 if (priv->progress_bar)
1861 gtk_widget_show (priv->progress_bar);
1863 /* if (priv->sort_toolitem) */
1864 /* gtk_widget_hide (priv->sort_toolitem); */
1866 /* if (priv->refresh_toolitem) */
1867 /* gtk_widget_hide (priv->refresh_toolitem); */
1869 /* if (priv->progress_toolitem) */
1870 /* gtk_tool_item_set_expand (GTK_TOOL_ITEM (priv->progress_toolitem), TRUE); */
1871 /* if (priv->progress_bar) */
1872 /* gtk_widget_show (priv->progress_bar); */
1874 /* if (priv->cancel_toolitem) */
1875 /* gtk_widget_show (priv->cancel_toolitem); */
1877 /* Show toolbar if it's hiden (optimized view ) */
1878 if (priv->optimized_view)
1879 gtk_widget_show (GTK_WIDGET (parent_priv->toolbar));
1882 g_return_if_reached ();
1887 cancel_progressbar (GtkToolButton *toolbutton,
1888 ModestMainWindow *self)
1891 ModestMainWindowPrivate *priv;
1893 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1895 /* Get operation observers and cancel its current operation */
1896 tmp = priv->progress_widgets;
1898 modest_progress_object_cancel_current_operation (MODEST_PROGRESS_OBJECT(tmp->data));
1899 tmp=g_slist_next(tmp);
1904 observers_empty (ModestMainWindow *self)
1907 ModestMainWindowPrivate *priv;
1908 gboolean is_empty = TRUE;
1909 guint pending_ops = 0;
1911 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1912 tmp = priv->progress_widgets;
1914 /* Check all observers */
1915 while (tmp && is_empty) {
1916 pending_ops = modest_progress_object_num_pending_operations (MODEST_PROGRESS_OBJECT(tmp->data));
1917 is_empty = pending_ops == 0;
1919 tmp = g_slist_next(tmp);
1926 on_queue_changed (ModestMailOperationQueue *queue,
1927 ModestMailOperation *mail_op,
1928 ModestMailOperationQueueNotification type,
1929 ModestMainWindow *self)
1931 ModestMainWindowPrivate *priv;
1932 ModestMailOperationTypeOperation op_type;
1933 ModestToolBarModes mode;
1935 gboolean mode_changed = FALSE;
1936 /* ModestMailOperationStatus status; */
1938 g_return_if_fail (MODEST_IS_MAIN_WINDOW (self));
1939 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
1941 /* Get toolbar mode from operation id*/
1942 op_type = modest_mail_operation_get_type_operation (mail_op);
1944 case MODEST_MAIL_OPERATION_TYPE_SEND:
1945 case MODEST_MAIL_OPERATION_TYPE_RECEIVE:
1946 case MODEST_MAIL_OPERATION_TYPE_OPEN:
1947 mode = TOOLBAR_MODE_TRANSFER;
1948 if (priv->current_toolbar_mode == TOOLBAR_MODE_NORMAL)
1949 mode_changed = TRUE;
1952 mode = TOOLBAR_MODE_NORMAL;
1957 /* Add operation observers and change toolbar if neccessary*/
1958 tmp = priv->progress_widgets;
1960 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED:
1961 if (mode == TOOLBAR_MODE_TRANSFER) {
1963 set_toolbar_transfer_mode(self);
1965 modest_progress_object_add_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1967 tmp = g_slist_next (tmp);
1971 case MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED:
1972 /* Change toolbar mode */
1973 if (mode == TOOLBAR_MODE_TRANSFER) {
1975 modest_progress_object_remove_operation (MODEST_PROGRESS_OBJECT (tmp->data),
1977 tmp = g_slist_next (tmp);
1980 /* If no more operations are being observed, NORMAL mode is enabled again */
1981 if (observers_empty (self)) {
1982 set_toolbar_mode (self, TOOLBAR_MODE_NORMAL);
1993 on_show_account_action_activated (GtkAction *action,
1996 ModestAccountData *acc_data;
1997 ModestMainWindow *self;
1998 ModestMainWindowPrivate *priv;
1999 ModestAccountMgr *mgr;
2000 const gchar *acc_name;
2002 self = MODEST_MAIN_WINDOW (user_data);
2003 priv = MODEST_MAIN_WINDOW_GET_PRIVATE(self);
2005 /* Get account data */
2006 acc_name = gtk_action_get_name (action);
2007 mgr = modest_runtime_get_account_mgr ();
2008 acc_data = modest_account_mgr_get_account_data (mgr, acc_name);
2010 /* Set the new visible & active account */
2011 if (acc_data->store_account) {
2012 modest_folder_view_set_account_id_of_visible_server_account (priv->folder_view,
2013 acc_data->store_account->account_name);
2014 modest_window_set_active_account (MODEST_WINDOW (self), acc_data->account_name);
2018 modest_account_mgr_free_account_data (mgr, acc_data);
2022 refresh_account (const gchar *account_name)
2026 win = MODEST_WINDOW (modest_window_mgr_get_main_window (modest_runtime_get_window_mgr ()));
2028 /* If account_name == NULL, we must update all (option All) */
2030 modest_ui_actions_do_send_receive_all (win);
2032 modest_ui_actions_do_send_receive (account_name, win);
2037 on_refresh_account_action_activated (GtkAction *action,
2040 refresh_account ((const gchar*) user_data);
2044 on_send_receive_csm_activated (GtkMenuItem *item,
2047 refresh_account ((const gchar*) user_data);
2051 on_zoom_minus_plus_not_implemented (ModestWindow *window)
2053 g_return_val_if_fail (MODEST_IS_MAIN_WINDOW (window), FALSE);
2055 hildon_banner_show_information (NULL, NULL, dgettext("hildon-common-strings", "ckct_ib_cannot_zoom_here"));
2061 on_folder_view_focus_in (GtkWidget *widget,
2062 GdkEventFocus *event,
2069 on_header_view_focus_in (GtkWidget *widget,
2070 GdkEventFocus *event,
2073 ModestMainWindow *main_window = MODEST_MAIN_WINDOW (userdata);
2074 ModestMainWindowPrivate *priv = MODEST_MAIN_WINDOW_GET_PRIVATE (main_window);
2076 if (modest_header_view_has_selected_headers (MODEST_HEADER_VIEW (priv->header_view))) {
2077 TnyList *selection = modest_header_view_get_selected_headers (MODEST_HEADER_VIEW (priv->header_view));
2078 TnyIterator *iterator = tny_list_create_iterator (selection);
2081 tny_iterator_first (iterator);
2082 header = TNY_HEADER (tny_iterator_get_current (iterator));
2084 if (tny_header_get_subject (header))
2085 gtk_window_set_title (GTK_WINDOW(main_window), tny_header_get_subject (header));
2087 gtk_window_set_title (GTK_WINDOW (main_window), _("mail_va_no_subject"));
2089 g_object_unref (header);
2090 g_object_unref (iterator);
2091 g_object_unref (selection);