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 static ModestWindow* modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show);
62 static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self);
63 static void modest_window_mgr_set_modal_default (ModestWindowMgr *self,
66 static gboolean modest_window_mgr_close_all_windows_default (ModestWindowMgr *self);
67 static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self,
70 static gboolean modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self,
73 static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self);
74 static ModestWindow *modest_window_mgr_show_initial_window_default (ModestWindowMgr *self);
75 static ModestWindow *modest_window_mgr_get_current_top_default (ModestWindowMgr *self);
76 static gboolean modest_window_mgr_screen_is_on_default (ModestWindowMgr *self);
77 static void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
78 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
79 ModestMailOperation *mail_op,
80 ModestMailOperationQueueNotification type,
81 ModestWindowMgr *self);
82 static void on_mail_operation_started (ModestMailOperation *mail_op,
84 static void on_mail_operation_finished (ModestMailOperation *mail_op,
89 WINDOW_LIST_EMPTY_SIGNAL,
90 PROGRESS_LIST_CHANGED_SIGNAL,
94 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
95 struct _ModestWindowMgrPrivate {
98 ModestWindow *main_window;
100 GSList *windows_that_prevent_hibernation;
101 GSList *preregistered_uids;
105 GtkWidget *cached_view;
106 GtkWidget *cached_editor;
107 guint idle_load_view_id;
108 guint idle_load_editor_id;
110 guint queue_change_handler;
111 TnyList *progress_operations;
115 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
116 MODEST_TYPE_WINDOW_MGR, \
117 ModestWindowMgrPrivate))
119 static GObjectClass *parent_class = NULL;
121 /* uncomment the following if you have defined any signals */
122 static guint signals[NUM_SIGNALS] = {0};
125 modest_window_mgr_get_type (void)
127 static GType my_type = 0;
129 static const GTypeInfo my_info = {
130 sizeof(ModestWindowMgrClass),
131 NULL, /* base init */
132 NULL, /* base finalize */
133 (GClassInitFunc) modest_window_mgr_class_init,
134 NULL, /* class finalize */
135 NULL, /* class data */
136 sizeof(ModestWindowMgr),
138 (GInstanceInitFunc) modest_window_mgr_init,
141 my_type = g_type_register_static (G_TYPE_OBJECT,
149 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
151 GObjectClass *gobject_class;
152 ModestWindowMgrClass *mgr_class;
154 gobject_class = (GObjectClass*) klass;
155 mgr_class = (ModestWindowMgrClass *) klass;
157 parent_class = g_type_class_peek_parent (klass);
158 gobject_class->finalize = modest_window_mgr_finalize;
159 mgr_class->register_window = modest_window_mgr_register_window_default;
160 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
161 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
162 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
163 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
164 mgr_class->get_main_window = modest_window_mgr_get_main_window_default;
165 mgr_class->get_modal = modest_window_mgr_get_modal_default;
166 mgr_class->set_modal = modest_window_mgr_set_modal_default;
167 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
168 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
169 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
170 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
171 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
172 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
173 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
174 mgr_class->create_caches = modest_window_mgr_create_caches_default;
176 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
180 * ModestWindowMgr::window-list-empty
181 * @self: the #ModestWindowMgr that emits the signal
182 * @user_data: user data set when the signal handler was connected
184 * Issued whenever the window list becomes empty
186 signals[WINDOW_LIST_EMPTY_SIGNAL] =
187 g_signal_new ("window-list-empty",
188 G_TYPE_FROM_CLASS (gobject_class),
190 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
192 g_cclosure_marshal_VOID__VOID,
196 * ModestWindowMgr::progress-list-changed
197 * @self: the #ModestWindowMgr that emits the signal
198 * @user_data: user data set when the signal handler was connected
200 * Issued whenever the progress mail operations list becomes changed
202 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
203 g_signal_new ("progress-list-changed",
204 G_TYPE_FROM_CLASS (gobject_class),
206 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
208 g_cclosure_marshal_VOID__VOID,
213 idle_load_view (ModestWindowMgr *mgr)
215 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
217 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
218 priv->idle_load_view_id = 0;
223 idle_load_editor (ModestWindowMgr *mgr)
225 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
227 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
228 priv->idle_load_editor_id = 0;
233 load_new_view (ModestWindowMgr *self)
235 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
236 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
237 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
241 load_new_editor (ModestWindowMgr *self)
243 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
244 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
245 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
249 modest_window_mgr_init (ModestWindowMgr *obj)
251 ModestWindowMgrPrivate *priv;
253 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
254 priv->banner_counter = 0;
255 priv->main_window = NULL;
257 priv->preregistered_uids = NULL;
259 priv->closing_time = 0;
261 priv->cached_view = NULL;
262 priv->cached_editor = NULL;
264 priv->windows_that_prevent_hibernation = NULL;
266 priv->queue_change_handler = 0;
267 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
271 modest_window_mgr_finalize (GObject *obj)
273 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
275 if (priv->idle_load_view_id > 0) {
276 g_source_remove (priv->idle_load_view_id);
277 priv->idle_load_view_id = 0;
280 if (priv->idle_load_editor_id > 0) {
281 g_source_remove (priv->idle_load_editor_id);
282 priv->idle_load_editor_id = 0;
285 if (priv->cached_view) {
286 gtk_widget_destroy (priv->cached_view);
287 priv->cached_view = NULL;
289 if (priv->cached_editor) {
290 gtk_widget_destroy (priv->cached_editor);
291 priv->cached_editor = NULL;
294 if (priv->windows_that_prevent_hibernation) {
295 g_slist_free (priv->windows_that_prevent_hibernation);
296 priv->cached_editor = NULL;
299 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
300 priv->sighandlers = NULL;
302 if (priv->queue_change_handler > 0) {
303 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
304 priv->queue_change_handler);
305 priv->queue_change_handler = 0;
308 if (priv->progress_operations) {
309 g_object_unref (priv->progress_operations);
310 priv->progress_operations = NULL;
313 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
314 g_slist_free (priv->preregistered_uids);
316 G_OBJECT_CLASS(parent_class)->finalize (obj);
320 modest_window_mgr_new (void)
322 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
328 /* do we have uid? */
330 has_uid (GSList *list, const gchar *uid)
332 GSList *cursor = list;
338 if (cursor->data && strcmp (cursor->data, uid) == 0)
340 cursor = g_slist_next (cursor);
346 /* remove all from the list have have uid = uid */
348 remove_uid (GSList *list, const gchar *uid)
350 GSList *cursor = list, *start = list;
356 GSList *next = g_slist_next (cursor);
357 if (cursor->data && strcmp (cursor->data, uid) == 0) {
358 g_free (cursor->data);
359 start = g_slist_delete_link (start, cursor);
368 append_uid (GSList *list, const gchar *uid)
370 return g_slist_append (list, g_strdup(uid));
376 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
378 ModestWindowMgrPrivate *priv;
381 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
382 g_return_if_fail (TNY_IS_HEADER(header));
384 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
385 if (alt_uid != NULL) {
386 uid = g_strdup (alt_uid);
388 uid = modest_tny_folder_get_header_unique_id (header);
391 if (!has_uid (priv->preregistered_uids, uid)) {
392 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
393 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
395 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
401 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
403 ModestWindowMgrPrivate *priv;
406 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
407 g_return_if_fail (TNY_IS_HEADER(header));
409 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
410 uid = modest_tny_folder_get_header_unique_id (header);
412 if (!has_uid (priv->preregistered_uids, uid)) {
413 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
414 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
416 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
418 if (has_uid (priv->preregistered_uids, uid)) {
419 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
420 if (has_uid (priv->preregistered_uids, uid))
421 g_debug ("BUG: uid %s NOT removed", uid);
423 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
430 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
433 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
435 /* we don't need 'self', but for API consistency... */
436 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
438 g_return_if_fail (win && GTK_IS_WINDOW(win));
439 g_return_if_fail (help_id);
441 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
442 g_strdup(help_id), g_free);
447 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
449 /* we don't need 'self', but for API consistency... */
450 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
451 g_return_val_if_fail (win, NULL);
453 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
457 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
459 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
463 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
470 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
473 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
477 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
482 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
483 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
485 uid = modest_tny_folder_get_header_unique_id (header);
488 return modest_window_mgr_find_registered_message_uid (self, uid, win);
494 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
497 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
501 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
504 ModestWindowMgrPrivate *priv = NULL;
506 gboolean has_header = FALSE;
508 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
509 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
511 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
516 has_header = has_uid (priv->preregistered_uids, msg_uid);
523 modest_window_mgr_get_window_list (ModestWindowMgr *self)
525 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
529 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
535 modest_window_mgr_register_window (ModestWindowMgr *self,
536 ModestWindow *window,
537 ModestWindow *parent)
539 /* If this is the first registered window then reset the
540 status of the TnyDevice as it might be forced to be offline
541 when modest is running in the background (see
542 modest_tny_account_store_new()) */
543 if (modest_window_mgr_get_num_windows (self) == 0) {
544 if (tny_device_is_forced (modest_runtime_get_device ()))
545 tny_device_reset (modest_runtime_get_device ());
548 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
552 modest_window_mgr_register_window_default (ModestWindowMgr *self,
553 ModestWindow *window,
554 ModestWindow *parent)
556 ModestWindowMgrPrivate *priv;
558 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
559 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
561 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
563 /* We set up the queue change handler */
564 if (priv->queue_change_handler == 0) {
565 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
567 G_CALLBACK (modest_window_mgr_on_queue_changed),
571 /* Check that it's not a second main window */
572 if (MODEST_IS_MAIN_WINDOW (window)) {
573 if (priv->main_window) {
574 g_warning ("%s: trying to register a second main window",
578 priv->main_window = window;
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,
681 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
683 ModestWindowMgrPrivate *priv;
685 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
687 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
688 priv->main_window = win;
692 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
694 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
698 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
700 ModestWindowMgrPrivate *priv;
702 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
704 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
705 if (priv->main_window)
706 return priv->main_window;
709 return modest_main_window_new ();
715 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
717 ModestWindowMgrPrivate *priv;
719 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
720 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
722 return priv->main_window != NULL;
727 modest_window_mgr_get_modal (ModestWindowMgr *self)
729 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
733 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
740 modest_window_mgr_set_modal (ModestWindowMgr *self,
744 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
748 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
757 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
759 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
760 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
762 /* Forget this window,
763 * so hibernation will be allowed again if no windows are remembered: */
764 priv->windows_that_prevent_hibernation =
765 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
769 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
771 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
772 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
774 GtkWindow *window = GTK_WINDOW (widget);
776 priv->windows_that_prevent_hibernation =
777 g_slist_append (priv->windows_that_prevent_hibernation, window);
779 /* Allow hibernation again when the window has been hidden: */
780 g_signal_connect (window, "hide",
781 G_CALLBACK (on_nonhibernating_window_hide), self);
785 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
788 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
790 if (GTK_WIDGET_VISIBLE(window)) {
791 on_nonhibernating_window_show (GTK_WIDGET (window), self);
793 /* Wait for it to be shown: */
794 g_signal_connect (window, "show",
795 G_CALLBACK (on_nonhibernating_window_show), self);
800 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
802 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
804 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
806 /* Prevent hibernation if any open windows are currently
807 * preventing hibernation: */
808 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
813 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
817 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
819 /* Iterate over all windows */
820 window_list = modest_window_mgr_get_window_list (self);
823 ModestWindow *window = MODEST_WINDOW (node->data);
825 /* This calls the vfunc,
826 * so each window can do its own thing: */
827 modest_window_save_state (window);
830 node = g_list_next (node);
832 g_list_free (window_list);
836 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
838 ModestWindowMgrPrivate *priv;
839 gint num_windows = 0;
842 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
844 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
846 window_list = modest_window_mgr_get_window_list (self);
849 num_windows = g_list_length (window_list);
850 g_list_free (window_list);
853 /* Do not take into account the main window if it was hidden */
854 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
857 return num_windows + priv->banner_counter;
861 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
864 ModestWindowMgrPrivate *priv;
866 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
868 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
870 if (priv->cached_editor) {
871 result = priv->cached_editor;
872 priv->cached_editor = NULL;
873 load_new_editor (self);
875 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
882 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
885 ModestWindowMgrPrivate *priv;
887 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
889 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
891 if (priv->cached_view) {
892 result = priv->cached_view;
893 priv->cached_view = NULL;
894 load_new_view (self);
896 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
903 modest_window_mgr_register_banner (ModestWindowMgr *self)
905 ModestWindowMgrPrivate *priv;
907 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
908 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
910 priv->banner_counter++;
914 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
916 ModestWindowMgrPrivate *priv;
918 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
919 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
921 priv->banner_counter--;
922 if (modest_window_mgr_get_num_windows (self) == 0)
923 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
927 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
929 ModestWindow *window = NULL;
931 /* Call the children */
932 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
935 ModestAccountMgr *mgr;
937 /* Show the initial window */
938 gtk_widget_show (GTK_WIDGET (window));
940 /* If there are no accounts then show the account wizard */
941 mgr = modest_runtime_get_account_mgr();
942 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
943 if (!modest_ui_actions_run_account_setup_wizard (window)) {
944 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
952 static ModestWindow *
953 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
955 /* By default it returns the main window creating it if
957 return modest_window_mgr_get_main_window (self, TRUE);
962 modest_window_mgr_get_current_top (ModestWindowMgr *self)
964 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
968 static ModestWindow *
969 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
971 g_return_val_if_reached (NULL);
975 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
977 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
981 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
983 /* Default implementation is assuming screen is always on */
989 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
991 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
995 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
997 load_new_editor (self);
998 load_new_view (self);
1002 tny_list_find (TnyList *list, GObject *item)
1004 TnyIterator *iterator;
1005 gboolean found = FALSE;
1007 for (iterator = tny_list_create_iterator (list);
1008 !tny_iterator_is_done (iterator) && !found;
1009 tny_iterator_next (iterator)) {
1010 GObject *current = tny_iterator_get_current (iterator);
1011 if (current == item)
1013 g_object_unref (current);
1015 g_object_unref (iterator);
1021 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1022 ModestMailOperation *mail_op,
1023 ModestMailOperationQueueNotification type,
1024 ModestWindowMgr *self)
1026 ModestWindowMgrPrivate *priv;
1028 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1030 /* We register to track progress */
1031 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1032 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1034 "operation-started",
1035 G_CALLBACK (on_mail_operation_started),
1037 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1039 "operation-finished",
1040 G_CALLBACK (on_mail_operation_finished),
1042 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1043 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1045 "operation-started");
1046 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1048 "operation-finished");
1049 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1050 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1051 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1057 on_mail_operation_started (ModestMailOperation *mail_op,
1060 ModestWindowMgr *self;
1061 ModestWindowMgrPrivate *priv;
1062 ModestMailOperationTypeOperation op_type;
1064 self = MODEST_WINDOW_MGR (user_data);
1065 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1067 /* First we check if the operation is a send receive operation,
1068 * If now, we don't handle this */
1069 op_type = modest_mail_operation_get_type_operation (mail_op);
1070 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1071 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1075 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1076 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1077 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1082 on_mail_operation_finished (ModestMailOperation *mail_op,
1085 ModestWindowMgr *self;
1086 ModestWindowMgrPrivate *priv;
1088 self = MODEST_WINDOW_MGR (user_data);
1089 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1091 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1092 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1093 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1098 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1100 ModestWindowMgrPrivate *priv;
1102 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1104 return tny_list_copy (priv->progress_operations);
1108 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1110 ModestWindowMgrPrivate *priv;
1112 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1114 return tny_list_get_length (priv->progress_operations) > 0;
1118 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1119 const gchar *account_name)
1121 ModestWindowMgrPrivate *priv;
1122 gint account_ops = 0;
1123 TnyIterator *iterator;
1125 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1127 if (account_name == NULL)
1130 for (iterator = tny_list_create_iterator (priv->progress_operations);
1131 !tny_iterator_is_done (iterator);
1132 tny_iterator_next (iterator)) {
1133 ModestMailOperation *mail_op;
1134 TnyAccount *account;
1136 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1137 account = modest_mail_operation_get_account (mail_op);
1139 if (account != NULL) {
1140 const gchar *current_name;
1142 current_name = tny_account_get_id (account);
1143 if (current_name && strcmp (current_name, account_name) == 0)
1145 g_object_unref (account);
1148 g_object_unref (mail_op);
1150 g_object_unref (iterator);
1157 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1161 /* Exit if there are no windows */
1162 if (!modest_window_mgr_get_num_windows (self)) {
1163 g_warning ("%s: there are no windows to close", __FUNCTION__);
1167 /* Check that there is no active modal dialog */
1168 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1169 while (modal && GTK_IS_DIALOG (modal)) {
1172 /* If it's a hildon note then don't try to close it as
1173 this is the default behaviour of WM, delete event
1174 is not issued for this kind of notes as we want the
1175 user to always click on a button */
1176 if (HILDON_IS_NOTE (modal)) {
1177 gtk_window_present (GTK_WINDOW (modal));
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 */