1 /* Copyright (c) 2006,2007 Nokia Corporation
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of the Nokia Corporation nor the names of its
14 * contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #include "modest-window-mgr.h"
32 #include "modest-runtime.h"
33 #include "modest-tny-folder.h"
34 #include "modest-ui-actions.h"
35 #include "modest-platform.h"
36 #include "modest-defs.h"
37 #include "widgets/modest-main-window.h"
38 #include "widgets/modest-msg-edit-window.h"
39 #include "widgets/modest-msg-view-window.h"
40 #include "modest-debug.h"
41 #include <tny-simple-list.h>
44 /* 'private'/'protected' functions */
45 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
46 static void modest_window_mgr_init (ModestWindowMgr *obj);
47 static void modest_window_mgr_finalize (GObject *obj);
49 static gboolean modest_window_mgr_register_window_default (ModestWindowMgr *self,
51 ModestWindow *parent);
52 static void modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
53 ModestWindow *window);
54 static void modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
56 static gboolean modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self);
57 static void modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
59 gboolean show_toolbars,
61 #ifndef MODEST_TOOLKIT_HILDON2
62 static ModestWindow* modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show);
64 static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self);
65 static void modest_window_mgr_set_modal_default (ModestWindowMgr *self,
68 static gboolean modest_window_mgr_close_all_windows_default (ModestWindowMgr *self);
69 static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self,
72 static gboolean modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self,
75 static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self);
76 static ModestWindow *modest_window_mgr_show_initial_window_default (ModestWindowMgr *self);
77 static ModestWindow *modest_window_mgr_get_current_top_default (ModestWindowMgr *self);
78 static gboolean modest_window_mgr_screen_is_on_default (ModestWindowMgr *self);
79 static void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
80 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
81 ModestMailOperation *mail_op,
82 ModestMailOperationQueueNotification type,
83 ModestWindowMgr *self);
84 static void on_mail_operation_started (ModestMailOperation *mail_op,
86 static void on_mail_operation_finished (ModestMailOperation *mail_op,
88 static gboolean modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self);
92 WINDOW_LIST_EMPTY_SIGNAL,
93 PROGRESS_LIST_CHANGED_SIGNAL,
97 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
98 struct _ModestWindowMgrPrivate {
101 #ifndef MODEST_TOOLKIT_HILDON2
102 ModestWindow *main_window;
104 GSList *windows_that_prevent_hibernation;
105 GSList *preregistered_uids;
109 GtkWidget *cached_view;
110 GtkWidget *cached_editor;
111 guint idle_load_view_id;
112 guint idle_load_editor_id;
114 guint queue_change_handler;
115 TnyList *progress_operations;
119 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
120 MODEST_TYPE_WINDOW_MGR, \
121 ModestWindowMgrPrivate))
123 static GObjectClass *parent_class = NULL;
125 /* uncomment the following if you have defined any signals */
126 static guint signals[NUM_SIGNALS] = {0};
129 modest_window_mgr_get_type (void)
131 static GType my_type = 0;
133 static const GTypeInfo my_info = {
134 sizeof(ModestWindowMgrClass),
135 NULL, /* base init */
136 NULL, /* base finalize */
137 (GClassInitFunc) modest_window_mgr_class_init,
138 NULL, /* class finalize */
139 NULL, /* class data */
140 sizeof(ModestWindowMgr),
142 (GInstanceInitFunc) modest_window_mgr_init,
145 my_type = g_type_register_static (G_TYPE_OBJECT,
153 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
155 GObjectClass *gobject_class;
156 ModestWindowMgrClass *mgr_class;
158 gobject_class = (GObjectClass*) klass;
159 mgr_class = (ModestWindowMgrClass *) klass;
161 parent_class = g_type_class_peek_parent (klass);
162 gobject_class->finalize = modest_window_mgr_finalize;
163 mgr_class->register_window = modest_window_mgr_register_window_default;
164 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
165 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
166 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
167 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
168 #ifndef MODEST_TOOLKIT_HILDON2
169 mgr_class->get_main_window = modest_window_mgr_get_main_window_default;
171 mgr_class->get_modal = modest_window_mgr_get_modal_default;
172 mgr_class->set_modal = modest_window_mgr_set_modal_default;
173 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
174 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
175 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
176 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
177 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
178 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
179 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
180 mgr_class->create_caches = modest_window_mgr_create_caches_default;
181 mgr_class->close_all_but_initial = modest_window_mgr_close_all_but_initial_default;
183 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
187 * ModestWindowMgr::window-list-empty
188 * @self: the #ModestWindowMgr that emits the signal
189 * @user_data: user data set when the signal handler was connected
191 * Issued whenever the window list becomes empty
193 signals[WINDOW_LIST_EMPTY_SIGNAL] =
194 g_signal_new ("window-list-empty",
195 G_TYPE_FROM_CLASS (gobject_class),
197 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
199 g_cclosure_marshal_VOID__VOID,
203 * ModestWindowMgr::progress-list-changed
204 * @self: the #ModestWindowMgr that emits the signal
205 * @user_data: user data set when the signal handler was connected
207 * Issued whenever the progress mail operations list becomes changed
209 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
210 g_signal_new ("progress-list-changed",
211 G_TYPE_FROM_CLASS (gobject_class),
213 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
215 g_cclosure_marshal_VOID__VOID,
220 idle_load_view (ModestWindowMgr *mgr)
222 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
224 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
225 priv->idle_load_view_id = 0;
230 idle_load_editor (ModestWindowMgr *mgr)
232 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
234 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
235 priv->idle_load_editor_id = 0;
240 load_new_view (ModestWindowMgr *self)
242 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
243 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
244 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
248 load_new_editor (ModestWindowMgr *self)
250 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
251 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
252 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
256 modest_window_mgr_init (ModestWindowMgr *obj)
258 ModestWindowMgrPrivate *priv;
260 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
261 priv->banner_counter = 0;
262 #ifndef MODEST_TOOLKIT_HILDON2
263 priv->main_window = NULL;
265 priv->preregistered_uids = NULL;
267 priv->closing_time = 0;
269 priv->cached_view = NULL;
270 priv->cached_editor = NULL;
272 priv->windows_that_prevent_hibernation = NULL;
274 priv->queue_change_handler = 0;
275 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
279 modest_window_mgr_finalize (GObject *obj)
281 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
283 if (priv->idle_load_view_id > 0) {
284 g_source_remove (priv->idle_load_view_id);
285 priv->idle_load_view_id = 0;
288 if (priv->idle_load_editor_id > 0) {
289 g_source_remove (priv->idle_load_editor_id);
290 priv->idle_load_editor_id = 0;
293 if (priv->cached_view) {
294 gtk_widget_destroy (priv->cached_view);
295 priv->cached_view = NULL;
297 if (priv->cached_editor) {
298 gtk_widget_destroy (priv->cached_editor);
299 priv->cached_editor = NULL;
302 if (priv->windows_that_prevent_hibernation) {
303 g_slist_free (priv->windows_that_prevent_hibernation);
304 priv->cached_editor = NULL;
307 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
308 priv->sighandlers = NULL;
310 if (priv->queue_change_handler > 0) {
311 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
312 priv->queue_change_handler);
313 priv->queue_change_handler = 0;
316 if (priv->progress_operations) {
317 g_object_unref (priv->progress_operations);
318 priv->progress_operations = NULL;
321 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
322 g_slist_free (priv->preregistered_uids);
324 G_OBJECT_CLASS(parent_class)->finalize (obj);
328 modest_window_mgr_new (void)
330 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
336 /* do we have uid? */
338 has_uid (GSList *list, const gchar *uid)
340 GSList *cursor = list;
346 if (cursor->data && strcmp (cursor->data, uid) == 0)
348 cursor = g_slist_next (cursor);
354 /* remove all from the list have have uid = uid */
356 remove_uid (GSList *list, const gchar *uid)
358 GSList *cursor = list, *start = list;
364 GSList *next = g_slist_next (cursor);
365 if (cursor->data && strcmp (cursor->data, uid) == 0) {
366 g_free (cursor->data);
367 start = g_slist_delete_link (start, cursor);
376 append_uid (GSList *list, const gchar *uid)
378 return g_slist_append (list, g_strdup(uid));
384 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
386 ModestWindowMgrPrivate *priv;
389 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
390 g_return_if_fail (TNY_IS_HEADER(header));
392 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
393 if (alt_uid != NULL) {
394 uid = g_strdup (alt_uid);
396 uid = modest_tny_folder_get_header_unique_id (header);
399 if (!has_uid (priv->preregistered_uids, uid)) {
400 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
401 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
403 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
409 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
411 ModestWindowMgrPrivate *priv;
414 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
415 g_return_if_fail (TNY_IS_HEADER(header));
417 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
418 uid = modest_tny_folder_get_header_unique_id (header);
420 if (!has_uid (priv->preregistered_uids, uid)) {
421 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
422 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
424 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
426 if (has_uid (priv->preregistered_uids, uid)) {
427 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
428 if (has_uid (priv->preregistered_uids, uid))
429 g_debug ("BUG: uid %s NOT removed", uid);
431 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
438 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
441 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
443 /* we don't need 'self', but for API consistency... */
444 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
446 g_return_if_fail (win && GTK_IS_WINDOW(win));
447 g_return_if_fail (help_id);
449 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
450 g_strdup(help_id), g_free);
455 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
457 /* we don't need 'self', but for API consistency... */
458 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
459 g_return_val_if_fail (win, NULL);
461 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
465 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
467 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
471 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
478 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
481 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
485 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
490 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
491 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
493 uid = modest_tny_folder_get_header_unique_id (header);
496 return modest_window_mgr_find_registered_message_uid (self, uid, win);
502 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
505 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
509 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
512 ModestWindowMgrPrivate *priv = NULL;
514 gboolean has_header = FALSE;
516 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
517 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
519 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
524 has_header = has_uid (priv->preregistered_uids, msg_uid);
531 modest_window_mgr_get_window_list (ModestWindowMgr *self)
533 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
537 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
543 modest_window_mgr_register_window (ModestWindowMgr *self,
544 ModestWindow *window,
545 ModestWindow *parent)
547 /* If this is the first registered window then reset the
548 status of the TnyDevice as it might be forced to be offline
549 when modest is running in the background (see
550 modest_tny_account_store_new()) */
551 if (modest_window_mgr_get_num_windows (self) == 0) {
552 if (tny_device_is_forced (modest_runtime_get_device ()))
553 tny_device_reset (modest_runtime_get_device ());
556 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
560 modest_window_mgr_register_window_default (ModestWindowMgr *self,
561 ModestWindow *window,
562 ModestWindow *parent)
564 ModestWindowMgrPrivate *priv;
566 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
567 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
569 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
571 /* We set up the queue change handler */
572 if (priv->queue_change_handler == 0) {
573 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
575 G_CALLBACK (modest_window_mgr_on_queue_changed),
579 #ifndef MODEST_TOOLKIT_HILDON2
580 /* Check that it's not a second main window */
581 if (MODEST_IS_MAIN_WINDOW (window)) {
582 if (priv->main_window) {
583 g_warning ("%s: trying to register a second main window",
587 priv->main_window = window;
592 /* remove from the list of pre-registered uids */
593 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
594 const gchar *uid = modest_msg_view_window_get_message_uid
595 (MODEST_MSG_VIEW_WINDOW (window));
597 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
599 if (has_uid (priv->preregistered_uids, uid)) {
600 priv->preregistered_uids =
601 remove_uid (priv->preregistered_uids,
602 modest_msg_view_window_get_message_uid
603 (MODEST_MSG_VIEW_WINDOW (window)));
605 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
606 const gchar *uid = modest_msg_edit_window_get_message_uid
607 (MODEST_MSG_EDIT_WINDOW (window));
609 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
611 priv->preregistered_uids =
612 remove_uid (priv->preregistered_uids,
613 modest_msg_edit_window_get_message_uid
614 (MODEST_MSG_EDIT_WINDOW (window)));
621 modest_window_mgr_unregister_window (ModestWindowMgr *self,
622 ModestWindow *window)
624 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
628 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
629 ModestWindow *window)
631 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
632 g_return_if_fail (MODEST_IS_WINDOW (window));
635 modest_window_save_state (window);
637 /* Disconnect all the window signals */
638 modest_window_disconnect_signals (window);
640 /* Destroy the window */
641 gtk_widget_destroy (GTK_WIDGET (window));
647 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
650 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
654 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
661 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
663 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
667 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
673 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
675 gboolean show_toolbars,
678 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
682 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
684 gboolean show_toolbars,
690 #ifndef MODEST_TOOLKIT_HILDON2
692 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
694 ModestWindowMgrPrivate *priv;
696 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
698 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
699 priv->main_window = win;
703 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
705 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
709 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
711 ModestWindowMgrPrivate *priv;
713 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
715 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
716 if (priv->main_window)
717 return priv->main_window;
720 return modest_main_window_new ();
726 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
728 ModestWindowMgrPrivate *priv;
730 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
731 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
733 return priv->main_window != NULL;
738 modest_window_mgr_get_modal (ModestWindowMgr *self)
740 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
744 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
751 modest_window_mgr_set_modal (ModestWindowMgr *self,
755 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
759 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
768 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
770 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
771 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
773 /* Forget this window,
774 * so hibernation will be allowed again if no windows are remembered: */
775 priv->windows_that_prevent_hibernation =
776 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
780 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
782 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
783 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
785 GtkWindow *window = GTK_WINDOW (widget);
787 priv->windows_that_prevent_hibernation =
788 g_slist_append (priv->windows_that_prevent_hibernation, window);
790 /* Allow hibernation again when the window has been hidden: */
791 g_signal_connect (window, "hide",
792 G_CALLBACK (on_nonhibernating_window_hide), self);
796 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
799 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
801 if (GTK_WIDGET_VISIBLE(window)) {
802 on_nonhibernating_window_show (GTK_WIDGET (window), self);
804 /* Wait for it to be shown: */
805 g_signal_connect (window, "show",
806 G_CALLBACK (on_nonhibernating_window_show), self);
811 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
813 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
815 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
817 /* Prevent hibernation if any open windows are currently
818 * preventing hibernation: */
819 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
824 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
828 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
830 /* Iterate over all windows */
831 window_list = modest_window_mgr_get_window_list (self);
834 ModestWindow *window = MODEST_WINDOW (node->data);
836 /* This calls the vfunc,
837 * so each window can do its own thing: */
838 modest_window_save_state (window);
841 node = g_list_next (node);
843 g_list_free (window_list);
847 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
849 ModestWindowMgrPrivate *priv;
850 gint num_windows = 0;
853 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
855 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
857 window_list = modest_window_mgr_get_window_list (self);
860 num_windows = g_list_length (window_list);
861 g_list_free (window_list);
864 #ifndef MODEST_TOOLKIT_HILDON2
865 /* Do not take into account the main window if it was hidden */
866 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
870 return num_windows + priv->banner_counter;
874 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
877 ModestWindowMgrPrivate *priv;
879 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
881 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
883 if (priv->cached_editor) {
884 result = priv->cached_editor;
885 priv->cached_editor = NULL;
886 load_new_editor (self);
888 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
895 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
898 ModestWindowMgrPrivate *priv;
900 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
902 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
904 if (priv->cached_view) {
905 result = priv->cached_view;
906 priv->cached_view = NULL;
907 load_new_view (self);
909 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
916 modest_window_mgr_register_banner (ModestWindowMgr *self)
918 ModestWindowMgrPrivate *priv;
920 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
921 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
923 priv->banner_counter++;
927 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
929 ModestWindowMgrPrivate *priv;
931 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
932 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
934 priv->banner_counter--;
935 if (modest_window_mgr_get_num_windows (self) == 0)
936 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
940 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
942 ModestWindow *window = NULL;
944 /* Call the children */
945 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
948 ModestAccountMgr *mgr;
950 /* Show the initial window */
951 gtk_widget_show (GTK_WIDGET (window));
953 /* If there are no accounts then show the account wizard */
954 mgr = modest_runtime_get_account_mgr();
955 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
956 if (!modest_ui_actions_run_account_setup_wizard (window)) {
957 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
965 static ModestWindow *
966 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
968 #ifndef MODEST_TOOLKIT_HILDON2
969 /* By default it returns the main window creating it if
971 return modest_window_mgr_get_main_window (self, TRUE);
979 modest_window_mgr_get_current_top (ModestWindowMgr *self)
981 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
985 static ModestWindow *
986 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
988 g_return_val_if_reached (NULL);
992 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
994 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
998 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
1000 /* Default implementation is assuming screen is always on */
1006 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
1008 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
1012 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
1014 load_new_editor (self);
1015 load_new_view (self);
1019 tny_list_find (TnyList *list, GObject *item)
1021 TnyIterator *iterator;
1022 gboolean found = FALSE;
1024 for (iterator = tny_list_create_iterator (list);
1025 !tny_iterator_is_done (iterator) && !found;
1026 tny_iterator_next (iterator)) {
1027 GObject *current = tny_iterator_get_current (iterator);
1028 if (current == item)
1030 g_object_unref (current);
1032 g_object_unref (iterator);
1038 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1039 ModestMailOperation *mail_op,
1040 ModestMailOperationQueueNotification type,
1041 ModestWindowMgr *self)
1043 ModestWindowMgrPrivate *priv;
1045 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1047 /* We register to track progress */
1048 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1049 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1051 "operation-started",
1052 G_CALLBACK (on_mail_operation_started),
1054 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1056 "operation-finished",
1057 G_CALLBACK (on_mail_operation_finished),
1059 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1060 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1062 "operation-started");
1063 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1065 "operation-finished");
1066 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1067 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1068 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1074 on_mail_operation_started (ModestMailOperation *mail_op,
1077 ModestWindowMgr *self;
1078 ModestWindowMgrPrivate *priv;
1079 ModestMailOperationTypeOperation op_type;
1081 self = MODEST_WINDOW_MGR (user_data);
1082 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1084 /* First we check if the operation is a send receive operation,
1085 * If now, we don't handle this */
1086 op_type = modest_mail_operation_get_type_operation (mail_op);
1087 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1088 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1092 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1093 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1094 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1099 on_mail_operation_finished (ModestMailOperation *mail_op,
1102 ModestWindowMgr *self;
1103 ModestWindowMgrPrivate *priv;
1105 self = MODEST_WINDOW_MGR (user_data);
1106 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1108 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1109 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1110 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1115 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1117 ModestWindowMgrPrivate *priv;
1119 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1121 return tny_list_copy (priv->progress_operations);
1125 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1127 ModestWindowMgrPrivate *priv;
1129 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1131 return tny_list_get_length (priv->progress_operations) > 0;
1135 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1136 const gchar *account_name)
1138 ModestWindowMgrPrivate *priv;
1139 gint account_ops = 0;
1140 TnyIterator *iterator;
1142 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1144 if (account_name == NULL)
1147 for (iterator = tny_list_create_iterator (priv->progress_operations);
1148 !tny_iterator_is_done (iterator);
1149 tny_iterator_next (iterator)) {
1150 ModestMailOperation *mail_op;
1151 TnyAccount *account;
1153 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1154 account = modest_mail_operation_get_account (mail_op);
1156 if (account != NULL) {
1157 const gchar *current_name;
1159 current_name = tny_account_get_id (account);
1160 if (current_name && strcmp (current_name, account_name) == 0)
1162 g_object_unref (account);
1165 g_object_unref (mail_op);
1167 g_object_unref (iterator);
1172 /* 'Protected method' must be only called by children */
1174 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1178 /* Exit if there are no windows */
1179 if (!modest_window_mgr_get_num_windows (self)) {
1180 g_warning ("%s: there are no windows to close", __FUNCTION__);
1184 /* Check that there is no active modal dialog */
1185 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1186 while (modal && GTK_IS_DIALOG (modal)) {
1189 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1190 #include <hildon/hildon.h>
1191 /* If it's a hildon note then don't try to close it as
1192 this is the default behaviour of WM, delete event
1193 is not issued for this kind of notes as we want the
1194 user to always click on a button */
1195 if (HILDON_IS_NOTE (modal)) {
1196 gtk_window_present (GTK_WINDOW (modal));
1201 /* Get the parent */
1202 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1204 /* Try to close it */
1205 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1207 /* Maybe the dialog was not closed, because a close
1208 confirmation dialog for example. Then ignore the
1210 if (GTK_IS_WINDOW (modal)) {
1211 gtk_window_present (GTK_WINDOW (modal));
1215 /* Get next modal */
1222 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1224 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1228 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1230 /* Empty default implementation */