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 (win && GTK_IS_WINDOW(win));
449 g_return_if_fail (help_id);
451 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
452 g_strdup(help_id), g_free);
457 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
459 /* we don't need 'self', but for API consistency... */
460 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
461 g_return_val_if_fail (win, NULL);
463 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
467 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
469 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
473 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
480 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
483 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
487 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
492 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
493 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
495 uid = modest_tny_folder_get_header_unique_id (header);
498 return modest_window_mgr_find_registered_message_uid (self, uid, win);
504 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
507 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
511 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
514 ModestWindowMgrPrivate *priv = NULL;
516 gboolean has_header = FALSE;
518 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
519 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
521 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
526 has_header = has_uid (priv->preregistered_uids, msg_uid);
533 modest_window_mgr_get_window_list (ModestWindowMgr *self)
535 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
539 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
545 modest_window_mgr_register_window (ModestWindowMgr *self,
546 ModestWindow *window,
547 ModestWindow *parent)
549 /* If this is the first registered window then reset the
550 status of the TnyDevice as it might be forced to be offline
551 when modest is running in the background (see
552 modest_tny_account_store_new()) */
553 if (modest_window_mgr_get_num_windows (self) == 0) {
554 if (tny_device_is_forced (modest_runtime_get_device ()))
555 tny_device_reset (modest_runtime_get_device ());
558 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
562 modest_window_mgr_register_window_default (ModestWindowMgr *self,
563 ModestWindow *window,
564 ModestWindow *parent)
566 ModestWindowMgrPrivate *priv;
568 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
569 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
571 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
573 /* We set up the queue change handler */
574 if (priv->queue_change_handler == 0) {
575 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
577 G_CALLBACK (modest_window_mgr_on_queue_changed),
582 /* remove from the list of pre-registered uids */
583 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
584 const gchar *uid = modest_msg_view_window_get_message_uid
585 (MODEST_MSG_VIEW_WINDOW (window));
587 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
589 if (has_uid (priv->preregistered_uids, uid)) {
590 priv->preregistered_uids =
591 remove_uid (priv->preregistered_uids,
592 modest_msg_view_window_get_message_uid
593 (MODEST_MSG_VIEW_WINDOW (window)));
595 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
596 const gchar *uid = modest_msg_edit_window_get_message_uid
597 (MODEST_MSG_EDIT_WINDOW (window));
599 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
601 priv->preregistered_uids =
602 remove_uid (priv->preregistered_uids,
603 modest_msg_edit_window_get_message_uid
604 (MODEST_MSG_EDIT_WINDOW (window)));
611 modest_window_mgr_unregister_window (ModestWindowMgr *self,
612 ModestWindow *window)
614 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
618 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
619 ModestWindow *window)
621 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
622 g_return_if_fail (MODEST_IS_WINDOW (window));
625 modest_window_save_state (window);
627 /* Disconnect all the window signals */
628 modest_window_disconnect_signals (window);
630 /* Destroy the window */
631 gtk_widget_destroy (GTK_WIDGET (window));
637 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
640 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
644 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
651 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
653 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
657 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
663 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
665 gboolean show_toolbars,
668 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
672 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
674 gboolean show_toolbars,
680 #ifndef MODEST_TOOLKIT_HILDON2
682 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
684 ModestWindowMgrPrivate *priv;
686 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
688 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
689 priv->main_window = win;
693 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
695 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
699 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
706 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
708 ModestWindowMgrPrivate *priv;
710 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
711 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
713 return priv->main_window != NULL;
718 modest_window_mgr_get_modal (ModestWindowMgr *self)
720 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
724 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
731 modest_window_mgr_set_modal (ModestWindowMgr *self,
735 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
739 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
748 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
750 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
751 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
753 /* Forget this window,
754 * so hibernation will be allowed again if no windows are remembered: */
755 priv->windows_that_prevent_hibernation =
756 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
760 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
762 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
763 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
765 GtkWindow *window = GTK_WINDOW (widget);
767 priv->windows_that_prevent_hibernation =
768 g_slist_append (priv->windows_that_prevent_hibernation, window);
770 /* Allow hibernation again when the window has been hidden: */
771 g_signal_connect (window, "hide",
772 G_CALLBACK (on_nonhibernating_window_hide), self);
776 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
779 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
781 if (GTK_WIDGET_VISIBLE(window)) {
782 on_nonhibernating_window_show (GTK_WIDGET (window), self);
784 /* Wait for it to be shown: */
785 g_signal_connect (window, "show",
786 G_CALLBACK (on_nonhibernating_window_show), self);
791 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
793 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
795 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
797 /* Prevent hibernation if any open windows are currently
798 * preventing hibernation: */
799 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
804 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
808 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
810 /* Iterate over all windows */
811 window_list = modest_window_mgr_get_window_list (self);
814 ModestWindow *window = MODEST_WINDOW (node->data);
816 /* This calls the vfunc,
817 * so each window can do its own thing: */
818 modest_window_save_state (window);
821 node = g_list_next (node);
823 g_list_free (window_list);
827 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
829 ModestWindowMgrPrivate *priv;
830 gint num_windows = 0;
833 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
835 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
837 window_list = modest_window_mgr_get_window_list (self);
840 num_windows = g_list_length (window_list);
841 g_list_free (window_list);
844 #ifndef MODEST_TOOLKIT_HILDON2
845 /* Do not take into account the main window if it was hidden */
846 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
850 return num_windows + priv->banner_counter;
854 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
857 ModestWindowMgrPrivate *priv;
859 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
861 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
863 if (priv->cached_editor) {
864 result = priv->cached_editor;
865 priv->cached_editor = NULL;
866 load_new_editor (self);
868 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
875 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
878 ModestWindowMgrPrivate *priv;
880 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
882 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
884 if (priv->cached_view) {
885 result = priv->cached_view;
886 priv->cached_view = NULL;
887 load_new_view (self);
889 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
896 modest_window_mgr_register_banner (ModestWindowMgr *self)
898 ModestWindowMgrPrivate *priv;
900 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
901 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
903 priv->banner_counter++;
907 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
909 ModestWindowMgrPrivate *priv;
911 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
912 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
914 priv->banner_counter--;
915 if (modest_window_mgr_get_num_windows (self) == 0)
916 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
920 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
922 ModestWindow *window = NULL;
924 /* Call the children */
925 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
928 ModestAccountMgr *mgr;
930 /* Show the initial window */
931 gtk_widget_show (GTK_WIDGET (window));
933 /* If there are no accounts then show the account wizard */
934 mgr = modest_runtime_get_account_mgr();
935 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
936 if (!modest_ui_actions_run_account_setup_wizard (window)) {
937 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
945 static ModestWindow *
946 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
948 #ifndef MODEST_TOOLKIT_HILDON2
949 /* By default it returns the main window creating it if
951 return modest_window_mgr_get_main_window (self, TRUE);
959 modest_window_mgr_get_current_top (ModestWindowMgr *self)
961 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
965 static ModestWindow *
966 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
968 g_return_val_if_reached (NULL);
972 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
974 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
978 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
980 /* Default implementation is assuming screen is always on */
986 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
988 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
992 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
994 load_new_editor (self);
995 load_new_view (self);
999 tny_list_find (TnyList *list, GObject *item)
1001 TnyIterator *iterator;
1002 gboolean found = FALSE;
1004 for (iterator = tny_list_create_iterator (list);
1005 !tny_iterator_is_done (iterator) && !found;
1006 tny_iterator_next (iterator)) {
1007 GObject *current = tny_iterator_get_current (iterator);
1008 if (current == item)
1010 g_object_unref (current);
1012 g_object_unref (iterator);
1018 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1019 ModestMailOperation *mail_op,
1020 ModestMailOperationQueueNotification type,
1021 ModestWindowMgr *self)
1023 ModestWindowMgrPrivate *priv;
1025 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1027 /* We register to track progress */
1028 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1029 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1031 "operation-started",
1032 G_CALLBACK (on_mail_operation_started),
1034 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1036 "operation-finished",
1037 G_CALLBACK (on_mail_operation_finished),
1039 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1040 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1042 "operation-started");
1043 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1045 "operation-finished");
1046 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1047 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1048 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1054 on_mail_operation_started (ModestMailOperation *mail_op,
1057 ModestWindowMgr *self;
1058 ModestWindowMgrPrivate *priv;
1059 ModestMailOperationTypeOperation op_type;
1061 self = MODEST_WINDOW_MGR (user_data);
1062 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1064 /* First we check if the operation is a send receive operation,
1065 * If now, we don't handle this */
1066 op_type = modest_mail_operation_get_type_operation (mail_op);
1067 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1068 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1072 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1073 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1074 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1079 on_mail_operation_finished (ModestMailOperation *mail_op,
1082 ModestWindowMgr *self;
1083 ModestWindowMgrPrivate *priv;
1085 self = MODEST_WINDOW_MGR (user_data);
1086 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1088 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1089 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1090 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1095 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1097 ModestWindowMgrPrivate *priv;
1099 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1101 return tny_list_copy (priv->progress_operations);
1105 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1107 ModestWindowMgrPrivate *priv;
1109 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1111 return tny_list_get_length (priv->progress_operations) > 0;
1115 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1116 const gchar *account_name)
1118 ModestWindowMgrPrivate *priv;
1119 gint account_ops = 0;
1120 TnyIterator *iterator;
1122 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1124 if (account_name == NULL)
1127 for (iterator = tny_list_create_iterator (priv->progress_operations);
1128 !tny_iterator_is_done (iterator);
1129 tny_iterator_next (iterator)) {
1130 ModestMailOperation *mail_op;
1131 TnyAccount *account;
1133 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1134 account = modest_mail_operation_get_account (mail_op);
1136 if (account != NULL) {
1137 const gchar *current_name;
1139 current_name = tny_account_get_id (account);
1140 if (current_name && strcmp (current_name, account_name) == 0)
1142 g_object_unref (account);
1145 g_object_unref (mail_op);
1147 g_object_unref (iterator);
1152 /* 'Protected method' must be only called by children */
1154 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1158 /* Exit if there are no windows */
1159 if (!modest_window_mgr_get_num_windows (self)) {
1160 g_warning ("%s: there are no windows to close", __FUNCTION__);
1164 /* Check that there is no active modal dialog */
1165 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1166 while (modal && GTK_IS_DIALOG (modal)) {
1169 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1170 #include <hildon/hildon.h>
1171 /* If it's a hildon note then don't try to close it as
1172 this is the default behaviour of WM, delete event
1173 is not issued for this kind of notes as we want the
1174 user to always click on a button */
1175 if (HILDON_IS_NOTE (modal)) {
1176 gtk_window_present (GTK_WINDOW (modal));
1181 /* Get the parent */
1182 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1184 /* Try to close it */
1185 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1187 /* Maybe the dialog was not closed, because a close
1188 confirmation dialog for example. Then ignore the
1190 if (GTK_IS_WINDOW (modal)) {
1191 gtk_window_present (GTK_WINDOW (modal));
1195 /* Get next modal */
1202 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1204 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1208 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1210 /* Empty default implementation */
1215 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1217 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1220 static ModestWindow *
1221 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1223 /* Default implementation returns NULL always */