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 "widgets/modest-main-window.h"
34 #include "widgets/modest-msg-edit-window.h"
35 #include "widgets/modest-msg-view-window.h"
36 /* include other impl specific header files */
38 /* 'private'/'protected' functions */
39 static void modest_window_mgr_class_init (ModestWindowMgrClass *klass);
40 static void modest_window_mgr_init (ModestWindowMgr *obj);
41 static void modest_window_mgr_finalize (GObject *obj);
43 static void on_window_destroy (ModestWindow *window,
44 ModestWindowMgr *self);
53 typedef struct _ModestWindowMgrPrivate ModestWindowMgrPrivate;
54 struct _ModestWindowMgrPrivate {
56 ModestWindow *main_window;
57 gboolean fullscreen_mode;
58 gboolean show_toolbars;
59 gboolean show_toolbars_fullscreen;
61 GSList* windows_that_prevent_hibernation;
63 #define MODEST_WINDOW_MGR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \
64 MODEST_TYPE_WINDOW_MGR, \
65 ModestWindowMgrPrivate))
67 static GObjectClass *parent_class = NULL;
69 /* uncomment the following if you have defined any signals */
70 /* static guint signals[LAST_SIGNAL] = {0}; */
73 modest_window_mgr_get_type (void)
75 static GType my_type = 0;
77 static const GTypeInfo my_info = {
78 sizeof(ModestWindowMgrClass),
80 NULL, /* base finalize */
81 (GClassInitFunc) modest_window_mgr_class_init,
82 NULL, /* class finalize */
83 NULL, /* class data */
84 sizeof(ModestWindowMgr),
86 (GInstanceInitFunc) modest_window_mgr_init,
89 my_type = g_type_register_static (G_TYPE_OBJECT,
97 modest_window_mgr_class_init (ModestWindowMgrClass *klass)
99 GObjectClass *gobject_class;
100 gobject_class = (GObjectClass*) klass;
102 parent_class = g_type_class_peek_parent (klass);
103 gobject_class->finalize = modest_window_mgr_finalize;
105 g_type_class_add_private (gobject_class, sizeof(ModestWindowMgrPrivate));
109 modest_window_mgr_init (ModestWindowMgr *obj)
111 ModestWindowMgrPrivate *priv;
113 priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
114 priv->window_list = NULL;
115 priv->main_window = NULL;
116 priv->fullscreen_mode = FALSE;
118 /* Could not initialize it from gconf, singletons are not
120 priv->show_toolbars = FALSE;
121 priv->show_toolbars_fullscreen = FALSE;
125 modest_window_mgr_finalize (GObject *obj)
127 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE(obj);
129 if (priv->window_list) {
130 GList *iter = priv->window_list;
131 /* unregister pending windows */
133 modest_window_mgr_unregister_window (MODEST_WINDOW_MGR (obj),
134 MODEST_WINDOW (iter->data));
135 iter = g_list_next (iter);
137 g_list_free (priv->window_list);
138 priv->window_list = NULL;
141 /* Do not unref priv->main_window because it does not hold a
144 G_OBJECT_CLASS(parent_class)->finalize (obj);
148 modest_window_mgr_new (void)
150 return MODEST_WINDOW_MGR(g_object_new(MODEST_TYPE_WINDOW_MGR, NULL));
154 modest_window_mgr_register_window (ModestWindowMgr *self,
155 ModestWindow *window)
157 static gboolean first_time = TRUE;
160 ModestWindowMgrPrivate *priv;
162 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
163 g_return_if_fail (MODEST_IS_WINDOW (window));
165 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
167 win = g_list_find (priv->window_list, window);
169 g_warning ("Trying to register an already registered window");
173 /* Check that it's not a second main window */
174 if (MODEST_IS_MAIN_WINDOW (window)) {
175 if (priv->main_window) {
176 g_warning ("Trying to register a second main window");
179 priv->main_window = window;
183 /* Add to list. Keep a reference to the window */
184 g_object_ref (window);
185 priv->window_list = g_list_prepend (priv->window_list, window);
187 /* Listen to object destruction */
188 g_signal_connect (window, "destroy", G_CALLBACK (on_window_destroy), self);
190 /* Put into fullscreen if needed */
191 if (priv->fullscreen_mode)
192 gtk_window_fullscreen (GTK_WINDOW (window));
196 ModestConf *conf = modest_runtime_get_conf ();
197 priv->show_toolbars =
198 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR, NULL);
199 priv->show_toolbars_fullscreen =
200 modest_conf_get_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN, NULL);
204 /* Show/hide toolbar */
205 if (priv->fullscreen_mode)
206 show = priv->show_toolbars_fullscreen;
208 show = priv->show_toolbars;
209 modest_window_show_toolbar (window, show);
213 on_window_destroy (ModestWindow *window, ModestWindowMgr *self)
215 /* Specific stuff first */
216 if (MODEST_IS_MAIN_WINDOW (window)) {
217 ModestWindowMgrPrivate *priv;
218 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
220 /* If more than one window already opened */
221 if (g_list_length (priv->window_list) > 1) {
223 /* If the user wants to close all the windows */
224 if (modest_main_window_close_all (MODEST_MAIN_WINDOW (window))) {
225 GList *iter = priv->window_list;
227 if (iter->data != window) {
228 GList *tmp = iter->next;
229 on_window_destroy (MODEST_WINDOW (iter->data),
233 iter = g_list_next (iter);
239 if (MODEST_IS_MSG_EDIT_WINDOW (window)) {
240 /* TODO: Save currently edited message to Drafts
245 /* Unregister window */
246 modest_window_mgr_unregister_window (self, window);
250 modest_window_mgr_unregister_window (ModestWindowMgr *self,
251 ModestWindow *window)
254 ModestWindowMgrPrivate *priv;
256 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
257 g_return_if_fail (MODEST_IS_WINDOW (window));
259 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
261 win = g_list_find (priv->window_list, window);
263 g_warning ("Trying to unregister a window that has not being registered yet");
267 /* Remove from list. Remove the reference to the window */
268 g_object_unref (win->data);
269 priv->window_list = g_list_remove_link (priv->window_list, win);
271 /* If there are no more windows registered then exit program */
272 if (priv->window_list == NULL) {
273 ModestConf *conf = modest_runtime_get_conf ();
275 /* Save show toolbar status */
276 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR_FULLSCREEN,
277 priv->show_toolbars_fullscreen, NULL);
278 modest_conf_set_bool (conf, MODEST_CONF_SHOW_TOOLBAR,
279 priv->show_toolbars, NULL);
287 compare_msguids (ModestWindow *win,
290 const gchar *msg_uid;
292 if (!MODEST_IS_MSG_VIEW_WINDOW (win))
295 /* Get message uid from msg window */
296 msg_uid = modest_msg_view_window_get_message_uid (MODEST_MSG_VIEW_WINDOW (win));
297 if (msg_uid && !strcmp (msg_uid, uid))
304 modest_window_mgr_find_window_by_msguid (ModestWindowMgr *self,
307 ModestWindowMgrPrivate *priv;
310 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
311 g_return_val_if_fail (msguid != NULL, NULL);
313 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
315 /* Look for the window */
316 if (priv->window_list)
317 win = g_list_find_custom (priv->window_list,
319 (GCompareFunc) compare_msguids);
328 modest_window_mgr_set_fullscreen_mode (ModestWindowMgr *self,
331 ModestWindowMgrPrivate *priv;
334 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
336 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
338 /* If there is no change do nothing */
339 if (priv->fullscreen_mode == on)
342 priv->fullscreen_mode = on;
345 win = priv->window_list;
348 gtk_window_fullscreen (GTK_WINDOW (win->data));
349 modest_window_show_toolbar (MODEST_WINDOW (win->data),
350 priv->show_toolbars_fullscreen);
352 gtk_window_unfullscreen (GTK_WINDOW (win->data));
353 modest_window_show_toolbar (MODEST_WINDOW (win->data),
354 priv->show_toolbars);
356 win = g_list_next (win);
361 modest_window_mgr_get_fullscreen_mode (ModestWindowMgr *self)
363 ModestWindowMgrPrivate *priv;
365 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
367 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
369 return priv->fullscreen_mode;
373 modest_window_mgr_show_toolbars (ModestWindowMgr *self,
374 gboolean show_toolbars,
377 ModestWindowMgrPrivate *priv;
379 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
381 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
383 /* If nothing changes then return. Otherwise cache it, do not
384 save to GConf for the moment, it will be done when all
385 windows become unregistered in order to avoid unnecessary
388 if (priv->show_toolbars_fullscreen == show_toolbars)
391 priv->show_toolbars_fullscreen = show_toolbars;
393 if (priv->show_toolbars == show_toolbars)
396 priv->show_toolbars = show_toolbars;
399 /* Apply now if the view mode is the right one */
400 if ((fullscreen && priv->fullscreen_mode) ||
401 (!fullscreen && !priv->fullscreen_mode)) {
403 GList *win = priv->window_list;
406 modest_window_show_toolbar (MODEST_WINDOW (win->data),
408 win = g_list_next (win);
414 modest_window_mgr_get_main_window (ModestWindowMgr *self)
416 ModestWindowMgrPrivate *priv;
418 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), NULL);
420 priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
422 return priv->main_window;
426 on_nonhibernating_window_hide(GtkWidget *widget, gpointer user_data)
428 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
429 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
431 /* Forget this window,
432 * so hibernation will be allowed again if no windows are remembered: */
433 priv->windows_that_prevent_hibernation =
434 g_slist_remove (priv->windows_that_prevent_hibernation, GTK_WINDOW(widget));
438 on_nonhibernating_window_show(GtkWidget *widget, gpointer user_data)
440 ModestWindowMgr *self = MODEST_WINDOW_MGR (user_data);
441 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
443 GtkWindow *window = GTK_WINDOW (widget);
445 priv->windows_that_prevent_hibernation =
446 g_slist_append (priv->windows_that_prevent_hibernation, window);
448 /* Allow hibernation again when the window has been hidden: */
449 g_signal_connect (window, "hide",
450 G_CALLBACK (on_nonhibernating_window_hide), self);
453 void modest_window_mgr_prevent_hibernation_while_window_is_shown (ModestWindowMgr *self, GtkWindow *window)
455 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
457 if (GTK_WIDGET_VISIBLE(window)) {
458 on_nonhibernating_window_show (GTK_WIDGET (window), self);
462 /* Wait for it to be shown: */
463 g_signal_connect (window, "show",
464 G_CALLBACK (on_nonhibernating_window_show), self);
468 gboolean modest_window_mgr_get_hibernation_is_prevented (ModestWindowMgr *self)
470 g_return_val_if_fail (MODEST_IS_WINDOW_MGR (self), FALSE);
472 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
474 /* Prevent hibernation if any open windows are currently
475 * preventing hibernation: */
476 return (g_slist_length (priv->windows_that_prevent_hibernation) > 0);
480 void modest_window_mgr_save_state_for_all_windows (ModestWindowMgr *self)
482 g_return_if_fail (MODEST_IS_WINDOW_MGR (self));
484 ModestWindowMgrPrivate *priv = MODEST_WINDOW_MGR_GET_PRIVATE (self);
486 /* Iterate over all windows */
487 GList *win = priv->window_list;
489 ModestWindow *window = MODEST_WINDOW (win->data);
491 /* This calls the vfunc,
492 * so each window can do its own thing: */
493 modest_window_save_state (window);
496 win = g_list_next (win);