No issues found
1 /*
2 * e-shell-window-private.c
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) version 3.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with the program; if not, see <http://www.gnu.org/licenses/>
16 *
17 *
18 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
19 *
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include "e-shell-window-private.h"
27
28 static void
29 shell_window_save_switcher_style_cb (GtkRadioAction *action,
30 GtkRadioAction *current,
31 EShellWindow *shell_window)
32 {
33 GSettings *settings;
34 GtkToolbarStyle style;
35 const gchar *string;
36
37 settings = g_settings_new ("org.gnome.evolution.shell");
38
39 style = gtk_radio_action_get_current_value (action);
40
41 switch (style) {
42 case GTK_TOOLBAR_ICONS:
43 string = "icons";
44 break;
45
46 case GTK_TOOLBAR_TEXT:
47 string = "text";
48 break;
49
50 case GTK_TOOLBAR_BOTH:
51 case GTK_TOOLBAR_BOTH_HORIZ:
52 string = "both";
53 break;
54
55 default:
56 string = "toolbar";
57 break;
58 }
59
60 g_settings_set_string (settings, "buttons-style", string);
61 g_object_unref (settings);
62 }
63
64 static void
65 shell_window_init_switcher_style (EShellWindow *shell_window)
66 {
67 GtkAction *action;
68 GSettings *settings;
69 GtkToolbarStyle style;
70 gchar *string;
71
72 settings = g_settings_new ("org.gnome.evolution.shell");
73
74 action = ACTION (SWITCHER_STYLE_ICONS);
75 string = g_settings_get_string (settings, "buttons-style");
76 g_object_unref (settings);
77
78 if (string != NULL) {
79 if (strcmp (string, "icons") == 0)
80 style = GTK_TOOLBAR_ICONS;
81 else if (strcmp (string, "text") == 0)
82 style = GTK_TOOLBAR_TEXT;
83 else if (strcmp (string, "both") == 0)
84 style = GTK_TOOLBAR_BOTH_HORIZ;
85 else
86 style = -1;
87
88 gtk_radio_action_set_current_value (
89 GTK_RADIO_ACTION (action), style);
90
91 g_free (string);
92 }
93
94 g_signal_connect (
95 action, "changed",
96 G_CALLBACK (shell_window_save_switcher_style_cb),
97 shell_window);
98 }
99
100 static void
101 shell_window_menu_item_select_cb (EShellWindow *shell_window,
102 GtkWidget *widget)
103 {
104 GtkAction *action;
105 GtkActivatable *activatable;
106 GtkLabel *label;
107 const gchar *tooltip;
108
109 activatable = GTK_ACTIVATABLE (widget);
110 action = gtk_activatable_get_related_action (activatable);
111 tooltip = gtk_action_get_tooltip (action);
112
113 if (tooltip == NULL)
114 return;
115
116 label = GTK_LABEL (shell_window->priv->tooltip_label);
117 gtk_label_set_text (label, tooltip);
118
119 gtk_widget_show (shell_window->priv->tooltip_label);
120 gtk_widget_hide (shell_window->priv->status_notebook);
121 }
122
123 static void
124 shell_window_menu_item_deselect_cb (EShellWindow *shell_window)
125 {
126 gtk_widget_hide (shell_window->priv->tooltip_label);
127 gtk_widget_show (shell_window->priv->status_notebook);
128 }
129
130 static void
131 shell_window_connect_proxy_cb (EShellWindow *shell_window,
132 GtkAction *action,
133 GtkWidget *proxy)
134 {
135 if (!GTK_IS_MENU_ITEM (proxy))
136 return;
137
138 g_signal_connect_swapped (
139 proxy, "select",
140 G_CALLBACK (shell_window_menu_item_select_cb),
141 shell_window);
142
143 g_signal_connect_swapped (
144 proxy, "deselect",
145 G_CALLBACK (shell_window_menu_item_deselect_cb),
146 shell_window);
147 }
148
149 static GtkWidget *
150 shell_window_construct_menubar (EShellWindow *shell_window)
151 {
152 EShellWindowClass *class;
153
154 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
155 if (class->construct_menubar == NULL)
156 return NULL;
157
158 return class->construct_menubar (shell_window);
159 }
160
161 static GtkWidget *
162 shell_window_construct_toolbar (EShellWindow *shell_window)
163 {
164 EShellWindowClass *class;
165
166 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
167 if (class->construct_toolbar == NULL)
168 return NULL;
169
170 return class->construct_toolbar (shell_window);
171 }
172
173 static GtkWidget *
174 shell_window_construct_sidebar (EShellWindow *shell_window)
175 {
176 EShellWindowClass *class;
177
178 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
179 if (class->construct_sidebar == NULL)
180 return NULL;
181
182 return class->construct_sidebar (shell_window);
183 }
184
185 static GtkWidget *
186 shell_window_construct_content (EShellWindow *shell_window)
187 {
188 EShellWindowClass *class;
189
190 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
191 if (class->construct_content == NULL)
192 return NULL;
193
194 return class->construct_content (shell_window);
195 }
196
197 static GtkWidget *
198 shell_window_construct_taskbar (EShellWindow *shell_window)
199 {
200 EShellWindowClass *class;
201
202 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
203 if (class->construct_taskbar == NULL)
204 return NULL;
205
206 return class->construct_taskbar (shell_window);
207 }
208
209 void
210 e_shell_window_private_init (EShellWindow *shell_window)
211 {
212 EShellWindowPrivate *priv = shell_window->priv;
213 GHashTable *loaded_views;
214 GArray *signal_handler_ids;
215
216 loaded_views = g_hash_table_new_full (
217 g_str_hash, g_str_equal,
218 (GDestroyNotify) g_free,
219 (GDestroyNotify) g_object_unref);
220
221 signal_handler_ids = g_array_new (FALSE, FALSE, sizeof (gulong));
222
223 priv->ui_manager = e_ui_manager_new ();
224 priv->loaded_views = loaded_views;
225 priv->signal_handler_ids = signal_handler_ids;
226
227 /* XXX This kind of violates the shell window being unaware
228 * of specific shell views, but we need a sane fallback. */
229 priv->active_view = "mail";
230
231 e_shell_window_add_action_group (shell_window, "shell");
232 e_shell_window_add_action_group (shell_window, "gal-view");
233 e_shell_window_add_action_group (shell_window, "new-item");
234 e_shell_window_add_action_group (shell_window, "new-source");
235 e_shell_window_add_action_group (shell_window, "custom-rules");
236 e_shell_window_add_action_group (shell_window, "switcher");
237 e_shell_window_add_action_group (shell_window, "new-window");
238 e_shell_window_add_action_group (shell_window, "lockdown-application-handlers");
239 e_shell_window_add_action_group (shell_window, "lockdown-printing");
240 e_shell_window_add_action_group (shell_window, "lockdown-print-setup");
241 e_shell_window_add_action_group (shell_window, "lockdown-save-to-disk");
242
243 gtk_window_set_title (GTK_WINDOW (shell_window), _("Evolution"));
244
245 g_signal_connect_swapped (
246 priv->ui_manager, "connect-proxy",
247 G_CALLBACK (shell_window_connect_proxy_cb), shell_window);
248 }
249
250 void
251 e_shell_window_private_constructed (EShellWindow *shell_window)
252 {
253 EShellWindowPrivate *priv = shell_window->priv;
254 EShell *shell;
255 GtkAction *action;
256 GtkAccelGroup *accel_group;
257 GtkUIManager *ui_manager;
258 GtkBox *box;
259 GtkPaned *paned;
260 GtkWidget *widget;
261 GtkWindow *window;
262 guint merge_id;
263 const gchar *id;
264
265 #ifndef G_OS_WIN32
266 GSettings *settings;
267 GtkActionGroup *action_group;
268 #endif
269
270 window = GTK_WINDOW (shell_window);
271
272 shell = e_shell_window_get_shell (shell_window);
273
274 ui_manager = e_shell_window_get_ui_manager (shell_window);
275 e_shell_configure_ui_manager (shell, E_UI_MANAGER (ui_manager));
276
277 /* Defer actions and menu merging until we have set express mode */
278
279 e_shell_window_actions_init (shell_window);
280
281 accel_group = gtk_ui_manager_get_accel_group (ui_manager);
282 gtk_window_add_accel_group (GTK_WINDOW (shell_window), accel_group);
283
284 merge_id = gtk_ui_manager_new_merge_id (ui_manager);
285 priv->custom_rule_merge_id = merge_id;
286
287 merge_id = gtk_ui_manager_new_merge_id (ui_manager);
288 priv->gal_view_merge_id = merge_id;
289
290 /* Construct window widgets. */
291
292 widget = gtk_vbox_new (FALSE, 0);
293 gtk_container_add (GTK_CONTAINER (shell_window), widget);
294 gtk_widget_show (widget);
295
296 box = GTK_BOX (widget);
297
298 widget = shell_window_construct_menubar (shell_window);
299 if (widget != NULL)
300 gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
301
302 widget = shell_window_construct_toolbar (shell_window);
303 if (widget != NULL)
304 gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
305
306 widget = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
307 gtk_box_pack_start (box, widget, TRUE, TRUE, 0);
308 priv->content_pane = g_object_ref (widget);
309 gtk_widget_show (widget);
310
311 widget = shell_window_construct_taskbar (shell_window);
312 if (widget != NULL)
313 gtk_box_pack_start (box, widget, FALSE, FALSE, 0);
314
315 paned = GTK_PANED (priv->content_pane);
316
317 widget = shell_window_construct_sidebar (shell_window);
318 if (widget != NULL)
319 gtk_paned_pack1 (paned, widget, FALSE, FALSE);
320
321 widget = shell_window_construct_content (shell_window);
322 if (widget != NULL)
323 gtk_paned_pack2 (paned, widget, TRUE, FALSE);
324
325 /* Create the switcher actions before we set the initial
326 * shell view, because the shell view relies on them for
327 * default settings during construction. */
328 e_shell_window_create_switcher_actions (shell_window);
329
330 /* Bunch of chores to do when the active view changes. */
331
332 g_signal_connect (
333 shell_window, "notify::active-view",
334 G_CALLBACK (e_shell_window_update_icon), NULL);
335
336 g_signal_connect (
337 shell_window, "notify::active-view",
338 G_CALLBACK (e_shell_window_update_title), NULL);
339
340 g_signal_connect (
341 shell_window, "notify::active-view",
342 G_CALLBACK (e_shell_window_update_view_menu), NULL);
343
344 g_signal_connect (
345 shell_window, "notify::active-view",
346 G_CALLBACK (e_shell_window_update_search_menu), NULL);
347
348 #ifndef G_OS_WIN32
349 /* Support lockdown. */
350
351 settings = g_settings_new ("org.gnome.desktop.lockdown");
352
353 action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
354
355 g_settings_bind (
356 settings, "disable-printing",
357 action_group, "visible",
358 G_SETTINGS_BIND_GET |
359 G_SETTINGS_BIND_INVERT_BOOLEAN);
360
361 action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
362
363 g_settings_bind (
364 settings, "disable-print-setup",
365 action_group, "visible",
366 G_SETTINGS_BIND_GET |
367 G_SETTINGS_BIND_INVERT_BOOLEAN);
368
369 action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK);
370
371 g_settings_bind (
372 settings, "disable-save-to-disk",
373 action_group, "visible",
374 G_SETTINGS_BIND_GET |
375 G_SETTINGS_BIND_INVERT_BOOLEAN);
376
377 g_object_unref (settings);
378 #endif /* G_OS_WIN32 */
379
380 /* Bind GObject properties to GObject properties. */
381
382 action = ACTION (WORK_OFFLINE);
383
384 g_object_bind_property (
385 shell, "online",
386 action, "visible",
387 G_BINDING_SYNC_CREATE);
388
389 g_object_bind_property (
390 shell, "network-available",
391 action, "sensitive",
392 G_BINDING_SYNC_CREATE);
393
394 action = ACTION (WORK_ONLINE);
395
396 g_object_bind_property (
397 shell, "online",
398 action, "visible",
399 G_BINDING_SYNC_CREATE |
400 G_BINDING_INVERT_BOOLEAN);
401
402 g_object_bind_property (
403 shell, "network-available",
404 action, "sensitive",
405 G_BINDING_SYNC_CREATE);
406
407 /* Bind GObject properties to GSettings keys. */
408
409 settings = g_settings_new ("org.gnome.evolution.shell");
410
411 /* Use G_SETTINGS_BIND_GET_NO_CHANGES so shell windows
412 * are initialized to the most recently used shell view,
413 * but still allows different windows to show different
414 * views at once. */
415 g_settings_bind (
416 settings, "default-component-id",
417 shell_window, "active-view",
418 G_SETTINGS_BIND_DEFAULT |
419 G_SETTINGS_BIND_GET_NO_CHANGES);
420
421 g_settings_bind (
422 settings, "folder-bar-width",
423 priv->content_pane, "position",
424 G_SETTINGS_BIND_DEFAULT);
425
426 g_settings_bind (
427 settings, "sidebar-visible",
428 shell_window, "sidebar-visible",
429 G_SETTINGS_BIND_DEFAULT);
430
431 g_settings_bind (
432 settings, "statusbar-visible",
433 shell_window, "taskbar-visible",
434 G_SETTINGS_BIND_DEFAULT);
435
436 if (e_shell_get_express_mode (shell)) {
437 e_shell_window_set_switcher_visible (shell_window, FALSE);
438 } else {
439 g_settings_bind (
440 settings, "buttons-visible",
441 shell_window, "switcher-visible",
442 G_SETTINGS_BIND_DEFAULT);
443 }
444
445 g_settings_bind (
446 settings, "toolbar-visible",
447 shell_window, "toolbar-visible",
448 G_SETTINGS_BIND_DEFAULT);
449
450 /* Configure the initial size and position of the window by way
451 * of either a user-supplied geometry string or the last recorded
452 * values. Note that if a geometry string is applied, the window
453 * size and position are -not- recorded. */
454 if (priv->geometry != NULL) {
455 if (!gtk_window_parse_geometry (window, priv->geometry))
456 g_printerr (
457 "Failed to parse geometry '%s'\n",
458 priv->geometry);
459 g_free (priv->geometry);
460 priv->geometry = NULL;
461 } else {
462 gtk_window_set_default_size (window, 640, 480);
463 e_restore_window (
464 window, "/org/gnome/evolution/shell/window/",
465 E_RESTORE_WINDOW_SIZE | E_RESTORE_WINDOW_POSITION);
466 }
467
468 shell_window_init_switcher_style (shell_window);
469
470 id = "org.gnome.evolution.shell";
471 e_plugin_ui_register_manager (ui_manager, id, shell_window);
472 e_plugin_ui_enable_manager (ui_manager, id);
473
474 gtk_application_add_window (GTK_APPLICATION (shell), window);
475
476 g_object_unref (settings);
477 }
478
479 void
480 e_shell_window_private_dispose (EShellWindow *shell_window)
481 {
482 EShellWindowPrivate *priv = shell_window->priv;
483
484 /* Need to disconnect handlers before we unref the shell. */
485 if (priv->signal_handler_ids != NULL) {
486 GArray *array = priv->signal_handler_ids;
487 gulong handler_id;
488 guint ii;
489
490 for (ii = 0; ii < array->len; ii++) {
491 handler_id = g_array_index (array, gulong, ii);
492 g_signal_handler_disconnect (priv->shell, handler_id);
493 }
494
495 g_array_free (array, TRUE);
496 priv->signal_handler_ids = NULL;
497 }
498
499 if (priv->shell != NULL) {
500 g_object_remove_weak_pointer (
501 G_OBJECT (priv->shell), &priv->shell);
502 priv->shell = NULL;
503 }
504
505 DISPOSE (priv->focus_tracker);
506 DISPOSE (priv->ui_manager);
507
508 g_hash_table_remove_all (priv->loaded_views);
509
510 DISPOSE (priv->alert_bar);
511 DISPOSE (priv->content_pane);
512 DISPOSE (priv->content_notebook);
513 DISPOSE (priv->sidebar_notebook);
514 DISPOSE (priv->switcher);
515 DISPOSE (priv->tooltip_label);
516 DISPOSE (priv->status_notebook);
517
518 priv->destroyed = TRUE;
519 }
520
521 void
522 e_shell_window_private_finalize (EShellWindow *shell_window)
523 {
524 EShellWindowPrivate *priv = shell_window->priv;
525
526 g_hash_table_destroy (priv->loaded_views);
527
528 g_free (priv->geometry);
529 }
530
531 void
532 e_shell_window_switch_to_view (EShellWindow *shell_window,
533 const gchar *view_name)
534 {
535 EShellView *shell_view;
536
537 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
538 g_return_if_fail (view_name != NULL);
539
540 if (shell_window->priv->active_view == view_name)
541 return;
542
543 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
544
545 shell_window->priv->active_view = view_name;
546 g_object_notify (G_OBJECT (shell_window), "active-view");
547
548 e_shell_view_update_actions (shell_view);
549 }
550
551 void
552 e_shell_window_update_icon (EShellWindow *shell_window)
553 {
554 EShellView *shell_view;
555 GtkAction *action;
556 const gchar *view_name;
557 gchar *icon_name = NULL;
558
559 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
560
561 view_name = e_shell_window_get_active_view (shell_window);
562 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
563
564 action = e_shell_view_get_action (shell_view);
565 g_object_get (action, "icon-name", &icon_name, NULL);
566 gtk_window_set_icon_name (GTK_WINDOW (shell_window), icon_name);
567 g_free (icon_name);
568 }
569
570 void
571 e_shell_window_update_title (EShellWindow *shell_window)
572 {
573 EShellView *shell_view;
574 const gchar *view_title;
575 const gchar *view_name;
576 gchar *window_title;
577
578 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
579
580 view_name = e_shell_window_get_active_view (shell_window);
581 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
582 view_title = e_shell_view_get_title (shell_view);
583
584 /* Translators: This is used for the main window title. */
585 window_title = g_strdup_printf (_("%s - Evolution"), view_title);
586 gtk_window_set_title (GTK_WINDOW (shell_window), window_title);
587 g_free (window_title);
588 }