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 "widgets/modest-main-window.h"
35 #include "widgets/modest-msg-edit-window.h"
36 #include "widgets/modest-msg-view-window.h"
37 /* include other impl specific header files */
39 /* 'private'/'protected' functions */
40 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
41 static void modest_window_mgr_init (ModestWindowMgr *obj);
42 static void modest_window_mgr_finalize (GObject *obj);
44 static void on_window_destroy (ModestWindow *window,
45 ModestWindowMgr *self);
54 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
55 struct _ModestWindowMgrPrivate {
57 ModestWindow *main_window;
58 gboolean fullscreen_mode;
59 gboolean show_toolbars;
60 gboolean show_toolbars_fullscreen;
62 GSList* windows_that_prevent_hibernation;
64 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
65 MODEST_TYPE_WINDOW_MGR, \
66 ModestWindowMgrPrivate))
68 static GObjectClass *parent_class = NULL;
70 /* uncomment the following if you have defined any signals */
71 /* static guint signals[LAST_SIGNAL] = {0}; */
74 modest_window_mgr_get_type (void)
76 static GType my_type = 0;
78 static const GTypeInfo my_info = {
79 sizeof(ModestWindowMgrClass),
81 NULL, /* base finalize */
82 (GClassInitFunc) modest_window_mgr_class_init,
83 NULL, /* class finalize */
84 NULL, /* class data */
85 sizeof(ModestWindowMgr),
87 (GInstanceInitFunc) modest_window_mgr_init,
90 my_type = g_type_register_static (G_TYPE_OBJECT,
98 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
100 GObjectClass *gobject_class;
101 gobject_class = (GObjectClass*) klass;
103 parent_class = g_type_class_peek_parent (klass);
104 gobject_class->finalize = modest_window_mgr_finalize;
106 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
110 modest_window_mgr_init (ModestWindowMgr *obj)
112 ModestWindowMgrPrivate *priv;
114 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
115 priv->window_list = NULL;
116 priv->main_window = NULL;
117 priv->fullscreen_mode = FALSE;
119 /* Could not initialize it from gconf, singletons are not
121 priv->show_toolbars = FALSE;
122 priv->show_toolbars_fullscreen = FALSE;
126 modest_window_mgr_finalize (GObject *obj)
128 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
130 if (priv->window_list) {
131 GList *iter = priv->window_list;
132 /* unregister pending windows */
134 modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj),
135 MODEST_WINDOW (iter->data));
136 iter = g_list_next (iter);
138 g_list_free (priv->window_list);
139 priv->window_list = NULL;
142 /* Do not unref priv->main_window because it does not hold a
145 G_OBJECT_CLASS(parent_class)->finalize (obj);
149 modest_window_mgr_new (void)
151 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
155 modest_window_mgr_register_window (ModestWindowMgr *self,
156 ModestWindow *window)
158 static gboolean first_time = TRUE;
161 ModestWindowMgrPrivate *priv;
163 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
164 g_return_if_fail (MODEST_IS_WINDOW (window));
166 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
168 win = g_list_find (priv->window_list, window);
170 g_warning ("Trying to register an already registered window");
174 /* Check that it's not a second main window */
175 if (MODEST_IS_MAIN_WINDOW (window)) {
176 if (priv->main_window) {
177 g_warning ("Trying to register a second main window");
180 priv->main_window = window;
184 /* Add to list. Keep a reference to the window */
185 g_object_ref (window);
186 priv->window_list = g_list_prepend (priv->window_list, window);
188 /* Listen to object destruction */
189 g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), self);
191 /* Put into fullscreen if needed */
192 if (priv->fullscreen_mode)
193 gtk_window_fullscreen (GTK_WINDOW (window));
197 ModestConf *conf = modest_runtime_get_conf ();
198 priv->show_toolbars =
199 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL);
200 priv->show_toolbars_fullscreen =
201 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL);
205 /* Show/hide toolbar */
206 if (priv->fullscreen_mode)
207 show = priv->show_toolbars_fullscreen;
209 show = priv->show_toolbars;
210 modest_window_show_toolbar (window, show);
214 on_window_destroy (ModestWindow *window, ModestWindowMgr *self)
216 /* Specific stuff first */
217 if (MODEST_IS_MAIN_WINDOW (window)) {
218 ModestWindowMgrPrivate *priv;
219 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
221 /* If more than one window already opened */
222 if (g_list_length (priv->window_list) > 1) {
224 /* If the user wants to close all the windows */
225 if (modest_main_window_close_all (MODEST_MAIN_WINDOW (window))) {
226 GList *iter = priv->window_list;
228 if (iter->data != window) {
229 GList *tmp = iter->next;
230 on_window_destroy (MODEST_WINDOW (iter->data),
234 iter = g_list_next (iter);
240 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
241 /* TODO: Save currently edited message to Drafts
246 /* Unregister window */
247 modest_window_mgr_unregister_window (self, window);
251 modest_window_mgr_unregister_window (ModestWindowMgr *self,
252 ModestWindow *window)
255 ModestWindowMgrPrivate *priv;
257 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
258 g_return_if_fail (MODEST_IS_WINDOW (window));
260 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
262 win = g_list_find (priv->window_list, window);
264 g_warning ("Trying to unregister a window that has not being registered yet");
268 /* Remove from list. Remove the reference to the window */
269 g_object_unref (win->data);
270 priv->window_list = g_list_remove_link (priv->window_list, win);
272 /* If there are no more windows registered then exit program */
273 if (priv->window_list == NULL) {
274 ModestConf *conf = modest_runtime_get_conf ();
276 /* Save show toolbar status */
277 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN,
278 priv->show_toolbars_fullscreen, NULL);
279 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR,
280 priv->show_toolbars, NULL);
288 compare_msguids (ModestWindow *win,
291 const gchar *msg_uid;
293 if (!MODEST_IS_MSG_VIEW_WINDOW (win))
296 /* Get message uid from msg window */
297 msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win));
299 if (msg_uid && !strcmp (msg_uid, uid))
306 modest_window_mgr_find_window_by_header (ModestWindowMgr *self,
309 ModestWindowMgrPrivate *priv;
313 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
314 g_return_val_if_fail (TNY_IS_HEADER (header), NULL);
316 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
317 msg_uid = modest_tny_folder_get_header_unique_id (header);
319 /* Look for the window */
320 if (priv->window_list)
321 win = g_list_find_custom (priv->window_list,
323 (GCompareFunc) compare_msguids);
327 /* Return the window */
335 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
338 ModestWindowMgrPrivate *priv;
341 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
343 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
345 /* If there is no change do nothing */
346 if (priv->fullscreen_mode == on)
349 priv->fullscreen_mode = on;
352 win = priv->window_list;
355 gtk_window_fullscreen (GTK_WINDOW (win->data));
356 modest_window_show_toolbar (MODEST_WINDOW (win->data),
357 priv->show_toolbars_fullscreen);
359 gtk_window_unfullscreen (GTK_WINDOW (win->data));
360 modest_window_show_toolbar (MODEST_WINDOW (win->data),
361 priv->show_toolbars);
363 win = g_list_next (win);
368 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
370 ModestWindowMgrPrivate *priv;
372 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
374 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
376 return priv->fullscreen_mode;
380 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
381 gboolean show_toolbars,
384 ModestWindowMgrPrivate *priv;
386 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
388 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
390 /* If nothing changes then return. Otherwise cache it, do not
391 save to GConf for the moment, it will be done when all
392 windows become unregistered in order to avoid unnecessary
395 if (priv->show_toolbars_fullscreen == show_toolbars)
398 priv->show_toolbars_fullscreen = show_toolbars;
400 if (priv->show_toolbars == show_toolbars)
403 priv->show_toolbars = show_toolbars;
406 /* Apply now if the view mode is the right one */
407 if ((fullscreen && priv->fullscreen_mode) ||
408 (!fullscreen && !priv->fullscreen_mode)) {
410 GList *win = priv->window_list;
413 modest_window_show_toolbar (MODEST_WINDOW (win->data),
415 win = g_list_next (win);
421 modest_window_mgr_get_main_window (ModestWindowMgr *self)
423 ModestWindowMgrPrivate *priv;
425 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
427 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
429 return priv->main_window;
433 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
435 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
436 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
438 /* Forget this window,
439 * so hibernation will be allowed again if no windows are remembered: */
440 priv->windows_that_prevent_hibernation =
441 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
445 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
447 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
448 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
450 GtkWindow *window = GTK_WINDOW (widget);
452 priv->windows_that_prevent_hibernation =
453 g_slist_append (priv->windows_that_prevent_hibernation, window);
455 /* Allow hibernation again when the window has been hidden: */
456 g_signal_connect (window, "hide",
457 G_CALLBACK (on_nonhibernating_window_hide), self);
460 void modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self, GtkWindow *window)
462 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
464 if (GTK_WIDGET_VISIBLE(window)) {
465 on_nonhibernating_window_show (GTK_WIDGET (window), self);
469 /* Wait for it to be shown: */
470 g_signal_connect (window, "show",
471 G_CALLBACK (on_nonhibernating_window_show), self);
475 gboolean modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
477 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
479 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
481 /* Prevent hibernation if any open windows are currently
482 * preventing hibernation: */
483 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
487 void modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
489 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
491 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
493 /* Iterate over all windows */
494 GList *win = priv->window_list;
496 ModestWindow *window = MODEST_WINDOW (win->data);
498 /* This calls the vfunc,
499 * so each window can do its own thing: */
500 modest_window_save_state (window);
503 win = g_list_next (win);