1 /* Copyright (c) 2006,2007 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.
31 #include "modest-window-mgr.h"
32 #include "modest-runtime.h"
33 #include "modest-tny-folder.h"
34 #include "modest-ui-actions.h"
35 #include "modest-platform.h"
36 #include "modest-defs.h"
37 #include "widgets/modest-main-window.h"
38 #include "widgets/modest-msg-edit-window.h"
39 #include "widgets/modest-msg-view-window.h"
40 #include "modest-debug.h"
41 #include <tny-simple-list.h>
44 /* 'private'/'protected' functions */
45 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
46 static void modest_window_mgr_init (ModestWindowMgr *obj);
47 static void modest_window_mgr_finalize (GObject *obj);
49 static gboolean modest_window_mgr_register_window_default (ModestWindowMgr *self,
51 ModestWindow *parent);
52 static void modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
53 ModestWindow *window);
54 static void modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
56 static gboolean modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self);
57 static void modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
59 gboolean show_toolbars,
61 #ifndef MODEST_TOOLKIT_HILDON2
62 static ModestWindow* modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show);
64 static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self);
65 static void modest_window_mgr_set_modal_default (ModestWindowMgr *self,
68 static gboolean modest_window_mgr_close_all_windows_default (ModestWindowMgr *self);
69 static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self,
72 static gboolean modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self,
75 static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self);
76 static ModestWindow *modest_window_mgr_show_initial_window_default (ModestWindowMgr *self);
77 static ModestWindow *modest_window_mgr_get_current_top_default (ModestWindowMgr *self);
78 static gboolean modest_window_mgr_screen_is_on_default (ModestWindowMgr *self);
79 static ModestWindow *modest_window_mgr_get_folder_window_default (ModestWindowMgr *self);
80 static void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
81 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
82 ModestMailOperation *mail_op,
83 ModestMailOperationQueueNotification type,
84 ModestWindowMgr *self);
85 static void on_mail_operation_started (ModestMailOperation *mail_op,
87 static void on_mail_operation_finished (ModestMailOperation *mail_op,
89 static gboolean modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self);
93 WINDOW_LIST_EMPTY_SIGNAL,
94 PROGRESS_LIST_CHANGED_SIGNAL,
98 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
99 struct _ModestWindowMgrPrivate {
100 guint banner_counter;
102 #ifndef MODEST_TOOLKIT_HILDON2
103 ModestWindow *main_window;
105 GSList *windows_that_prevent_hibernation;
106 GSList *preregistered_uids;
110 GtkWidget *cached_view;
111 GtkWidget *cached_editor;
112 guint idle_load_view_id;
113 guint idle_load_editor_id;
115 guint queue_change_handler;
116 TnyList *progress_operations;
120 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
121 MODEST_TYPE_WINDOW_MGR, \
122 ModestWindowMgrPrivate))
124 static GObjectClass *parent_class = NULL;
126 /* uncomment the following if you have defined any signals */
127 static guint signals[NUM_SIGNALS] = {0};
130 modest_window_mgr_get_type (void)
132 static GType my_type = 0;
134 static const GTypeInfo my_info = {
135 sizeof(ModestWindowMgrClass),
136 NULL, /* base init */
137 NULL, /* base finalize */
138 (GClassInitFunc) modest_window_mgr_class_init,
139 NULL, /* class finalize */
140 NULL, /* class data */
141 sizeof(ModestWindowMgr),
143 (GInstanceInitFunc) modest_window_mgr_init,
146 my_type = g_type_register_static (G_TYPE_OBJECT,
154 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
156 GObjectClass *gobject_class;
157 ModestWindowMgrClass *mgr_class;
159 gobject_class = (GObjectClass*) klass;
160 mgr_class = (ModestWindowMgrClass *) klass;
162 parent_class = g_type_class_peek_parent (klass);
163 gobject_class->finalize = modest_window_mgr_finalize;
164 mgr_class->register_window = modest_window_mgr_register_window_default;
165 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
166 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
167 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
168 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
169 #ifndef MODEST_TOOLKIT_HILDON2
170 mgr_class->get_main_window = modest_window_mgr_get_main_window_default;
172 mgr_class->get_modal = modest_window_mgr_get_modal_default;
173 mgr_class->set_modal = modest_window_mgr_set_modal_default;
174 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
175 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
176 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
177 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
178 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
179 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
180 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
181 mgr_class->create_caches = modest_window_mgr_create_caches_default;
182 mgr_class->close_all_but_initial = modest_window_mgr_close_all_but_initial_default;
183 mgr_class->get_folder_window = modest_window_mgr_get_folder_window_default;
185 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
189 * ModestWindowMgr::window-list-empty
190 * @self: the #ModestWindowMgr that emits the signal
191 * @user_data: user data set when the signal handler was connected
193 * Issued whenever the window list becomes empty
195 signals[WINDOW_LIST_EMPTY_SIGNAL] =
196 g_signal_new ("window-list-empty",
197 G_TYPE_FROM_CLASS (gobject_class),
199 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
201 g_cclosure_marshal_VOID__VOID,
205 * ModestWindowMgr::progress-list-changed
206 * @self: the #ModestWindowMgr that emits the signal
207 * @user_data: user data set when the signal handler was connected
209 * Issued whenever the progress mail operations list becomes changed
211 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
212 g_signal_new ("progress-list-changed",
213 G_TYPE_FROM_CLASS (gobject_class),
215 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
217 g_cclosure_marshal_VOID__VOID,
222 idle_load_view (ModestWindowMgr *mgr)
224 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
226 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
227 priv->idle_load_view_id = 0;
232 idle_load_editor (ModestWindowMgr *mgr)
234 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
236 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
237 priv->idle_load_editor_id = 0;
242 load_new_view (ModestWindowMgr *self)
244 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
245 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
246 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
250 load_new_editor (ModestWindowMgr *self)
252 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
253 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
254 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
258 modest_window_mgr_init (ModestWindowMgr *obj)
260 ModestWindowMgrPrivate *priv;
262 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
263 priv->banner_counter = 0;
264 #ifndef MODEST_TOOLKIT_HILDON2
265 priv->main_window = NULL;
267 priv->preregistered_uids = NULL;
269 priv->closing_time = 0;
271 priv->cached_view = NULL;
272 priv->cached_editor = NULL;
274 priv->windows_that_prevent_hibernation = NULL;
276 priv->queue_change_handler = 0;
277 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
281 modest_window_mgr_finalize (GObject *obj)
283 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
285 if (priv->idle_load_view_id > 0) {
286 g_source_remove (priv->idle_load_view_id);
287 priv->idle_load_view_id = 0;
290 if (priv->idle_load_editor_id > 0) {
291 g_source_remove (priv->idle_load_editor_id);
292 priv->idle_load_editor_id = 0;
295 if (priv->cached_view) {
296 gtk_widget_destroy (priv->cached_view);
297 priv->cached_view = NULL;
299 if (priv->cached_editor) {
300 gtk_widget_destroy (priv->cached_editor);
301 priv->cached_editor = NULL;
304 if (priv->windows_that_prevent_hibernation) {
305 g_slist_free (priv->windows_that_prevent_hibernation);
306 priv->cached_editor = NULL;
309 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
310 priv->sighandlers = NULL;
312 if (priv->queue_change_handler > 0) {
313 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
314 priv->queue_change_handler);
315 priv->queue_change_handler = 0;
318 if (priv->progress_operations) {
319 g_object_unref (priv->progress_operations);
320 priv->progress_operations = NULL;
323 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
324 g_slist_free (priv->preregistered_uids);
326 G_OBJECT_CLASS(parent_class)->finalize (obj);
330 modest_window_mgr_new (void)
332 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
338 /* do we have uid? */
340 has_uid (GSList *list, const gchar *uid)
342 GSList *cursor = list;
348 if (cursor->data && strcmp (cursor->data, uid) == 0)
350 cursor = g_slist_next (cursor);
356 /* remove all from the list have have uid = uid */
358 remove_uid (GSList *list, const gchar *uid)
360 GSList *cursor = list, *start = list;
366 GSList *next = g_slist_next (cursor);
367 if (cursor->data && strcmp (cursor->data, uid) == 0) {
368 g_free (cursor->data);
369 start = g_slist_delete_link (start, cursor);
378 append_uid (GSList *list, const gchar *uid)
380 return g_slist_append (list, g_strdup(uid));
386 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
388 ModestWindowMgrPrivate *priv;
391 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
392 g_return_if_fail (TNY_IS_HEADER(header));
394 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
395 if (alt_uid != NULL) {
396 uid = g_strdup (alt_uid);
398 uid = modest_tny_folder_get_header_unique_id (header);
401 if (!has_uid (priv->preregistered_uids, uid)) {
402 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
403 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
405 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
411 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
413 ModestWindowMgrPrivate *priv;
416 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
417 g_return_if_fail (TNY_IS_HEADER(header));
419 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
420 uid = modest_tny_folder_get_header_unique_id (header);
422 if (!has_uid (priv->preregistered_uids, uid)) {
423 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
424 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
426 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
428 if (has_uid (priv->preregistered_uids, uid)) {
429 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
430 if (has_uid (priv->preregistered_uids, uid))
431 g_debug ("BUG: uid %s NOT removed", uid);
433 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
440 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
443 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
445 /* we don't need 'self', but for API consistency... */
446 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
448 g_return_if_fail (help_id);
450 if (GTK_IS_WINDOW (win)) {
451 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
452 g_strdup(help_id), g_free);
458 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
460 /* we don't need 'self', but for API consistency... */
461 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
462 g_return_val_if_fail (win, NULL);
464 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
468 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
470 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
474 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
481 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
484 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
488 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
493 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
494 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
496 uid = modest_tny_folder_get_header_unique_id (header);
499 return modest_window_mgr_find_registered_message_uid (self, uid, win);
505 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
508 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
512 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
515 ModestWindowMgrPrivate *priv = NULL;
517 gboolean has_header = FALSE;
519 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
520 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
522 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
527 has_header = has_uid (priv->preregistered_uids, msg_uid);
534 modest_window_mgr_get_window_list (ModestWindowMgr *self)
536 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
540 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
546 modest_window_mgr_register_window (ModestWindowMgr *self,
547 ModestWindow *window,
548 ModestWindow *parent)
550 gboolean no_windows, retval;
552 no_windows = (modest_window_mgr_get_num_windows (self) == 0);
554 retval = MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
557 /* If this is the first registered window then reset the
558 status of the TnyDevice as it might be forced to be offline
559 when modest is running in the background (see
560 modest_tny_account_store_new()) */
561 if (tny_device_is_forced (modest_runtime_get_device ()))
562 tny_device_reset (modest_runtime_get_device ());
564 /* Do also allow modest to shutdown when the
565 application is closed */
566 modest_runtime_set_allow_shutdown (TRUE);
572 modest_window_mgr_register_window_default (ModestWindowMgr *self,
573 ModestWindow *window,
574 ModestWindow *parent)
576 ModestWindowMgrPrivate *priv;
578 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
579 g_return_val_if_fail (MODEST_IS_WINDOW (window), FALSE);
581 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
583 /* We set up the queue change handler */
584 if (priv->queue_change_handler == 0) {
585 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
587 G_CALLBACK (modest_window_mgr_on_queue_changed),
592 /* remove from the list of pre-registered uids */
593 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
594 const gchar *uid = modest_msg_view_window_get_message_uid
595 (MODEST_MSG_VIEW_WINDOW (window));
597 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
599 if (has_uid (priv->preregistered_uids, uid)) {
600 priv->preregistered_uids =
601 remove_uid (priv->preregistered_uids,
602 modest_msg_view_window_get_message_uid
603 (MODEST_MSG_VIEW_WINDOW (window)));
605 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
606 const gchar *uid = modest_msg_edit_window_get_message_uid
607 (MODEST_MSG_EDIT_WINDOW (window));
609 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
611 priv->preregistered_uids =
612 remove_uid (priv->preregistered_uids,
613 modest_msg_edit_window_get_message_uid
614 (MODEST_MSG_EDIT_WINDOW (window)));
621 modest_window_mgr_unregister_window (ModestWindowMgr *self,
622 ModestWindow *window)
624 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
628 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
629 ModestWindow *window)
631 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
632 g_return_if_fail (MODEST_IS_WINDOW (window));
635 modest_window_save_state (window);
637 /* Disconnect all the window signals */
638 modest_window_disconnect_signals (window);
640 /* Destroy the window */
641 gtk_widget_destroy (GTK_WIDGET (window));
647 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
650 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
654 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
661 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
663 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
667 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
673 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
675 gboolean show_toolbars,
678 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
682 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
684 gboolean show_toolbars,
690 #ifndef MODEST_TOOLKIT_HILDON2
692 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
694 ModestWindowMgrPrivate *priv;
696 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
698 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
699 priv->main_window = win;
703 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
705 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
709 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
716 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
718 ModestWindowMgrPrivate *priv;
720 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
721 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
723 return priv->main_window != NULL;
728 modest_window_mgr_get_modal (ModestWindowMgr *self)
730 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
734 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
741 modest_window_mgr_set_modal (ModestWindowMgr *self,
745 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
749 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
758 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
760 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
761 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
763 /* Forget this window,
764 * so hibernation will be allowed again if no windows are remembered: */
765 priv->windows_that_prevent_hibernation =
766 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
770 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
772 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
773 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
775 GtkWindow *window = GTK_WINDOW (widget);
777 priv->windows_that_prevent_hibernation =
778 g_slist_append (priv->windows_that_prevent_hibernation, window);
780 /* Allow hibernation again when the window has been hidden: */
781 g_signal_connect (window, "hide",
782 G_CALLBACK (on_nonhibernating_window_hide), self);
786 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
789 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
791 if (GTK_WIDGET_VISIBLE(window)) {
792 on_nonhibernating_window_show (GTK_WIDGET (window), self);
794 /* Wait for it to be shown: */
795 g_signal_connect (window, "show",
796 G_CALLBACK (on_nonhibernating_window_show), self);
801 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
803 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
805 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
807 /* Prevent hibernation if any open windows are currently
808 * preventing hibernation: */
809 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
814 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
818 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
820 /* Iterate over all windows */
821 window_list = modest_window_mgr_get_window_list (self);
824 ModestWindow *window = MODEST_WINDOW (node->data);
826 /* This calls the vfunc,
827 * so each window can do its own thing: */
828 modest_window_save_state (window);
831 node = g_list_next (node);
833 g_list_free (window_list);
837 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
839 ModestWindowMgrPrivate *priv;
840 gint num_windows = 0;
843 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
845 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
847 window_list = modest_window_mgr_get_window_list (self);
850 num_windows = g_list_length (window_list);
851 g_list_free (window_list);
854 #ifndef MODEST_TOOLKIT_HILDON2
855 /* Do not take into account the main window if it was hidden */
856 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
860 return num_windows + priv->banner_counter;
864 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
867 ModestWindowMgrPrivate *priv;
869 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
871 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
873 if (priv->cached_editor) {
874 result = priv->cached_editor;
875 priv->cached_editor = NULL;
876 load_new_editor (self);
878 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
885 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
888 ModestWindowMgrPrivate *priv;
890 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
892 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
894 if (priv->cached_view) {
895 result = priv->cached_view;
896 priv->cached_view = NULL;
897 load_new_view (self);
899 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
906 modest_window_mgr_register_banner (ModestWindowMgr *self)
908 ModestWindowMgrPrivate *priv;
910 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
911 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
913 priv->banner_counter++;
917 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
919 ModestWindowMgrPrivate *priv;
921 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
922 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
924 priv->banner_counter--;
925 if (modest_window_mgr_get_num_windows (self) == 0)
926 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
930 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
932 ModestWindow *window = NULL;
934 /* Call the children */
935 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
938 ModestAccountMgr *mgr;
940 /* Show the initial window */
941 gtk_widget_show (GTK_WIDGET (window));
943 /* If there are no accounts then show the account wizard */
944 mgr = modest_runtime_get_account_mgr();
945 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
946 if (!modest_ui_actions_run_account_setup_wizard (window)) {
947 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
955 static ModestWindow *
956 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
958 #ifndef MODEST_TOOLKIT_HILDON2
959 /* By default it returns the main window creating it if
961 return modest_window_mgr_get_main_window (self, TRUE);
969 modest_window_mgr_get_current_top (ModestWindowMgr *self)
971 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
975 static ModestWindow *
976 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
978 g_return_val_if_reached (NULL);
982 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
984 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
988 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
990 /* Default implementation is assuming screen is always on */
996 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
998 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
1002 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
1004 load_new_editor (self);
1005 load_new_view (self);
1009 tny_list_find (TnyList *list, GObject *item)
1011 TnyIterator *iterator;
1012 gboolean found = FALSE;
1014 for (iterator = tny_list_create_iterator (list);
1015 !tny_iterator_is_done (iterator) && !found;
1016 tny_iterator_next (iterator)) {
1017 GObject *current = tny_iterator_get_current (iterator);
1018 if (current == item)
1020 g_object_unref (current);
1022 g_object_unref (iterator);
1028 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1029 ModestMailOperation *mail_op,
1030 ModestMailOperationQueueNotification type,
1031 ModestWindowMgr *self)
1033 ModestWindowMgrPrivate *priv;
1035 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1037 /* We register to track progress */
1038 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1039 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1041 "operation-started",
1042 G_CALLBACK (on_mail_operation_started),
1044 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1046 "operation-finished",
1047 G_CALLBACK (on_mail_operation_finished),
1049 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1050 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1052 "operation-started");
1053 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1055 "operation-finished");
1056 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1057 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1058 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1064 on_mail_operation_started (ModestMailOperation *mail_op,
1067 ModestWindowMgr *self;
1068 ModestWindowMgrPrivate *priv;
1069 ModestMailOperationTypeOperation op_type;
1071 self = MODEST_WINDOW_MGR (user_data);
1072 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1074 /* First we check if the operation is a send receive operation,
1075 * If now, we don't handle this */
1076 op_type = modest_mail_operation_get_type_operation (mail_op);
1077 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1078 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1082 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1083 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1084 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1089 on_mail_operation_finished (ModestMailOperation *mail_op,
1092 ModestWindowMgr *self;
1093 ModestWindowMgrPrivate *priv;
1095 self = MODEST_WINDOW_MGR (user_data);
1096 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1098 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1099 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1100 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1105 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1107 ModestWindowMgrPrivate *priv;
1109 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1111 return tny_list_copy (priv->progress_operations);
1115 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1117 ModestWindowMgrPrivate *priv;
1119 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1121 return tny_list_get_length (priv->progress_operations) > 0;
1125 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1126 const gchar *account_name)
1128 ModestWindowMgrPrivate *priv;
1129 gint account_ops = 0;
1130 TnyIterator *iterator;
1132 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1134 if (account_name == NULL)
1137 for (iterator = tny_list_create_iterator (priv->progress_operations);
1138 !tny_iterator_is_done (iterator);
1139 tny_iterator_next (iterator)) {
1140 ModestMailOperation *mail_op;
1141 TnyAccount *account;
1143 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1144 account = modest_mail_operation_get_account (mail_op);
1146 if (account != NULL) {
1147 const gchar *current_name;
1149 current_name = tny_account_get_id (account);
1150 if (current_name && strcmp (current_name, account_name) == 0)
1152 g_object_unref (account);
1155 g_object_unref (mail_op);
1157 g_object_unref (iterator);
1162 /* 'Protected method' must be only called by children */
1164 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1168 /* Exit if there are no windows */
1169 if (!modest_window_mgr_get_num_windows (self)) {
1170 g_warning ("%s: there are no windows to close", __FUNCTION__);
1174 /* Check that there is no active modal dialog */
1175 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1176 while (modal && GTK_IS_DIALOG (modal)) {
1179 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1180 #include <hildon/hildon.h>
1181 /* If it's a hildon note then don't try to close it as
1182 this is the default behaviour of WM, delete event
1183 is not issued for this kind of notes as we want the
1184 user to always click on a button */
1185 if (HILDON_IS_NOTE (modal)) {
1186 gtk_window_present (GTK_WINDOW (modal));
1191 /* Get the parent */
1192 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1194 /* Try to close it */
1195 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1197 /* Maybe the dialog was not closed, because a close
1198 confirmation dialog for example. Then ignore the
1200 if (GTK_IS_WINDOW (modal)) {
1201 gtk_window_present (GTK_WINDOW (modal));
1205 /* Get next modal */
1212 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1214 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1218 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1220 /* Empty default implementation */
1225 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1227 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1230 static ModestWindow *
1231 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1233 /* Default implementation returns NULL always */