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-msg-edit-window.h"
38 #include "widgets/modest-msg-view-window.h"
39 #include "modest-debug.h"
40 #include <tny-simple-list.h>
43 /* 'private'/'protected' functions */
44 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
45 static void modest_window_mgr_init (ModestWindowMgr *obj);
46 static void modest_window_mgr_finalize (GObject *obj);
48 static gboolean modest_window_mgr_register_window_default (ModestWindowMgr *self,
50 ModestWindow *parent);
51 static void modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
52 ModestWindow *window);
53 static void modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
55 static gboolean modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self);
56 static void modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
58 gboolean show_toolbars,
60 static GtkWindow *modest_window_mgr_get_modal_default (ModestWindowMgr *self);
61 static void modest_window_mgr_set_modal_default (ModestWindowMgr *self,
64 static gboolean modest_window_mgr_close_all_windows_default (ModestWindowMgr *self);
65 static gboolean modest_window_mgr_find_registered_header_default (ModestWindowMgr *self,
68 static gboolean modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self,
71 static GList *modest_window_mgr_get_window_list_default (ModestWindowMgr *self);
72 static ModestWindow *modest_window_mgr_show_initial_window_default (ModestWindowMgr *self);
73 static ModestWindow *modest_window_mgr_get_current_top_default (ModestWindowMgr *self);
74 static gboolean modest_window_mgr_screen_is_on_default (ModestWindowMgr *self);
75 static ModestWindow *modest_window_mgr_get_folder_window_default (ModestWindowMgr *self);
76 static void modest_window_mgr_create_caches_default (ModestWindowMgr *self);
77 static void modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
78 ModestMailOperation *mail_op,
79 ModestMailOperationQueueNotification type,
80 ModestWindowMgr *self);
81 static void on_mail_operation_started (ModestMailOperation *mail_op,
83 static void on_mail_operation_finished (ModestMailOperation *mail_op,
85 static gboolean modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self);
89 WINDOW_LIST_EMPTY_SIGNAL,
90 PROGRESS_LIST_CHANGED_SIGNAL,
94 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
95 struct _ModestWindowMgrPrivate {
98 GSList *windows_that_prevent_hibernation;
99 GSList *preregistered_uids;
103 GtkWidget *cached_view;
104 GtkWidget *cached_editor;
105 guint idle_load_view_id;
106 guint idle_load_editor_id;
108 guint queue_change_handler;
109 TnyList *progress_operations;
113 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
114 MODEST_TYPE_WINDOW_MGR, \
115 ModestWindowMgrPrivate))
117 static GObjectClass *parent_class = NULL;
119 /* uncomment the following if you have defined any signals */
120 static guint signals[NUM_SIGNALS] = {0};
123 modest_window_mgr_get_type (void)
125 static GType my_type = 0;
127 static const GTypeInfo my_info = {
128 sizeof(ModestWindowMgrClass),
129 NULL, /* base init */
130 NULL, /* base finalize */
131 (GClassInitFunc) modest_window_mgr_class_init,
132 NULL, /* class finalize */
133 NULL, /* class data */
134 sizeof(ModestWindowMgr),
136 (GInstanceInitFunc) modest_window_mgr_init,
139 my_type = g_type_register_static (G_TYPE_OBJECT,
147 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
149 GObjectClass *gobject_class;
150 ModestWindowMgrClass *mgr_class;
152 gobject_class = (GObjectClass*) klass;
153 mgr_class = (ModestWindowMgrClass *) klass;
155 parent_class = g_type_class_peek_parent (klass);
156 gobject_class->finalize = modest_window_mgr_finalize;
157 mgr_class->register_window = modest_window_mgr_register_window_default;
158 mgr_class->unregister_window = modest_window_mgr_unregister_window_default;
159 mgr_class->set_fullscreen_mode = modest_window_mgr_set_fullscreen_mode_default;
160 mgr_class->get_fullscreen_mode = modest_window_mgr_get_fullscreen_mode_default;
161 mgr_class->show_toolbars = modest_window_mgr_show_toolbars_default;
162 mgr_class->get_modal = modest_window_mgr_get_modal_default;
163 mgr_class->set_modal = modest_window_mgr_set_modal_default;
164 mgr_class->close_all_windows = modest_window_mgr_close_all_windows_default;
165 mgr_class->find_registered_header = modest_window_mgr_find_registered_header_default;
166 mgr_class->find_registered_message_uid = modest_window_mgr_find_registered_message_uid_default;
167 mgr_class->get_window_list = modest_window_mgr_get_window_list_default;
168 mgr_class->show_initial_window = modest_window_mgr_show_initial_window_default;
169 mgr_class->get_current_top = modest_window_mgr_get_current_top_default;
170 mgr_class->screen_is_on = modest_window_mgr_screen_is_on_default;
171 mgr_class->create_caches = modest_window_mgr_create_caches_default;
172 mgr_class->close_all_but_initial = modest_window_mgr_close_all_but_initial_default;
173 mgr_class->get_folder_window = modest_window_mgr_get_folder_window_default;
175 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
179 * ModestWindowMgr::window-list-empty
180 * @self: the #ModestWindowMgr that emits the signal
181 * @user_data: user data set when the signal handler was connected
183 * Issued whenever the window list becomes empty
185 signals[WINDOW_LIST_EMPTY_SIGNAL] =
186 g_signal_new ("window-list-empty",
187 G_TYPE_FROM_CLASS (gobject_class),
189 G_STRUCT_OFFSET (ModestWindowMgrClass, window_list_empty),
191 g_cclosure_marshal_VOID__VOID,
195 * ModestWindowMgr::progress-list-changed
196 * @self: the #ModestWindowMgr that emits the signal
197 * @user_data: user data set when the signal handler was connected
199 * Issued whenever the progress mail operations list becomes changed
201 signals[PROGRESS_LIST_CHANGED_SIGNAL] =
202 g_signal_new ("progress-list-changed",
203 G_TYPE_FROM_CLASS (gobject_class),
205 G_STRUCT_OFFSET (ModestWindowMgrClass, progress_list_changed),
207 g_cclosure_marshal_VOID__VOID,
212 idle_load_view (ModestWindowMgr *mgr)
214 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
216 priv->cached_view = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
217 priv->idle_load_view_id = 0;
222 idle_load_editor (ModestWindowMgr *mgr)
224 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (mgr);
226 priv->cached_editor = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
227 priv->idle_load_editor_id = 0;
232 load_new_view (ModestWindowMgr *self)
234 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
235 if ((priv->cached_view == NULL) && (priv->idle_load_view_id == 0))
236 priv->idle_load_view_id = g_timeout_add (2500, (GSourceFunc) idle_load_view, self);
240 load_new_editor (ModestWindowMgr *self)
242 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
243 if ((priv->cached_editor == NULL) && (priv->idle_load_editor_id == 0))
244 priv->idle_load_editor_id = g_timeout_add (5000, (GSourceFunc) idle_load_editor, self);
248 modest_window_mgr_init (ModestWindowMgr *obj)
250 ModestWindowMgrPrivate *priv;
252 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
253 priv->banner_counter = 0;
254 priv->preregistered_uids = NULL;
256 priv->closing_time = 0;
258 priv->cached_view = NULL;
259 priv->cached_editor = NULL;
261 priv->windows_that_prevent_hibernation = NULL;
263 priv->queue_change_handler = 0;
264 priv->progress_operations = TNY_LIST (tny_simple_list_new ());
268 modest_window_mgr_finalize (GObject *obj)
270 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
272 if (priv->idle_load_view_id > 0) {
273 g_source_remove (priv->idle_load_view_id);
274 priv->idle_load_view_id = 0;
277 if (priv->idle_load_editor_id > 0) {
278 g_source_remove (priv->idle_load_editor_id);
279 priv->idle_load_editor_id = 0;
282 if (priv->cached_view) {
283 gtk_widget_destroy (priv->cached_view);
284 priv->cached_view = NULL;
286 if (priv->cached_editor) {
287 gtk_widget_destroy (priv->cached_editor);
288 priv->cached_editor = NULL;
291 if (priv->windows_that_prevent_hibernation) {
292 g_slist_free (priv->windows_that_prevent_hibernation);
293 priv->cached_editor = NULL;
296 modest_signal_mgr_disconnect_all_and_destroy (priv->sighandlers);
297 priv->sighandlers = NULL;
299 if (priv->queue_change_handler > 0) {
300 g_signal_handler_disconnect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
301 priv->queue_change_handler);
302 priv->queue_change_handler = 0;
305 if (priv->progress_operations) {
306 g_object_unref (priv->progress_operations);
307 priv->progress_operations = NULL;
310 g_slist_foreach (priv->preregistered_uids, (GFunc)g_free, NULL);
311 g_slist_free (priv->preregistered_uids);
313 G_OBJECT_CLASS(parent_class)->finalize (obj);
317 modest_window_mgr_new (void)
319 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
325 /* do we have uid? */
327 has_uid (GSList *list, const gchar *uid)
329 GSList *cursor = list;
335 if (cursor->data && strcmp (cursor->data, uid) == 0)
337 cursor = g_slist_next (cursor);
343 /* remove all from the list have have uid = uid */
345 remove_uid (GSList *list, const gchar *uid)
347 GSList *cursor = list, *start = list;
353 GSList *next = g_slist_next (cursor);
354 if (cursor->data && strcmp (cursor->data, uid) == 0) {
355 g_free (cursor->data);
356 start = g_slist_delete_link (start, cursor);
365 append_uid (GSList *list, const gchar *uid)
367 return g_slist_append (list, g_strdup(uid));
373 modest_window_mgr_register_header (ModestWindowMgr *self, TnyHeader *header, const gchar *alt_uid)
375 ModestWindowMgrPrivate *priv;
378 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
379 g_return_if_fail (TNY_IS_HEADER(header));
381 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
382 if (alt_uid != NULL) {
383 uid = g_strdup (alt_uid);
385 uid = modest_tny_folder_get_header_unique_id (header);
388 if (!has_uid (priv->preregistered_uids, uid)) {
389 MODEST_DEBUG_BLOCK(g_debug ("registering new uid %s", uid););
390 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
392 MODEST_DEBUG_BLOCK(g_debug ("already had uid %s", uid););
398 modest_window_mgr_unregister_header (ModestWindowMgr *self, TnyHeader *header)
400 ModestWindowMgrPrivate *priv;
403 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
404 g_return_if_fail (TNY_IS_HEADER(header));
406 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
407 uid = modest_tny_folder_get_header_unique_id (header);
409 if (!has_uid (priv->preregistered_uids, uid)) {
410 MODEST_DEBUG_BLOCK(g_debug ("trying to unregister non-existing uid %s", uid););
411 priv->preregistered_uids = append_uid (priv->preregistered_uids, uid);
413 MODEST_DEBUG_BLOCK(g_debug ("unregistering uid %s", uid););
415 if (has_uid (priv->preregistered_uids, uid)) {
416 priv->preregistered_uids = remove_uid (priv->preregistered_uids, uid);
417 if (has_uid (priv->preregistered_uids, uid))
418 g_debug ("BUG: uid %s NOT removed", uid);
420 MODEST_DEBUG_BLOCK(g_debug ("uid %s removed", uid););
427 #define MODEST_WINDOW_HELP_ID_PARAM "help-id"
430 modest_window_mgr_register_help_id (ModestWindowMgr *self, GtkWindow *win, const gchar* help_id)
432 /* we don't need 'self', but for API consistency... */
433 g_return_if_fail (self && MODEST_IS_WINDOW_MGR(self));
435 g_return_if_fail (help_id);
437 if (GTK_IS_WINDOW (win)) {
438 g_object_set_data_full (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM,
439 g_strdup(help_id), g_free);
445 modest_window_mgr_get_help_id (ModestWindowMgr *self, GtkWindow *win)
447 /* we don't need 'self', but for API consistency... */
448 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR (self), NULL);
449 g_return_val_if_fail (win, NULL);
451 return g_object_get_data (G_OBJECT(win), MODEST_WINDOW_HELP_ID_PARAM);
455 modest_window_mgr_close_all_windows (ModestWindowMgr *self)
457 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_windows (self);
461 modest_window_mgr_close_all_windows_default (ModestWindowMgr *self)
468 modest_window_mgr_find_registered_header (ModestWindowMgr *self, TnyHeader *header,
471 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_header (self, header, win);
475 modest_window_mgr_find_registered_header_default (ModestWindowMgr *self, TnyHeader *header,
480 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
481 g_return_val_if_fail (TNY_IS_HEADER(header), FALSE);
483 uid = modest_tny_folder_get_header_unique_id (header);
486 return modest_window_mgr_find_registered_message_uid (self, uid, win);
492 modest_window_mgr_find_registered_message_uid (ModestWindowMgr *self, const gchar *msg_uid,
495 return MODEST_WINDOW_MGR_GET_CLASS (self)->find_registered_message_uid (self, msg_uid, win);
499 modest_window_mgr_find_registered_message_uid_default (ModestWindowMgr *self, const gchar *msg_uid,
502 ModestWindowMgrPrivate *priv = NULL;
504 gboolean has_header = FALSE;
506 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
507 g_return_val_if_fail (msg_uid && msg_uid[0] != '\0', FALSE);
509 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
514 has_header = has_uid (priv->preregistered_uids, msg_uid);
521 modest_window_mgr_get_window_list (ModestWindowMgr *self)
523 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_window_list (self);
527 modest_window_mgr_get_window_list_default (ModestWindowMgr *self)
533 modest_window_mgr_register_window (ModestWindowMgr *self,
534 ModestWindow *window,
535 ModestWindow *parent)
537 gboolean no_windows, retval;
539 no_windows = (modest_window_mgr_get_num_windows (self) == 0);
541 retval = MODEST_WINDOW_MGR_GET_CLASS (self)->register_window (self, window, parent);
544 /* If this is the first registered window then reset the
545 status of the TnyDevice as it might be forced to be offline
546 when modest is running in the background (see
547 modest_tny_account_store_new()) */
548 if (tny_device_is_forced (modest_runtime_get_device ()))
549 tny_device_reset (modest_runtime_get_device ());
551 /* Do also allow modest to shutdown when the
552 application is closed */
553 modest_runtime_set_allow_shutdown (TRUE);
559 modest_window_mgr_register_window_default (ModestWindowMgr *self,
560 ModestWindow *window,
561 ModestWindow *parent)
563 ModestWindowMgrPrivate *priv;
565 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
566 g_return_val_if_fail (MODEST_IS_WINDOW (window), FALSE);
568 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
570 /* We set up the queue change handler */
571 if (priv->queue_change_handler == 0) {
572 priv->queue_change_handler = g_signal_connect (G_OBJECT (modest_runtime_get_mail_operation_queue ()),
574 G_CALLBACK (modest_window_mgr_on_queue_changed),
579 /* remove from the list of pre-registered uids */
580 if (MODEST_IS_MSG_VIEW_WINDOW(window)) {
581 const gchar *uid = modest_msg_view_window_get_message_uid
582 (MODEST_MSG_VIEW_WINDOW (window));
584 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid ? uid : "<none>"););
586 if (has_uid (priv->preregistered_uids, uid)) {
587 priv->preregistered_uids =
588 remove_uid (priv->preregistered_uids,
589 modest_msg_view_window_get_message_uid
590 (MODEST_MSG_VIEW_WINDOW (window)));
592 } else if (MODEST_IS_MSG_EDIT_WINDOW(window)) {
593 const gchar *uid = modest_msg_edit_window_get_message_uid
594 (MODEST_MSG_EDIT_WINDOW (window));
596 MODEST_DEBUG_BLOCK(g_debug ("registering window for %s", uid););
598 priv->preregistered_uids =
599 remove_uid (priv->preregistered_uids,
600 modest_msg_edit_window_get_message_uid
601 (MODEST_MSG_EDIT_WINDOW (window)));
608 modest_window_mgr_unregister_window (ModestWindowMgr *self,
609 ModestWindow *window)
611 MODEST_WINDOW_MGR_GET_CLASS (self)->unregister_window (self, window);
615 modest_window_mgr_unregister_window_default (ModestWindowMgr *self,
616 ModestWindow *window)
618 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
619 g_return_if_fail (MODEST_IS_WINDOW (window));
622 modest_window_save_state (window);
624 /* Disconnect all the window signals */
625 modest_window_disconnect_signals (window);
627 /* Destroy the window */
628 gtk_widget_destroy (GTK_WIDGET (window));
634 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
637 MODEST_WINDOW_MGR_GET_CLASS (self)->set_fullscreen_mode (self, on);
641 modest_window_mgr_set_fullscreen_mode_default (ModestWindowMgr *self,
648 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
650 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_fullscreen_mode (self);
654 modest_window_mgr_get_fullscreen_mode_default (ModestWindowMgr *self)
660 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
662 gboolean show_toolbars,
665 return MODEST_WINDOW_MGR_GET_CLASS (self)->show_toolbars (self, window_type, show_toolbars, fullscreen);
669 modest_window_mgr_show_toolbars_default (ModestWindowMgr *self,
671 gboolean show_toolbars,
678 modest_window_mgr_get_modal (ModestWindowMgr *self)
680 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_modal (self);
684 modest_window_mgr_get_modal_default (ModestWindowMgr *self)
691 modest_window_mgr_set_modal (ModestWindowMgr *self,
695 MODEST_WINDOW_MGR_GET_CLASS (self)->set_modal (self, window, parent);
699 modest_window_mgr_set_modal_default (ModestWindowMgr *self,
708 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
710 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
711 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
713 /* Forget this window,
714 * so hibernation will be allowed again if no windows are remembered: */
715 priv->windows_that_prevent_hibernation =
716 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
720 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
722 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
723 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
725 GtkWindow *window = GTK_WINDOW (widget);
727 priv->windows_that_prevent_hibernation =
728 g_slist_append (priv->windows_that_prevent_hibernation, window);
730 /* Allow hibernation again when the window has been hidden: */
731 g_signal_connect (window, "hide",
732 G_CALLBACK (on_nonhibernating_window_hide), self);
736 modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self,
739 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
741 if (GTK_WIDGET_VISIBLE(window)) {
742 on_nonhibernating_window_show (GTK_WIDGET (window), self);
744 /* Wait for it to be shown: */
745 g_signal_connect (window, "show",
746 G_CALLBACK (on_nonhibernating_window_show), self);
751 modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
753 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
755 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
757 /* Prevent hibernation if any open windows are currently
758 * preventing hibernation: */
759 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
764 modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
768 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
770 /* Iterate over all windows */
771 window_list = modest_window_mgr_get_window_list (self);
774 ModestWindow *window = MODEST_WINDOW (node->data);
776 /* This calls the vfunc,
777 * so each window can do its own thing: */
778 modest_window_save_state (window);
781 node = g_list_next (node);
783 g_list_free (window_list);
787 modest_window_mgr_get_num_windows (ModestWindowMgr *self)
789 ModestWindowMgrPrivate *priv;
790 gint num_windows = 0;
793 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), -1);
795 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
797 window_list = modest_window_mgr_get_window_list (self);
800 num_windows = g_list_length (window_list);
801 g_list_free (window_list);
804 return num_windows + priv->banner_counter;
808 modest_window_mgr_get_msg_edit_window (ModestWindowMgr *self)
811 ModestWindowMgrPrivate *priv;
813 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
815 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
817 if (priv->cached_editor) {
818 result = priv->cached_editor;
819 priv->cached_editor = NULL;
820 load_new_editor (self);
822 result = g_object_new (MODEST_TYPE_MSG_EDIT_WINDOW, NULL);
829 modest_window_mgr_get_msg_view_window (ModestWindowMgr *self)
832 ModestWindowMgrPrivate *priv;
834 g_return_val_if_fail (self && MODEST_IS_WINDOW_MGR(self), NULL);
836 priv = MODEST_WINDOW_MGR_GET_PRIVATE(self);
838 if (priv->cached_view) {
839 result = priv->cached_view;
840 priv->cached_view = NULL;
841 load_new_view (self);
843 result = g_object_new (MODEST_TYPE_MSG_VIEW_WINDOW, NULL);
850 modest_window_mgr_register_banner (ModestWindowMgr *self)
852 ModestWindowMgrPrivate *priv;
854 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
855 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
857 priv->banner_counter++;
861 modest_window_mgr_unregister_banner (ModestWindowMgr *self)
863 ModestWindowMgrPrivate *priv;
865 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
866 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
868 priv->banner_counter--;
869 if (modest_window_mgr_get_num_windows (self) == 0)
870 g_signal_emit (self, signals[WINDOW_LIST_EMPTY_SIGNAL], 0);
874 modest_window_mgr_show_initial_window (ModestWindowMgr *self)
876 ModestWindow *window = NULL;
878 /* Call the children */
879 window = MODEST_WINDOW_MGR_GET_CLASS (self)->show_initial_window (self);
882 ModestAccountMgr *mgr;
884 /* Show the initial window */
885 gtk_widget_show (GTK_WIDGET (window));
887 /* If there are no accounts then show the account wizard */
888 mgr = modest_runtime_get_account_mgr();
889 if (!modest_account_mgr_has_accounts (mgr, TRUE)) {
890 if (!modest_ui_actions_run_account_setup_wizard (window)) {
891 g_debug ("%s: couldn't show account setup wizard", __FUNCTION__);
899 static ModestWindow *
900 modest_window_mgr_show_initial_window_default (ModestWindowMgr *self)
902 g_warning ("You must implement %s", __FUNCTION__);
909 modest_window_mgr_get_current_top (ModestWindowMgr *self)
911 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_current_top (self);
915 static ModestWindow *
916 modest_window_mgr_get_current_top_default (ModestWindowMgr *self)
918 g_return_val_if_reached (NULL);
922 modest_window_mgr_screen_is_on (ModestWindowMgr *self)
924 return MODEST_WINDOW_MGR_GET_CLASS (self)->screen_is_on (self);
928 modest_window_mgr_screen_is_on_default (ModestWindowMgr *self)
930 /* Default implementation is assuming screen is always on */
936 modest_window_mgr_create_caches (ModestWindowMgr *mgr)
938 MODEST_WINDOW_MGR_GET_CLASS (mgr)->create_caches (mgr);
942 modest_window_mgr_create_caches_default (ModestWindowMgr *self)
944 load_new_editor (self);
945 load_new_view (self);
949 tny_list_find (TnyList *list, GObject *item)
951 TnyIterator *iterator;
952 gboolean found = FALSE;
954 for (iterator = tny_list_create_iterator (list);
955 !tny_iterator_is_done (iterator) && !found;
956 tny_iterator_next (iterator)) {
957 GObject *current = tny_iterator_get_current (iterator);
960 g_object_unref (current);
962 g_object_unref (iterator);
968 modest_window_mgr_on_queue_changed (ModestMailOperationQueue *queue,
969 ModestMailOperation *mail_op,
970 ModestMailOperationQueueNotification type,
971 ModestWindowMgr *self)
973 ModestWindowMgrPrivate *priv;
975 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
977 /* We register to track progress */
978 if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_ADDED) {
979 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
982 G_CALLBACK (on_mail_operation_started),
984 priv->sighandlers = modest_signal_mgr_connect (priv->sighandlers,
986 "operation-finished",
987 G_CALLBACK (on_mail_operation_finished),
989 } else if (type == MODEST_MAIL_OPERATION_QUEUE_OPERATION_REMOVED) {
990 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
992 "operation-started");
993 priv->sighandlers = modest_signal_mgr_disconnect (priv->sighandlers,
995 "operation-finished");
996 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
997 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
998 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1004 on_mail_operation_started (ModestMailOperation *mail_op,
1007 ModestWindowMgr *self;
1008 ModestWindowMgrPrivate *priv;
1009 ModestMailOperationTypeOperation op_type;
1011 self = MODEST_WINDOW_MGR (user_data);
1012 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1014 /* First we check if the operation is a send receive operation,
1015 * If now, we don't handle this */
1016 op_type = modest_mail_operation_get_type_operation (mail_op);
1017 if (op_type != MODEST_MAIL_OPERATION_TYPE_SEND &&
1018 op_type != MODEST_MAIL_OPERATION_TYPE_SEND_AND_RECEIVE) {
1022 if (!tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1023 tny_list_prepend (priv->progress_operations, G_OBJECT (mail_op));
1024 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1029 on_mail_operation_finished (ModestMailOperation *mail_op,
1032 ModestWindowMgr *self;
1033 ModestWindowMgrPrivate *priv;
1035 self = MODEST_WINDOW_MGR (user_data);
1036 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1038 if (tny_list_find (priv->progress_operations, G_OBJECT (mail_op))) {
1039 tny_list_remove (priv->progress_operations, G_OBJECT (mail_op));
1040 g_signal_emit (self, signals[PROGRESS_LIST_CHANGED_SIGNAL], 0);
1045 modest_window_mgr_get_progress_operations (ModestWindowMgr *self)
1047 ModestWindowMgrPrivate *priv;
1049 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1051 return tny_list_copy (priv->progress_operations);
1055 modest_window_mgr_has_progress_operation (ModestWindowMgr *self)
1057 ModestWindowMgrPrivate *priv;
1059 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1061 return tny_list_get_length (priv->progress_operations) > 0;
1065 modest_window_mgr_has_progress_operation_on_account (ModestWindowMgr *self,
1066 const gchar *account_name)
1068 ModestWindowMgrPrivate *priv;
1069 gint account_ops = 0;
1070 TnyIterator *iterator;
1072 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
1074 if (account_name == NULL)
1077 for (iterator = tny_list_create_iterator (priv->progress_operations);
1078 !tny_iterator_is_done (iterator);
1079 tny_iterator_next (iterator)) {
1080 ModestMailOperation *mail_op;
1081 TnyAccount *account;
1083 mail_op= MODEST_MAIL_OPERATION (tny_iterator_get_current (iterator));
1084 account = modest_mail_operation_get_account (mail_op);
1086 if (account != NULL) {
1087 const gchar *current_name;
1089 current_name = tny_account_get_id (account);
1090 if (current_name && strcmp (current_name, account_name) == 0)
1092 g_object_unref (account);
1095 g_object_unref (mail_op);
1097 g_object_unref (iterator);
1102 /* 'Protected method' must be only called by children */
1104 _modest_window_mgr_close_active_modals (ModestWindowMgr *self)
1108 /* Exit if there are no windows */
1109 if (!modest_window_mgr_get_num_windows (self)) {
1110 g_warning ("%s: there are no windows to close", __FUNCTION__);
1114 /* Check that there is no active modal dialog */
1115 modal = (GtkWidget *) modest_window_mgr_get_modal (self);
1116 while (modal && GTK_IS_DIALOG (modal)) {
1119 #if defined(MODEST_TOOLKIT_HILDON2) || defined(MODEST_TOOLKIT_HILDON)
1120 #include <hildon/hildon.h>
1121 /* If it's a hildon note then don't try to close it as
1122 this is the default behaviour of WM, delete event
1123 is not issued for this kind of notes as we want the
1124 user to always click on a button */
1125 if (HILDON_IS_NOTE (modal)) {
1126 gtk_window_present (GTK_WINDOW (modal));
1131 /* Get the parent */
1132 parent = (GtkWidget *) gtk_window_get_transient_for (GTK_WINDOW (modal));
1134 /* Try to close it */
1135 gtk_dialog_response (GTK_DIALOG (modal), GTK_RESPONSE_DELETE_EVENT);
1137 /* Maybe the dialog was not closed, because a close
1138 confirmation dialog for example. Then ignore the
1140 if (GTK_IS_WINDOW (modal)) {
1141 gtk_window_present (GTK_WINDOW (modal));
1145 /* Get next modal */
1152 modest_window_mgr_close_all_but_initial (ModestWindowMgr *self)
1154 return MODEST_WINDOW_MGR_GET_CLASS (self)->close_all_but_initial (self);
1158 modest_window_mgr_close_all_but_initial_default (ModestWindowMgr *self)
1160 /* Empty default implementation */
1165 modest_window_mgr_get_folder_window (ModestWindowMgr *self)
1167 return MODEST_WINDOW_MGR_GET_CLASS (self)->get_folder_window (self);
1170 static ModestWindow *
1171 modest_window_mgr_get_folder_window_default (ModestWindowMgr *self)
1173 /* Default implementation returns NULL always */