evolution-3.6.4/shell/e-shell-window-private.c

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 }