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),
581 #ifndef MODEST_TOOLKIT_HILDON2
582 /* Check that it's not a second main window */
583 if (MODEST_IS_MAIN_WINDOW (window)) {
584 if (priv->main_window) {
585 g_warning ("%s: trying to register a second main window",
589 priv->main_window = window;
594 /* remove from the list of pre-registered uids */
595 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
596 const gchar *uid = modest_msg_view_window_get_message_uid
597 (MODEST_MSG_VIEW_WINDOW (window));
599 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
601 if (has_uid (priv->preregistered_uids, uid)) {
602 priv->preregistered_uids =
603 remove_uid (priv->preregistered_uids,
604 modest_msg_view_window_get_message_uid
605 (MODEST_MSG_VIEW_WINDOW (window)));
607 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
608 const gchar *uid = modest_msg_edit_window_get_message_uid
609 (MODEST_MSG_EDIT_WINDOW (window));
611 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
613 priv->preregistered_uids =
614 remove_uid (priv->preregistered_uids,
615 modest_msg_edit_window_get_message_uid
616 (MODEST_MSG_EDIT_WINDOW (window)));
623 modest_window_mgr_unregister_window (ModestWindowMgr *self,
624 ModestWindow *window)
626 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
630 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
631 ModestWindow *window)
633 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
634 g_return_if_fail (MODEST_IS_WINDOW (window));
637 modest_window_save_state (window);
639 /* Disconnect all the window signals */
640 modest_window_disconnect_signals (window);
642 /* Destroy the window */
643 gtk_widget_destroy (GTK_WIDGET (window));
649 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
652 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
656 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
663 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
665 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
669 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
675 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
677 gboolean show_toolbars,
680 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
684 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
686 gboolean show_toolbars,
692 #ifndef MODEST_TOOLKIT_HILDON2
694 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
696 ModestWindowMgrPrivate *priv;
698 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
700 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
701 priv->main_window = win;
705 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
707 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
711 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
713 ModestWindowMgrPrivate *priv;
715 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
717 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
718 if (priv->main_window)
719 return priv->main_window;
722 return modest_main_window_new ();
728 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
730 ModestWindowMgrPrivate *priv;
732 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
733 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
735 return priv->main_window != NULL;
740 modest_window_mgr_get_modal (ModestWindowMgr *self)
742 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
746 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
753 modest_window_mgr_set_modal (ModestWindowMgr *self,
757 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
761 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
770 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
772 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
773 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
775 /* Forget this window,
776 * so hibernation will be allowed again if no windows are remembered: */
777 priv->windows_that_prevent_hibernation =
778 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
782 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
784 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
785 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
787 GtkWindow *window = GTK_WINDOW (widget);
789 priv->windows_that_prevent_hibernation =
790 g_slist_append (priv->windows_that_prevent_hibernation, window);
792 /* Allow hibernation again when the window has been hidden: */
793 g_signal_connect (window, "hide",
794 G_CALLBACK (on_nonhibernating_window_hide), self);
798 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
801 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
803 if (GTK_WIDGET_VISIBLE(window)) {
804 on_nonhibernating_window_show (GTK_WIDGET (window), self);
806 /* Wait for it to be shown: */
807 g_signal_connect (window, "show",
808 G_CALLBACK (on_nonhibernating_window_show), self);
813 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
815 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
817 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
819 /* Prevent hibernation if any open windows are currently
820 * preventing hibernation: */
821 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
826 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
830 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
832 /* Iterate over all windows */
833 window_list = modest_window_mgr_get_window_list (self);
836 ModestWindow *window = MODEST_WINDOW (node->data);
838 /* This calls the vfunc,
839 * so each window can do its own thing: */
840 modest_window_save_state (window);
843 node = g_list_next (node);
845 g_list_free (window_list);
849 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
851 ModestWindowMgrPrivate *priv;
852 gint num_windows = 0;
855 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
857 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
859 window_list = modest_window_mgr_get_window_list (self);
862 num_windows = g_list_length (window_list);
863 g_list_free (window_list);
866 #ifndef MODEST_TOOLKIT_HILDON2
867 /* Do not take into account the main window if it was hidden */
868 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
872 return num_windows + priv->banner_counter;
876 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
879 ModestWindowMgrPrivate *priv;
881 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
883 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
885 if (priv->cached_editor) {
886 result = priv->cached_editor;
887 priv->cached_editor = NULL;
888 load_new_editor (self);
890 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
897 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
900 ModestWindowMgrPrivate *priv;
902 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
904 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
906 if (priv->cached_view) {
907 result = priv->cached_view;
908 priv->cached_view = NULL;
909 load_new_view (self);
911 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
918 modest_window_mgr_register_banner (ModestWindowMgr *self)
920 ModestWindowMgrPrivate *priv;
922 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
923 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
925 priv->banner_counter++;
929 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
931 ModestWindowMgrPrivate *priv;
933 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
934 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
936 priv->banner_counter--;
937 if (modest_window_mgr_get_num_windows (self) == 0)
938 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
942 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
944 ModestWindow *window = NULL;
946 /* Call the children */
947 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
950 ModestAccountMgr *mgr;
952 /* Show the initial window */
953 gtk_widget_show (GTK_WIDGET (window));
955 /* If there are no accounts then show the account wizard */
956 mgr = modest_runtime_get_account_mgr();
957 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
958 if (!modest_ui_actions_run_account_setup_wizard (window)) {
959 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
967 static ModestWindow *
968 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
970 #ifndef MODEST_TOOLKIT_HILDON2
971 /* By default it returns the main window creating it if
973 return modest_window_mgr_get_main_window (self, TRUE);
981 modest_window_mgr_get_current_top (ModestWindowMgr *self)
983 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
987 static ModestWindow *
988 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
990 g_return_val_if_reached (NULL);
994 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
996 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
1000 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
1002 /* Default implementation is assuming screen is always on */
1008 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
1010 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
1014 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
1016 load_new_editor (self);
1017 load_new_view (self);
1021 tny_list_find (TnyList *list, GObject *item)
1023 TnyIterator *iterator;
1024 gboolean found = FALSE;
1026 for (iterator = tny_list_create_iterator (list);
1027 !tny_iterator_is_done (iterator) && !found;
1028 tny_iterator_next (iterator)) {
1029 GObject *current = tny_iterator_get_current (iterator);
1030 if (current == item)
1032 g_object_unref (current);
1034 g_object_unref (iterator);
1040 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1041 ModestMailOperation *mail_op,
1042 ModestMailOperationQueueNotification type,
1043 ModestWindowMgr *self)
1045 ModestWindowMgrPrivate *priv;
1047 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1049 /* We register to track progress */
1050 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1051 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1053 "operation-started",
1054 G_CALLBACK (on_mail_operation_started),
1056 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1058 "operation-finished",
1059 G_CALLBACK (on_mail_operation_finished),
1061 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1062 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1064 "operation-started");
1065 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1067 "operation-finished");
1068 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1069 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1070 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1076 on_mail_operation_started (ModestMailOperation *mail_op,
1079 ModestWindowMgr *self;
1080 ModestWindowMgrPrivate *priv;
1081 ModestMailOperationTypeOperation op_type;
1083 self = MODEST_WINDOW_MGR (user_data);
1084 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1086 /* First we check if the operation is a send receive operation,
1087 * If now, we don't handle this */
1088 op_type = modest_mail_operation_get_type_operation (mail_op);
1089 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1090 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1094 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1095 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1096 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1101 on_mail_operation_finished (ModestMailOperation *mail_op,
1104 ModestWindowMgr *self;
1105 ModestWindowMgrPrivate *priv;
1107 self = MODEST_WINDOW_MGR (user_data);
1108 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1110 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1111 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1112 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1117 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1119 ModestWindowMgrPrivate *priv;
1121 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1123 return tny_list_copy (priv->progress_operations);
1127 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1129 ModestWindowMgrPrivate *priv;
1131 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1133 return tny_list_get_length (priv->progress_operations) > 0;
1137 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1138 const gchar *account_name)
1140 ModestWindowMgrPrivate *priv;
1141 gint account_ops = 0;
1142 TnyIterator *iterator;
1144 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1146 if (account_name == NULL)
1149 for (iterator = tny_list_create_iterator (priv->progress_operations);
1150 !tny_iterator_is_done (iterator);
1151 tny_iterator_next (iterator)) {
1152 ModestMailOperation *mail_op;
1153 TnyAccount *account;
1155 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1156 account = modest_mail_operation_get_account (mail_op);
1158 if (account != NULL) {
1159 const gchar *current_name;
1161 current_name = tny_account_get_id (account);
1162 if (current_name && strcmp (current_name, account_name) == 0)
1164 g_object_unref (account);
1167 g_object_unref (mail_op);
1169 g_object_unref (iterator);
1174 /* 'Protected method' must be only called by children */
1176 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1180 /* Exit if there are no windows */
1181 if (!modest_window_mgr_get_num_windows (self)) {
1182 g_warning ("%s: there are no windows to close", __FUNCTION__);
1186 /* Check that there is no active modal dialog */
1187 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1188 while (modal && GTK_IS_DIALOG (modal)) {
1191 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1192 #include <hildon/hildon.h>
1193 /* If it's a hildon note then don't try to close it as
1194 this is the default behaviour of WM, delete event
1195 is not issued for this kind of notes as we want the
1196 user to always click on a button */
1197 if (HILDON_IS_NOTE (modal)) {
1198 gtk_window_present (GTK_WINDOW (modal));
1203 /* Get the parent */
1204 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1206 /* Try to close it */
1207 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1209 /* Maybe the dialog was not closed, because a close
1210 confirmation dialog for example. Then ignore the
1212 if (GTK_IS_WINDOW (modal)) {
1213 gtk_window_present (GTK_WINDOW (modal));
1217 /* Get next modal */
1224 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1226 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1230 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1232 /* Empty default implementation */
1237 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1239 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1242 static ModestWindow *
1243 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1245 /* Default implementation returns NULL always */