2 * e-shell-window-private.c
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, see <http://www.gnu.org/licenses/>.
17 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
25 #include "e-shell-window-private.h"
28 shell_window_save_switcher_style_cb (GtkRadioAction
*action
,
29 GtkRadioAction
*current
,
30 EShellWindow
*shell_window
)
33 GtkToolbarStyle style
;
36 settings
= e_util_ref_settings ("org.gnome.evolution.shell");
38 style
= gtk_radio_action_get_current_value (action
);
41 case GTK_TOOLBAR_ICONS
:
45 case GTK_TOOLBAR_TEXT
:
49 case GTK_TOOLBAR_BOTH
:
50 case GTK_TOOLBAR_BOTH_HORIZ
:
59 g_settings_set_string (settings
, "buttons-style", string
);
60 g_object_unref (settings
);
64 shell_window_init_switcher_style (EShellWindow
*shell_window
)
68 GtkToolbarStyle style
;
71 settings
= e_util_ref_settings ("org.gnome.evolution.shell");
73 action
= ACTION (SWITCHER_STYLE_ICONS
);
74 string
= g_settings_get_string (settings
, "buttons-style");
75 g_object_unref (settings
);
78 if (strcmp (string
, "icons") == 0)
79 style
= GTK_TOOLBAR_ICONS
;
80 else if (strcmp (string
, "text") == 0)
81 style
= GTK_TOOLBAR_TEXT
;
82 else if (strcmp (string
, "both") == 0)
83 style
= GTK_TOOLBAR_BOTH_HORIZ
;
87 gtk_radio_action_set_current_value (
88 GTK_RADIO_ACTION (action
), style
);
95 G_CALLBACK (shell_window_save_switcher_style_cb
),
100 shell_window_menu_item_select_cb (EShellWindow
*shell_window
,
104 GtkActivatable
*activatable
;
106 const gchar
*tooltip
;
108 activatable
= GTK_ACTIVATABLE (widget
);
109 action
= gtk_activatable_get_related_action (activatable
);
110 tooltip
= gtk_action_get_tooltip (action
);
115 label
= GTK_LABEL (shell_window
->priv
->tooltip_label
);
116 gtk_label_set_text (label
, tooltip
);
118 gtk_widget_show (shell_window
->priv
->tooltip_label
);
119 gtk_widget_hide (shell_window
->priv
->status_notebook
);
123 shell_window_menu_item_deselect_cb (EShellWindow
*shell_window
)
125 gtk_widget_hide (shell_window
->priv
->tooltip_label
);
126 gtk_widget_show (shell_window
->priv
->status_notebook
);
130 shell_window_connect_proxy_cb (EShellWindow
*shell_window
,
134 if (!GTK_IS_MENU_ITEM (proxy
))
137 g_signal_connect_swapped (
139 G_CALLBACK (shell_window_menu_item_select_cb
),
142 g_signal_connect_swapped (
144 G_CALLBACK (shell_window_menu_item_deselect_cb
),
149 shell_window_construct_menubar (EShellWindow
*shell_window
)
151 EShellWindowClass
*class;
153 class = E_SHELL_WINDOW_GET_CLASS (shell_window
);
154 if (class->construct_menubar
== NULL
)
157 return class->construct_menubar (shell_window
);
161 shell_window_construct_toolbar (EShellWindow
*shell_window
)
163 EShellWindowClass
*class;
165 class = E_SHELL_WINDOW_GET_CLASS (shell_window
);
166 if (class->construct_toolbar
== NULL
)
169 return class->construct_toolbar (shell_window
);
173 shell_window_construct_sidebar (EShellWindow
*shell_window
)
175 EShellWindowClass
*class;
177 class = E_SHELL_WINDOW_GET_CLASS (shell_window
);
178 if (class->construct_sidebar
== NULL
)
181 return class->construct_sidebar (shell_window
);
185 shell_window_construct_content (EShellWindow
*shell_window
)
187 EShellWindowClass
*class;
189 class = E_SHELL_WINDOW_GET_CLASS (shell_window
);
190 if (class->construct_content
== NULL
)
193 return class->construct_content (shell_window
);
197 shell_window_construct_taskbar (EShellWindow
*shell_window
)
199 EShellWindowClass
*class;
201 class = E_SHELL_WINDOW_GET_CLASS (shell_window
);
202 if (class->construct_taskbar
== NULL
)
205 return class->construct_taskbar (shell_window
);
209 e_shell_window_private_init (EShellWindow
*shell_window
)
211 EShellWindowPrivate
*priv
= shell_window
->priv
;
212 GHashTable
*loaded_views
;
213 GArray
*signal_handler_ids
;
215 loaded_views
= g_hash_table_new_full (
216 g_str_hash
, g_str_equal
,
217 (GDestroyNotify
) g_free
,
218 (GDestroyNotify
) g_object_unref
);
220 signal_handler_ids
= g_array_new (FALSE
, FALSE
, sizeof (gulong
));
222 priv
->ui_manager
= gtk_ui_manager_new ();
223 priv
->loaded_views
= loaded_views
;
224 priv
->signal_handler_ids
= signal_handler_ids
;
226 /* XXX This kind of violates the shell window being unaware
227 * of specific shell views, but we need a sane fallback. */
228 priv
->active_view
= "mail";
230 e_shell_window_add_action_group (shell_window
, "shell");
231 e_shell_window_add_action_group (shell_window
, "gal-view");
232 e_shell_window_add_action_group (shell_window
, "new-item");
233 e_shell_window_add_action_group (shell_window
, "new-source");
234 e_shell_window_add_action_group (shell_window
, "custom-rules");
235 e_shell_window_add_action_group (shell_window
, "switcher");
236 e_shell_window_add_action_group (shell_window
, "new-window");
237 e_shell_window_add_action_group (shell_window
, "lockdown-application-handlers");
238 e_shell_window_add_action_group (shell_window
, "lockdown-printing");
239 e_shell_window_add_action_group (shell_window
, "lockdown-print-setup");
240 e_shell_window_add_action_group (shell_window
, "lockdown-save-to-disk");
242 gtk_window_set_title (GTK_WINDOW (shell_window
), _("Evolution"));
244 g_signal_connect_swapped (
245 priv
->ui_manager
, "connect-proxy",
246 G_CALLBACK (shell_window_connect_proxy_cb
), shell_window
);
250 shell_window_check_is_main_instance (GtkApplication
*application
,
253 GList
*windows
, *link
;
255 g_return_val_if_fail (GTK_IS_APPLICATION (application
), FALSE
);
256 g_return_val_if_fail (GTK_IS_WINDOW (window
), FALSE
);
258 windows
= gtk_application_get_windows (application
);
259 for (link
= windows
; link
; link
= g_list_next (link
)) {
260 GtkWindow
*wnd
= link
->data
;
262 if (E_IS_SHELL_WINDOW (wnd
) && wnd
!= window
)
270 e_shell_window_private_constructed (EShellWindow
*shell_window
)
272 EShellWindowPrivate
*priv
= shell_window
->priv
;
275 GtkAccelGroup
*accel_group
;
276 GtkUIManager
*ui_manager
;
286 GtkActionGroup
*action_group
;
289 window
= GTK_WINDOW (shell_window
);
291 shell
= e_shell_window_get_shell (shell_window
);
292 shell_window
->priv
->is_main_instance
= shell_window_check_is_main_instance (GTK_APPLICATION (shell
), window
);
294 ui_manager
= e_shell_window_get_ui_manager (shell_window
);
296 /* Defer actions and menu merging until we have set express mode */
298 e_shell_window_actions_init (shell_window
);
300 accel_group
= gtk_ui_manager_get_accel_group (ui_manager
);
301 gtk_window_add_accel_group (GTK_WINDOW (shell_window
), accel_group
);
303 merge_id
= gtk_ui_manager_new_merge_id (ui_manager
);
304 priv
->custom_rule_merge_id
= merge_id
;
306 merge_id
= gtk_ui_manager_new_merge_id (ui_manager
);
307 priv
->gal_view_merge_id
= merge_id
;
309 /* Construct window widgets. */
311 widget
= gtk_box_new (GTK_ORIENTATION_VERTICAL
, 0);
312 gtk_container_add (GTK_CONTAINER (shell_window
), widget
);
313 gtk_widget_show (widget
);
315 box
= GTK_BOX (widget
);
317 widget
= shell_window_construct_menubar (shell_window
);
319 gtk_box_pack_start (box
, widget
, FALSE
, FALSE
, 0);
321 widget
= shell_window_construct_toolbar (shell_window
);
323 gtk_box_pack_start (box
, widget
, FALSE
, FALSE
, 0);
325 widget
= gtk_paned_new (GTK_ORIENTATION_HORIZONTAL
);
326 gtk_box_pack_start (box
, widget
, TRUE
, TRUE
, 0);
327 priv
->content_pane
= g_object_ref (widget
);
328 gtk_widget_show (widget
);
330 widget
= shell_window_construct_taskbar (shell_window
);
332 gtk_box_pack_start (box
, widget
, FALSE
, FALSE
, 0);
334 paned
= GTK_PANED (priv
->content_pane
);
336 widget
= shell_window_construct_sidebar (shell_window
);
338 gtk_paned_pack1 (paned
, widget
, FALSE
, FALSE
);
340 widget
= shell_window_construct_content (shell_window
);
342 gtk_paned_pack2 (paned
, widget
, TRUE
, FALSE
);
344 /* Create the switcher actions before we set the initial
345 * shell view, because the shell view relies on them for
346 * default settings during construction. */
347 e_shell_window_create_switcher_actions (shell_window
);
349 /* Bunch of chores to do when the active view changes. */
351 e_signal_connect_notify (
352 shell_window
, "notify::active-view",
353 G_CALLBACK (e_shell_window_update_icon
), NULL
);
355 e_signal_connect_notify (
356 shell_window
, "notify::active-view",
357 G_CALLBACK (e_shell_window_update_title
), NULL
);
359 e_signal_connect_notify (
360 shell_window
, "notify::active-view",
361 G_CALLBACK (e_shell_window_update_view_menu
), NULL
);
363 e_signal_connect_notify (
364 shell_window
, "notify::active-view",
365 G_CALLBACK (e_shell_window_update_search_menu
), NULL
);
368 /* Support lockdown. */
370 settings
= e_util_ref_settings ("org.gnome.desktop.lockdown");
372 action_group
= ACTION_GROUP (LOCKDOWN_PRINTING
);
375 settings
, "disable-printing",
376 action_group
, "visible",
377 G_SETTINGS_BIND_GET
|
378 G_SETTINGS_BIND_INVERT_BOOLEAN
);
380 action_group
= ACTION_GROUP (LOCKDOWN_PRINT_SETUP
);
383 settings
, "disable-print-setup",
384 action_group
, "visible",
385 G_SETTINGS_BIND_GET
|
386 G_SETTINGS_BIND_INVERT_BOOLEAN
);
388 action_group
= ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK
);
391 settings
, "disable-save-to-disk",
392 action_group
, "visible",
393 G_SETTINGS_BIND_GET
|
394 G_SETTINGS_BIND_INVERT_BOOLEAN
);
396 g_object_unref (settings
);
397 #endif /* G_OS_WIN32 */
399 /* Bind GObject properties to GObject properties. */
401 action
= ACTION (WORK_OFFLINE
);
403 e_binding_bind_property (
406 G_BINDING_SYNC_CREATE
);
408 e_binding_bind_property (
409 shell
, "network-available",
411 G_BINDING_SYNC_CREATE
);
413 action
= ACTION (WORK_ONLINE
);
415 e_binding_bind_property (
418 G_BINDING_SYNC_CREATE
|
419 G_BINDING_INVERT_BOOLEAN
);
421 e_binding_bind_property (
422 shell
, "network-available",
424 G_BINDING_SYNC_CREATE
);
426 /* Bind GObject properties to GSettings keys. */
428 settings
= e_util_ref_settings ("org.gnome.evolution.shell");
430 /* Use G_SETTINGS_BIND_GET_NO_CHANGES so shell windows
431 * are initialized to the most recently used shell view,
432 * but still allows different windows to show different
435 settings
, "default-component-id",
436 shell_window
, "active-view",
437 G_SETTINGS_BIND_DEFAULT
|
438 G_SETTINGS_BIND_GET_NO_CHANGES
);
440 if (e_shell_window_is_main_instance (shell_window
)) {
442 settings
, "folder-bar-width",
443 priv
->content_pane
, "position",
444 G_SETTINGS_BIND_DEFAULT
);
447 settings
, "sidebar-visible",
448 shell_window
, "sidebar-visible",
449 G_SETTINGS_BIND_DEFAULT
);
452 settings
, "statusbar-visible",
453 shell_window
, "taskbar-visible",
454 G_SETTINGS_BIND_DEFAULT
);
457 settings
, "buttons-visible",
458 shell_window
, "switcher-visible",
459 G_SETTINGS_BIND_DEFAULT
);
462 settings
, "toolbar-visible",
463 shell_window
, "toolbar-visible",
464 G_SETTINGS_BIND_DEFAULT
);
467 settings
, "folder-bar-width-sub",
468 priv
->content_pane
, "position",
469 G_SETTINGS_BIND_DEFAULT
|
470 G_SETTINGS_BIND_GET_NO_CHANGES
);
473 settings
, "sidebar-visible-sub",
474 shell_window
, "sidebar-visible",
475 G_SETTINGS_BIND_DEFAULT
|
476 G_SETTINGS_BIND_GET_NO_CHANGES
);
479 settings
, "statusbar-visible-sub",
480 shell_window
, "taskbar-visible",
481 G_SETTINGS_BIND_DEFAULT
|
482 G_SETTINGS_BIND_GET_NO_CHANGES
);
485 settings
, "buttons-visible-sub",
486 shell_window
, "switcher-visible",
487 G_SETTINGS_BIND_DEFAULT
|
488 G_SETTINGS_BIND_GET_NO_CHANGES
);
491 settings
, "toolbar-visible-sub",
492 shell_window
, "toolbar-visible",
493 G_SETTINGS_BIND_DEFAULT
|
494 G_SETTINGS_BIND_GET_NO_CHANGES
);
497 /* Configure the initial size and position of the window by way
498 * of either a user-supplied geometry string or the last recorded
499 * values. Note that if a geometry string is applied, the window
500 * size and position are -not- recorded. */
501 if (priv
->geometry
!= NULL
) {
502 if (!gtk_window_parse_geometry (window
, priv
->geometry
))
504 "Failed to parse geometry '%s'\n",
506 g_free (priv
->geometry
);
507 priv
->geometry
= NULL
;
509 gtk_window_set_default_size (window
, 640, 480);
511 window
, "/org/gnome/evolution/shell/window/",
512 E_RESTORE_WINDOW_SIZE
| E_RESTORE_WINDOW_POSITION
);
515 shell_window_init_switcher_style (shell_window
);
517 id
= "org.gnome.evolution.shell";
518 e_plugin_ui_register_manager (ui_manager
, id
, shell_window
);
519 e_plugin_ui_enable_manager (ui_manager
, id
);
521 gtk_application_add_window (GTK_APPLICATION (shell
), window
);
523 g_object_unref (settings
);
527 e_shell_window_private_dispose (EShellWindow
*shell_window
)
529 EShellWindowPrivate
*priv
= shell_window
->priv
;
531 /* Need to disconnect handlers before we unref the shell. */
532 if (priv
->signal_handler_ids
!= NULL
) {
533 GArray
*array
= priv
->signal_handler_ids
;
537 for (ii
= 0; ii
< array
->len
; ii
++) {
538 handler_id
= g_array_index (array
, gulong
, ii
);
539 g_signal_handler_disconnect (priv
->shell
, handler_id
);
542 g_array_free (array
, TRUE
);
543 priv
->signal_handler_ids
= NULL
;
546 if (priv
->shell
!= NULL
) {
547 g_object_remove_weak_pointer (
548 G_OBJECT (priv
->shell
), &priv
->shell
);
552 g_clear_object (&priv
->focus_tracker
);
553 g_clear_object (&priv
->ui_manager
);
555 g_hash_table_remove_all (priv
->loaded_views
);
557 g_clear_object (&priv
->alert_bar
);
558 g_clear_object (&priv
->content_pane
);
559 g_clear_object (&priv
->content_notebook
);
560 g_clear_object (&priv
->sidebar_notebook
);
561 g_clear_object (&priv
->switcher
);
562 g_clear_object (&priv
->tooltip_label
);
563 g_clear_object (&priv
->status_notebook
);
565 priv
->destroyed
= TRUE
;
569 e_shell_window_private_finalize (EShellWindow
*shell_window
)
571 EShellWindowPrivate
*priv
= shell_window
->priv
;
573 g_hash_table_destroy (priv
->loaded_views
);
575 g_free (priv
->geometry
);
579 e_shell_window_switch_to_view (EShellWindow
*shell_window
,
580 const gchar
*view_name
)
582 EShellView
*shell_view
;
584 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window
));
585 g_return_if_fail (view_name
!= NULL
);
587 if (shell_window
->priv
->active_view
== view_name
)
590 shell_view
= e_shell_window_get_shell_view (shell_window
, view_name
);
592 shell_window
->priv
->active_view
= view_name
;
593 g_object_notify (G_OBJECT (shell_window
), "active-view");
595 e_shell_view_update_actions (shell_view
);
599 e_shell_window_update_icon (EShellWindow
*shell_window
)
601 EShellView
*shell_view
;
603 const gchar
*view_name
;
604 gchar
*icon_name
= NULL
;
606 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window
));
608 view_name
= e_shell_window_get_active_view (shell_window
);
609 shell_view
= e_shell_window_get_shell_view (shell_window
, view_name
);
611 action
= e_shell_view_get_action (shell_view
);
612 g_object_get (action
, "icon-name", &icon_name
, NULL
);
613 gtk_window_set_icon_name (GTK_WINDOW (shell_window
), icon_name
);
618 e_shell_window_update_title (EShellWindow
*shell_window
)
620 EShellView
*shell_view
;
621 const gchar
*view_title
;
622 const gchar
*view_name
;
625 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window
));
627 view_name
= e_shell_window_get_active_view (shell_window
);
628 shell_view
= e_shell_window_get_shell_view (shell_window
, view_name
);
629 view_title
= e_shell_view_get_title (shell_view
);
631 /* Translators: This is used for the main window title. */
632 window_title
= g_strdup_printf (_("%s - Evolution"), view_title
);
633 gtk_window_set_title (GTK_WINDOW (shell_window
), window_title
);
634 g_free (window_title
);