No issues found
1 /*
2 * e-shell-window.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 /**
23 * SECTION: e-shell-window
24 * @short_description: the main window
25 * @include: shell/e-shell-window.h
26 **/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include "e-shell-window-private.h"
33
34 enum {
35 PROP_0,
36 PROP_ACTIVE_VIEW,
37 PROP_ALERT_BAR,
38 PROP_FOCUS_TRACKER,
39 PROP_GEOMETRY,
40 PROP_SAFE_MODE,
41 PROP_SHELL,
42 PROP_SIDEBAR_VISIBLE,
43 PROP_SWITCHER_VISIBLE,
44 PROP_TASKBAR_VISIBLE,
45 PROP_TOOLBAR_VISIBLE,
46 PROP_UI_MANAGER
47 };
48
49 enum {
50 SHELL_VIEW_CREATED,
51 LAST_SIGNAL
52 };
53
54 static gulong signals[LAST_SIGNAL];
55
56 /* Forward Declarations */
57 static void e_shell_window_alert_sink_init
58 (EAlertSinkInterface *interface);
59
60 G_DEFINE_TYPE_WITH_CODE (
61 EShellWindow,
62 e_shell_window,
63 GTK_TYPE_WINDOW,
64 G_IMPLEMENT_INTERFACE (
65 E_TYPE_ALERT_SINK, e_shell_window_alert_sink_init)
66 G_IMPLEMENT_INTERFACE (
67 E_TYPE_EXTENSIBLE, NULL))
68
69 static void
70 shell_window_menubar_update_new_menu (EShellWindow *shell_window)
71 {
72 GtkWidget *menu;
73 GtkWidget *widget;
74 const gchar *path;
75
76 /* Update the "File -> New" submenu. */
77 path = "/main-menu/file-menu/new-menu";
78 menu = e_shell_window_create_new_menu (shell_window);
79 widget = e_shell_window_get_managed_widget (shell_window, path);
80 gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
81 gtk_widget_show (widget);
82 }
83
84 static void shell_window_backend_prefer_item_changed_cb
85 (EShellBackend *backend,
86 GParamSpec *pspec,
87 EShellWindow *shell_window);
88
89 static void
90 shell_window_toolbar_update_new_menu (EShellWindow *shell_window,
91 GParamSpec *pspec,
92 GtkMenuToolButton *menu_tool_button)
93 {
94 GtkWidget *menu;
95
96 /* Update the "New" menu tool button submenu. */
97 menu = e_shell_window_create_new_menu (shell_window);
98 gtk_menu_tool_button_set_menu (menu_tool_button, menu);
99
100 if (pspec && g_strcmp0 (pspec->name, "active-view") == 0) {
101 EShellView *shell_view;
102 EShellBackend *shell_backend;
103
104 shell_view = e_shell_window_peek_shell_view (
105 shell_window,
106 e_shell_window_get_active_view (shell_window));
107 g_return_if_fail (shell_view != NULL);
108
109 shell_backend = e_shell_view_get_shell_backend (shell_view);
110
111 g_signal_handlers_disconnect_by_func (
112 shell_backend,
113 shell_window_backend_prefer_item_changed_cb,
114 shell_window);
115
116 g_signal_connect (
117 shell_backend, "notify::prefer-new-item",
118 G_CALLBACK (shell_window_backend_prefer_item_changed_cb),
119 shell_window);
120
121 shell_window_backend_prefer_item_changed_cb (
122 shell_backend, NULL, shell_window);
123 }
124 }
125
126 static void
127 shell_window_backend_prefer_item_changed_cb (EShellBackend *backend,
128 GParamSpec *pspec,
129 EShellWindow *shell_window)
130 {
131 EShellView *shell_view;
132 EShellBackend *shell_backend;
133
134 shell_view = e_shell_window_peek_shell_view (
135 shell_window,
136 e_shell_window_get_active_view (shell_window));
137 g_return_if_fail (shell_view != NULL);
138
139 shell_backend = e_shell_view_get_shell_backend (shell_view);
140 if (shell_backend != backend)
141 return;
142
143 e_shell_window_set_toolbar_new_prefer_item (
144 shell_window,
145 e_shell_backend_get_prefer_new_item (shell_backend));
146 }
147
148 static void
149 shell_window_set_notebook_page (EShellWindow *shell_window,
150 GParamSpec *pspec,
151 GtkNotebook *notebook)
152 {
153 EShellView *shell_view;
154 const gchar *view_name;
155 gint page_num;
156
157 view_name = e_shell_window_get_active_view (shell_window);
158 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
159
160 page_num = e_shell_view_get_page_num (shell_view);
161 g_return_if_fail (page_num >= 0);
162
163 gtk_notebook_set_current_page (notebook, page_num);
164 }
165
166 static void
167 shell_window_online_button_clicked_cb (EOnlineButton *button,
168 EShellWindow *shell_window)
169 {
170 if (e_online_button_get_online (button))
171 gtk_action_activate (ACTION (WORK_OFFLINE));
172 else
173 gtk_action_activate (ACTION (WORK_ONLINE));
174 }
175
176 static void
177 shell_window_update_close_action_cb (EShellWindow *shell_window)
178 {
179 EShell *shell;
180 GtkApplication *application;
181 GList *list;
182 gint n_shell_windows = 0;
183
184 shell = e_shell_window_get_shell (shell_window);
185
186 application = GTK_APPLICATION (shell);
187 list = gtk_application_get_windows (application);
188
189 /* Count the shell windows. */
190 while (list != NULL) {
191 if (E_IS_SHELL_WINDOW (list->data))
192 n_shell_windows++;
193 list = g_list_next (list);
194 }
195
196 /* Disable Close Window if there's only one shell window.
197 * Helps prevent users from accidentally quitting. */
198 gtk_action_set_sensitive (ACTION (CLOSE), n_shell_windows > 1);
199 }
200
201 static void
202 shell_window_set_geometry (EShellWindow *shell_window,
203 const gchar *geometry)
204 {
205 g_return_if_fail (shell_window->priv->geometry == NULL);
206
207 shell_window->priv->geometry = g_strdup (geometry);
208 }
209
210 static void
211 shell_window_set_shell (EShellWindow *shell_window,
212 EShell *shell)
213 {
214 GArray *array;
215 gulong handler_id;
216
217 g_return_if_fail (shell_window->priv->shell == NULL);
218
219 shell_window->priv->shell = shell;
220
221 g_object_add_weak_pointer (
222 G_OBJECT (shell), &shell_window->priv->shell);
223
224 /* Need to disconnect these when the window is closing. */
225
226 array = shell_window->priv->signal_handler_ids;
227
228 handler_id = g_signal_connect_swapped (
229 shell, "window-added",
230 G_CALLBACK (shell_window_update_close_action_cb),
231 shell_window);
232
233 g_array_append_val (array, handler_id);
234
235 handler_id = g_signal_connect_swapped (
236 shell, "window-removed",
237 G_CALLBACK (shell_window_update_close_action_cb),
238 shell_window);
239
240 g_array_append_val (array, handler_id);
241
242 g_object_notify (G_OBJECT (shell), "online");
243 }
244
245 static void
246 shell_window_set_property (GObject *object,
247 guint property_id,
248 const GValue *value,
249 GParamSpec *pspec)
250 {
251 switch (property_id) {
252 case PROP_ACTIVE_VIEW:
253 e_shell_window_set_active_view (
254 E_SHELL_WINDOW (object),
255 g_value_get_string (value));
256 return;
257
258 case PROP_GEOMETRY:
259 shell_window_set_geometry (
260 E_SHELL_WINDOW (object),
261 g_value_get_string (value));
262 return;
263
264 case PROP_SAFE_MODE:
265 e_shell_window_set_safe_mode (
266 E_SHELL_WINDOW (object),
267 g_value_get_boolean (value));
268 return;
269
270 case PROP_SHELL:
271 shell_window_set_shell (
272 E_SHELL_WINDOW (object),
273 g_value_get_object (value));
274 return;
275
276 case PROP_SIDEBAR_VISIBLE:
277 e_shell_window_set_sidebar_visible (
278 E_SHELL_WINDOW (object),
279 g_value_get_boolean (value));
280 return;
281
282 case PROP_SWITCHER_VISIBLE:
283 e_shell_window_set_switcher_visible (
284 E_SHELL_WINDOW (object),
285 g_value_get_boolean (value));
286 return;
287
288 case PROP_TASKBAR_VISIBLE:
289 e_shell_window_set_taskbar_visible (
290 E_SHELL_WINDOW (object),
291 g_value_get_boolean (value));
292 return;
293
294 case PROP_TOOLBAR_VISIBLE:
295 e_shell_window_set_toolbar_visible (
296 E_SHELL_WINDOW (object),
297 g_value_get_boolean (value));
298 return;
299 }
300
301 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
302 }
303
304 static void
305 shell_window_get_property (GObject *object,
306 guint property_id,
307 GValue *value,
308 GParamSpec *pspec)
309 {
310 switch (property_id) {
311 case PROP_ACTIVE_VIEW:
312 g_value_set_string (
313 value, e_shell_window_get_active_view (
314 E_SHELL_WINDOW (object)));
315 return;
316
317 case PROP_ALERT_BAR:
318 g_value_set_object (
319 value, e_shell_window_get_alert_bar (
320 E_SHELL_WINDOW (object)));
321 return;
322
323 case PROP_FOCUS_TRACKER:
324 g_value_set_object (
325 value, e_shell_window_get_focus_tracker (
326 E_SHELL_WINDOW (object)));
327 return;
328
329 case PROP_SAFE_MODE:
330 g_value_set_boolean (
331 value, e_shell_window_get_safe_mode (
332 E_SHELL_WINDOW (object)));
333 return;
334
335 case PROP_SHELL:
336 g_value_set_object (
337 value, e_shell_window_get_shell (
338 E_SHELL_WINDOW (object)));
339 return;
340
341 case PROP_SIDEBAR_VISIBLE:
342 g_value_set_boolean (
343 value, e_shell_window_get_sidebar_visible (
344 E_SHELL_WINDOW (object)));
345 return;
346
347 case PROP_SWITCHER_VISIBLE:
348 g_value_set_boolean (
349 value, e_shell_window_get_switcher_visible (
350 E_SHELL_WINDOW (object)));
351 return;
352
353 case PROP_TASKBAR_VISIBLE:
354 g_value_set_boolean (
355 value, e_shell_window_get_taskbar_visible (
356 E_SHELL_WINDOW (object)));
357 return;
358
359 case PROP_TOOLBAR_VISIBLE:
360 g_value_set_boolean (
361 value, e_shell_window_get_toolbar_visible (
362 E_SHELL_WINDOW (object)));
363 return;
364
365 case PROP_UI_MANAGER:
366 g_value_set_object (
367 value, e_shell_window_get_ui_manager (
368 E_SHELL_WINDOW (object)));
369 return;
370 }
371
372 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
373 }
374
375 static void
376 shell_window_dispose (GObject *object)
377 {
378 e_shell_window_private_dispose (E_SHELL_WINDOW (object));
379
380 /* Chain up to parent's dispose() method. */
381 G_OBJECT_CLASS (e_shell_window_parent_class)->dispose (object);
382 }
383
384 static void
385 shell_window_finalize (GObject *object)
386 {
387 e_shell_window_private_finalize (E_SHELL_WINDOW (object));
388
389 /* Chain up to parent's finalize() method. */
390 G_OBJECT_CLASS (e_shell_window_parent_class)->finalize (object);
391 }
392
393 static void
394 shell_window_constructed (GObject *object)
395 {
396 EShellWindow *shell_window = E_SHELL_WINDOW (object);
397
398 e_shell_window_private_constructed (shell_window);
399
400 e_extensible_load_extensions (E_EXTENSIBLE (object));
401
402 if (e_shell_get_meego_mode (shell_window->priv->shell) &&
403 e_shell_get_small_screen_mode (shell_window->priv->shell))
404 gtk_window_set_decorated (GTK_WINDOW (object), FALSE);
405
406 /* Chain up to parent's constructed() method. */
407 G_OBJECT_CLASS (e_shell_window_parent_class)->constructed (object);
408 }
409
410 static GtkWidget *
411 shell_window_construct_menubar (EShellWindow *shell_window)
412 {
413 GtkWidget *main_menu;
414
415 main_menu = e_shell_window_get_managed_widget (
416 shell_window, "/main-menu");
417 gtk_widget_show (main_menu);
418
419 if (e_shell_get_small_screen_mode (shell_window->priv->shell)) {
420 GtkWidget *parent, *child;
421
422 parent = gtk_widget_get_parent (main_menu);
423 g_object_ref (parent);
424 gtk_container_remove ((GtkContainer *) parent, main_menu);
425 child = gtk_hbox_new (FALSE, 0);
426 gtk_box_pack_start ((GtkBox *) child, main_menu, TRUE, TRUE, 0);
427 gtk_widget_show (child);
428 gtk_container_add ((GtkContainer *) parent, child);
429 shell_window->priv->menubar_box = child;
430
431 g_object_bind_property (
432 main_menu, "visible",
433 child, "visible",
434 G_BINDING_BIDIRECTIONAL |
435 G_BINDING_SYNC_CREATE);
436
437 main_menu = child;
438 }
439
440 g_signal_connect (
441 shell_window, "notify::active-view",
442 G_CALLBACK (shell_window_menubar_update_new_menu), NULL);
443
444 return main_menu;
445 }
446
447 GtkWidget *
448 e_shell_window_get_menu_bar_box (EShellWindow *shell_window)
449 {
450 return shell_window->priv->menubar_box;
451 }
452
453 static GtkWidget *
454 shell_window_construct_toolbar (EShellWindow *shell_window)
455 {
456 EShell *shell;
457 GtkUIManager *ui_manager;
458 GtkWidget *toolbar;
459 GtkWidget *box;
460 GtkToolItem *item;
461
462 shell = e_shell_window_get_shell (shell_window);
463 ui_manager = e_shell_window_get_ui_manager (shell_window);
464
465 box = gtk_hbox_new (FALSE, 0);
466 gtk_widget_show (box);
467
468 g_object_bind_property (
469 shell_window, "toolbar-visible",
470 box, "visible",
471 G_BINDING_SYNC_CREATE);
472
473 toolbar = e_shell_window_get_managed_widget (
474 shell_window, "/main-toolbar");
475
476 gtk_style_context_add_class (
477 gtk_widget_get_style_context (toolbar),
478 GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
479
480 if (e_shell_get_meego_mode (shell))
481 gtk_widget_set_name (GTK_WIDGET (toolbar), "MeeGoToolbar");
482
483 /* XXX Having this separator in the UI definition doesn't work
484 * because GtkUIManager is unaware of the "New" button, so
485 * it makes the separator invisible. One possibility is to
486 * define a GtkAction subclass for which create_tool_item()
487 * return an EMenuToolButton. Then both this separator
488 * and the "New" button could be added to the UI definition.
489 * Tempting, but the "New" button and its dynamically
490 * generated menu is already a complex beast, and I'm not
491 * convinced having it proxy some new type of GtkAction
492 * is worth the extra effort. */
493 item = gtk_separator_tool_item_new ();
494 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
495 gtk_widget_show (GTK_WIDGET (item));
496
497 item = e_menu_tool_button_new (_("New"));
498 gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
499 gtk_widget_add_accelerator (
500 GTK_WIDGET (item), "clicked",
501 gtk_ui_manager_get_accel_group (ui_manager),
502 GDK_KEY_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
503 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
504 gtk_widget_show (GTK_WIDGET (item));
505
506 g_signal_connect (
507 shell_window, "notify::active-view",
508 G_CALLBACK (shell_window_toolbar_update_new_menu),
509 GTK_MENU_TOOL_BUTTON (item));
510
511 g_signal_connect_swapped (
512 item, "notify::prefer-item",
513 G_CALLBACK (shell_window_toolbar_update_new_menu),
514 shell_window);
515
516 gtk_box_pack_start (GTK_BOX (box), toolbar, TRUE, TRUE, 0);
517
518 toolbar = e_shell_window_get_managed_widget (
519 shell_window, "/search-toolbar");
520 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
521 if (e_shell_get_express_mode (shell))
522 gtk_box_pack_start (GTK_BOX (box), toolbar, FALSE, FALSE, 0);
523 if (e_shell_get_meego_mode (shell))
524 gtk_widget_set_name (GTK_WIDGET (toolbar), "MeeGoToolbar");
525
526 toolbar = e_shell_window_get_managed_widget (
527 shell_window, "/close-toolbar");
528 gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE);
529 if (e_shell_get_meego_mode (shell))
530 gtk_box_pack_start (GTK_BOX (box), toolbar, FALSE, FALSE, 0);
531 if (e_shell_get_meego_mode (shell))
532 gtk_widget_set_name (GTK_WIDGET (toolbar), "MeeGoToolbar");
533
534 return box;
535 }
536
537 static GtkWidget *
538 shell_window_construct_sidebar (EShellWindow *shell_window)
539 {
540 GtkWidget *notebook;
541 GtkWidget *switcher;
542
543 switcher = e_shell_switcher_new ();
544 shell_window->priv->switcher = g_object_ref_sink (switcher);
545
546 g_object_bind_property (
547 shell_window, "sidebar-visible",
548 switcher, "visible",
549 G_BINDING_SYNC_CREATE);
550
551 g_object_bind_property (
552 shell_window, "switcher-visible",
553 switcher, "toolbar-visible",
554 G_BINDING_SYNC_CREATE);
555
556 notebook = gtk_notebook_new ();
557 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
558 gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
559 gtk_container_add (GTK_CONTAINER (switcher), notebook);
560 shell_window->priv->sidebar_notebook = g_object_ref (notebook);
561 gtk_widget_show (notebook);
562
563 g_signal_connect (
564 shell_window, "notify::active-view",
565 G_CALLBACK (shell_window_set_notebook_page), notebook);
566
567 return switcher;
568 }
569
570 static GtkWidget *
571 shell_window_construct_content (EShellWindow *shell_window)
572 {
573 GtkWidget *box;
574 GtkWidget *widget;
575
576 box = gtk_vbox_new (FALSE, 0);
577 gtk_widget_show (box);
578
579 widget = e_alert_bar_new ();
580 gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
581 shell_window->priv->alert_bar = g_object_ref (widget);
582 /* EAlertBar controls its own visibility. */
583
584 widget = gtk_notebook_new ();
585 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
586 gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
587 gtk_box_pack_start (GTK_BOX (box), widget, TRUE, TRUE, 0);
588 shell_window->priv->content_notebook = g_object_ref (widget);
589 gtk_widget_show (widget);
590
591 g_signal_connect (
592 shell_window, "notify::active-view",
593 G_CALLBACK (shell_window_set_notebook_page), widget);
594
595 return box;
596 }
597
598 static GtkWidget *
599 shell_window_construct_taskbar (EShellWindow *shell_window)
600 {
601 EShell *shell;
602 GtkWidget *notebook;
603 GtkWidget *status_area;
604 GtkWidget *online_button;
605 GtkWidget *tooltip_label;
606 gint height;
607
608 shell = e_shell_window_get_shell (shell_window);
609
610 status_area = gtk_hbox_new (FALSE, 3);
611 gtk_container_set_border_width (GTK_CONTAINER (status_area), 3);
612
613 g_object_bind_property (
614 shell_window, "taskbar-visible",
615 status_area, "visible",
616 G_BINDING_SYNC_CREATE);
617
618 /* Make the status area as large as the task bar. */
619 gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height);
620 gtk_widget_set_size_request (status_area, -1, (height * 2) + 6);
621
622 online_button = e_online_button_new ();
623 gtk_box_pack_start (
624 GTK_BOX (status_area), online_button, FALSE, TRUE, 0);
625 gtk_widget_show (online_button);
626
627 g_object_bind_property (
628 shell, "online",
629 online_button, "online",
630 G_BINDING_SYNC_CREATE);
631
632 g_object_bind_property (
633 shell, "network-available",
634 online_button, "sensitive",
635 G_BINDING_SYNC_CREATE);
636
637 g_signal_connect (
638 online_button, "clicked",
639 G_CALLBACK (shell_window_online_button_clicked_cb),
640 shell_window);
641
642 tooltip_label = gtk_label_new ("");
643 gtk_misc_set_alignment (GTK_MISC (tooltip_label), 0.0, 0.5);
644 gtk_box_pack_start (
645 GTK_BOX (status_area), tooltip_label, TRUE, TRUE, 0);
646 shell_window->priv->tooltip_label = g_object_ref (tooltip_label);
647 gtk_widget_hide (tooltip_label);
648
649 notebook = gtk_notebook_new ();
650 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (notebook), FALSE);
651 gtk_notebook_set_show_border (GTK_NOTEBOOK (notebook), FALSE);
652 gtk_box_pack_start (GTK_BOX (status_area), notebook, TRUE, TRUE, 0);
653 shell_window->priv->status_notebook = g_object_ref (notebook);
654 gtk_widget_show (notebook);
655
656 g_signal_connect (
657 shell_window, "notify::active-view",
658 G_CALLBACK (shell_window_set_notebook_page), notebook);
659
660 return status_area;
661 }
662
663 static EShellView *
664 shell_window_create_shell_view (EShellWindow *shell_window,
665 const gchar *view_name)
666 {
667 EShell *shell;
668 EShellView *shell_view;
669 EShellBackend *shell_backend;
670 GHashTable *loaded_views;
671 GtkUIManager *ui_manager;
672 GtkNotebook *notebook;
673 GtkAction *action;
674 GtkWidget *widget;
675 const gchar *name;
676 const gchar *id;
677 gint page_num;
678 GType type;
679
680 shell = e_shell_window_get_shell (shell_window);
681 shell_backend = e_shell_get_backend_by_name (shell, view_name);
682
683 if (shell_backend == NULL) {
684 g_critical ("Unknown shell view name: %s", view_name);
685 return NULL;
686 }
687
688 name = E_SHELL_BACKEND_GET_CLASS (shell_backend)->name;
689 type = E_SHELL_BACKEND_GET_CLASS (shell_backend)->shell_view_type;
690
691 /* First off, start the shell backend. */
692 e_shell_backend_start (shell_backend);
693
694 /* Determine the page number for the new shell view. */
695 notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
696 page_num = gtk_notebook_get_n_pages (notebook);
697
698 /* Get the switcher action for this view. */
699 action = e_shell_window_get_shell_view_action (shell_window, name);
700
701 /* Create the shell view. */
702 shell_view = g_object_new (
703 type, "action", action, "page-num", page_num,
704 "shell-window", shell_window, NULL);
705
706 /* Register the shell view. */
707 loaded_views = shell_window->priv->loaded_views;
708 g_hash_table_insert (loaded_views, g_strdup (name), shell_view);
709
710 /* Register the GtkUIManager ID for the shell view. */
711 id = E_SHELL_VIEW_GET_CLASS (shell_view)->ui_manager_id;
712 ui_manager = e_shell_window_get_ui_manager (shell_window);
713 e_plugin_ui_register_manager (ui_manager, id, shell_view);
714
715 /* Add pages to the various shell window notebooks. */
716
717 /* We can't determine the shell view's page number until after the
718 * shell view is fully initialized because the shell view may load
719 * other shell views during initialization, and those other shell
720 * views will append their widgets to the notebooks before us. */
721 page_num = gtk_notebook_get_n_pages (notebook);
722 e_shell_view_set_page_num (shell_view, page_num);
723
724 notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook);
725 widget = GTK_WIDGET (e_shell_view_get_shell_content (shell_view));
726 gtk_notebook_append_page (notebook, widget, NULL);
727
728 notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook);
729 widget = GTK_WIDGET (e_shell_view_get_shell_sidebar (shell_view));
730 gtk_notebook_append_page (notebook, widget, NULL);
731
732 notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook);
733 widget = GTK_WIDGET (e_shell_view_get_shell_taskbar (shell_view));
734 gtk_notebook_append_page (notebook, widget, NULL);
735
736 /* Listen for changes that affect the shell window. */
737
738 g_signal_connect_swapped (
739 action, "notify::icon-name",
740 G_CALLBACK (e_shell_window_update_icon), shell_window);
741
742 g_signal_connect_swapped (
743 shell_view, "notify::title",
744 G_CALLBACK (e_shell_window_update_title), shell_window);
745
746 g_signal_connect_swapped (
747 shell_view, "notify::view-id",
748 G_CALLBACK (e_shell_window_update_view_menu), shell_window);
749
750 return shell_view;
751 }
752
753 static void
754 shell_window_realize (GtkWidget *widget)
755 {
756 EShellWindow *shell_window;
757
758 shell_window = E_SHELL_WINDOW (widget);
759 e_shell_adapt_window_size (
760 shell_window->priv->shell,
761 GTK_WINDOW (widget));
762
763 /* Chain up to parent's dispose() method. */
764 GTK_WIDGET_CLASS (e_shell_window_parent_class)->realize (widget);
765 }
766
767 static void
768 shell_window_submit_alert (EAlertSink *alert_sink,
769 EAlert *alert)
770 {
771 EShellWindow *shell_window;
772 GtkWidget *alert_bar;
773 GtkWidget *dialog;
774
775 shell_window = E_SHELL_WINDOW (alert_sink);
776 alert_bar = e_shell_window_get_alert_bar (shell_window);
777
778 switch (e_alert_get_message_type (alert)) {
779 case GTK_MESSAGE_INFO:
780 case GTK_MESSAGE_WARNING:
781 case GTK_MESSAGE_ERROR:
782 e_alert_bar_add_alert (
783 E_ALERT_BAR (alert_bar), alert);
784 break;
785
786 default:
787 dialog = e_alert_dialog_new (
788 GTK_WINDOW (shell_window), alert);
789 gtk_dialog_run (GTK_DIALOG (dialog));
790 gtk_widget_destroy (dialog);
791 break;
792 }
793 }
794
795 static void
796 e_shell_window_class_init (EShellWindowClass *class)
797 {
798 GObjectClass *object_class;
799 GtkWidgetClass *widget_class;
800
801 g_type_class_add_private (class, sizeof (EShellWindowPrivate));
802
803 object_class = G_OBJECT_CLASS (class);
804 object_class->set_property = shell_window_set_property;
805 object_class->get_property = shell_window_get_property;
806 object_class->dispose = shell_window_dispose;
807 object_class->finalize = shell_window_finalize;
808 object_class->constructed = shell_window_constructed;
809
810 widget_class = GTK_WIDGET_CLASS (class);
811 widget_class->realize = shell_window_realize;
812
813 class->construct_menubar = shell_window_construct_menubar;
814 class->construct_toolbar = shell_window_construct_toolbar;
815 class->construct_sidebar = shell_window_construct_sidebar;
816 class->construct_content = shell_window_construct_content;
817 class->construct_taskbar = shell_window_construct_taskbar;
818 class->create_shell_view = shell_window_create_shell_view;
819
820 /**
821 * EShellWindow:active-view
822 *
823 * Name of the active #EShellView.
824 **/
825 g_object_class_install_property (
826 object_class,
827 PROP_ACTIVE_VIEW,
828 g_param_spec_string (
829 "active-view",
830 "Active Shell View",
831 "Name of the active shell view",
832 NULL,
833 G_PARAM_READWRITE));
834
835 /**
836 * EShellWindow:alert-bar
837 *
838 * Displays informational and error messages.
839 **/
840 g_object_class_install_property (
841 object_class,
842 PROP_ALERT_BAR,
843 g_param_spec_object (
844 "alert-bar",
845 "Alert Bar",
846 "Displays informational and error messages",
847 E_TYPE_ALERT_BAR,
848 G_PARAM_READABLE));
849
850 /**
851 * EShellWindow:focus-tracker
852 *
853 * The shell window's #EFocusTracker.
854 **/
855 g_object_class_install_property (
856 object_class,
857 PROP_FOCUS_TRACKER,
858 g_param_spec_object (
859 "focus-tracker",
860 "Focus Tracker",
861 "The shell window's EFocusTracker",
862 E_TYPE_FOCUS_TRACKER,
863 G_PARAM_READABLE));
864
865 /**
866 * EShellWindow:geometry
867 *
868 * User-specified initial window geometry string.
869 **/
870 g_object_class_install_property (
871 object_class,
872 PROP_GEOMETRY,
873 g_param_spec_string (
874 "geometry",
875 "Geometry",
876 "Initial window geometry string",
877 NULL,
878 G_PARAM_WRITABLE |
879 G_PARAM_CONSTRUCT_ONLY));
880
881 /**
882 * EShellWindow:safe-mode
883 *
884 * Whether the shell window is in safe mode.
885 **/
886 g_object_class_install_property (
887 object_class,
888 PROP_SAFE_MODE,
889 g_param_spec_boolean (
890 "safe-mode",
891 "Safe Mode",
892 "Whether the shell window is in safe mode",
893 FALSE,
894 G_PARAM_READWRITE |
895 G_PARAM_CONSTRUCT));
896
897 /**
898 * EShellWindow:shell
899 *
900 * The #EShell singleton.
901 **/
902 g_object_class_install_property (
903 object_class,
904 PROP_SHELL,
905 g_param_spec_object (
906 "shell",
907 "Shell",
908 "The EShell singleton",
909 E_TYPE_SHELL,
910 G_PARAM_READWRITE |
911 G_PARAM_CONSTRUCT_ONLY));
912
913 /**
914 * EShellWindow:sidebar-visible
915 *
916 * Whether the shell window's side bar is visible.
917 **/
918 g_object_class_install_property (
919 object_class,
920 PROP_SIDEBAR_VISIBLE,
921 g_param_spec_boolean (
922 "sidebar-visible",
923 "Sidebar Visible",
924 "Whether the shell window's side bar is visible",
925 TRUE,
926 G_PARAM_READWRITE));
927
928 /**
929 * EShellWindow:switcher-visible
930 *
931 * Whether the shell window's switcher buttons are visible.
932 **/
933 g_object_class_install_property (
934 object_class,
935 PROP_SWITCHER_VISIBLE,
936 g_param_spec_boolean (
937 "switcher-visible",
938 "Switcher Visible",
939 "Whether the shell window's "
940 "switcher buttons are visible",
941 TRUE,
942 G_PARAM_READWRITE));
943
944 /**
945 * EShellWindow:taskbar-visible
946 *
947 * Whether the shell window's task bar is visible.
948 **/
949 g_object_class_install_property (
950 object_class,
951 PROP_TASKBAR_VISIBLE,
952 g_param_spec_boolean (
953 "taskbar-visible",
954 "Taskbar Visible",
955 "Whether the shell window's task bar is visible",
956 TRUE,
957 G_PARAM_READWRITE));
958
959 /**
960 * EShellWindow:toolbar-visible
961 *
962 * Whether the shell window's tool bar is visible.
963 **/
964 g_object_class_install_property (
965 object_class,
966 PROP_TOOLBAR_VISIBLE,
967 g_param_spec_boolean (
968 "toolbar-visible",
969 "Toolbar Visible",
970 "Whether the shell window's tool bar is visible",
971 TRUE,
972 G_PARAM_READWRITE));
973
974 /**
975 * EShellWindow:ui-manager
976 *
977 * The shell window's #GtkUIManager.
978 **/
979 g_object_class_install_property (
980 object_class,
981 PROP_UI_MANAGER,
982 g_param_spec_object (
983 "ui-manager",
984 "UI Manager",
985 "The shell window's GtkUIManager",
986 GTK_TYPE_UI_MANAGER,
987 G_PARAM_READABLE));
988
989 /**
990 * EShellWindow::shell-view-created
991 * @shell_window: the #EShellWindow which emitted the signal
992 * @shell_view: the new #EShellView
993 *
994 * Emitted when a new #EShellView is instantiated by way of
995 * e_shell_window_get_shell_view(). The signal detail denotes
996 * the new view name, which can be used to obtain notification
997 * of when a particular #EShellView is created.
998 **/
999 signals[SHELL_VIEW_CREATED] = g_signal_new (
1000 "shell-view-created",
1001 G_OBJECT_CLASS_TYPE (object_class),
1002 G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
1003 G_STRUCT_OFFSET (EShellWindowClass, shell_view_created),
1004 NULL, NULL,
1005 g_cclosure_marshal_VOID__OBJECT,
1006 G_TYPE_NONE, 1,
1007 E_TYPE_SHELL_VIEW);
1008 }
1009
1010 static void
1011 e_shell_window_alert_sink_init (EAlertSinkInterface *interface)
1012 {
1013 interface->submit_alert = shell_window_submit_alert;
1014 }
1015
1016 static void
1017 e_shell_window_init (EShellWindow *shell_window)
1018 {
1019 shell_window->priv = E_SHELL_WINDOW_GET_PRIVATE (shell_window);
1020
1021 e_shell_window_private_init (shell_window);
1022 }
1023
1024 /**
1025 * e_shell_window_new:
1026 * @shell: an #EShell
1027 * @safe_mode: whether to initialize the window to "safe mode"
1028 * @geometry: initial window geometry string, or %NULL
1029 *
1030 * Returns a new #EShellWindow.
1031 *
1032 * It's up to the various #EShellView<!-- -->'s to define exactly
1033 * what "safe mode" means, but the #EShell usually puts the initial
1034 * #EShellWindow into "safe mode" if detects the previous Evolution
1035 * session crashed.
1036 *
1037 * The initial view for the window is determined by GSettings key
1038 * <filename>/org/gnome/evolution/shell/default-component-id</filename>.
1039 * Or, if the GSettings key is not set or can't be read, the first view
1040 * in the switcher is used.
1041 *
1042 * Returns: a new #EShellWindow
1043 **/
1044 GtkWidget *
1045 e_shell_window_new (EShell *shell,
1046 gboolean safe_mode,
1047 const gchar *geometry)
1048 {
1049 return g_object_new (
1050 E_TYPE_SHELL_WINDOW,
1051 "shell", shell, "geometry", geometry,
1052 "safe-mode", safe_mode, NULL);
1053 }
1054
1055 /**
1056 * e_shell_window_get_shell:
1057 * @shell_window: an #EShellWindow
1058 *
1059 * Returns the #EShell that was passed to e_shell_window_new().
1060 *
1061 * Returns: the #EShell
1062 **/
1063 EShell *
1064 e_shell_window_get_shell (EShellWindow *shell_window)
1065 {
1066 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1067
1068 return E_SHELL (shell_window->priv->shell);
1069 }
1070
1071 /**
1072 * e_shell_window_get_shell_view:
1073 * @shell_window: an #EShellWindow
1074 * @view_name: name of a shell view
1075 *
1076 * Returns the #EShellView named @view_name (see the
1077 * <structfield>name</structfield> field in #EShellBackendInfo). This
1078 * will also instantiate the #EShellView the first time it's requested.
1079 * To reduce resource consumption, Evolution tries to delay instantiating
1080 * shell views until the user switches to them. So in general, only the
1081 * active view name, as returned by e_shell_window_get_active_view(),
1082 * should be requested.
1083 *
1084 * The function emits a #EShellWindow::shell-view-created signal with
1085 * @view_name as the signal detail when it instantiates an #EShellView.
1086 *
1087 * Returns: the requested #EShellView, or %NULL if no such view is
1088 * registered
1089 **/
1090 EShellView *
1091 e_shell_window_get_shell_view (EShellWindow *shell_window,
1092 const gchar *view_name)
1093 {
1094 EShellView *shell_view;
1095 EShellWindowClass *class;
1096
1097 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1098 g_return_val_if_fail (view_name != NULL, NULL);
1099
1100 shell_view = e_shell_window_peek_shell_view (shell_window, view_name);
1101 if (shell_view != NULL)
1102 return shell_view;
1103
1104 class = E_SHELL_WINDOW_GET_CLASS (shell_window);
1105 g_return_val_if_fail (class->create_shell_view != NULL, NULL);
1106
1107 shell_view = class->create_shell_view (shell_window, view_name);
1108
1109 g_signal_emit (
1110 shell_window, signals[SHELL_VIEW_CREATED],
1111 g_quark_from_string (view_name), shell_view);
1112
1113 return shell_view;
1114 }
1115
1116 /**
1117 * e_shell_window_peek_shell_view:
1118 * @shell_window: an #EShellWindow
1119 * @view_name: name of a shell view
1120 *
1121 * Returns the #EShellView named @view_name (see the
1122 * <structfield>name</structfield> field in #EShellBackendInfo), or
1123 * %NULL if the requested view has not yet been instantiated. Unlike
1124 * e_shell_window_get_shell_view(), this function will not instantiate
1125 * the view itself.
1126 *
1127 * Returns: the requested #EShellView, or %NULL if no such view is
1128 * instantiated
1129 **/
1130 EShellView *
1131 e_shell_window_peek_shell_view (EShellWindow *shell_window,
1132 const gchar *view_name)
1133 {
1134 GHashTable *loaded_views;
1135
1136 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1137 g_return_val_if_fail (view_name != NULL, NULL);
1138
1139 loaded_views = shell_window->priv->loaded_views;
1140
1141 return g_hash_table_lookup (loaded_views, view_name);
1142 }
1143
1144 /**
1145 * e_shell_window_get_shell_view_action:
1146 * @shell_window: an #EShellWindow
1147 * @view_name: name of a shell view
1148 *
1149 * Returns the switcher action for @view_name.
1150 *
1151 * An #EShellWindow creates a #GtkRadioAction for each registered subclass
1152 * of #EShellView. This action gets passed to the #EShellSwitcher, which
1153 * displays a button that proxies the action. When the #EShellView named
1154 * @view_name is active, the action's icon becomes the @shell_window icon.
1155 *
1156 * Returns: the switcher action for the #EShellView named @view_name,
1157 * or %NULL if no such shell view exists
1158 **/
1159 GtkAction *
1160 e_shell_window_get_shell_view_action (EShellWindow *shell_window,
1161 const gchar *view_name)
1162 {
1163 GtkAction *action;
1164 gchar *action_name;
1165
1166 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1167 g_return_val_if_fail (view_name != NULL, NULL);
1168
1169 action_name = g_strdup_printf (E_SHELL_SWITCHER_FORMAT, view_name);
1170 action = e_shell_window_get_action (shell_window, action_name);
1171 g_free (action_name);
1172
1173 return action;
1174 }
1175
1176 /**
1177 * e_shell_window_get_alert_bar:
1178 * @shell_window: an #EShellWindow
1179 *
1180 * Returns the #EAlertBar used to display informational and error messages.
1181 *
1182 * Returns: the #EAlertBar for @shell_window
1183 **/
1184 GtkWidget *
1185 e_shell_window_get_alert_bar (EShellWindow *shell_window)
1186 {
1187 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1188
1189 return shell_window->priv->alert_bar;
1190 }
1191
1192 /**
1193 * e_shell_window_get_focus_tracker:
1194 * @shell_window: an #EShellWindow
1195 *
1196 * Returns @shell_window<!-- -->'s focus tracker, which directs
1197 * Cut, Copy, Paste and Select All main menu activations to the
1198 * appropriate editable or selectable widget.
1199 *
1200 * Returns: the #EFocusTracker for @shell_window
1201 **/
1202 EFocusTracker *
1203 e_shell_window_get_focus_tracker (EShellWindow *shell_window)
1204 {
1205 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1206
1207 return shell_window->priv->focus_tracker;
1208 }
1209
1210 /**
1211 * e_shell_window_get_ui_manager:
1212 * @shell_window: an #EShellWindow
1213 *
1214 * Returns @shell_window<!-- -->'s user interface manager, which
1215 * manages the window's menus and toolbars via #GtkAction<!-- -->s.
1216 * This is the mechanism by which shell views and plugins can extend
1217 * Evolution's menus and toolbars.
1218 *
1219 * Returns: the #GtkUIManager for @shell_window
1220 **/
1221 GtkUIManager *
1222 e_shell_window_get_ui_manager (EShellWindow *shell_window)
1223 {
1224 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1225
1226 return shell_window->priv->ui_manager;
1227 }
1228
1229 /**
1230 * e_shell_window_get_action:
1231 * @shell_window: an #EShellWindow
1232 * @action_name: the name of an action
1233 *
1234 * Returns the #GtkAction named @action_name in @shell_window<!-- -->'s
1235 * user interface manager, or %NULL if no such action exists.
1236 *
1237 * Returns: the #GtkAction named @action_name
1238 **/
1239 GtkAction *
1240 e_shell_window_get_action (EShellWindow *shell_window,
1241 const gchar *action_name)
1242 {
1243 GtkUIManager *ui_manager;
1244
1245 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1246 g_return_val_if_fail (action_name != NULL, NULL);
1247
1248 ui_manager = e_shell_window_get_ui_manager (shell_window);
1249
1250 return e_lookup_action (ui_manager, action_name);
1251 }
1252
1253 /**
1254 * e_shell_window_get_action_group:
1255 * @shell_window: an #EShellWindow
1256 * @group_name: the name of an action group
1257 *
1258 * Returns the #GtkActionGroup named @group_name in
1259 * @shell_window<!-- -->'s user interface manager, or %NULL if no
1260 * such action group exists.
1261 *
1262 * Returns: the #GtkActionGroup named @group_name
1263 **/
1264 GtkActionGroup *
1265 e_shell_window_get_action_group (EShellWindow *shell_window,
1266 const gchar *group_name)
1267 {
1268 GtkUIManager *ui_manager;
1269
1270 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1271 g_return_val_if_fail (group_name != NULL, NULL);
1272
1273 ui_manager = e_shell_window_get_ui_manager (shell_window);
1274
1275 return e_lookup_action_group (ui_manager, group_name);
1276 }
1277
1278 /**
1279 * e_shell_window_get_managed_widget:
1280 * @shell_window: an #EShellWindow
1281 * @widget_path: path in the UI definintion
1282 *
1283 * Looks up a widget in @shell_window<!-- -->'s user interface manager by
1284 * following a path. See gtk_ui_manager_get_widget() for more information
1285 * about paths.
1286 *
1287 * Returns: the widget found by following the path, or %NULL if no widget
1288 * was found
1289 **/
1290 GtkWidget *
1291 e_shell_window_get_managed_widget (EShellWindow *shell_window,
1292 const gchar *widget_path)
1293 {
1294 GtkUIManager *ui_manager;
1295 GtkWidget *widget;
1296
1297 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1298 g_return_val_if_fail (widget_path != NULL, NULL);
1299
1300 ui_manager = e_shell_window_get_ui_manager (shell_window);
1301 widget = gtk_ui_manager_get_widget (ui_manager, widget_path);
1302
1303 g_return_val_if_fail (widget != NULL, NULL);
1304
1305 return widget;
1306 }
1307
1308 /**
1309 * e_shell_window_get_active_view:
1310 * @shell_window: an #EShellWindow
1311 *
1312 * Returns the name of the active #EShellView.
1313 *
1314 * Returns: the name of the active view
1315 **/
1316 const gchar *
1317 e_shell_window_get_active_view (EShellWindow *shell_window)
1318 {
1319 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1320
1321 return shell_window->priv->active_view;
1322 }
1323
1324 /**
1325 * e_shell_window_set_active_view:
1326 * @shell_window: an #EShellWindow
1327 * @view_name: the name of the shell view to switch to
1328 *
1329 * Switches @shell_window to the #EShellView named @view_name, causing
1330 * the entire content of @shell_window to change. This is typically
1331 * called as a result of the user clicking one of the switcher buttons.
1332 *
1333 * The name of the newly activated shell view is also written to GSettings key
1334 * <filename>/org/gnome/evolution/shell/default-component-id</filename>.
1335 * This makes the active shell view persistent across Evolution sessions.
1336 * It also causes new shell windows created within the current Evolution
1337 * session to open to the most recently selected shell view.
1338 **/
1339 void
1340 e_shell_window_set_active_view (EShellWindow *shell_window,
1341 const gchar *view_name)
1342 {
1343 GtkAction *action;
1344 EShellView *shell_view;
1345
1346 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1347 g_return_if_fail (view_name != NULL);
1348
1349 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1350 g_return_if_fail (shell_view != NULL);
1351
1352 action = e_shell_view_get_action (shell_view);
1353 gtk_action_activate (action);
1354 }
1355
1356 /**
1357 * e_shell_window_get_safe_mode:
1358 * @shell_window: an #EShellWindow
1359 *
1360 * Returns %TRUE if @shell_window is in "safe mode".
1361 *
1362 * It's up to the various #EShellView<!-- -->'s to define exactly
1363 * what "safe mode" means. The @shell_window simply manages the
1364 * "safe mode" state.
1365 *
1366 * Returns: %TRUE if @shell_window is in "safe mode"
1367 **/
1368 gboolean
1369 e_shell_window_get_safe_mode (EShellWindow *shell_window)
1370 {
1371 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
1372
1373 return shell_window->priv->safe_mode;
1374 }
1375
1376 /**
1377 * e_shell_window_set_safe_mode:
1378 * @shell_window: an #EShellWindow
1379 * @safe_mode: whether to put @shell_window into "safe mode"
1380 *
1381 * If %TRUE, puts @shell_window into "safe mode".
1382 *
1383 * It's up to the various #EShellView<!-- -->'s to define exactly
1384 * what "safe mode" means. The @shell_window simply manages the
1385 * "safe mode" state.
1386 **/
1387 void
1388 e_shell_window_set_safe_mode (EShellWindow *shell_window,
1389 gboolean safe_mode)
1390 {
1391 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1392
1393 if (shell_window->priv->safe_mode == safe_mode)
1394 return;
1395
1396 shell_window->priv->safe_mode = safe_mode;
1397
1398 g_object_notify (G_OBJECT (shell_window), "safe-mode");
1399 }
1400
1401 /**
1402 * e_shell_window_add_action_group:
1403 * @shell_window: an #EShellWindow
1404 * @group_name: the name of the new action group
1405 *
1406 * Creates a new #GtkActionGroup and adds it to @shell_window<!-- -->'s
1407 * user interface manager. This also takes care of details like setting
1408 * the translation domain.
1409 **/
1410 void
1411 e_shell_window_add_action_group (EShellWindow *shell_window,
1412 const gchar *group_name)
1413 {
1414 GtkActionGroup *action_group;
1415 GtkUIManager *ui_manager;
1416 const gchar *domain;
1417
1418 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1419 g_return_if_fail (group_name != NULL);
1420
1421 ui_manager = e_shell_window_get_ui_manager (shell_window);
1422 domain = GETTEXT_PACKAGE;
1423
1424 action_group = gtk_action_group_new (group_name);
1425 gtk_action_group_set_translation_domain (action_group, domain);
1426 gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
1427 g_object_unref (action_group);
1428 }
1429
1430 /**
1431 * e_shell_window_get_sidebar_visible:
1432 * @shell_window: an #EShellWindow
1433 *
1434 * Returns %TRUE if @shell_window<!-- -->'s side bar is visible.
1435 *
1436 * Returns: %TRUE is the side bar is visible
1437 **/
1438 gboolean
1439 e_shell_window_get_sidebar_visible (EShellWindow *shell_window)
1440 {
1441 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
1442
1443 return shell_window->priv->sidebar_visible;
1444 }
1445
1446 /**
1447 * e_shell_window_set_sidebar_visible:
1448 * @shell_window: an #EShellWindow
1449 * @sidebar_visible: whether the side bar should be visible
1450 *
1451 * Makes @shell_window<!-- -->'s side bar visible or invisible.
1452 **/
1453 void
1454 e_shell_window_set_sidebar_visible (EShellWindow *shell_window,
1455 gboolean sidebar_visible)
1456 {
1457 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1458
1459 if (shell_window->priv->sidebar_visible == sidebar_visible)
1460 return;
1461
1462 shell_window->priv->sidebar_visible = sidebar_visible;
1463
1464 g_object_notify (G_OBJECT (shell_window), "sidebar-visible");
1465 }
1466
1467 /**
1468 * e_shell_window_get_switcher_visible:
1469 * @shell_window: an #EShellWindow
1470 *
1471 * Returns %TRUE if @shell_window<!-- -->'s switcher buttons are visible.
1472 *
1473 * Returns: %TRUE is the switcher buttons are visible
1474 **/
1475 gboolean
1476 e_shell_window_get_switcher_visible (EShellWindow *shell_window)
1477 {
1478 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
1479
1480 return shell_window->priv->switcher_visible;
1481 }
1482
1483 /**
1484 * e_shell_window_set_switcher_visible:
1485 * @shell_window: an #EShellWindow
1486 * @switcher_visible: whether the switcher buttons should be visible
1487 *
1488 * Makes @shell_window<!-- -->'s switcher buttons visible or invisible.
1489 **/
1490 void
1491 e_shell_window_set_switcher_visible (EShellWindow *shell_window,
1492 gboolean switcher_visible)
1493 {
1494 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1495
1496 if (shell_window->priv->switcher_visible == switcher_visible)
1497 return;
1498
1499 shell_window->priv->switcher_visible = switcher_visible;
1500
1501 g_object_notify (G_OBJECT (shell_window), "switcher-visible");
1502 }
1503
1504 /**
1505 * e_shell_window_get_taskbar_visible:
1506 * @shell_window: an #EShellWindow
1507 *
1508 * Returns %TRUE if @shell_window<!-- -->'s task bar is visible.
1509 *
1510 * Returns: %TRUE is the task bar is visible
1511 **/
1512 gboolean
1513 e_shell_window_get_taskbar_visible (EShellWindow *shell_window)
1514 {
1515 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
1516
1517 return shell_window->priv->taskbar_visible;
1518 }
1519
1520 /**
1521 * e_shell_window_set_taskbar_visible:
1522 * @shell_window: an #EShellWindow
1523 * @taskbar_visible: whether the task bar should be visible
1524 *
1525 * Makes @shell_window<!-- -->'s task bar visible or invisible.
1526 **/
1527 void
1528 e_shell_window_set_taskbar_visible (EShellWindow *shell_window,
1529 gboolean taskbar_visible)
1530 {
1531 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1532
1533 if (shell_window->priv->taskbar_visible == taskbar_visible)
1534 return;
1535
1536 shell_window->priv->taskbar_visible = taskbar_visible;
1537
1538 g_object_notify (G_OBJECT (shell_window), "taskbar-visible");
1539 }
1540
1541 /**
1542 * e_shell_window_get_toolbar_visible:
1543 * @shell_window: an #EShellWindow
1544 *
1545 * Returns %TRUE if @shell_window<!-- -->'s tool bar is visible.
1546 *
1547 * Returns: %TRUE if the tool bar is visible
1548 **/
1549 gboolean
1550 e_shell_window_get_toolbar_visible (EShellWindow *shell_window)
1551 {
1552 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), FALSE);
1553
1554 return shell_window->priv->toolbar_visible;
1555 }
1556
1557 /**
1558 * e_shell_window_set_toolbar_visible:
1559 * @shell_window: an #EShellWindow
1560 * @toolbar_visible: whether the tool bar should be visible
1561 *
1562 * Makes @shell_window<!-- -->'s tool bar visible or invisible.
1563 **/
1564 void
1565 e_shell_window_set_toolbar_visible (EShellWindow *shell_window,
1566 gboolean toolbar_visible)
1567 {
1568 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1569
1570 if (shell_window->priv->toolbar_visible == toolbar_visible)
1571 return;
1572
1573 shell_window->priv->toolbar_visible = toolbar_visible;
1574
1575 g_object_notify (G_OBJECT (shell_window), "toolbar-visible");
1576 }
1577
1578 /**
1579 * e_shell_window_set_toolbar_new_prefer_item:
1580 * @shell_window: an #EShellWindow
1581 * @prefer_item: prefer-item name to be set
1582 *
1583 * Sets prefer item on the New button for current view.
1584 *
1585 * Since: 3.4
1586 **/
1587 void
1588 e_shell_window_set_toolbar_new_prefer_item (EShellWindow *shell_window,
1589 const gchar *prefer_item)
1590 {
1591 GtkWidget *toolbar;
1592 GtkToolItem *item;
1593
1594 g_return_if_fail (shell_window != NULL);
1595 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1596
1597 toolbar = e_shell_window_get_managed_widget (shell_window, "/main-toolbar");
1598 g_return_if_fail (toolbar != NULL);
1599
1600 item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), 0);
1601 g_return_if_fail (item != NULL);
1602 g_return_if_fail (E_IS_MENU_TOOL_BUTTON (item));
1603
1604 e_menu_tool_button_set_prefer_item (E_MENU_TOOL_BUTTON (item), prefer_item);
1605 }
1606
1607 /**
1608 * e_shell_window_get_toolbar_new_prefer_item:
1609 * @shell_window: an #EShellWindow
1610 *
1611 * Returns: name of preferred item on the New button for current view.
1612 *
1613 * Since: 3.4
1614 **/
1615 const gchar *
1616 e_shell_window_get_toolbar_new_prefer_item (EShellWindow *shell_window)
1617 {
1618 GtkWidget *toolbar;
1619 GtkToolItem *item;
1620
1621 g_return_val_if_fail (shell_window != NULL, NULL);
1622 g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL);
1623
1624 toolbar = e_shell_window_get_managed_widget (shell_window, "/main-toolbar");
1625 g_return_val_if_fail (toolbar != NULL, NULL);
1626
1627 item = gtk_toolbar_get_nth_item (GTK_TOOLBAR (toolbar), 0);
1628 g_return_val_if_fail (item != NULL, NULL);
1629 g_return_val_if_fail (E_IS_MENU_TOOL_BUTTON (item), NULL);
1630
1631 return e_menu_tool_button_get_prefer_item (E_MENU_TOOL_BUTTON (item));
1632 }
1633
1634 /**
1635 * e_shell_window_register_new_item_actions:
1636 * @shell_window: an #EShellWindow
1637 * @backend_name: name of an #EShellBackend
1638 * @entries: an array of #GtkActionEntry<!-- -->s
1639 * @n_entries: number of elements in the array
1640 *
1641 * Registers a list of #GtkAction<!-- -->s to appear in
1642 * @shell_window<!-- -->'s "New" menu and toolbar button. This
1643 * function should be called from an #EShell<!-- -->'s
1644 * #GtkApplication::window-added signal handler. The #EShellBackend
1645 * calling this function should pass its own name for the @backend_name
1646 * argument (i.e. the <structfield>name</structfield> field from its own
1647 * #EShellBackendInfo).
1648 *
1649 * The registered #GtkAction<!-- -->s should be for creating individual
1650 * items such as an email message or a calendar appointment. The action
1651 * labels should be marked for translation with the "New" context using
1652 * the NC_() macro.
1653 **/
1654 void
1655 e_shell_window_register_new_item_actions (EShellWindow *shell_window,
1656 const gchar *backend_name,
1657 GtkActionEntry *entries,
1658 guint n_entries)
1659 {
1660 GtkActionGroup *action_group;
1661 GtkAccelGroup *accel_group;
1662 GtkUIManager *ui_manager;
1663 guint ii;
1664
1665 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1666 g_return_if_fail (backend_name != NULL);
1667 g_return_if_fail (entries != NULL);
1668
1669 action_group = ACTION_GROUP (NEW_ITEM);
1670 ui_manager = e_shell_window_get_ui_manager (shell_window);
1671 accel_group = gtk_ui_manager_get_accel_group (ui_manager);
1672 backend_name = g_intern_string (backend_name);
1673
1674 /* XXX The action label translations are retrieved from the
1675 * message context "New", but gtk_action_group_add_actions()
1676 * does not support message contexts. So we have to fetch
1677 * the label translations ourselves before adding them to
1678 * the action group.
1679 *
1680 * gtk_action_group_set_translate_func() does not help here
1681 * because the action tooltips do not use a message context
1682 * (though I suppose they could). */
1683 for (ii = 0; ii < n_entries; ii++)
1684 entries[ii].label = g_dpgettext2 (
1685 GETTEXT_PACKAGE, "New", entries[ii].label);
1686
1687 gtk_action_group_add_actions (
1688 action_group, entries, n_entries, shell_window);
1689
1690 /* Tag each action with the name of the shell backend that
1691 * registered it. This is used to help sort actions in the
1692 * "New" menu. */
1693
1694 for (ii = 0; ii < n_entries; ii++) {
1695 const gchar *action_name;
1696 GtkAction *action;
1697
1698 action_name = entries[ii].name;
1699
1700 action = gtk_action_group_get_action (
1701 action_group, action_name);
1702
1703 gtk_action_set_accel_group (action, accel_group);
1704
1705 g_object_set_data (
1706 G_OBJECT (action),
1707 "backend-name", (gpointer) backend_name);
1708
1709 /* The first action becomes the first item in the "New"
1710 * menu, and consequently its icon is shown in the "New"
1711 * button when the shell backend's view is active. This
1712 * is all sorted out in shell_window_extract_actions().
1713 * Note, the data value just needs to be non-zero. */
1714 if (ii == 0)
1715 g_object_set_data (
1716 G_OBJECT (action),
1717 "primary", GINT_TO_POINTER (TRUE));
1718 }
1719 }
1720
1721 /**
1722 * e_shell_window_register_new_source_actions:
1723 * @shell_window: an #EShellWindow
1724 * @backend_name: name of an #EShellBackend
1725 * @entries: an array of #GtkActionEntry<!-- -->s
1726 * @n_entries: number of elements in the array
1727 *
1728 * Registers a list of #GtkAction<!-- -->s to appear in
1729 * @shell_window<!-- -->'s "New" menu and toolbar button. This
1730 * function should be called from an #EShell<!-- -->'s
1731 * #GtkApplication::window-added signal handler. The #EShellBackend
1732 * calling this function should pass its own name for the @backend_name
1733 * argument (i.e. the <structfield>name</structfield> field from its own
1734 * #EShellBackendInfo).
1735 *
1736 * The registered #GtkAction<!-- -->s should be for creating item
1737 * containers such as an email folder or a calendar. The action labels
1738 * should be marked for translation with the "New" context using the
1739 * NC_() macro.
1740 **/
1741 void
1742 e_shell_window_register_new_source_actions (EShellWindow *shell_window,
1743 const gchar *backend_name,
1744 GtkActionEntry *entries,
1745 guint n_entries)
1746 {
1747 GtkActionGroup *action_group;
1748 GtkAccelGroup *accel_group;
1749 GtkUIManager *ui_manager;
1750 guint ii;
1751
1752 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1753 g_return_if_fail (backend_name != NULL);
1754 g_return_if_fail (entries != NULL);
1755
1756 action_group = ACTION_GROUP (NEW_SOURCE);
1757 ui_manager = e_shell_window_get_ui_manager (shell_window);
1758 accel_group = gtk_ui_manager_get_accel_group (ui_manager);
1759 backend_name = g_intern_string (backend_name);
1760
1761 /* XXX The action label translations are retrieved from the
1762 * message context "New", but gtk_action_group_add_actions()
1763 * does not support message contexts. So we have to fetch
1764 * the label translations ourselves before adding them to
1765 * the action group.
1766 *
1767 * gtk_action_group_set_translate_func() does not help here
1768 * because the action tooltips do not use a message context
1769 * (though I suppose they could). */
1770 for (ii = 0; ii < n_entries; ii++)
1771 entries[ii].label = g_dpgettext2 (
1772 GETTEXT_PACKAGE, "New", entries[ii].label);
1773
1774 gtk_action_group_add_actions (
1775 action_group, entries, n_entries, shell_window);
1776
1777 /* Tag each action with the name of the shell backend that
1778 * registered it. This is used to help sort actions in the
1779 * "New" menu. */
1780
1781 for (ii = 0; ii < n_entries; ii++) {
1782 const gchar *action_name;
1783 GtkAction *action;
1784
1785 action_name = entries[ii].name;
1786
1787 action = gtk_action_group_get_action (
1788 action_group, action_name);
1789
1790 gtk_action_set_accel_group (action, accel_group);
1791
1792 g_object_set_data (
1793 G_OBJECT (action),
1794 "backend-name", (gpointer) backend_name);
1795 }
1796 }