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 /* If this is the first registered window then reset the
551 status of the TnyDevice as it might be forced to be offline
552 when modest is running in the background (see
553 modest_tny_account_store_new()) */
554 if (modest_window_mgr_get_num_windows (self) == 0) {
555 if (tny_device_is_forced (modest_runtime_get_device ()))
556 tny_device_reset (modest_runtime_get_device ());
559 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
563 modest_window_mgr_register_window_default (ModestWindowMgr *self,
564 ModestWindow *window,
565 ModestWindow *parent)
567 ModestWindowMgrPrivate *priv;
569 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
570 g_return_val_if_fail (MODEST_IS_WINDOW (window), FALSE);
572 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
574 /* We set up the queue change handler */
575 if (priv->queue_change_handler == 0) {
576 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
578 G_CALLBACK (modest_window_mgr_on_queue_changed),
583 /* remove from the list of pre-registered uids */
584 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
585 const gchar *uid = modest_msg_view_window_get_message_uid
586 (MODEST_MSG_VIEW_WINDOW (window));
588 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
590 if (has_uid (priv->preregistered_uids, uid)) {
591 priv->preregistered_uids =
592 remove_uid (priv->preregistered_uids,
593 modest_msg_view_window_get_message_uid
594 (MODEST_MSG_VIEW_WINDOW (window)));
596 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
597 const gchar *uid = modest_msg_edit_window_get_message_uid
598 (MODEST_MSG_EDIT_WINDOW (window));
600 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
602 priv->preregistered_uids =
603 remove_uid (priv->preregistered_uids,
604 modest_msg_edit_window_get_message_uid
605 (MODEST_MSG_EDIT_WINDOW (window)));
612 modest_window_mgr_unregister_window (ModestWindowMgr *self,
613 ModestWindow *window)
615 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
619 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
620 ModestWindow *window)
622 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
623 g_return_if_fail (MODEST_IS_WINDOW (window));
626 modest_window_save_state (window);
628 /* Disconnect all the window signals */
629 modest_window_disconnect_signals (window);
631 /* Destroy the window */
632 gtk_widget_destroy (GTK_WIDGET (window));
638 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
641 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
645 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
652 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
654 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
658 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
664 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
666 gboolean show_toolbars,
669 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
673 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
675 gboolean show_toolbars,
681 #ifndef MODEST_TOOLKIT_HILDON2
683 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
685 ModestWindowMgrPrivate *priv;
687 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
689 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
690 priv->main_window = win;
694 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
696 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
700 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
707 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
709 ModestWindowMgrPrivate *priv;
711 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
712 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
714 return priv->main_window != NULL;
719 modest_window_mgr_get_modal (ModestWindowMgr *self)
721 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
725 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
732 modest_window_mgr_set_modal (ModestWindowMgr *self,
736 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
740 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
749 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
751 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
752 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
754 /* Forget this window,
755 * so hibernation will be allowed again if no windows are remembered: */
756 priv->windows_that_prevent_hibernation =
757 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
761 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
763 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
764 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
766 GtkWindow *window = GTK_WINDOW (widget);
768 priv->windows_that_prevent_hibernation =
769 g_slist_append (priv->windows_that_prevent_hibernation, window);
771 /* Allow hibernation again when the window has been hidden: */
772 g_signal_connect (window, "hide",
773 G_CALLBACK (on_nonhibernating_window_hide), self);
777 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
780 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
782 if (GTK_WIDGET_VISIBLE(window)) {
783 on_nonhibernating_window_show (GTK_WIDGET (window), self);
785 /* Wait for it to be shown: */
786 g_signal_connect (window, "show",
787 G_CALLBACK (on_nonhibernating_window_show), self);
792 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
794 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
796 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
798 /* Prevent hibernation if any open windows are currently
799 * preventing hibernation: */
800 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
805 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
809 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
811 /* Iterate over all windows */
812 window_list = modest_window_mgr_get_window_list (self);
815 ModestWindow *window = MODEST_WINDOW (node->data);
817 /* This calls the vfunc,
818 * so each window can do its own thing: */
819 modest_window_save_state (window);
822 node = g_list_next (node);
824 g_list_free (window_list);
828 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
830 ModestWindowMgrPrivate *priv;
831 gint num_windows = 0;
834 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
836 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
838 window_list = modest_window_mgr_get_window_list (self);
841 num_windows = g_list_length (window_list);
842 g_list_free (window_list);
845 #ifndef MODEST_TOOLKIT_HILDON2
846 /* Do not take into account the main window if it was hidden */
847 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
851 return num_windows + priv->banner_counter;
855 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
858 ModestWindowMgrPrivate *priv;
860 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
862 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
864 if (priv->cached_editor) {
865 result = priv->cached_editor;
866 priv->cached_editor = NULL;
867 load_new_editor (self);
869 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
876 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
879 ModestWindowMgrPrivate *priv;
881 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
883 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
885 if (priv->cached_view) {
886 result = priv->cached_view;
887 priv->cached_view = NULL;
888 load_new_view (self);
890 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
897 modest_window_mgr_register_banner (ModestWindowMgr *self)
899 ModestWindowMgrPrivate *priv;
901 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
902 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
904 priv->banner_counter++;
908 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
910 ModestWindowMgrPrivate *priv;
912 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
913 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
915 priv->banner_counter--;
916 if (modest_window_mgr_get_num_windows (self) == 0)
917 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
921 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
923 ModestWindow *window = NULL;
925 /* Call the children */
926 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
929 ModestAccountMgr *mgr;
931 /* Show the initial window */
932 gtk_widget_show (GTK_WIDGET (window));
934 /* If there are no accounts then show the account wizard */
935 mgr = modest_runtime_get_account_mgr();
936 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
937 if (!modest_ui_actions_run_account_setup_wizard (window)) {
938 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
946 static ModestWindow *
947 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
949 #ifndef MODEST_TOOLKIT_HILDON2
950 /* By default it returns the main window creating it if
952 return modest_window_mgr_get_main_window (self, TRUE);
960 modest_window_mgr_get_current_top (ModestWindowMgr *self)
962 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
966 static ModestWindow *
967 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
969 g_return_val_if_reached (NULL);
973 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
975 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
979 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
981 /* Default implementation is assuming screen is always on */
987 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
989 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
993 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
995 load_new_editor (self);
996 load_new_view (self);
1000 tny_list_find (TnyList *list, GObject *item)
1002 TnyIterator *iterator;
1003 gboolean found = FALSE;
1005 for (iterator = tny_list_create_iterator (list);
1006 !tny_iterator_is_done (iterator) && !found;
1007 tny_iterator_next (iterator)) {
1008 GObject *current = tny_iterator_get_current (iterator);
1009 if (current == item)
1011 g_object_unref (current);
1013 g_object_unref (iterator);
1019 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1020 ModestMailOperation *mail_op,
1021 ModestMailOperationQueueNotification type,
1022 ModestWindowMgr *self)
1024 ModestWindowMgrPrivate *priv;
1026 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1028 /* We register to track progress */
1029 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1030 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1032 "operation-started",
1033 G_CALLBACK (on_mail_operation_started),
1035 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1037 "operation-finished",
1038 G_CALLBACK (on_mail_operation_finished),
1040 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1041 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1043 "operation-started");
1044 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1046 "operation-finished");
1047 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1048 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1049 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1055 on_mail_operation_started (ModestMailOperation *mail_op,
1058 ModestWindowMgr *self;
1059 ModestWindowMgrPrivate *priv;
1060 ModestMailOperationTypeOperation op_type;
1062 self = MODEST_WINDOW_MGR (user_data);
1063 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1065 /* First we check if the operation is a send receive operation,
1066 * If now, we don't handle this */
1067 op_type = modest_mail_operation_get_type_operation (mail_op);
1068 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1069 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1073 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1074 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1075 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1080 on_mail_operation_finished (ModestMailOperation *mail_op,
1083 ModestWindowMgr *self;
1084 ModestWindowMgrPrivate *priv;
1086 self = MODEST_WINDOW_MGR (user_data);
1087 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1089 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1090 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1091 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1096 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1098 ModestWindowMgrPrivate *priv;
1100 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1102 return tny_list_copy (priv->progress_operations);
1106 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1108 ModestWindowMgrPrivate *priv;
1110 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1112 return tny_list_get_length (priv->progress_operations) > 0;
1116 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1117 const gchar *account_name)
1119 ModestWindowMgrPrivate *priv;
1120 gint account_ops = 0;
1121 TnyIterator *iterator;
1123 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1125 if (account_name == NULL)
1128 for (iterator = tny_list_create_iterator (priv->progress_operations);
1129 !tny_iterator_is_done (iterator);
1130 tny_iterator_next (iterator)) {
1131 ModestMailOperation *mail_op;
1132 TnyAccount *account;
1134 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1135 account = modest_mail_operation_get_account (mail_op);
1137 if (account != NULL) {
1138 const gchar *current_name;
1140 current_name = tny_account_get_id (account);
1141 if (current_name && strcmp (current_name, account_name) == 0)
1143 g_object_unref (account);
1146 g_object_unref (mail_op);
1148 g_object_unref (iterator);
1153 /* 'Protected method' must be only called by children */
1155 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1159 /* Exit if there are no windows */
1160 if (!modest_window_mgr_get_num_windows (self)) {
1161 g_warning ("%s: there are no windows to close", __FUNCTION__);
1165 /* Check that there is no active modal dialog */
1166 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1167 while (modal && GTK_IS_DIALOG (modal)) {
1170 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1171 #include <hildon/hildon.h>
1172 /* If it's a hildon note then don't try to close it as
1173 this is the default behaviour of WM, delete event
1174 is not issued for this kind of notes as we want the
1175 user to always click on a button */
1176 if (HILDON_IS_NOTE (modal)) {
1177 gtk_window_present (GTK_WINDOW (modal));
1182 /* Get the parent */
1183 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1185 /* Try to close it */
1186 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1188 /* Maybe the dialog was not closed, because a close
1189 confirmation dialog for example. Then ignore the
1191 if (GTK_IS_WINDOW (modal)) {
1192 gtk_window_present (GTK_WINDOW (modal));
1196 /* Get next modal */
1203 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1205 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1209 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1211 /* Empty default implementation */
1216 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1218 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1221 static ModestWindow *
1222 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1224 /* Default implementation returns NULL always */