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-msg-edit-window.h"
38 #include "widgets/modest-msg-view-window.h"
39 #include "modest-debug.h"
40 #include <tny-simple-list.h>
43 /* 'private'/'protected' functions */
44 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
45 static void modest_window_mgr_init (ModestWindowMgr *obj);
46 static void modest_window_mgr_finalize (GObject *obj);
48 static gboolean modest_window_mgr_register_window_default (ModestWindowMgr *self,
50 ModestWindow *parent);
51 static void modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
52 ModestWindow *window);
53 static void modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
55 static gboolean modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self);
56 static void modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
58 gboolean show_toolbars,
60 static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self);
61 static void modest_window_mgr_set_modal_default (ModestWindowMgr *self,
64 static gboolean modest_window_mgr_close_all_windows_default (ModestWindowMgr *self);
65 static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self,
68 static gboolean modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self,
71 static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self);
72 static ModestWindow *modest_window_mgr_show_initial_window_default (ModestWindowMgr *self);
73 static ModestWindow *modest_window_mgr_get_current_top_default (ModestWindowMgr *self);
74 static gboolean modest_window_mgr_screen_is_on_default (ModestWindowMgr *self);
75 static ModestWindow *modest_window_mgr_get_folder_window_default (ModestWindowMgr *self);
76 static void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
77 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
78 ModestMailOperation *mail_op,
79 ModestMailOperationQueueNotification type,
80 ModestWindowMgr *self);
81 static void on_mail_operation_started (ModestMailOperation *mail_op,
83 static void on_mail_operation_finished (ModestMailOperation *mail_op,
85 static gboolean modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self);
89 WINDOW_LIST_EMPTY_SIGNAL,
90 PROGRESS_LIST_CHANGED_SIGNAL,
94 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
95 struct _ModestWindowMgrPrivate {
98 GSList *windows_that_prevent_hibernation;
99 GSList *preregistered_uids;
103 GtkWidget *cached_view;
104 GtkWidget *cached_editor;
105 guint idle_load_view_id;
106 guint idle_load_editor_id;
108 guint queue_change_handler;
109 TnyList *progress_operations;
113 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
114 MODEST_TYPE_WINDOW_MGR, \
115 ModestWindowMgrPrivate))
117 static GObjectClass *parent_class = NULL;
119 /* uncomment the following if you have defined any signals */
120 static guint signals[NUM_SIGNALS] = {0};
123 modest_window_mgr_get_type (void)
125 static GType my_type = 0;
127 static const GTypeInfo my_info = {
128 sizeof(ModestWindowMgrClass),
129 NULL, /* base init */
130 NULL, /* base finalize */
131 (GClassInitFunc) modest_window_mgr_class_init,
132 NULL, /* class finalize */
133 NULL, /* class data */
134 sizeof(ModestWindowMgr),
136 (GInstanceInitFunc) modest_window_mgr_init,
139 my_type = g_type_register_static (G_TYPE_OBJECT,
147 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
149 GObjectClass *gobject_class;
150 ModestWindowMgrClass *mgr_class;
152 gobject_class = (GObjectClass*) klass;
153 mgr_class = (ModestWindowMgrClass *) klass;
155 parent_class = g_type_class_peek_parent (klass);
156 gobject_class->finalize = modest_window_mgr_finalize;
157 mgr_class->register_window = modest_window_mgr_register_window_default;
158 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
159 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
160 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
161 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
162 mgr_class->get_modal = modest_window_mgr_get_modal_default;
163 mgr_class->set_modal = modest_window_mgr_set_modal_default;
164 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
165 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
166 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
167 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
168 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
169 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
170 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
171 mgr_class->create_caches = modest_window_mgr_create_caches_default;
172 mgr_class->close_all_but_initial = modest_window_mgr_close_all_but_initial_default;
173 mgr_class->get_folder_window = modest_window_mgr_get_folder_window_default;
175 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
179 * ModestWindowMgr::window-list-empty
180 * @self: the #ModestWindowMgr that emits the signal
181 * @user_data: user data set when the signal handler was connected
183 * Issued whenever the window list becomes empty
185 signals[WINDOW_LIST_EMPTY_SIGNAL] =
186 g_signal_new ("window-list-empty",
187 G_TYPE_FROM_CLASS (gobject_class),
189 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
191 g_cclosure_marshal_VOID__VOID,
195 * ModestWindowMgr::progress-list-changed
196 * @self: the #ModestWindowMgr that emits the signal
197 * @user_data: user data set when the signal handler was connected
199 * Issued whenever the progress mail operations list becomes changed
201 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
202 g_signal_new ("progress-list-changed",
203 G_TYPE_FROM_CLASS (gobject_class),
205 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
207 g_cclosure_marshal_VOID__VOID,
212 idle_load_view (ModestWindowMgr *mgr)
214 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
216 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
217 priv->idle_load_view_id = 0;
222 idle_load_editor (ModestWindowMgr *mgr)
224 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
226 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
227 priv->idle_load_editor_id = 0;
232 load_new_view (ModestWindowMgr *self)
234 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
235 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
236 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
240 load_new_editor (ModestWindowMgr *self)
242 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
243 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
244 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
248 modest_window_mgr_init (ModestWindowMgr *obj)
250 ModestWindowMgrPrivate *priv;
252 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
253 priv->banner_counter = 0;
254 priv->preregistered_uids = NULL;
256 priv->closing_time = 0;
258 priv->cached_view = NULL;
259 priv->cached_editor = NULL;
261 priv->windows_that_prevent_hibernation = NULL;
263 priv->queue_change_handler = 0;
264 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
268 modest_window_mgr_finalize (GObject *obj)
270 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
272 if (priv->idle_load_view_id > 0) {
273 g_source_remove (priv->idle_load_view_id);
274 priv->idle_load_view_id = 0;
277 if (priv->idle_load_editor_id > 0) {
278 g_source_remove (priv->idle_load_editor_id);
279 priv->idle_load_editor_id = 0;
282 if (priv->cached_view) {
283 gtk_widget_destroy (priv->cached_view);
284 priv->cached_view = NULL;
286 if (priv->cached_editor) {
287 gtk_widget_destroy (priv->cached_editor);
288 priv->cached_editor = NULL;
291 if (priv->windows_that_prevent_hibernation) {
292 g_slist_free (priv->windows_that_prevent_hibernation);
293 priv->cached_editor = NULL;
296 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
297 priv->sighandlers = NULL;
299 if (priv->queue_change_handler > 0) {
300 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
301 priv->queue_change_handler);
302 priv->queue_change_handler = 0;
305 if (priv->progress_operations) {
306 g_object_unref (priv->progress_operations);
307 priv->progress_operations = NULL;
310 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
311 g_slist_free (priv->preregistered_uids);
313 G_OBJECT_CLASS(parent_class)->finalize (obj);
317 modest_window_mgr_new (void)
319 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
325 /* do we have uid? */
327 has_uid (GSList *list, const gchar *uid)
329 GSList *cursor = list;
335 if (cursor->data && strcmp (cursor->data, uid) == 0)
337 cursor = g_slist_next (cursor);
343 /* remove all from the list have have uid = uid */
345 remove_uid (GSList *list, const gchar *uid)
347 GSList *cursor = list, *start = list;
353 GSList *next = g_slist_next (cursor);
354 if (cursor->data && strcmp (cursor->data, uid) == 0) {
355 g_free (cursor->data);
356 start = g_slist_delete_link (start, cursor);
365 append_uid (GSList *list, const gchar *uid)
367 return g_slist_append (list, g_strdup(uid));
373 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
375 ModestWindowMgrPrivate *priv;
378 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
379 g_return_if_fail (TNY_IS_HEADER(header));
381 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
382 if (alt_uid != NULL) {
383 uid = g_strdup (alt_uid);
385 uid = modest_tny_folder_get_header_unique_id (header);
388 if (!has_uid (priv->preregistered_uids, uid)) {
389 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
390 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
392 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
398 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
400 ModestWindowMgrPrivate *priv;
403 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
404 g_return_if_fail (TNY_IS_HEADER(header));
406 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
407 uid = modest_tny_folder_get_header_unique_id (header);
409 if (!has_uid (priv->preregistered_uids, uid)) {
410 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
411 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
413 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
415 if (has_uid (priv->preregistered_uids, uid)) {
416 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
417 if (has_uid (priv->preregistered_uids, uid))
418 g_debug ("BUG: uid %s NOT removed", uid);
420 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
427 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
430 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
432 /* we don't need 'self', but for API consistency... */
433 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
435 g_return_if_fail (help_id);
437 if (GTK_IS_WINDOW (win)) {
438 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
439 g_strdup(help_id), g_free);
445 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
447 /* we don't need 'self', but for API consistency... */
448 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
449 g_return_val_if_fail (win, NULL);
451 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
455 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
457 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
461 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
468 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
471 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
475 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
480 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
481 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
483 uid = modest_tny_folder_get_header_unique_id (header);
486 return modest_window_mgr_find_registered_message_uid (self, uid, win);
492 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
495 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
499 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
502 ModestWindowMgrPrivate *priv = NULL;
504 gboolean has_header = FALSE;
506 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
507 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
509 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
514 has_header = has_uid (priv->preregistered_uids, msg_uid);
521 modest_window_mgr_get_window_list (ModestWindowMgr *self)
523 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
527 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
533 modest_window_mgr_register_window (ModestWindowMgr *self,
534 ModestWindow *window,
535 ModestWindow *parent)
537 gboolean no_windows, retval;
539 no_windows = (modest_window_mgr_get_num_windows (self) == 0);
541 retval = MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
544 /* If this is the first registered window then reset the
545 status of the TnyDevice as it might be forced to be offline
546 when modest is running in the background (see
547 modest_tny_account_store_new()) */
548 if (tny_device_is_forced (modest_runtime_get_device ()))
549 tny_device_reset (modest_runtime_get_device ());
551 /* Do also allow modest to shutdown when the
552 application is closed */
553 modest_runtime_set_allow_shutdown (TRUE);
560 modest_window_mgr_register_window_default (ModestWindowMgr *self,
561 ModestWindow *window,
562 ModestWindow *parent)
564 ModestWindowMgrPrivate *priv;
566 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
567 g_return_val_if_fail (MODEST_IS_WINDOW (window), FALSE);
569 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
571 /* We set up the queue change handler */
572 if (priv->queue_change_handler == 0) {
573 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
575 G_CALLBACK (modest_window_mgr_on_queue_changed),
580 /* remove from the list of pre-registered uids */
581 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
582 const gchar *uid = modest_msg_view_window_get_message_uid
583 (MODEST_MSG_VIEW_WINDOW (window));
585 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
587 if (has_uid (priv->preregistered_uids, uid)) {
588 priv->preregistered_uids =
589 remove_uid (priv->preregistered_uids,
590 modest_msg_view_window_get_message_uid
591 (MODEST_MSG_VIEW_WINDOW (window)));
593 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
594 const gchar *uid = modest_msg_edit_window_get_message_uid
595 (MODEST_MSG_EDIT_WINDOW (window));
597 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
599 priv->preregistered_uids =
600 remove_uid (priv->preregistered_uids,
601 modest_msg_edit_window_get_message_uid
602 (MODEST_MSG_EDIT_WINDOW (window)));
609 modest_window_mgr_unregister_window (ModestWindowMgr *self,
610 ModestWindow *window)
612 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
616 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
617 ModestWindow *window)
619 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
620 g_return_if_fail (MODEST_IS_WINDOW (window));
623 modest_window_save_state (window);
625 /* Disconnect all the window signals */
626 modest_window_disconnect_signals (window);
628 /* Destroy the window */
629 gtk_widget_destroy (GTK_WIDGET (window));
635 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
638 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
642 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
649 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
651 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
655 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
661 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
663 gboolean show_toolbars,
666 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
670 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
672 gboolean show_toolbars,
679 modest_window_mgr_get_modal (ModestWindowMgr *self)
681 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
685 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
692 modest_window_mgr_set_modal (ModestWindowMgr *self,
696 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
700 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
709 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
711 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
712 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
714 /* Forget this window,
715 * so hibernation will be allowed again if no windows are remembered: */
716 priv->windows_that_prevent_hibernation =
717 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
721 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
723 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
724 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
726 GtkWindow *window = GTK_WINDOW (widget);
728 priv->windows_that_prevent_hibernation =
729 g_slist_append (priv->windows_that_prevent_hibernation, window);
731 /* Allow hibernation again when the window has been hidden: */
732 g_signal_connect (window, "hide",
733 G_CALLBACK (on_nonhibernating_window_hide), self);
737 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
740 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
742 if (GTK_WIDGET_VISIBLE(window)) {
743 on_nonhibernating_window_show (GTK_WIDGET (window), self);
745 /* Wait for it to be shown: */
746 g_signal_connect (window, "show",
747 G_CALLBACK (on_nonhibernating_window_show), self);
752 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
754 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
756 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
758 /* Prevent hibernation if any open windows are currently
759 * preventing hibernation: */
760 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
765 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
769 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
771 /* Iterate over all windows */
772 window_list = modest_window_mgr_get_window_list (self);
775 ModestWindow *window = MODEST_WINDOW (node->data);
777 /* This calls the vfunc,
778 * so each window can do its own thing: */
779 modest_window_save_state (window);
782 node = g_list_next (node);
784 g_list_free (window_list);
788 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
790 ModestWindowMgrPrivate *priv;
791 gint num_windows = 0;
794 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
796 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
798 window_list = modest_window_mgr_get_window_list (self);
801 num_windows = g_list_length (window_list);
802 g_list_free (window_list);
805 return num_windows + priv->banner_counter;
809 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
812 ModestWindowMgrPrivate *priv;
814 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
816 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
818 if (priv->cached_editor) {
819 result = priv->cached_editor;
820 priv->cached_editor = NULL;
821 load_new_editor (self);
823 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
830 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
833 ModestWindowMgrPrivate *priv;
835 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
837 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
839 if (priv->cached_view) {
840 result = priv->cached_view;
841 priv->cached_view = NULL;
842 load_new_view (self);
844 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
851 modest_window_mgr_register_banner (ModestWindowMgr *self)
853 ModestWindowMgrPrivate *priv;
855 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
856 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
858 priv->banner_counter++;
862 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
864 ModestWindowMgrPrivate *priv;
866 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
867 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
869 priv->banner_counter--;
870 if (modest_window_mgr_get_num_windows (self) == 0)
871 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
875 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
877 ModestWindow *window = NULL;
879 /* Call the children */
880 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
883 ModestAccountMgr *mgr;
885 /* Show the initial window */
886 gtk_widget_show (GTK_WIDGET (window));
888 /* If there are no accounts then show the account wizard */
889 mgr = modest_runtime_get_account_mgr();
890 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
891 if (!modest_ui_actions_run_account_setup_wizard (window)) {
892 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
900 static ModestWindow *
901 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
903 g_warning ("You must implement %s", __FUNCTION__);
910 modest_window_mgr_get_current_top (ModestWindowMgr *self)
912 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
916 static ModestWindow *
917 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
919 g_return_val_if_reached (NULL);
923 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
925 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
929 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
931 /* Default implementation is assuming screen is always on */
937 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
939 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
943 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
945 load_new_editor (self);
946 load_new_view (self);
950 tny_list_find (TnyList *list, GObject *item)
952 TnyIterator *iterator;
953 gboolean found = FALSE;
955 for (iterator = tny_list_create_iterator (list);
956 !tny_iterator_is_done (iterator) && !found;
957 tny_iterator_next (iterator)) {
958 GObject *current = tny_iterator_get_current (iterator);
961 g_object_unref (current);
963 g_object_unref (iterator);
969 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
970 ModestMailOperation *mail_op,
971 ModestMailOperationQueueNotification type,
972 ModestWindowMgr *self)
974 ModestWindowMgrPrivate *priv;
976 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
978 /* We register to track progress */
979 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
980 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
983 G_CALLBACK (on_mail_operation_started),
985 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
987 "operation-finished",
988 G_CALLBACK (on_mail_operation_finished),
990 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
991 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
993 "operation-started");
994 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
996 "operation-finished");
997 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
998 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
999 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1005 on_mail_operation_started (ModestMailOperation *mail_op,
1008 ModestWindowMgr *self;
1009 ModestWindowMgrPrivate *priv;
1010 ModestMailOperationTypeOperation op_type;
1012 self = MODEST_WINDOW_MGR (user_data);
1013 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1015 /* First we check if the operation is a send receive operation,
1016 * If now, we don't handle this */
1017 op_type = modest_mail_operation_get_type_operation (mail_op);
1018 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1019 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1023 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1024 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1025 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1030 on_mail_operation_finished (ModestMailOperation *mail_op,
1033 ModestWindowMgr *self;
1034 ModestWindowMgrPrivate *priv;
1036 self = MODEST_WINDOW_MGR (user_data);
1037 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1039 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1040 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1041 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1046 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1048 ModestWindowMgrPrivate *priv;
1050 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1052 return tny_list_copy (priv->progress_operations);
1056 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1058 ModestWindowMgrPrivate *priv;
1060 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1062 return tny_list_get_length (priv->progress_operations) > 0;
1066 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1067 const gchar *account_name)
1069 ModestWindowMgrPrivate *priv;
1070 gint account_ops = 0;
1071 TnyIterator *iterator;
1073 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1075 if (account_name == NULL)
1078 for (iterator = tny_list_create_iterator (priv->progress_operations);
1079 !tny_iterator_is_done (iterator);
1080 tny_iterator_next (iterator)) {
1081 ModestMailOperation *mail_op;
1082 TnyAccount *account;
1084 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1085 account = modest_mail_operation_get_account (mail_op);
1087 if (account != NULL) {
1088 const gchar *current_name;
1090 current_name = tny_account_get_id (account);
1091 if (current_name && strcmp (current_name, account_name) == 0)
1093 g_object_unref (account);
1096 g_object_unref (mail_op);
1098 g_object_unref (iterator);
1103 /* 'Protected method' must be only called by children */
1105 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1109 /* Exit if there are no windows */
1110 if (!modest_window_mgr_get_num_windows (self)) {
1111 g_warning ("%s: there are no windows to close", __FUNCTION__);
1115 /* Check that there is no active modal dialog */
1116 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1117 while (modal && GTK_IS_DIALOG (modal)) {
1120 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1121 #include <hildon/hildon.h>
1122 /* If it's a hildon note then don't try to close it as
1123 this is the default behaviour of WM, delete event
1124 is not issued for this kind of notes as we want the
1125 user to always click on a button */
1126 if (HILDON_IS_NOTE (modal)) {
1127 gtk_window_present (GTK_WINDOW (modal));
1132 /* Get the parent */
1133 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1135 /* Try to close it */
1136 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1138 /* Maybe the dialog was not closed, because a close
1139 confirmation dialog for example. Then ignore the
1141 if (GTK_IS_WINDOW (modal)) {
1142 gtk_window_present (GTK_WINDOW (modal));
1146 /* Get next modal */
1153 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1155 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1159 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1161 /* Empty default implementation */
1166 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1168 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1171 static ModestWindow *
1172 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1174 /* Default implementation returns NULL always */