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,
86 static gboolean modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self);
90 WINDOW_LIST_EMPTY_SIGNAL,
91 PROGRESS_LIST_CHANGED_SIGNAL,
95 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
96 struct _ModestWindowMgrPrivate {
99 ModestWindow *main_window;
101 GSList *windows_that_prevent_hibernation;
102 GSList *preregistered_uids;
106 GtkWidget *cached_view;
107 GtkWidget *cached_editor;
108 guint idle_load_view_id;
109 guint idle_load_editor_id;
111 guint queue_change_handler;
112 TnyList *progress_operations;
116 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
117 MODEST_TYPE_WINDOW_MGR, \
118 ModestWindowMgrPrivate))
120 static GObjectClass *parent_class = NULL;
122 /* uncomment the following if you have defined any signals */
123 static guint signals[NUM_SIGNALS] = {0};
126 modest_window_mgr_get_type (void)
128 static GType my_type = 0;
130 static const GTypeInfo my_info = {
131 sizeof(ModestWindowMgrClass),
132 NULL, /* base init */
133 NULL, /* base finalize */
134 (GClassInitFunc) modest_window_mgr_class_init,
135 NULL, /* class finalize */
136 NULL, /* class data */
137 sizeof(ModestWindowMgr),
139 (GInstanceInitFunc) modest_window_mgr_init,
142 my_type = g_type_register_static (G_TYPE_OBJECT,
150 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
152 GObjectClass *gobject_class;
153 ModestWindowMgrClass *mgr_class;
155 gobject_class = (GObjectClass*) klass;
156 mgr_class = (ModestWindowMgrClass *) klass;
158 parent_class = g_type_class_peek_parent (klass);
159 gobject_class->finalize = modest_window_mgr_finalize;
160 mgr_class->register_window = modest_window_mgr_register_window_default;
161 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
162 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
163 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
164 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
165 mgr_class->get_main_window = modest_window_mgr_get_main_window_default;
166 mgr_class->get_modal = modest_window_mgr_get_modal_default;
167 mgr_class->set_modal = modest_window_mgr_set_modal_default;
168 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
169 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
170 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
171 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
172 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
173 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
174 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
175 mgr_class->create_caches = modest_window_mgr_create_caches_default;
176 mgr_class->close_all_but_initial = modest_window_mgr_close_all_but_initial_default;
178 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
182 * ModestWindowMgr::window-list-empty
183 * @self: the #ModestWindowMgr that emits the signal
184 * @user_data: user data set when the signal handler was connected
186 * Issued whenever the window list becomes empty
188 signals[WINDOW_LIST_EMPTY_SIGNAL] =
189 g_signal_new ("window-list-empty",
190 G_TYPE_FROM_CLASS (gobject_class),
192 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
194 g_cclosure_marshal_VOID__VOID,
198 * ModestWindowMgr::progress-list-changed
199 * @self: the #ModestWindowMgr that emits the signal
200 * @user_data: user data set when the signal handler was connected
202 * Issued whenever the progress mail operations list becomes changed
204 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
205 g_signal_new ("progress-list-changed",
206 G_TYPE_FROM_CLASS (gobject_class),
208 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
210 g_cclosure_marshal_VOID__VOID,
215 idle_load_view (ModestWindowMgr *mgr)
217 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
219 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
220 priv->idle_load_view_id = 0;
225 idle_load_editor (ModestWindowMgr *mgr)
227 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
229 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
230 priv->idle_load_editor_id = 0;
235 load_new_view (ModestWindowMgr *self)
237 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
238 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
239 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
243 load_new_editor (ModestWindowMgr *self)
245 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
246 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
247 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
251 modest_window_mgr_init (ModestWindowMgr *obj)
253 ModestWindowMgrPrivate *priv;
255 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
256 priv->banner_counter = 0;
257 priv->main_window = NULL;
259 priv->preregistered_uids = NULL;
261 priv->closing_time = 0;
263 priv->cached_view = NULL;
264 priv->cached_editor = NULL;
266 priv->windows_that_prevent_hibernation = NULL;
268 priv->queue_change_handler = 0;
269 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
273 modest_window_mgr_finalize (GObject *obj)
275 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
277 if (priv->idle_load_view_id > 0) {
278 g_source_remove (priv->idle_load_view_id);
279 priv->idle_load_view_id = 0;
282 if (priv->idle_load_editor_id > 0) {
283 g_source_remove (priv->idle_load_editor_id);
284 priv->idle_load_editor_id = 0;
287 if (priv->cached_view) {
288 gtk_widget_destroy (priv->cached_view);
289 priv->cached_view = NULL;
291 if (priv->cached_editor) {
292 gtk_widget_destroy (priv->cached_editor);
293 priv->cached_editor = NULL;
296 if (priv->windows_that_prevent_hibernation) {
297 g_slist_free (priv->windows_that_prevent_hibernation);
298 priv->cached_editor = NULL;
301 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
302 priv->sighandlers = NULL;
304 if (priv->queue_change_handler > 0) {
305 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
306 priv->queue_change_handler);
307 priv->queue_change_handler = 0;
310 if (priv->progress_operations) {
311 g_object_unref (priv->progress_operations);
312 priv->progress_operations = NULL;
315 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
316 g_slist_free (priv->preregistered_uids);
318 G_OBJECT_CLASS(parent_class)->finalize (obj);
322 modest_window_mgr_new (void)
324 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
330 /* do we have uid? */
332 has_uid (GSList *list, const gchar *uid)
334 GSList *cursor = list;
340 if (cursor->data && strcmp (cursor->data, uid) == 0)
342 cursor = g_slist_next (cursor);
348 /* remove all from the list have have uid = uid */
350 remove_uid (GSList *list, const gchar *uid)
352 GSList *cursor = list, *start = list;
358 GSList *next = g_slist_next (cursor);
359 if (cursor->data && strcmp (cursor->data, uid) == 0) {
360 g_free (cursor->data);
361 start = g_slist_delete_link (start, cursor);
370 append_uid (GSList *list, const gchar *uid)
372 return g_slist_append (list, g_strdup(uid));
378 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
380 ModestWindowMgrPrivate *priv;
383 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
384 g_return_if_fail (TNY_IS_HEADER(header));
386 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
387 if (alt_uid != NULL) {
388 uid = g_strdup (alt_uid);
390 uid = modest_tny_folder_get_header_unique_id (header);
393 if (!has_uid (priv->preregistered_uids, uid)) {
394 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
395 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
397 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
403 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
405 ModestWindowMgrPrivate *priv;
408 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
409 g_return_if_fail (TNY_IS_HEADER(header));
411 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
412 uid = modest_tny_folder_get_header_unique_id (header);
414 if (!has_uid (priv->preregistered_uids, uid)) {
415 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
416 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
418 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
420 if (has_uid (priv->preregistered_uids, uid)) {
421 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
422 if (has_uid (priv->preregistered_uids, uid))
423 g_debug ("BUG: uid %s NOT removed", uid);
425 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
432 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
435 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
437 /* we don't need 'self', but for API consistency... */
438 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
440 g_return_if_fail (win && GTK_IS_WINDOW(win));
441 g_return_if_fail (help_id);
443 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
444 g_strdup(help_id), g_free);
449 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
451 /* we don't need 'self', but for API consistency... */
452 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
453 g_return_val_if_fail (win, NULL);
455 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
459 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
461 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
465 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
472 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
475 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
479 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
484 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
485 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
487 uid = modest_tny_folder_get_header_unique_id (header);
490 return modest_window_mgr_find_registered_message_uid (self, uid, win);
496 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
499 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
503 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
506 ModestWindowMgrPrivate *priv = NULL;
508 gboolean has_header = FALSE;
510 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
511 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
513 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
518 has_header = has_uid (priv->preregistered_uids, msg_uid);
525 modest_window_mgr_get_window_list (ModestWindowMgr *self)
527 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
531 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
537 modest_window_mgr_register_window (ModestWindowMgr *self,
538 ModestWindow *window,
539 ModestWindow *parent)
541 /* If this is the first registered window then reset the
542 status of the TnyDevice as it might be forced to be offline
543 when modest is running in the background (see
544 modest_tny_account_store_new()) */
545 if (modest_window_mgr_get_num_windows (self) == 0) {
546 if (tny_device_is_forced (modest_runtime_get_device ()))
547 tny_device_reset (modest_runtime_get_device ());
550 return MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
554 modest_window_mgr_register_window_default (ModestWindowMgr *self,
555 ModestWindow *window,
556 ModestWindow *parent)
558 ModestWindowMgrPrivate *priv;
560 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
561 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
563 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
565 /* We set up the queue change handler */
566 if (priv->queue_change_handler == 0) {
567 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
569 G_CALLBACK (modest_window_mgr_on_queue_changed),
573 /* Check that it's not a second main window */
574 if (MODEST_IS_MAIN_WINDOW (window)) {
575 if (priv->main_window) {
576 g_warning ("%s: trying to register a second main window",
580 priv->main_window = window;
584 /* remove from the list of pre-registered uids */
585 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
586 const gchar *uid = modest_msg_view_window_get_message_uid
587 (MODEST_MSG_VIEW_WINDOW (window));
589 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
591 if (has_uid (priv->preregistered_uids, uid)) {
592 priv->preregistered_uids =
593 remove_uid (priv->preregistered_uids,
594 modest_msg_view_window_get_message_uid
595 (MODEST_MSG_VIEW_WINDOW (window)));
597 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
598 const gchar *uid = modest_msg_edit_window_get_message_uid
599 (MODEST_MSG_EDIT_WINDOW (window));
601 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
603 priv->preregistered_uids =
604 remove_uid (priv->preregistered_uids,
605 modest_msg_edit_window_get_message_uid
606 (MODEST_MSG_EDIT_WINDOW (window)));
613 modest_window_mgr_unregister_window (ModestWindowMgr *self,
614 ModestWindow *window)
616 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
620 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
621 ModestWindow *window)
623 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
624 g_return_if_fail (MODEST_IS_WINDOW (window));
627 modest_window_save_state (window);
629 /* Disconnect all the window signals */
630 modest_window_disconnect_signals (window);
632 /* Destroy the window */
633 gtk_widget_destroy (GTK_WIDGET (window));
639 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
642 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
646 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
653 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
655 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
659 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
665 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
667 gboolean show_toolbars,
670 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
674 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
676 gboolean show_toolbars,
683 modest_window_mgr_set_main_window (ModestWindowMgr *self, ModestWindow *win)
685 ModestWindowMgrPrivate *priv;
687 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
689 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
690 priv->main_window = win;
694 modest_window_mgr_get_main_window (ModestWindowMgr *self, gboolean show)
696 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_main_window (self, show);
700 modest_window_mgr_get_main_window_default (ModestWindowMgr *self, gboolean show)
702 ModestWindowMgrPrivate *priv;
704 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
706 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
707 if (priv->main_window)
708 return priv->main_window;
711 return modest_main_window_new ();
717 modest_window_mgr_main_window_exists (ModestWindowMgr *self)
719 ModestWindowMgrPrivate *priv;
721 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
722 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
724 return priv->main_window != NULL;
729 modest_window_mgr_get_modal (ModestWindowMgr *self)
731 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
735 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
742 modest_window_mgr_set_modal (ModestWindowMgr *self,
746 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
750 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
759 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
761 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
762 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
764 /* Forget this window,
765 * so hibernation will be allowed again if no windows are remembered: */
766 priv->windows_that_prevent_hibernation =
767 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
771 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
773 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
774 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
776 GtkWindow *window = GTK_WINDOW (widget);
778 priv->windows_that_prevent_hibernation =
779 g_slist_append (priv->windows_that_prevent_hibernation, window);
781 /* Allow hibernation again when the window has been hidden: */
782 g_signal_connect (window, "hide",
783 G_CALLBACK (on_nonhibernating_window_hide), self);
787 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
790 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
792 if (GTK_WIDGET_VISIBLE(window)) {
793 on_nonhibernating_window_show (GTK_WIDGET (window), self);
795 /* Wait for it to be shown: */
796 g_signal_connect (window, "show",
797 G_CALLBACK (on_nonhibernating_window_show), self);
802 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
804 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
806 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
808 /* Prevent hibernation if any open windows are currently
809 * preventing hibernation: */
810 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
815 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
819 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
821 /* Iterate over all windows */
822 window_list = modest_window_mgr_get_window_list (self);
825 ModestWindow *window = MODEST_WINDOW (node->data);
827 /* This calls the vfunc,
828 * so each window can do its own thing: */
829 modest_window_save_state (window);
832 node = g_list_next (node);
834 g_list_free (window_list);
838 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
840 ModestWindowMgrPrivate *priv;
841 gint num_windows = 0;
844 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
846 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
848 window_list = modest_window_mgr_get_window_list (self);
851 num_windows = g_list_length (window_list);
852 g_list_free (window_list);
855 /* Do not take into account the main window if it was hidden */
856 if (num_windows && priv->main_window && !GTK_WIDGET_VISIBLE (priv->main_window))
859 return num_windows + priv->banner_counter;
863 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
866 ModestWindowMgrPrivate *priv;
868 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
870 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
872 if (priv->cached_editor) {
873 result = priv->cached_editor;
874 priv->cached_editor = NULL;
875 load_new_editor (self);
877 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
884 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
887 ModestWindowMgrPrivate *priv;
889 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
891 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
893 if (priv->cached_view) {
894 result = priv->cached_view;
895 priv->cached_view = NULL;
896 load_new_view (self);
898 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
905 modest_window_mgr_register_banner (ModestWindowMgr *self)
907 ModestWindowMgrPrivate *priv;
909 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
910 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
912 priv->banner_counter++;
916 modest_window_mgr_unregister_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--;
924 if (modest_window_mgr_get_num_windows (self) == 0)
925 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
929 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
931 ModestWindow *window = NULL;
933 /* Call the children */
934 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
937 ModestAccountMgr *mgr;
939 /* Show the initial window */
940 gtk_widget_show (GTK_WIDGET (window));
942 /* If there are no accounts then show the account wizard */
943 mgr = modest_runtime_get_account_mgr();
944 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
945 if (!modest_ui_actions_run_account_setup_wizard (window)) {
946 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
954 static ModestWindow *
955 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
957 /* By default it returns the main window creating it if
959 return modest_window_mgr_get_main_window (self, TRUE);
964 modest_window_mgr_get_current_top (ModestWindowMgr *self)
966 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
970 static ModestWindow *
971 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
973 g_return_val_if_reached (NULL);
977 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
979 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
983 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
985 /* Default implementation is assuming screen is always on */
991 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
993 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
997 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
999 load_new_editor (self);
1000 load_new_view (self);
1004 tny_list_find (TnyList *list, GObject *item)
1006 TnyIterator *iterator;
1007 gboolean found = FALSE;
1009 for (iterator = tny_list_create_iterator (list);
1010 !tny_iterator_is_done (iterator) && !found;
1011 tny_iterator_next (iterator)) {
1012 GObject *current = tny_iterator_get_current (iterator);
1013 if (current == item)
1015 g_object_unref (current);
1017 g_object_unref (iterator);
1023 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
1024 ModestMailOperation *mail_op,
1025 ModestMailOperationQueueNotification type,
1026 ModestWindowMgr *self)
1028 ModestWindowMgrPrivate *priv;
1030 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1032 /* We register to track progress */
1033 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
1034 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1036 "operation-started",
1037 G_CALLBACK (on_mail_operation_started),
1039 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
1041 "operation-finished",
1042 G_CALLBACK (on_mail_operation_finished),
1044 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
1045 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1047 "operation-started");
1048 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
1050 "operation-finished");
1051 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1052 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1053 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1059 on_mail_operation_started (ModestMailOperation *mail_op,
1062 ModestWindowMgr *self;
1063 ModestWindowMgrPrivate *priv;
1064 ModestMailOperationTypeOperation op_type;
1066 self = MODEST_WINDOW_MGR (user_data);
1067 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1069 /* First we check if the operation is a send receive operation,
1070 * If now, we don't handle this */
1071 op_type = modest_mail_operation_get_type_operation (mail_op);
1072 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1073 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1077 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1078 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1079 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1084 on_mail_operation_finished (ModestMailOperation *mail_op,
1087 ModestWindowMgr *self;
1088 ModestWindowMgrPrivate *priv;
1090 self = MODEST_WINDOW_MGR (user_data);
1091 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1093 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1094 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1095 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1100 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1102 ModestWindowMgrPrivate *priv;
1104 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1106 return tny_list_copy (priv->progress_operations);
1110 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1112 ModestWindowMgrPrivate *priv;
1114 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1116 return tny_list_get_length (priv->progress_operations) > 0;
1120 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1121 const gchar *account_name)
1123 ModestWindowMgrPrivate *priv;
1124 gint account_ops = 0;
1125 TnyIterator *iterator;
1127 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1129 if (account_name == NULL)
1132 for (iterator = tny_list_create_iterator (priv->progress_operations);
1133 !tny_iterator_is_done (iterator);
1134 tny_iterator_next (iterator)) {
1135 ModestMailOperation *mail_op;
1136 TnyAccount *account;
1138 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1139 account = modest_mail_operation_get_account (mail_op);
1141 if (account != NULL) {
1142 const gchar *current_name;
1144 current_name = tny_account_get_id (account);
1145 if (current_name && strcmp (current_name, account_name) == 0)
1147 g_object_unref (account);
1150 g_object_unref (mail_op);
1152 g_object_unref (iterator);
1157 /* 'Protected method' must be only called by children */
1159 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1163 /* Exit if there are no windows */
1164 if (!modest_window_mgr_get_num_windows (self)) {
1165 g_warning ("%s: there are no windows to close", __FUNCTION__);
1169 /* Check that there is no active modal dialog */
1170 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1171 while (modal && GTK_IS_DIALOG (modal)) {
1174 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1175 #include <hildon/hildon.h>
1176 /* If it's a hildon note then don't try to close it as
1177 this is the default behaviour of WM, delete event
1178 is not issued for this kind of notes as we want the
1179 user to always click on a button */
1180 if (HILDON_IS_NOTE (modal)) {
1181 gtk_window_present (GTK_WINDOW (modal));
1186 /* Get the parent */
1187 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1189 /* Try to close it */
1190 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1192 /* Maybe the dialog was not closed, because a close
1193 confirmation dialog for example. Then ignore the
1195 if (GTK_IS_WINDOW (modal)) {
1196 gtk_window_present (GTK_WINDOW (modal));
1200 /* Get next modal */
1207 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1209 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1213 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1215 /* Empty default implementation */