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 void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
80 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
81 ModestMailOperation *mail_op,
82 ModestMailOperationQueueNotification type,
83 ModestWindowMgr *self);
84 static void on_mail_operation_started (ModestMailOperation *mail_op,
86 static void on_mail_operation_finished (ModestMailOperation *mail_op,
91 WINDOW_LIST_EMPTY_SIGNAL,
92 PROGRESS_LIST_CHANGED_SIGNAL,
96 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
97 struct _ModestWindowMgrPrivate {
100 #ifndef MODEST_TOOLKIT_HILDON2
101 ModestWindow *main_window;
103 GSList *windows_that_prevent_hibernation;
104 GSList *preregistered_uids;
108 GtkWidget *cached_view;
109 GtkWidget *cached_editor;
110 guint idle_load_view_id;
111 guint idle_load_editor_id;
113 guint queue_change_handler;
114 TnyList *progress_operations;
118 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
119 MODEST_TYPE_WINDOW_MGR, \
120 ModestWindowMgrPrivate))
122 static GObjectClass *parent_class = NULL;
124 /* uncomment the following if you have defined any signals */
125 static guint signals[NUM_SIGNALS] = {0};
128 modest_window_mgr_get_type (void)
130 static GType my_type = 0;
132 static const GTypeInfo my_info = {
133 sizeof(ModestWindowMgrClass),
134 NULL, /* base init */
135 NULL, /* base finalize */
136 (GClassInitFunc) modest_window_mgr_class_init,
137 NULL, /* class finalize */
138 NULL, /* class data */
139 sizeof(ModestWindowMgr),
141 (GInstanceInitFunc) modest_window_mgr_init,
144 my_type = g_type_register_static (G_TYPE_OBJECT,
152 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
154 GObjectClass *gobject_class;
155 ModestWindowMgrClass *mgr_class;
157 gobject_class = (GObjectClass*) klass;
158 mgr_class = (ModestWindowMgrClass *) klass;
160 parent_class = g_type_class_peek_parent (klass);
161 gobject_class->finalize = modest_window_mgr_finalize;
162 mgr_class->register_window = modest_window_mgr_register_window_default;
163 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
164 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
165 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
166 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
167 #ifndef MODEST_TOOLKIT_HILDON2
168 mgr_class->get_main_window = modest_window_mgr_get_main_window_default;
170 mgr_class->get_modal = modest_window_mgr_get_modal_default;
171 mgr_class->set_modal = modest_window_mgr_set_modal_default;
172 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
173 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
174 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
175 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
176 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
177 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
178 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
179 mgr_class->create_caches = modest_window_mgr_create_caches_default;
181 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
185 * ModestWindowMgr::window-list-empty
186 * @self: the #ModestWindowMgr that emits the signal
187 * @user_data: user data set when the signal handler was connected
189 * Issued whenever the window list becomes empty
191 signals[WINDOW_LIST_EMPTY_SIGNAL] =
192 g_signal_new ("window-list-empty",
193 G_TYPE_FROM_CLASS (gobject_class),
195 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
197 g_cclosure_marshal_VOID__VOID,
201 * ModestWindowMgr::progress-list-changed
202 * @self: the #ModestWindowMgr that emits the signal
203 * @user_data: user data set when the signal handler was connected
205 * Issued whenever the progress mail operations list becomes changed
207 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
208 g_signal_new ("progress-list-changed",
209 G_TYPE_FROM_CLASS (gobject_class),
211 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
213 g_cclosure_marshal_VOID__VOID,
218 idle_load_view (ModestWindowMgr *mgr)
220 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
222 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
223 priv->idle_load_view_id = 0;
228 idle_load_editor (ModestWindowMgr *mgr)
230 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
232 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
233 priv->idle_load_editor_id = 0;
238 load_new_view (ModestWindowMgr *self)
240 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
241 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
242 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
246 load_new_editor (ModestWindowMgr *self)
248 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
249 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
250 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
254 modest_window_mgr_init (ModestWindowMgr *obj)
256 ModestWindowMgrPrivate *priv;
258 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
259 priv->banner_counter = 0;
260 #ifndef MODEST_TOOLKIT_HILDON2
261 priv->main_window = NULL;
263 priv->preregistered_uids = NULL;
265 priv->closing_time = 0;
267 priv->cached_view = NULL;
268 priv->cached_editor = NULL;
270 priv->windows_that_prevent_hibernation = NULL;
272 priv->queue_change_handler = 0;
273 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
277 modest_window_mgr_finalize (GObject *obj)
279 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
281 if (priv->idle_load_view_id > 0) {
282 g_source_remove (priv->idle_load_view_id);
283 priv->idle_load_view_id = 0;
286 if (priv->idle_load_editor_id > 0) {
287 g_source_remove (priv->idle_load_editor_id);
288 priv->idle_load_editor_id = 0;
291 if (priv->cached_view) {
292 gtk_widget_destroy (priv->cached_view);
293 priv->cached_view = NULL;
295 if (priv->cached_editor) {
296 gtk_widget_destroy (priv->cached_editor);
297 priv->cached_editor = NULL;
300 if (priv->windows_that_prevent_hibernation) {
301 g_slist_free (priv->windows_that_prevent_hibernation);
302 priv->cached_editor = NULL;
305 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
306 priv->sighandlers = NULL;
308 if (priv->queue_change_handler > 0) {
309 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
310 priv->queue_change_handler);
311 priv->queue_change_handler = 0;
314 if (priv->progress_operations) {
315 g_object_unref (priv->progress_operations);
316 priv->progress_operations = NULL;
319 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
320 g_slist_free (priv->preregistered_uids);
322 G_OBJECT_CLASS(parent_class)->finalize (obj);
326 modest_window_mgr_new (void)
328 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
334 /* do we have uid? */
336 has_uid (GSList *list, const gchar *uid)
338 GSList *cursor = list;
344 if (cursor->data && strcmp (cursor->data, uid) == 0)
346 cursor = g_slist_next (cursor);
352 /* remove all from the list have have uid = uid */
354 remove_uid (GSList *list, const gchar *uid)
356 GSList *cursor = list, *start = list;
362 GSList *next = g_slist_next (cursor);
363 if (cursor->data && strcmp (cursor->data, uid) == 0) {
364 g_free (cursor->data);
365 start = g_slist_delete_link (start, cursor);
374 append_uid (GSList *list, const gchar *uid)
376 return g_slist_append (list, g_strdup(uid));
382 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
384 ModestWindowMgrPrivate *priv;
387 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
388 g_return_if_fail (TNY_IS_HEADER(header));
390 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
391 if (alt_uid != NULL) {
392 uid = g_strdup (alt_uid);
394 uid = modest_tny_folder_get_header_unique_id (header);
397 if (!has_uid (priv->preregistered_uids, uid)) {
398 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
399 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
401 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
407 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
409 ModestWindowMgrPrivate *priv;
412 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
413 g_return_if_fail (TNY_IS_HEADER(header));
415 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
416 uid = modest_tny_folder_get_header_unique_id (header);
418 if (!has_uid (priv->preregistered_uids, uid)) {
419 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
420 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
422 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
424 if (has_uid (priv->preregistered_uids, uid)) {
425 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
426 if (has_uid (priv->preregistered_uids, uid))
427 g_debug ("BUG: uid %s NOT removed", uid);
429 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
436 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
439 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
441 /* we don't need 'self', but for API consistency... */
442 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
444 g_return_if_fail (win && GTK_IS_WINDOW(win));
445 g_return_if_fail (help_id);
447 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
448 g_strdup(help_id), g_free);
453 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
455 /* we don't need 'self', but for API consistency... */
456 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
457 g_return_val_if_fail (win, NULL);
459 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
463 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
465 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
469 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
476 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
479 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
483 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
488 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
489 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
491 uid = modest_tny_folder_get_header_unique_id (header);
494 return modest_window_mgr_find_registered_message_uid (self, uid, win);
500 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
503 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
507 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
510 ModestWindowMgrPrivate *priv = NULL;
512 gboolean has_header = FALSE;
514 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
515 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
517 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
522 has_header = has_uid (priv->preregistered_uids, msg_uid);
529 modest_window_mgr_get_window_list (ModestWindowMgr *self)
531 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
535 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
541 modest_window_mgr_register_window (ModestWindowMgr *self,
542 ModestWindow *window,
543 ModestWindow *parent)
545 /* If this is the first registered window then reset the
546 status of the TnyDevice as it might be forced to be offline
547 when modest is running in the background (see
548 modest_tny_account_store_new()) */
549 if (modest_window_mgr_get_num_windows (self) == 0) {
550 if (tny_device_is_forced (modest_runtime_get_device ()))
551 tny_device_reset (modest_runtime_get_device ());
554 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
558 modest_window_mgr_register_window_default (ModestWindowMgr *self,
559 ModestWindow *window,
560 ModestWindow *parent)
562 ModestWindowMgrPrivate *priv;
564 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
565 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
567 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
569 /* We set up the queue change handler */
570 if (priv->queue_change_handler == 0) {
571 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
573 G_CALLBACK (modest_window_mgr_on_queue_changed),
577 #ifndef MODEST_TOOLKIT_HILDON2
578 /* Check that it's not a second main window */
579 if (MODEST_IS_MAIN_WINDOW (window)) {
580 if (priv->main_window) {
581 g_warning ("%s: trying to register a second main window",
585 priv->main_window = window;
590 /* remove from the list of pre-registered uids */
591 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
592 const gchar *uid = modest_msg_view_window_get_message_uid
593 (MODEST_MSG_VIEW_WINDOW (window));
595 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
597 if (has_uid (priv->preregistered_uids, uid)) {
598 priv->preregistered_uids =
599 remove_uid (priv->preregistered_uids,
600 modest_msg_view_window_get_message_uid
601 (MODEST_MSG_VIEW_WINDOW (window)));
603 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
604 const gchar *uid = modest_msg_edit_window_get_message_uid
605 (MODEST_MSG_EDIT_WINDOW (window));
607 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
609 priv->preregistered_uids =
610 remove_uid (priv->preregistered_uids,
611 modest_msg_edit_window_get_message_uid
612 (MODEST_MSG_EDIT_WINDOW (window)));
619 modest_window_mgr_unregister_window (ModestWindowMgr *self,
620 ModestWindow *window)
622 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
626 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
627 ModestWindow *window)
629 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
630 g_return_if_fail (MODEST_IS_WINDOW (window));
633 modest_window_save_state (window);
635 /* Disconnect all the window signals */
636 modest_window_disconnect_signals (window);
638 /* Destroy the window */
639 gtk_widget_destroy (GTK_WIDGET (window));
645 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
648 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
652 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
659 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
661 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
665 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
671 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
673 gboolean show_toolbars,
676 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
680 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
682 gboolean show_toolbars,
688 #ifndef MODEST_TOOLKIT_HILDON2
690 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
692 ModestWindowMgrPrivate *priv;
694 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
696 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
697 priv->main_window = win;
701 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
703 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
707 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
709 ModestWindowMgrPrivate *priv;
711 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
713 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
714 if (priv->main_window)
715 return priv->main_window;
718 return modest_main_window_new ();
724 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
726 ModestWindowMgrPrivate *priv;
728 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
729 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
731 return priv->main_window != NULL;
736 modest_window_mgr_get_modal (ModestWindowMgr *self)
738 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
742 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
749 modest_window_mgr_set_modal (ModestWindowMgr *self,
753 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
757 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
766 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
768 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
769 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
771 /* Forget this window,
772 * so hibernation will be allowed again if no windows are remembered: */
773 priv->windows_that_prevent_hibernation =
774 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
778 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
780 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
781 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
783 GtkWindow *window = GTK_WINDOW (widget);
785 priv->windows_that_prevent_hibernation =
786 g_slist_append (priv->windows_that_prevent_hibernation, window);
788 /* Allow hibernation again when the window has been hidden: */
789 g_signal_connect (window, "hide",
790 G_CALLBACK (on_nonhibernating_window_hide), self);
794 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
797 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
799 if (GTK_WIDGET_VISIBLE(window)) {
800 on_nonhibernating_window_show (GTK_WIDGET (window), self);
802 /* Wait for it to be shown: */
803 g_signal_connect (window, "show",
804 G_CALLBACK (on_nonhibernating_window_show), self);
809 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
811 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
813 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
815 /* Prevent hibernation if any open windows are currently
816 * preventing hibernation: */
817 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
822 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
826 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
828 /* Iterate over all windows */
829 window_list = modest_window_mgr_get_window_list (self);
832 ModestWindow *window = MODEST_WINDOW (node->data);
834 /* This calls the vfunc,
835 * so each window can do its own thing: */
836 modest_window_save_state (window);
839 node = g_list_next (node);
841 g_list_free (window_list);
845 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
847 ModestWindowMgrPrivate *priv;
848 gint num_windows = 0;
851 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
853 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
855 window_list = modest_window_mgr_get_window_list (self);
858 num_windows = g_list_length (window_list);
859 g_list_free (window_list);
862 #ifndef MODEST_TOOLKIT_HILDON2
863 /* Do not take into account the main window if it was hidden */
864 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
868 return num_windows + priv->banner_counter;
872 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
875 ModestWindowMgrPrivate *priv;
877 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
879 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
881 if (priv->cached_editor) {
882 result = priv->cached_editor;
883 priv->cached_editor = NULL;
884 load_new_editor (self);
886 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
893 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
896 ModestWindowMgrPrivate *priv;
898 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
900 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
902 if (priv->cached_view) {
903 result = priv->cached_view;
904 priv->cached_view = NULL;
905 load_new_view (self);
907 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
914 modest_window_mgr_register_banner (ModestWindowMgr *self)
916 ModestWindowMgrPrivate *priv;
918 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
919 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
921 priv->banner_counter++;
925 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
927 ModestWindowMgrPrivate *priv;
929 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
930 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
932 priv->banner_counter--;
933 if (modest_window_mgr_get_num_windows (self) == 0)
934 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
938 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
940 ModestWindow *window = NULL;
942 /* Call the children */
943 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
946 ModestAccountMgr *mgr;
948 /* Show the initial window */
949 gtk_widget_show (GTK_WIDGET (window));
951 /* If there are no accounts then show the account wizard */
952 mgr = modest_runtime_get_account_mgr();
953 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
954 if (!modest_ui_actions_run_account_setup_wizard (window)) {
955 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
963 static ModestWindow *
964 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
966 #ifndef MODEST_TOOLKIT_HILDON2
967 /* By default it returns the main window creating it if
969 return modest_window_mgr_get_main_window (self, TRUE);
977 modest_window_mgr_get_current_top (ModestWindowMgr *self)
979 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
983 static ModestWindow *
984 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
986 g_return_val_if_reached (NULL);
990 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
992 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
996 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
998 /* Default implementation is assuming screen is always on */
1004 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
1006 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
1010 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
1012 load_new_editor (self);
1013 load_new_view (self);
1017 tny_list_find (TnyList *list, GObject *item)
1019 TnyIterator *iterator;
1020 gboolean found = FALSE;
1022 for (iterator = tny_list_create_iterator (list);
1023 !tny_iterator_is_done (iterator) && !found;
1024 tny_iterator_next (iterator)) {
1025 GObject *current = tny_iterator_get_current (iterator);
1026 if (current == item)
1028 g_object_unref (current);
1030 g_object_unref (iterator);
1036 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1037 ModestMailOperation *mail_op,
1038 ModestMailOperationQueueNotification type,
1039 ModestWindowMgr *self)
1041 ModestWindowMgrPrivate *priv;
1043 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1045 /* We register to track progress */
1046 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1047 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1049 "operation-started",
1050 G_CALLBACK (on_mail_operation_started),
1052 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1054 "operation-finished",
1055 G_CALLBACK (on_mail_operation_finished),
1057 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1058 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1060 "operation-started");
1061 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1063 "operation-finished");
1064 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1065 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1066 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1072 on_mail_operation_started (ModestMailOperation *mail_op,
1075 ModestWindowMgr *self;
1076 ModestWindowMgrPrivate *priv;
1077 ModestMailOperationTypeOperation op_type;
1079 self = MODEST_WINDOW_MGR (user_data);
1080 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1082 /* First we check if the operation is a send receive operation,
1083 * If now, we don't handle this */
1084 op_type = modest_mail_operation_get_type_operation (mail_op);
1085 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1086 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1090 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1091 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1092 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1097 on_mail_operation_finished (ModestMailOperation *mail_op,
1100 ModestWindowMgr *self;
1101 ModestWindowMgrPrivate *priv;
1103 self = MODEST_WINDOW_MGR (user_data);
1104 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1106 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1107 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1108 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1113 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1115 ModestWindowMgrPrivate *priv;
1117 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1119 return tny_list_copy (priv->progress_operations);
1123 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1125 ModestWindowMgrPrivate *priv;
1127 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1129 return tny_list_get_length (priv->progress_operations) > 0;
1133 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1134 const gchar *account_name)
1136 ModestWindowMgrPrivate *priv;
1137 gint account_ops = 0;
1138 TnyIterator *iterator;
1140 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1142 if (account_name == NULL)
1145 for (iterator = tny_list_create_iterator (priv->progress_operations);
1146 !tny_iterator_is_done (iterator);
1147 tny_iterator_next (iterator)) {
1148 ModestMailOperation *mail_op;
1149 TnyAccount *account;
1151 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1152 account = modest_mail_operation_get_account (mail_op);
1154 if (account != NULL) {
1155 const gchar *current_name;
1157 current_name = tny_account_get_id (account);
1158 if (current_name && strcmp (current_name, account_name) == 0)
1160 g_object_unref (account);
1163 g_object_unref (mail_op);
1165 g_object_unref (iterator);
1172 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1176 /* Exit if there are no windows */
1177 if (!modest_window_mgr_get_num_windows (self)) {
1178 g_warning ("%s: there are no windows to close", __FUNCTION__);
1182 /* Check that there is no active modal dialog */
1183 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1184 while (modal && GTK_IS_DIALOG (modal)) {
1187 /* If it's a hildon note then don't try to close it as
1188 this is the default behaviour of WM, delete event
1189 is not issued for this kind of notes as we want the
1190 user to always click on a button */
1191 if (HILDON_IS_NOTE (modal)) {
1192 gtk_window_present (GTK_WINDOW (modal));
1196 /* Get the parent */
1197 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1199 /* Try to close it */
1200 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1202 /* Maybe the dialog was not closed, because a close
1203 confirmation dialog for example. Then ignore the
1205 if (GTK_IS_WINDOW (modal)) {
1206 gtk_window_present (GTK_WINDOW (modal));
1210 /* Get next modal */