No issues found
1 /*
2 * e-shell-window-actions.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 #include "e-preferences-window.h"
28
29 #include <e-util/e-dialog-utils.h>
30 #include <e-util/e-print.h>
31 #include <gal-define-views-dialog.h>
32
33 #include <libedataserverui/libedataserverui.h>
34
35 #define EVOLUTION_COPYRIGHT \
36 "Copyright \xC2\xA9 1999 - 2008 Novell, Inc. and Others\n" \
37 "Copyright \xC2\xA9 2008 - 2012 The Evolution Team"
38
39 /* Authors and Documenters
40 *
41 * The names below must be in UTF-8. The breaking of escaped strings
42 * is so the hexadecimal sequences don't swallow too many characters.
43 *
44 * SO THAT MEANS, FOR 8-BIT CHARACTERS USE \xXX HEX ENCODING ONLY!
45 *
46 * Not all environments are UTF-8 and not all editors can handle it.
47 */
48 static const gchar *authors[] = {
49 "Aaron Weber",
50 "Abel Cheung",
51 "Abhishek Parwal",
52 "Adam Weinberger",
53 "Adi Attar",
54 "Ahmad Riza H Nst",
55 "Aidan Delaney",
56 "Aishwarya K",
57 "Akagic Amila",
58 "Akhil Laddha",
59 "Akira Tagoh",
60 "Alastair McKinstry",
61 "Alastair Tse",
62 "Alejandro Andres",
63 "Alessandro Decina",
64 "Alex Graveley",
65 "Alex Jiang",
66 "Alex Jones",
67 "Alex Kloss",
68 "Alexander Shopov",
69 "Alfred Peng",
70 "Ali Abdin",
71 "Ali Akcaagac",
72 "Almer S. Tigelaar",
73 "Amish",
74 "Anand V M",
75 "Anders Carlsson",
76 "Andre Klapper",
77 "Andrea Campi",
78 "Andreas Henriksson",
79 "Andreas Hyden",
80 "Andreas J. Guelzow",
81 "Andreas K\xC3\xB6hler",
82 "Andreas Köhler",
83 "Andrew Ruthven",
84 "Andrew T. Veliath",
85 "Andrew Wu",
86 "Ankit Patel",
87 "Anna Marie Dirks",
88 "Antonio Xu",
89 "Arafat Medini",
90 "Arangel Angov",
91 "Archit Baweja",
92 "Ariel Rios",
93 "Arik Devens",
94 "Armin Bauer",
95 "Arturo Espinosa Aldama",
96 "Arulanandan P",
97 "Arun Prakash",
98 "Arvind Sundararajan",
99 "Arvind",
100 "Ashish",
101 "B S Srinidhi",
102 "Bastien Nocera",
103 "Behnam Esfahbod",
104 "Ben Gamari",
105 "Benjamin Berg",
106 "Benjamin Kahn",
107 "Benoît Dejean",
108 "Bernard Leach",
109 "Bertrand Guiheneuf",
110 "Bharath Acharya",
111 "Bill Zhu",
112 "Bj\xC3\xB6rn Torkelsson",
113 "Björn Lindqvist",
114 "Bob Doan",
115 "Bob Mauchin",
116 "Boby Wang",
117 "Bolian Yin",
118 "Brian Mury",
119 "Brian Pepple",
120 "Bruce Tao",
121 "Calvin Liu",
122 "Cantona Su",
123 "Carl Sun",
124 "Carlos Garcia Campos",
125 "Carlos Garnacho Parro",
126 "Carlos Perell\xC3\xB3" " Mar\xC3\xAD" "n",
127 "Carsten Guenther",
128 "Carsten Schaar",
129 "Changwoo Ryu",
130 "Chao-Hsiung Liao",
131 "Charles Zhang",
132 "Chema Celorio",
133 "Chenthill Palanisamy",
134 "Chpe",
135 "Chris Halls",
136 "Chris Heath",
137 "Chris Phelps",
138 "Chris Toshok",
139 "Christian Hammond",
140 "Christian Kellner",
141 "Christian Kirbach",
142 "Christian Krause",
143 "Christian Kreibich",
144 "Christian Neumair",
145 "Christophe Fergeau",
146 "Christophe Merlet",
147 "Christopher Blizzard",
148 "Christopher J. Lahey",
149 "Christopher R. Gabriel",
150 "Claude Paroz",
151 "Claudio Saavedra",
152 "Clifford R. Conover",
153 "Cody Russell",
154 "Colin Leroy",
155 "Craig Small",
156 "Dafydd Harries",
157 "Damian Ivereigh",
158 "Damien Carbery",
159 "Damon Chaplin",
160 "Dan Berger",
161 "Dan Damian",
162 "Dan Nguyen",
163 "Dan Winship",
164 "Daniel Gryniewicz",
165 "Daniel Nylander",
166 "Daniel van Eeden",
167 "Daniel Veillard",
168 "Daniel Yacob",
169 "Danilo \xC5\xA0" "egan",
170 "Danilo Segan",
171 "Darin Adler",
172 "Dave Benson",
173 "Dave Camp",
174 "Dave Fallon",
175 "Dave Malcolm",
176 "Dave West",
177 "David Farning",
178 "David Kaelbling",
179 "David Malcolm",
180 "David Moore",
181 "David Mosberger",
182 "David Richards",
183 "David Trowbridge",
184 "David Turner",
185 "David Woodhouse",
186 "Denis Washington",
187 "Devashish Sharma",
188 "Diego Escalante Urrelo",
189 "Diego Gonzalez",
190 "Diego Sevilla Ruiz",
191 "Dietmar Maurer",
192 "Dinesh Layek",
193 "Djihed Afifi",
194 "Dmitry Mastrukov",
195 "Dodji Seketeli",
196 "Duarte Loreto",
197 "Dulmandakh Sukhbaatar",
198 "Duncan Mak",
199 "Ebby Wiselyn",
200 "Ed Catmur",
201 "Edd Dumbill",
202 "Edgar Luna Díaz",
203 "Edward Rudd",
204 "Elijah Newren",
205 "Elizabeth Greene",
206 "Elliot Lee",
207 "Elliot Turner",
208 "Eneko Lacunza",
209 "Enver Altin",
210 "Erdal Ronahi",
211 "Eric Busboom",
212 "Eric Zhao",
213 "Eskil Heyn Olsen",
214 "Ettore Perazzoli",
215 "Evan Yan",
216 "Fatih Demir",
217 "Fazlu & Hannah",
218 "Federico Mena Quintero",
219 "Fernando Herrera",
220 "Francisco Javier F. Serrador",
221 "Frank Arnold",
222 "Frank Belew",
223 "Frederic Crozat",
224 "Frederic Peters",
225 "Funda Wang",
226 "Gabor Kelemen",
227 "Ganesh",
228 "Gareth Owen",
229 "Gary Coady",
230 "Gary Ekker",
231 "Gavin Scott",
232 "Gediminas Paulauskas",
233 "Gerg\xC5\x91 \xC3\x89rdi",
234 "George Lebl",
235 "Gerardo Marin",
236 "Gert Kulyk",
237 "Giancarlo Capella",
238 "Gil Osher",
239 "Gilbert Fang",
240 "Gilles Dartiguelongue",
241 "Grahame Bowland",
242 "Greg Hudson",
243 "Gregory Leblanc",
244 "Gregory McLean",
245 "Grzegorz Goawski",
246 "Gustavo Gir\xC3\x8E" "ldez",
247 "Gustavo Maciel Dias Vieira",
248 "H P Nadig",
249 "H\xC3\xA9" "ctor Garc\xC3\xAD" "a \xC3\x81" "lvarez",
250 "Hans Petter Jansson",
251 "Hao Sheng",
252 "Hari Prasad Nadig",
253 "Harish K",
254 "Harish Krishnaswamy",
255 "Harry Lu",
256 "Hasbullah Bin Pit",
257 "Havoc Pennington",
258 "Heath Harrelson",
259 "Hein-Pieter van Braam",
260 "Herbert V. Riedel",
261 "Hiroyuki Ikezoe",
262 "Iain Buchanan",
263 "Iain Holmes",
264 "Ian Campbell",
265 "Ilkka Tuohela",
266 "Irene Huang",
267 "Ismael Olea",
268 "Israel Escalante",
269 "Iv\xC3\xA1" "n Frade",
270 "Iván Frade",
271 "J.H.M. Dassen (Ray)",
272 "JP Rosevear",
273 "J\xC3\xBC" "rg Billeter",
274 "Jürg Billeter",
275 "Jack Jia",
276 "Jacob Ulysses Berkman",
277 "Jacob Berkman",
278 "Jaka Mocnik",
279 "Jakub Steiner",
280 "James Doc Livingston",
281 "James Bowes",
282 "James Henstridge",
283 "James Willcox",
284 "Jan Arne Petersen",
285 "Jan Tichavsky",
286 "Jan Van Buggenhout",
287 "Jared Moore",
288 "Jarkko Ranta",
289 "Jason Leach",
290 "Jason Tackaberry",
291 "Jayaradha",
292 "Jean-Noel Guiheneuf",
293 "Jedy Wang",
294 "Jeff Bailey",
295 "Jeff Cai",
296 "Jeff Garzik",
297 "Jeffrey Stedfast",
298 "Jens Granseuer",
299 "Jens Seidel",
300 "Jeremy Katz",
301 "Jeremy Wise",
302 "Jerome Lacoste",
303 "Jerry Yu",
304 "Jes\xC3\xBA" "s Bravo \xC3\x81" "lvarez",
305 "Jesse Pavel",
306 "Ji Lee",
307 "Joan Sanfeliu",
308 "Jody Goldberg",
309 "Joe Marcus Clarke",
310 "Joe Shaw",
311 "John Gotts",
312 "Johnny Jacob",
313 "Johnny",
314 "Jon Ander Hernandez",
315 "Jon K Hellan",
316 "Jon Oberheide",
317 "Jon Trowbridge",
318 "Jonas Borgstr",
319 "Jonathan Blandford",
320 "Jonathan Dieter",
321 "Jonathon Jongsma",
322 "Jos Dehaes",
323 "Josselin Mouette",
324 "JP Rosvear",
325 "Jukka Zitting",
326 "Jules Colding",
327 "Julian Missig",
328 "Julio M. Merino Vidal",
329 "Jürg Billeter",
330 "Karl Eichwalder",
331 "Karl Relton",
332 "Karsten Br\xC3\xA4" "ckelmann",
333 "Kaushal Kumar",
334 "Kenneth Christiansen",
335 "Kenny Graunke",
336 "Keshav Upadhyaya",
337 "Kevin Breit",
338 "Kevin Piche",
339 "Kevin Vandersloot",
340 "Khasim Shaheed",
341 "Kidd Wang",
342 "Kjartan Maraas",
343 "Krishnan R",
344 "Krisztian Pifko",
345 "Kyle Ambroff",
346 "Larry Ewing",
347 "Laszlo (Laca) Peter",
348 "Laurent Dhima",
349 "Lauris Kaplinski",
350 "Leon Zhang",
351 "Li Yuan",
352 "Loïc Minier",
353 "Loïc Minier",
354 "Lorenzo Gil Sanchez",
355 "Luca Ferretti",
356 "Lucky Wankhede",
357 "Luis Villa",
358 "Lutz M",
359 "M Victor Aloysius J",
360 "Maciej Stachowiak",
361 "Makuchaku",
362 "Malcolm Tredinnick",
363 "Marco Pesenti Gritti",
364 "Marius Andreiana",
365 "Marius Vollmer",
366 "Mark Crichton",
367 "Mark G. Adams",
368 "Mark Gordon",
369 "Mark McLoughlin",
370 "Mark Moulder",
371 "Mark Tearle",
372 "Martha Burke",
373 "Martin Baulig",
374 "Martin Hicks",
375 "Martin Meyer",
376 "Martin Norb\xC3\xA4" "ck",
377 "Martyn Russell",
378 "Masahiro Sakai",
379 "Mathieu Lacage",
380 "Matias Mutchinick",
381 "Matt Bissiri",
382 "Matt Brown",
383 "Matt Loper",
384 "Matt Martin",
385 "Matt Wilson",
386 "Matthew Barnes",
387 "Matthew Daniel",
388 "Matthew Hall",
389 "Matthew Loper",
390 "Matthew Wilson",
391 "Matthias Clasen",
392 "Max Horn",
393 "Maxx Cao",
394 "Mayank Jain",
395 "Meilof Veeningen",
396 "Mengjie Yu",
397 "Michael Granger",
398 "Michael M. Morrison",
399 "Michael MacDonald",
400 "Michael Meeks",
401 "Michael Monreal",
402 "Michael Terry",
403 "Michael Zucchi",
404 "Michel Daenzer",
405 "Miguel Angel Lopez Hernandez",
406 "Miguel de Icaza",
407 "Mikael Hallendal",
408 "Mikael Nilsson",
409 "Mike Castle",
410 "Mike Kestner",
411 "Mike McEwan",
412 "Mikhail Zabaluev",
413 "Milan Crha",
414 "Miles Lane",
415 "Mohammad Damt",
416 "Morten Welinder",
417 "Mubeen Jukaku",
418 "Murray Cumming",
419 "Naba Kumar",
420 "Nagappan Alagappan",
421 "Nancy Cai",
422 "Nat Friedman",
423 "Nathan Owens",
424 "Nicel KM",
425 "Nicholas J Kreucher",
426 "Nicholas Miell",
427 "Nick Sukharev",
428 "Nickolay V. Shmyrev",
429 "Nike Gerdts",
430 "Noel",
431 "Nuno Ferreira",
432 "Nyall Dawson",
433 "Ondrej Jirman",
434 "Oswald Rodrigues",
435 "Owen Taylor",
436 "Oystein Gisnas",
437 "P Chenthill",
438 "P S Chakravarthi",
439 "Pablo Gonzalo del Campo",
440 "Pablo Saratxaga",
441 "Pamplona Hackers",
442 "Paolo Molaro",
443 "Parag Goel",
444 "Parthasarathi Susarla",
445 "Pascal Terjan",
446 "Patrick Ohly",
447 "Paul Bolle",
448 "Paul Lindner",
449 "Pavel Cisler",
450 "Pavel Roskin",
451 "Pavithran",
452 "Pawan Chitrakar",
453 "Pedro Villavicencio",
454 "Peter Pouliot",
455 "Peter Teichman",
456 "Peter Williams",
457 "Peteris Krisjanis",
458 "Petta Pietikainen",
459 "Phil Goembel",
460 "Philip Van Hoof",
461 "Philip Zhao",
462 "Poornima Nayak",
463 "Pratik V. Parikh",
464 "Praveen Kumar",
465 "Priit Laes",
466 "Priyanshu Raj",
467 "Radek Doul\xC3\xADk",
468 "Raghavendran R",
469 "Raja R Harinath",
470 "Rajeev Ramanathan",
471 "Rajesh Ranjan",
472 "Rakesh k.g",
473 "Ramiro Estrugo",
474 "Ranjan Somani",
475 "Ray Strode",
476 "Rhys Jones",
477 "Ricardo Markiewicz",
478 "Richard Boulton",
479 "Richard Hult",
480 "Richard Li",
481 "Rob Bradford",
482 "Robert Brady",
483 "Robert Sedak",
484 "Robin Slomkowski",
485 "Rodney Dawes",
486 "Rodrigo Moya",
487 "Rohini S",
488 "Rohini",
489 "Roland Illig",
490 "Ronald Kuetemeier",
491 "Roozbeh Pournader",
492 "Ross Burton",
493 "Rouslan Solomakhin",
494 "Runa Bhattacharjee",
495 "Russell Steinthal",
496 "Rusty Conover",
497 "Ryan P. Skadberg",
498 "S Antony Vincent Pandian",
499 "S N Tejasvi",
500 "S. \xC3\x87" "a\xC4\x9F" "lar Onur",
501 "S.Antony Vincent Pandian",
502 "S. Caglar Onur",
503 "Sam Creasey",
504 "Sam Yang",
505 "Sam\xC3\xBA" "el J\xC3\xB3" "n Gunnarsson",
506 "Sankar P",
507 "Sanlig Badral",
508 "Sanshao Jiang",
509 "Sarfraaz Ahmed",
510 "Sayamindu Dasgupta",
511 "Sean Atkinson",
512 "Sean Gao",
513 "Sebastian Rittau",
514 "Sebastian Wilhelmi",
515 "Sebastien Bacher",
516 "Sergey Panov",
517 "Seth Alves",
518 "Seth Nickell",
519 "Shakti Sen",
520 "Shi Pu",
521 "Shilpa C",
522 "Shree Krishnan",
523 "Shreyas Srinivasan",
524 "Simon Zheng",
525 "Simos Xenitellis",
526 "Sivaiah Nallagatla",
527 "Srinivasa Ragavan",
528 "Stanislav Brabec",
529 "Stanislav Visnovsky",
530 "Stéphane Raimbault",
531 "Stephen Cook",
532 "Steve Murphy",
533 "Steven Zhang",
534 "Stuart Parmenter",
535 "Subodh Soni",
536 "Suman Manjunath",
537 "Sunil Mohan Adapa",
538 "Suresh Chandrasekharan",
539 "Sushma Rai",
540 "Sven Herzberg",
541 "Szabolcs Ban",
542 "T\xC3\xB5" "ivo Leedj\xC3\xA4" "rv",
543 "Takao Fujiwara",
544 "Takayuki Kusano",
545 "Takeshi Aihana",
546 "Tambet Ingo",
547 "Taylor Hayward",
548 "Ted Percival",
549 "Theppitak Karoonboonyanan",
550 "Thomas Cataldo",
551 "Thomas Klausner",
552 "Thomas Mirlacher",
553 "Thouis R. Jones",
554 "Tim Wo",
555 "Tim Yamin",
556 "Timo Hoenig",
557 "Timo Sirainen",
558 "Timothy Lee",
559 "Timur Bakeyev",
560 "Tino Meinen",
561 "Tobias Mueller",
562 "Tõivo Leedjärv",
563 "Tom Tromey",
564 "Tomas Ogren",
565 "Tomasz K\xC5\x82" "oczko",
566 "Tomislav Vujec",
567 "Tommi Komulainen",
568 "Tommi Vainikainen",
569 "Tony Tsui",
570 "Tor Lillqvist",
571 "Trent Lloyd",
572 "Tuomas J. Lukka",
573 "Tuomas Kuosmanen",
574 "Ulrich Neumann",
575 "Umesh Tiwari",
576 "Umeshtej",
577 "Ushveen Kaur",
578 "V Ravi Kumar Raju",
579 "Vadim Strizhevsky",
580 "Valek Filippov",
581 "Vandana Shenoy .B",
582 "Vardhman Jain",
583 "Veerapuram Varadhan",
584 "Vincent Noel",
585 "Vincent van Adrighem",
586 "Viren",
587 "Vivek Jain",
588 "Vladimer Sichinava",
589 "Vladimir Vukicevic",
590 "Wadim Dziedzic",
591 "Wang Jian",
592 "Wang Xin",
593 "Wayne Davis",
594 "William Jon McCann",
595 "Wouter Bolsterlee",
596 "Xan Lopez",
597 "Xiurong Simon Zheng",
598 "Yanko Kaneti",
599 "Yi Jin",
600 "Yong Sun",
601 "Yu Mengjie",
602 "Yuedong Du",
603 "Yukihiro Nakai",
604 "Yuri Pankov",
605 "Yuri Syrota",
606 "Zach Frey",
607 "Zan Lynx",
608 "Zbigniew Chyla",
609 "\xC3\x98ystein Gisn\xC3\xA5s",
610 "\xC5\xBDygimantas Beru\xC4\x8Dka",
611 NULL
612 };
613
614 static const gchar *documenters[] = {
615 "Aaron Weber",
616 "Binika Preet",
617 "Dan Winship",
618 "David Trowbridge",
619 "Jessica Prabhakar",
620 "JP Rosevear",
621 "Radhika Nair",
622 NULL
623 };
624
625 /**
626 * E_SHELL_WINDOW_ACTION_ABOUT:
627 * @window: an #EShellWindow
628 *
629 * Activation of this action displays the application's About dialog.
630 *
631 * Main menu item: Help -> About
632 **/
633 static void
634 action_about_cb (GtkAction *action,
635 EShellWindow *shell_window)
636 {
637 gchar *translator_credits;
638
639 /* The translator-credits string is for translators to list
640 * per-language credits for translation, displayed in the
641 * about dialog. */
642 translator_credits = _("translator-credits");
643 if (strcmp (translator_credits, "translator-credits") == 0)
644 translator_credits = NULL;
645
646 gtk_show_about_dialog (
647 GTK_WINDOW (shell_window),
648 "program-name", "Evolution",
649 "version", VERSION,
650 "copyright", EVOLUTION_COPYRIGHT,
651 "comments", _("Groupware Suite"),
652 "website", PACKAGE_URL,
653 "website-label", _("Evolution Website"),
654 "authors", authors,
655 "documenters", documenters,
656 "translator-credits", translator_credits,
657 "logo-icon-name", "evolution",
658 "license-type", GTK_LICENSE_GPL_2_0,
659 NULL);
660 }
661
662 /**
663 * E_SHELL_WINDOW_ACTION_CLOSE:
664 * @window: an #EShellWindow
665 *
666 * Activation of this action closes @window. If this is the last window,
667 * the application initiates shutdown.
668 *
669 * Main menu item: File -> Close
670 **/
671 static void
672 action_close_cb (GtkAction *action,
673 EShellWindow *shell_window)
674 {
675 GtkWidget *widget;
676 GdkWindow *window;
677 GdkEvent *event;
678
679 widget = GTK_WIDGET (shell_window);
680 window = gtk_widget_get_window (widget);
681
682 /* Synthesize a delete_event on this window. */
683 event = gdk_event_new (GDK_DELETE);
684 event->any.window = g_object_ref (window);
685 event->any.send_event = TRUE;
686 gtk_main_do_event (event);
687 gdk_event_free (event);
688 }
689
690 /**
691 * E_SHELL_WINDOW_ACTION_CONTENTS:
692 * @window: an #EShellWindow
693 *
694 * Activation of this action opens the application's user manual.
695 *
696 * Main menu item: Help -> Contents
697 **/
698 static void
699 action_contents_cb (GtkAction *action,
700 EShellWindow *shell_window)
701 {
702 #ifdef G_OS_WIN32
703 /* On Windows, link to online help instead.
704 * See https://bugzilla.gnome.org/show_bug.cgi?id=576478 */
705 gchar *online_help_url;
706
707 online_help_url = g_strconcat (
708 "http://library.gnome.org/users/evolution/",
709 BASE_VERSION, NULL);
710 e_show_uri (GTK_WINDOW (shell_window), online_help_url);
711 g_free (online_help_url);
712 #else
713 e_display_help (GTK_WINDOW (shell_window), NULL);
714 #endif
715 }
716
717 static void
718 action_custom_rule_cb (GtkAction *action,
719 EShellWindow *shell_window)
720 {
721 EFilterRule *rule;
722 EShellView *shell_view;
723 const gchar *view_name;
724
725 rule = g_object_get_data (G_OBJECT (action), "rule");
726 g_return_if_fail (rule != NULL);
727
728 view_name = e_shell_window_get_active_view (shell_window);
729 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
730
731 rule = g_object_get_data (G_OBJECT (action), "rule");
732 g_return_if_fail (E_IS_FILTER_RULE (rule));
733
734 e_shell_view_custom_search (shell_view, rule);
735 }
736
737 /**
738 * E_SHELL_WINDOW_ACTION_GAL_DEFINE_VIEWS:
739 * @window: an #EShellWindow
740 *
741 * Activation of this action opens a dialog for editing GAL views for
742 * the current shell view.
743 *
744 * Main menu item: View -> Current View -> Define Views...
745 **/
746 static void
747 action_gal_define_views_cb (GtkAction *action,
748 EShellWindow *shell_window)
749 {
750 EShellView *shell_view;
751 EShellViewClass *shell_view_class;
752 GalViewCollection *view_collection;
753 GtkWidget *dialog;
754 const gchar *view_name;
755
756 view_name = e_shell_window_get_active_view (shell_window);
757 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
758 shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
759 view_collection = shell_view_class->view_collection;
760 g_return_if_fail (view_collection != NULL);
761
762 dialog = gal_define_views_dialog_new (view_collection);
763 gtk_dialog_run (GTK_DIALOG (dialog));
764 gal_view_collection_save (view_collection);
765 gtk_widget_destroy (dialog);
766
767 e_shell_window_update_view_menu (shell_window);
768 }
769
770 /**
771 * E_SHELL_WINDOW_ACTION_GAL_CUSTOM_VIEW:
772 * @window: an #EShellWindow
773 *
774 * This radio action is selected when using a custom GAL view that has
775 * not been saved.
776 *
777 * Main menu item: View -> Current View -> Custom View
778 **/
779 static void
780 action_gal_view_cb (GtkRadioAction *action,
781 GtkRadioAction *current,
782 EShellWindow *shell_window)
783 {
784 EShellView *shell_view;
785 const gchar *view_name;
786 const gchar *view_id;
787
788 view_name = e_shell_window_get_active_view (shell_window);
789 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
790 view_id = g_object_get_data (G_OBJECT (current), "view-id");
791 e_shell_view_set_view_id (shell_view, view_id);
792 }
793
794 /**
795 * E_SHELL_WINDOW_ACTION_GAL_SAVE_CUSTOM_VIEW:
796 * @window: an #EShellWindow
797 *
798 * Activation of this action saves a custom GAL view.
799 *
800 * Main menu item: View -> Current View -> Save Custom View...
801 **/
802
803 /**
804 * E_SHELL_WINDOW_ACTION_IMPORT:
805 * @window: an #EShellWindow
806 *
807 * Activation of this action opens the Evolution Import Assistant.
808 *
809 * Main menu item: File -> Import...
810 **/
811 static void
812 action_import_cb (GtkAction *action,
813 EShellWindow *shell_window)
814 {
815 GtkWidget *assistant;
816
817 assistant = e_import_assistant_new (GTK_WINDOW (shell_window));
818
819 /* These are "Run Last" signals, so use g_signal_connect_after()
820 * to give the default handlers a chance to run before we destroy
821 * the window. */
822
823 g_signal_connect_after (
824 assistant, "cancel",
825 G_CALLBACK (gtk_widget_destroy), NULL);
826
827 g_signal_connect_after (
828 assistant, "finished",
829 G_CALLBACK (gtk_widget_destroy), NULL);
830
831 gtk_widget_show (assistant);
832 }
833
834 /**
835 * E_SHELL_WINDOW_ACTION_NEW_WINDOW:
836 * @window: an #EShellWindow
837 *
838 * Activation of this action opens a new shell window.
839 *
840 * Main menu item: File -> New Window
841 **/
842 static void
843 action_new_window_cb (GtkAction *action,
844 EShellWindow *shell_window)
845 {
846 EShell *shell;
847 const gchar *view_name;
848
849 shell = e_shell_window_get_shell (shell_window);
850 view_name = e_shell_window_get_active_view (shell_window);
851
852 e_shell_create_shell_window (shell, view_name);
853 }
854
855 /**
856 * E_SHELL_WINDOW_ACTION_PAGE_SETUP:
857 * @window: an #EShellWindow
858 *
859 * Activation of this action opens the application's Page Setup dialog.
860 *
861 * Main menu item: File -> Page Setup...
862 **/
863 static void
864 action_page_setup_cb (GtkAction *action,
865 EShellWindow *shell_window)
866 {
867 e_print_run_page_setup_dialog (GTK_WINDOW (shell_window));
868 }
869
870 /**
871 * E_SHELL_WINDOW_ACTION_CATEGORIES
872 * @window: and #EShellWindow
873 *
874 * Activation of this action opens the Categories Editor dialog.
875 *
876 * Main menu item: Edit -> Available categories
877 **/
878 static void
879 action_categories_cb (GtkAction *action,
880 EShellWindow *shell_window)
881 {
882 GtkWidget *content_area;
883 GtkWidget *dialog;
884 GtkWidget *editor;
885
886 editor = e_categories_editor_new ();
887 e_categories_editor_set_entry_visible (
888 E_CATEGORIES_EDITOR (editor), FALSE);
889
890 dialog = gtk_dialog_new_with_buttons (
891 _("Categories Editor"),
892 GTK_WINDOW (shell_window),
893 GTK_DIALOG_DESTROY_WITH_PARENT,
894 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, NULL);
895 gtk_container_set_border_width (GTK_CONTAINER (dialog), 12);
896 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
897 gtk_box_pack_start (
898 GTK_BOX (content_area), GTK_WIDGET (editor), TRUE, TRUE, 6);
899 gtk_box_set_spacing (GTK_BOX (content_area), 12);
900
901 gtk_dialog_run (GTK_DIALOG (dialog));
902
903 gtk_widget_destroy (dialog);
904 }
905
906 /**
907 * E_SHELL_WINDOW_ACTION_PREFERENCES:
908 * @window: an #EShellWindow
909 *
910 * Activation of this action opens the application's Preferences window.
911 *
912 * Main menu item: Edit -> Preferences
913 **/
914 static void
915 action_preferences_cb (GtkAction *action,
916 EShellWindow *shell_window)
917 {
918 EShell *shell;
919 GtkWidget *preferences_window;
920 EShellView *shell_view;
921 EShellBackend *shell_backend;
922 EShellBackendClass *shell_backend_class;
923 const gchar *view_name;
924
925 shell = e_shell_window_get_shell (shell_window);
926 preferences_window = e_shell_get_preferences_window (shell);
927 e_preferences_window_setup (E_PREFERENCES_WINDOW (preferences_window));
928
929 gtk_window_set_transient_for (
930 GTK_WINDOW (preferences_window),
931 GTK_WINDOW (shell_window));
932 gtk_window_set_position (
933 GTK_WINDOW (preferences_window),
934 GTK_WIN_POS_CENTER_ON_PARENT);
935 gtk_window_present (GTK_WINDOW (preferences_window));
936
937 view_name = e_shell_window_get_active_view (shell_window);
938 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
939
940 shell_backend = e_shell_view_get_shell_backend (shell_view);
941 shell_backend_class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
942
943 if (shell_backend_class->preferences_page != NULL) {
944 if (e_shell_get_express_mode (shell))
945 e_preferences_window_filter_page (
946 E_PREFERENCES_WINDOW (preferences_window),
947 shell_backend_class->preferences_page);
948 else
949 e_preferences_window_show_page (
950 E_PREFERENCES_WINDOW (preferences_window),
951 shell_backend_class->preferences_page);
952 }
953 }
954
955 /**
956 * E_SHELL_WINDOW_ACTION_QUICK_REFERENCE:
957 * @window: an #EShellWindow
958 *
959 * Activation of this action opens a printable table of useful shortcut
960 * keys for this application.
961 *
962 * Main menu item: Help -> Quick Reference
963 **/
964 static void
965 action_quick_reference_cb (GtkAction *action,
966 EShellWindow *shell_window)
967 {
968 const gchar * const *language_names;
969 gboolean app_launched = FALSE;
970
971 language_names = g_get_language_names ();
972 while (*language_names != NULL && !app_launched) {
973 const gchar *language = *language_names++;
974 gchar *filename;
975
976 /* This must be a valid language AND a language with
977 * no encoding suffix. The next language should have
978 * no encoding suffix. */
979 if (language == NULL || strchr (language, '.') != NULL)
980 continue;
981
982 filename = g_build_filename (
983 EVOLUTION_HELPDIR, "quickref",
984 language, "quickref.pdf", NULL);
985
986 if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
987 GFile *file;
988 gchar *uri;
989 GError *error = NULL;
990
991 file = g_file_new_for_path (filename);
992 uri = g_file_get_uri (file);
993
994 app_launched = g_app_info_launch_default_for_uri (
995 uri, NULL, &error);
996
997 if (error != NULL) {
998 /* FIXME Show an error dialog. */
999 g_warning ("%s", error->message);
1000 g_error_free (error);
1001 }
1002
1003 g_object_unref (file);
1004 g_free (uri);
1005 }
1006
1007 g_free (filename);
1008 }
1009 }
1010
1011 /**
1012 * E_SHELL_WINDOW_ACTION_QUIT:
1013 * @window: an #EShellWindow
1014 *
1015 * Activation of this action initiates application shutdown.
1016 *
1017 * Main menu item: File -> Quit
1018 **/
1019 static void
1020 action_quit_cb (GtkAction *action,
1021 EShellWindow *shell_window)
1022 {
1023 EShell *shell;
1024
1025 shell = e_shell_window_get_shell (shell_window);
1026 e_shell_quit (shell, E_SHELL_QUIT_ACTION);
1027 }
1028
1029 /**
1030 * E_SHELL_WINDOW_ACTION_SEARCH_ADVANCED:
1031 * @window: an #EShellWindow
1032 *
1033 * Activation of this action opens an Advanced Search dialog.
1034 *
1035 * Main menu item: Search -> Advanced Search...
1036 **/
1037 static void
1038 action_search_advanced_cb (GtkAction *action,
1039 EShellWindow *shell_window)
1040 {
1041 EShellView *shell_view;
1042 EShellContent *shell_content;
1043 const gchar *view_name;
1044
1045 view_name = e_shell_window_get_active_view (shell_window);
1046 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1047 shell_content = e_shell_view_get_shell_content (shell_view);
1048
1049 e_shell_content_run_advanced_search_dialog (shell_content);
1050 e_shell_window_update_search_menu (shell_window);
1051 }
1052
1053 /**
1054 * E_SHELL_WINDOW_ACTION_SEARCH_CLEAR:
1055 * @window: an #EShellWindow
1056 *
1057 * Activation of this action clears the most recent search results.
1058 *
1059 * Main menu item: Search -> Clear
1060 **/
1061 static void
1062 action_search_clear_cb (GtkAction *action,
1063 EShellWindow *shell_window)
1064 {
1065 EShellView *shell_view;
1066 const gchar *view_name;
1067
1068 view_name = e_shell_window_get_active_view (shell_window);
1069 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1070
1071 e_shell_view_clear_search (shell_view);
1072 }
1073
1074 /**
1075 * E_SHELL_WINDOW_ACTION_SEARCH_EDIT:
1076 * @window: an #EShellWindow
1077 *
1078 * Activation of this action opens a dialog for editing saved searches.
1079 *
1080 * Main menu item: Search -> Edit Saved Searches...
1081 **/
1082 static void
1083 action_search_edit_cb (GtkAction *action,
1084 EShellWindow *shell_window)
1085 {
1086 EShellView *shell_view;
1087 EShellContent *shell_content;
1088 const gchar *view_name;
1089
1090 view_name = e_shell_window_get_active_view (shell_window);
1091 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1092 shell_content = e_shell_view_get_shell_content (shell_view);
1093
1094 e_shell_content_run_edit_searches_dialog (shell_content);
1095 e_shell_window_update_search_menu (shell_window);
1096 }
1097
1098 /**
1099 * E_SHELL_WINDOW_ACTION_SEARCH_OPTIONS:
1100 * @window: an #EShellWindow
1101 *
1102 * Activation of this action displays a menu of search options.
1103 * This appears as a "find" icon in the window's search entry.
1104 **/
1105 static void
1106 action_search_options_cb (GtkAction *action,
1107 EShellWindow *shell_window)
1108 {
1109 EShellView *shell_view;
1110 EShellViewClass *shell_view_class;
1111 const gchar *view_name;
1112 const gchar *widget_path;
1113
1114 view_name = e_shell_window_get_active_view (shell_window);
1115 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1116 shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
1117
1118 widget_path = shell_view_class->search_options;
1119 e_shell_view_show_popup_menu (shell_view, widget_path, NULL);
1120 }
1121
1122 /**
1123 * E_SHELL_WINDOW_ACTION_SEARCH_QUICK:
1124 * @window: an #EShellWindow
1125 *
1126 * Activation of this action executes the current search conditions.
1127 *
1128 * Main menu item: Search -> Find Now
1129 **/
1130 static void
1131 action_search_quick_cb (GtkAction *action,
1132 EShellWindow *shell_window)
1133 {
1134 EShellView *shell_view;
1135 const gchar *view_name;
1136
1137 view_name = e_shell_window_get_active_view (shell_window);
1138 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1139
1140 e_shell_view_execute_search (shell_view);
1141 }
1142
1143 /**
1144 * E_SHELL_WINDOW_ACTION_SEARCH_SAVE:
1145 * @window: an #EShellWindow
1146 *
1147 * Activation of this action saves the current search conditions.
1148 *
1149 * Main menu item: Search -> Save Search...
1150 **/
1151 static void
1152 action_search_save_cb (GtkAction *action,
1153 EShellWindow *shell_window)
1154 {
1155 EShellView *shell_view;
1156 EShellContent *shell_content;
1157 const gchar *view_name;
1158
1159 view_name = e_shell_window_get_active_view (shell_window);
1160 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
1161 shell_content = e_shell_view_get_shell_content (shell_view);
1162
1163 e_shell_content_run_save_search_dialog (shell_content);
1164 e_shell_window_update_search_menu (shell_window);
1165 }
1166
1167 /**
1168 * E_SHELL_WINDOW_ACTION_SHOW_SIDEBAR:
1169 * @window: an #EShellWindow
1170 *
1171 * This toggle action controls whether the side bar is visible.
1172 *
1173 * Main menu item: View -> Layout -> Show Side Bar
1174 **/
1175
1176 /**
1177 * E_SHELL_WINDOW_ACTION_SHOW_SWITCHER:
1178 * @window: an #EShellWindow
1179 *
1180 * This toggle action controls whether the switcher buttons are visible.
1181 *
1182 * Main menu item: View -> Switcher Appearance -> Show Buttons
1183 **/
1184
1185 /**
1186 * E_SHELL_WINDOW_ACTION_SHOW_TASKBAR:
1187 * @window: an #EShellWindow
1188 *
1189 * This toggle action controls whether the task bar is visible.
1190 *
1191 * Main menu item: View -> Layout -> Show Status Bar
1192 **/
1193
1194 /**
1195 * E_SHELL_WINDOW_ACTION_SHOW_TOOLBAR:
1196 * @window: an #EShellWindow
1197 *
1198 * This toggle action controls whether the tool bar is visible.
1199 *
1200 * Main menu item: View -> Layout -> Show Tool Bar
1201 **/
1202
1203 /**
1204 * E_SHELL_WINDOW_ACTION_SUBMIT_BUG:
1205 * @window: an #EShellWindow
1206 *
1207 * Activation of this action allows users to report a bug using
1208 * Bug Buddy.
1209 *
1210 * Main menu item: Help -> Submit Bug Report
1211 **/
1212 static void
1213 action_submit_bug_cb (GtkAction *action,
1214 EShellWindow *shell_window)
1215 {
1216 const gchar *command_line;
1217 GError *error = NULL;
1218
1219 command_line = "bug-buddy --package=Evolution";
1220
1221 g_debug ("Spawning: %s", command_line);
1222 g_spawn_command_line_async (command_line, &error);
1223
1224 if (error != NULL) {
1225 const gchar *message;
1226
1227 if (error->code == G_SPAWN_ERROR_NOENT)
1228 message = _("Bug Buddy is not installed.");
1229 else
1230 message = _("Bug Buddy could not be run.");
1231 e_notice (shell_window, GTK_MESSAGE_ERROR, message);
1232 g_error_free (error);
1233 }
1234 }
1235
1236 static void
1237 action_switcher_cb (GtkRadioAction *action,
1238 GtkRadioAction *current,
1239 EShellWindow *shell_window)
1240 {
1241 const gchar *view_name;
1242
1243 view_name = g_object_get_data (G_OBJECT (current), "view-name");
1244 e_shell_window_switch_to_view (shell_window, view_name);
1245 }
1246
1247 static void
1248 action_new_view_window_cb (GtkAction *action,
1249 EShellWindow *shell_window)
1250 {
1251 EShell *shell;
1252 const gchar *view_name;
1253
1254 shell = e_shell_window_get_shell (shell_window);
1255 view_name = g_object_get_data (G_OBJECT (action), "view-name");
1256
1257 fprintf (stderr, "create new window: %s\n", view_name);
1258
1259 e_shell_create_shell_window (shell, view_name);
1260 }
1261
1262 /**
1263 * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_BOTH:
1264 * @window: an #EShellWindow
1265 *
1266 * This radio action displays switcher buttons with icons and text.
1267 *
1268 * Main menu item: View -> Switcher Appearance -> Icons and Text
1269 **/
1270
1271 /**
1272 * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS:
1273 * @window: an #EShellWindow
1274 *
1275 * This radio action displays switcher buttons with icons only.
1276 *
1277 * Main menu item: View -> Switcher Appearance -> Icons Only
1278 **/
1279
1280 /**
1281 * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_TEXT:
1282 * @window: an #EShellWindow
1283 *
1284 * This radio action displays switcher buttons with text only.
1285 *
1286 * Main menu item: View -> Switcher Appearance -> Text Only
1287 **/
1288
1289 /**
1290 * E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_USER:
1291 * @window: an #EShellWindow
1292 *
1293 * This radio action displays switcher buttons according to the desktop
1294 * toolbar setting.
1295 *
1296 * Main menu item: View -> Switcher Appearance -> Toolbar Style
1297 **/
1298 static void
1299 action_switcher_style_cb (GtkRadioAction *action,
1300 GtkRadioAction *current,
1301 EShellWindow *shell_window)
1302 {
1303 EShellSwitcher *switcher;
1304 GtkToolbarStyle style;
1305
1306 switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
1307 style = gtk_radio_action_get_current_value (action);
1308
1309 switch (style) {
1310 case GTK_TOOLBAR_ICONS:
1311 case GTK_TOOLBAR_TEXT:
1312 case GTK_TOOLBAR_BOTH:
1313 case GTK_TOOLBAR_BOTH_HORIZ:
1314 e_shell_switcher_set_style (switcher, style);
1315 break;
1316
1317 default:
1318 e_shell_switcher_unset_style (switcher);
1319 break;
1320 }
1321 }
1322
1323 /**
1324 * E_SHELL_WINDOW_ACTION_WORK_OFFLINE:
1325 * @window: an #EShellWindow
1326 *
1327 * Activation of this action puts the application into offline mode.
1328 *
1329 * Main menu item: File -> Work Offline
1330 **/
1331 static void
1332 action_work_offline_cb (GtkAction *action,
1333 EShellWindow *shell_window)
1334 {
1335 EShell *shell;
1336 EShellSettings *shell_settings;
1337
1338 shell = e_shell_window_get_shell (shell_window);
1339 shell_settings = e_shell_get_shell_settings (shell);
1340
1341 e_shell_set_online (shell, FALSE);
1342
1343 /* XXX The sense of the setting is reversed. Would be more
1344 * intuitive and less error-prone as "start-online". */
1345 e_shell_settings_set_boolean (
1346 shell_settings, "start-offline", TRUE);
1347 }
1348
1349 /**
1350 * E_SHELL_WINDOW_ACTION_WORK_ONLINE:
1351 * @window: an #EShellWindow
1352 *
1353 * Activation of this action puts the application into online mode.
1354 *
1355 * Main menu item: File -> Work Online
1356 **/
1357 static void
1358 action_work_online_cb (GtkAction *action,
1359 EShellWindow *shell_window)
1360 {
1361 EShell *shell;
1362 EShellSettings *shell_settings;
1363
1364 shell = e_shell_window_get_shell (shell_window);
1365 shell_settings = e_shell_get_shell_settings (shell);
1366
1367 e_shell_set_online (shell, TRUE);
1368
1369 /* XXX The sense of the setting is reversed. Would be more
1370 * intuitive and less error-prone as "start-online". */
1371 e_shell_settings_set_boolean (
1372 shell_settings, "start-offline", FALSE);
1373 }
1374
1375 /**
1376 * E_SHELL_WINDOW_ACTION_GROUP_CUSTOM_RULES:
1377 * @window: an #EShellWindow
1378 **/
1379
1380 /**
1381 * E_SHELL_WINDOW_ACTION_GROUP_GAL_VIEW:
1382 * @window: an #EShellWindow
1383 **/
1384
1385 /**
1386 * E_SHELL_WINDOW_ACTION_GROUP_NEW_ITEM:
1387 * @window: an #EShellWindow
1388 **/
1389
1390 /**
1391 * E_SHELL_WINDOW_ACTION_GROUP_NEW_SOURCE:
1392 * @window: an #EShellWindow
1393 **/
1394
1395 /**
1396 * E_SHELL_WINDOW_ACTION_GROUP_SHELL:
1397 * @window: an #EShellWindow
1398 **/
1399
1400 /**
1401 * E_SHELL_WINDOW_ACTION_GROUP_SWITCHER:
1402 * @window: an #EShellWindow
1403 **/
1404
1405 static GtkActionEntry shell_entries[] = {
1406
1407 { "about",
1408 GTK_STOCK_ABOUT,
1409 NULL,
1410 NULL,
1411 N_("Show information about Evolution"),
1412 G_CALLBACK (action_about_cb) },
1413
1414 { "close",
1415 GTK_STOCK_CLOSE,
1416 N_("_Close Window"),
1417 "<Control>w",
1418 N_("Close this window"),
1419 G_CALLBACK (action_close_cb) },
1420
1421 { "close-window-menu",
1422 GTK_STOCK_CLOSE,
1423 NULL,
1424 "<Control>w",
1425 N_("Close this window"),
1426 G_CALLBACK (action_close_cb) },
1427
1428 { "close-window",
1429 GTK_STOCK_CLOSE,
1430 N_("_Close Window"),
1431 "<Control>w",
1432 N_("Close this window"),
1433 G_CALLBACK (action_close_cb) },
1434
1435 { "contents",
1436 GTK_STOCK_HELP,
1437 N_("_Contents"),
1438 "F1",
1439 N_("Open the Evolution User Guide"),
1440 G_CALLBACK (action_contents_cb) },
1441
1442 { "copy-clipboard",
1443 GTK_STOCK_COPY,
1444 NULL,
1445 NULL,
1446 N_("Copy the selection"),
1447 NULL }, /* Handled by EFocusTracker */
1448
1449 { "cut-clipboard",
1450 GTK_STOCK_CUT,
1451 NULL,
1452 NULL,
1453 N_("Cut the selection"),
1454 NULL }, /* Handled by EFocusTracker */
1455
1456 { "delete-selection",
1457 GTK_STOCK_DELETE,
1458 NULL,
1459 NULL,
1460 N_("Delete the selection"),
1461 NULL }, /* Handled by EFocusTracker */
1462
1463 { "import",
1464 "stock_mail-import",
1465 N_("I_mport..."),
1466 NULL,
1467 N_("Import data from other programs"),
1468 G_CALLBACK (action_import_cb) },
1469
1470 { "new-window",
1471 "window-new",
1472 N_("New _Window"),
1473 "<Control><Shift>w",
1474 N_("Create a new window displaying this view"),
1475 G_CALLBACK (action_new_window_cb) },
1476
1477 { "paste-clipboard",
1478 GTK_STOCK_PASTE,
1479 NULL,
1480 NULL,
1481 N_("Paste the clipboard"),
1482 NULL }, /* Handled by EFocusTracker */
1483
1484 { "categories",
1485 NULL,
1486 N_("Available Cate_gories"),
1487 NULL,
1488 N_("Manage available categories"),
1489 G_CALLBACK (action_categories_cb) },
1490
1491 { "preferences",
1492 GTK_STOCK_PREFERENCES,
1493 NULL,
1494 "<Control><Shift>s",
1495 N_("Configure Evolution"),
1496 G_CALLBACK (action_preferences_cb) },
1497
1498 { "quick-reference",
1499 NULL,
1500 N_("_Quick Reference"),
1501 NULL,
1502 N_("Show Evolution's shortcut keys"),
1503 G_CALLBACK (action_quick_reference_cb) },
1504
1505 { "quit",
1506 GTK_STOCK_QUIT,
1507 NULL,
1508 NULL,
1509 N_("Exit the program"),
1510 G_CALLBACK (action_quit_cb) },
1511
1512 { "search-advanced",
1513 NULL,
1514 N_("_Advanced Search..."),
1515 NULL,
1516 N_("Construct a more advanced search"),
1517 G_CALLBACK (action_search_advanced_cb) },
1518
1519 { "search-clear",
1520 GTK_STOCK_CLEAR,
1521 NULL,
1522 "<Control><Shift>q",
1523 N_("Clear the current search parameters"),
1524 G_CALLBACK (action_search_clear_cb) },
1525
1526 { "search-edit",
1527 NULL,
1528 N_("_Edit Saved Searches..."),
1529 NULL,
1530 N_("Manage your saved searches"),
1531 G_CALLBACK (action_search_edit_cb) },
1532
1533 { "search-options",
1534 GTK_STOCK_FIND,
1535 NULL,
1536 NULL,
1537 N_("Click here to change the search type"),
1538 G_CALLBACK (action_search_options_cb) },
1539
1540 { "search-quick",
1541 GTK_STOCK_FIND,
1542 N_("_Find Now"),
1543 "", /* Block the default Ctrl+F. */
1544 N_("Execute the current search parameters"),
1545 G_CALLBACK (action_search_quick_cb) },
1546
1547 { "search-save",
1548 NULL,
1549 N_("_Save Search..."),
1550 NULL,
1551 N_("Save the current search parameters"),
1552 G_CALLBACK (action_search_save_cb) },
1553
1554 { "select-all",
1555 GTK_STOCK_SELECT_ALL,
1556 NULL,
1557 "<Control>a",
1558 N_("Select all text"),
1559 NULL }, /* Handled by EFocusTracker */
1560
1561 { "submit-bug",
1562 NULL,
1563 N_("Submit _Bug Report..."),
1564 NULL,
1565 N_("Submit a bug report using Bug Buddy"),
1566 G_CALLBACK (action_submit_bug_cb) },
1567
1568 { "work-offline",
1569 "stock_disconnect",
1570 N_("_Work Offline"),
1571 NULL,
1572 N_("Put Evolution into offline mode"),
1573 G_CALLBACK (action_work_offline_cb) },
1574
1575 { "work-online",
1576 "stock_connect",
1577 N_("_Work Online"),
1578 NULL,
1579 N_("Put Evolution into online mode"),
1580 G_CALLBACK (action_work_online_cb) },
1581
1582 /*** Menus ***/
1583
1584 { "edit-menu",
1585 NULL,
1586 N_("_Edit"),
1587 NULL,
1588 NULL,
1589 NULL },
1590
1591 { "file-menu",
1592 NULL,
1593 N_("_File"),
1594 NULL,
1595 NULL,
1596 NULL },
1597
1598 { "help-menu",
1599 NULL,
1600 N_("_Help"),
1601 NULL,
1602 NULL,
1603 NULL },
1604
1605 { "layout-menu",
1606 NULL,
1607 N_("Lay_out"),
1608 NULL,
1609 NULL,
1610 NULL },
1611
1612 { "new-menu",
1613 GTK_STOCK_NEW,
1614 N_("_New"),
1615 "",
1616 NULL,
1617 NULL },
1618
1619 { "search-menu",
1620 NULL,
1621 N_("_Search"),
1622 NULL,
1623 NULL,
1624 NULL },
1625
1626 { "switcher-menu",
1627 NULL,
1628 N_("_Switcher Appearance"),
1629 NULL,
1630 NULL,
1631 NULL },
1632
1633 { "view-menu",
1634 NULL,
1635 N_("_View"),
1636 NULL,
1637 NULL,
1638 NULL },
1639
1640 { "window-menu",
1641 NULL,
1642 N_("_Window"),
1643 NULL,
1644 NULL,
1645 NULL }
1646 };
1647
1648 static EPopupActionEntry shell_popup_entries[] = {
1649
1650 { "popup-copy-clipboard",
1651 NULL,
1652 "copy-clipboard" },
1653
1654 { "popup-cut-clipboard",
1655 NULL,
1656 "cut-clipboard" },
1657
1658 { "popup-delete-selection",
1659 NULL,
1660 "delete-selection" },
1661
1662 { "popup-paste-clipboard",
1663 NULL,
1664 "paste-clipboard" }
1665 };
1666
1667 static GtkToggleActionEntry shell_toggle_entries[] = {
1668
1669 { "show-sidebar",
1670 NULL,
1671 N_("Show Side _Bar"),
1672 NULL,
1673 N_("Show the side bar"),
1674 NULL,
1675 TRUE },
1676
1677 { "show-switcher",
1678 NULL,
1679 N_("Show _Buttons"),
1680 NULL,
1681 N_("Show the switcher buttons"),
1682 NULL,
1683 TRUE },
1684
1685 { "show-taskbar",
1686 NULL,
1687 N_("Show _Status Bar"),
1688 NULL,
1689 N_("Show the status bar"),
1690 NULL,
1691 TRUE },
1692
1693 { "show-toolbar",
1694 NULL,
1695 N_("Show _Tool Bar"),
1696 NULL,
1697 N_("Show the tool bar"),
1698 NULL,
1699 TRUE }
1700 };
1701
1702 static GtkRadioActionEntry shell_switcher_entries[] = {
1703
1704 /* This action represents the initial active shell view.
1705 * It should not be visible in the UI, nor should it be
1706 * possible to switch to it from another shell view. */
1707 { "switcher-initial",
1708 NULL,
1709 NULL,
1710 NULL,
1711 NULL,
1712 -1 }
1713 };
1714
1715 static GtkRadioActionEntry shell_switcher_style_entries[] = {
1716
1717 { "switcher-style-icons",
1718 NULL,
1719 N_("_Icons Only"),
1720 NULL,
1721 N_("Display window buttons with icons only"),
1722 GTK_TOOLBAR_ICONS },
1723
1724 { "switcher-style-text",
1725 NULL,
1726 N_("_Text Only"),
1727 NULL,
1728 N_("Display window buttons with text only"),
1729 GTK_TOOLBAR_TEXT },
1730
1731 { "switcher-style-both",
1732 NULL,
1733 N_("Icons _and Text"),
1734 NULL,
1735 N_("Display window buttons with icons and text"),
1736 GTK_TOOLBAR_BOTH_HORIZ },
1737
1738 { "switcher-style-user",
1739 NULL,
1740 N_("Tool_bar Style"),
1741 NULL,
1742 N_("Display window buttons using the desktop toolbar setting"),
1743 -1 }
1744 };
1745
1746 static GtkActionEntry shell_gal_view_entries[] = {
1747
1748 { "gal-define-views",
1749 NULL,
1750 N_("Define Views..."),
1751 NULL,
1752 N_("Create or edit views"),
1753 G_CALLBACK (action_gal_define_views_cb) },
1754
1755 { "gal-save-custom-view",
1756 NULL,
1757 N_("Save Custom View..."),
1758 NULL,
1759 N_("Save current custom view"),
1760 NULL }, /* Handled by subclasses. */
1761
1762 /*** Menus ***/
1763
1764 { "gal-view-menu",
1765 NULL,
1766 N_("C_urrent View"),
1767 NULL,
1768 NULL,
1769 NULL }
1770 };
1771
1772 static GtkRadioActionEntry shell_gal_view_radio_entries[] = {
1773
1774 { "gal-custom-view",
1775 NULL,
1776 N_("Custom View"),
1777 NULL,
1778 N_("Current view is a customized view"),
1779 -1 }
1780 };
1781
1782 static GtkActionEntry shell_lockdown_print_setup_entries[] = {
1783
1784 { "page-setup",
1785 GTK_STOCK_PAGE_SETUP,
1786 NULL,
1787 NULL,
1788 N_("Change the page settings for your current printer"),
1789 G_CALLBACK (action_page_setup_cb) }
1790 };
1791
1792 static void
1793 shell_window_extract_actions (EShellWindow *shell_window,
1794 GList **source_list,
1795 GList **destination_list)
1796 {
1797 const gchar *current_view;
1798 GList *match_list = NULL;
1799 GList *iter;
1800
1801 /* Pick out the actions from the source list that are tagged
1802 * as belonging to the current EShellView and move them to the
1803 * destination list. */
1804
1805 current_view = e_shell_window_get_active_view (shell_window);
1806
1807 /* Example: Suppose [A] and [C] are tagged for this EShellView.
1808 *
1809 * source_list = [A] -> [B] -> [C]
1810 * ^ ^
1811 * | |
1812 * match_list = [ ] --------> [ ]
1813 *
1814 *
1815 * destination_list = [1] -> [2] (other actions)
1816 */
1817 for (iter = *source_list; iter != NULL; iter = iter->next) {
1818 GtkAction *action = iter->data;
1819 const gchar *backend_name;
1820
1821 backend_name = g_object_get_data (
1822 G_OBJECT (action), "backend-name");
1823
1824 if (strcmp (backend_name, current_view) != 0)
1825 continue;
1826
1827 if (g_object_get_data (G_OBJECT (action), "primary"))
1828 match_list = g_list_prepend (match_list, iter);
1829 else
1830 match_list = g_list_append (match_list, iter);
1831 }
1832
1833 /* source_list = [B] match_list = [A] -> [C] */
1834 for (iter = match_list; iter != NULL; iter = iter->next) {
1835 GList *link = iter->data;
1836
1837 iter->data = link->data;
1838 *source_list = g_list_delete_link (*source_list, link);
1839 }
1840
1841 /* destination_list = [1] -> [2] -> [A] -> [C] */
1842 *destination_list = g_list_concat (*destination_list, match_list);
1843 }
1844
1845 void
1846 e_shell_window_actions_init (EShellWindow *shell_window)
1847 {
1848 GtkActionGroup *action_group;
1849 EFocusTracker *focus_tracker;
1850 GtkUIManager *ui_manager;
1851 gchar *path;
1852
1853 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
1854
1855 ui_manager = e_shell_window_get_ui_manager (shell_window);
1856 e_ui_manager_add_ui_from_file (
1857 E_UI_MANAGER (ui_manager), "evolution-shell.ui");
1858
1859 /* Shell Actions */
1860 action_group = ACTION_GROUP (SHELL);
1861 gtk_action_group_add_actions (
1862 action_group, shell_entries,
1863 G_N_ELEMENTS (shell_entries), shell_window);
1864 e_action_group_add_popup_actions (
1865 action_group, shell_popup_entries,
1866 G_N_ELEMENTS (shell_popup_entries));
1867 gtk_action_group_add_toggle_actions (
1868 action_group, shell_toggle_entries,
1869 G_N_ELEMENTS (shell_toggle_entries), shell_window);
1870 gtk_action_group_add_radio_actions (
1871 action_group, shell_switcher_style_entries,
1872 G_N_ELEMENTS (shell_switcher_style_entries),
1873 E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
1874 G_CALLBACK (action_switcher_style_cb), shell_window);
1875 gtk_action_group_add_actions (
1876 action_group, shell_gal_view_entries,
1877 G_N_ELEMENTS (shell_gal_view_entries), shell_window);
1878 gtk_action_group_add_radio_actions (
1879 action_group, shell_gal_view_radio_entries,
1880 G_N_ELEMENTS (shell_gal_view_radio_entries),
1881 0, G_CALLBACK (action_gal_view_cb), shell_window);
1882
1883 /* Switcher Actions */
1884 action_group = ACTION_GROUP (SWITCHER);
1885 gtk_action_group_add_radio_actions (
1886 action_group, shell_switcher_entries,
1887 G_N_ELEMENTS (shell_switcher_entries),
1888 -1, G_CALLBACK (action_switcher_cb), shell_window);
1889
1890 /* Lockdown Print Setup Actions */
1891 action_group = ACTION_GROUP (LOCKDOWN_PRINT_SETUP);
1892 gtk_action_group_add_actions (
1893 action_group, shell_lockdown_print_setup_entries,
1894 G_N_ELEMENTS (shell_lockdown_print_setup_entries),
1895 shell_window);
1896
1897 /* Configure an EFocusTracker to manage selection actions. */
1898
1899 focus_tracker = e_focus_tracker_new (GTK_WINDOW (shell_window));
1900 e_focus_tracker_set_cut_clipboard_action (
1901 focus_tracker, ACTION (CUT_CLIPBOARD));
1902 e_focus_tracker_set_copy_clipboard_action (
1903 focus_tracker, ACTION (COPY_CLIPBOARD));
1904 e_focus_tracker_set_paste_clipboard_action (
1905 focus_tracker, ACTION (PASTE_CLIPBOARD));
1906 e_focus_tracker_set_delete_selection_action (
1907 focus_tracker, ACTION (DELETE_SELECTION));
1908 e_focus_tracker_set_select_all_action (
1909 focus_tracker, ACTION (SELECT_ALL));
1910 shell_window->priv->focus_tracker = focus_tracker;
1911
1912 /* Fine tuning. */
1913
1914 gtk_action_set_sensitive (ACTION (SEARCH_QUICK), FALSE);
1915
1916 g_object_bind_property (
1917 shell_window, "sidebar-visible",
1918 ACTION (SHOW_SIDEBAR), "active",
1919 G_BINDING_BIDIRECTIONAL |
1920 G_BINDING_SYNC_CREATE);
1921
1922 g_object_bind_property (
1923 shell_window, "switcher-visible",
1924 ACTION (SHOW_SWITCHER), "active",
1925 G_BINDING_BIDIRECTIONAL |
1926 G_BINDING_SYNC_CREATE);
1927
1928 g_object_bind_property (
1929 shell_window, "taskbar-visible",
1930 ACTION (SHOW_TASKBAR), "active",
1931 G_BINDING_BIDIRECTIONAL |
1932 G_BINDING_SYNC_CREATE);
1933
1934 g_object_bind_property (
1935 shell_window, "toolbar-visible",
1936 ACTION (SHOW_TOOLBAR), "active",
1937 G_BINDING_BIDIRECTIONAL |
1938 G_BINDING_SYNC_CREATE);
1939
1940 g_object_bind_property (
1941 ACTION (SHOW_SIDEBAR), "active",
1942 ACTION (SHOW_SWITCHER), "sensitive",
1943 G_BINDING_SYNC_CREATE);
1944
1945 g_object_bind_property (
1946 ACTION (SHOW_SIDEBAR), "active",
1947 ACTION (SWITCHER_STYLE_BOTH), "sensitive",
1948 G_BINDING_SYNC_CREATE);
1949
1950 g_object_bind_property (
1951 ACTION (SHOW_SIDEBAR), "active",
1952 ACTION (SWITCHER_STYLE_ICONS), "sensitive",
1953 G_BINDING_SYNC_CREATE);
1954
1955 g_object_bind_property (
1956 ACTION (SHOW_SIDEBAR), "active",
1957 ACTION (SWITCHER_STYLE_TEXT), "sensitive",
1958 G_BINDING_SYNC_CREATE);
1959
1960 g_object_bind_property (
1961 ACTION (SHOW_SIDEBAR), "active",
1962 ACTION (SWITCHER_STYLE_USER), "sensitive",
1963 G_BINDING_SYNC_CREATE);
1964
1965 g_object_bind_property (
1966 ACTION (SHOW_SIDEBAR), "active",
1967 ACTION (SWITCHER_MENU), "sensitive",
1968 G_BINDING_SYNC_CREATE);
1969
1970 /* Submitting bug reports requires bug-buddy. */
1971 path = g_find_program_in_path ("bug-buddy");
1972 if (path == NULL)
1973 gtk_action_set_visible (ACTION (SUBMIT_BUG), FALSE);
1974 g_free (path);
1975
1976 /* Viewing user documentation requires the evolution-help
1977 * Fedora package. Look for one of the files it installs. */
1978 path = g_build_filename (
1979 EVOLUTION_DATADIR, "help", "C",
1980 PACKAGE, "index.page", NULL);
1981 if (!g_file_test (path, G_FILE_TEST_IS_REGULAR))
1982 gtk_action_set_visible (ACTION (CONTENTS), FALSE);
1983 g_free (path);
1984 }
1985
1986 static GList *
1987 express_filter_new_actions (GList *list)
1988 {
1989 GList *l, *filtered = NULL;
1990
1991 for (l = list; l; l = l->next) {
1992 const gchar *backend_name;
1993
1994 backend_name = g_object_get_data (
1995 G_OBJECT (l->data), "backend-name");
1996
1997 /* only the addressbook pieces in express mode */
1998 if (!strcmp (backend_name, "addressbook"))
1999 filtered = g_list_prepend (filtered, l->data);
2000 }
2001 g_list_free (list);
2002
2003 return g_list_reverse (filtered);
2004 }
2005
2006 GtkWidget *
2007 e_shell_window_create_new_menu (EShellWindow *shell_window)
2008 {
2009 EShell *shell;
2010 GtkActionGroup *action_group;
2011 GList *new_item_actions;
2012 GList *new_source_actions;
2013 GList *iter, *list = NULL;
2014 GtkWidget *menu;
2015 GtkWidget *separator;
2016
2017 shell = e_shell_window_get_shell (shell_window);
2018
2019 /* Get sorted lists of "new item" and "new source" actions. */
2020
2021 action_group = ACTION_GROUP (NEW_ITEM);
2022
2023 new_item_actions = g_list_sort (
2024 gtk_action_group_list_actions (action_group),
2025 (GCompareFunc) e_action_compare_by_label);
2026
2027 action_group = ACTION_GROUP (NEW_SOURCE);
2028
2029 new_source_actions = g_list_sort (
2030 gtk_action_group_list_actions (action_group),
2031 (GCompareFunc) e_action_compare_by_label);
2032
2033 /* Give priority to actions that belong to this shell view. */
2034
2035 shell_window_extract_actions (
2036 shell_window, &new_item_actions, &list);
2037
2038 shell_window_extract_actions (
2039 shell_window, &new_source_actions, &list);
2040
2041 /* Convert the actions to menu item proxy widgets. */
2042
2043 for (iter = list; iter != NULL; iter = iter->next)
2044 iter->data = gtk_action_create_menu_item (iter->data);
2045
2046 if (e_shell_get_express_mode (shell)) {
2047 new_item_actions = express_filter_new_actions (new_item_actions);
2048 g_list_free (new_source_actions);
2049 new_source_actions = NULL;
2050 }
2051
2052 for (iter = new_item_actions; iter != NULL; iter = iter->next)
2053 iter->data = gtk_action_create_menu_item (iter->data);
2054
2055 for (iter = new_source_actions; iter != NULL; iter = iter->next)
2056 iter->data = gtk_action_create_menu_item (iter->data);
2057
2058 /* Add menu separators. */
2059
2060 if (new_item_actions != NULL) {
2061 separator = gtk_separator_menu_item_new ();
2062 new_item_actions = g_list_prepend (new_item_actions, separator);
2063 gtk_widget_show (GTK_WIDGET (separator));
2064 }
2065
2066 if (new_source_actions != NULL) {
2067 separator = gtk_separator_menu_item_new ();
2068 new_source_actions = g_list_prepend (new_source_actions, separator);
2069 gtk_widget_show (GTK_WIDGET (separator));
2070 }
2071
2072 /* Merge everything into one list, reflecting the menu layout. */
2073
2074 list = g_list_concat (list, new_item_actions);
2075 new_item_actions = NULL; /* just for clarity */
2076
2077 list = g_list_concat (list, new_source_actions);
2078 new_source_actions = NULL; /* just for clarity */
2079
2080 /* And finally, build the menu. */
2081
2082 menu = gtk_menu_new ();
2083
2084 for (iter = list; iter != NULL; iter = iter->next)
2085 gtk_menu_shell_append (GTK_MENU_SHELL (menu), iter->data);
2086
2087 g_list_free (list);
2088
2089 return menu;
2090 }
2091
2092 static GtkAction *
2093 e_shell_window_create_switcher_action (GType type,
2094 EShellViewClass *class,
2095 const gchar *name,
2096 const gchar *tooltip,
2097 const gchar *view_name)
2098 {
2099 GtkAction *action;
2100
2101 action = g_object_new (
2102 type,
2103 "name", name,
2104 "label", class->label,
2105 "tooltip", tooltip,
2106 "icon-name", class->icon_name,
2107 NULL);
2108
2109 g_object_set_data (
2110 G_OBJECT (action),
2111 "view-name", (gpointer) view_name);
2112
2113 return action;
2114 }
2115
2116 /*
2117 * Create both the actions to switch the current window, and also
2118 * to create each view in a new window.
2119 */
2120 void
2121 e_shell_window_create_switcher_actions (EShellWindow *shell_window)
2122 {
2123 GSList *group = NULL;
2124 GtkRadioAction *s_action;
2125 GtkActionGroup *s_action_group;
2126 GtkActionGroup *n_action_group;
2127 GtkUIManager *ui_manager;
2128 EShellSwitcher *switcher;
2129 EShell *shell;
2130 GList *list, *iter;
2131 guint merge_id;
2132 guint ii = 0;
2133
2134 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
2135
2136 s_action_group = ACTION_GROUP (SWITCHER);
2137 n_action_group = ACTION_GROUP (NEW_WINDOW);
2138 switcher = E_SHELL_SWITCHER (shell_window->priv->switcher);
2139 ui_manager = e_shell_window_get_ui_manager (shell_window);
2140 merge_id = gtk_ui_manager_new_merge_id (ui_manager);
2141 shell = e_shell_window_get_shell (shell_window);
2142 list = e_shell_get_shell_backends (shell);
2143
2144 /* Construct a group of radio actions from the various EShellView
2145 * subclasses and register them with the EShellSwitcher. These
2146 * actions are manifested as switcher buttons and View->Window
2147 * menu items. */
2148
2149 s_action = GTK_RADIO_ACTION (ACTION (SWITCHER_INITIAL));
2150 gtk_radio_action_set_group (s_action, group);
2151 group = gtk_radio_action_get_group (s_action);
2152
2153 for (iter = list; iter != NULL; iter = iter->next) {
2154 EShellBackend *shell_backend = iter->data;
2155 EShellBackendClass *backend_class;
2156 EShellViewClass *class;
2157 GtkAction *n_action;
2158 GType view_type;
2159 const gchar *view_name;
2160 gchar *accelerator;
2161 gchar *s_action_name;
2162 gchar *n_action_name;
2163 gchar *tooltip;
2164
2165 /* The backend name is also the view name. */
2166 backend_class = E_SHELL_BACKEND_GET_CLASS (shell_backend);
2167 view_type = backend_class->shell_view_type;
2168 view_name = backend_class->name;
2169
2170 if (!g_type_is_a (view_type, E_TYPE_SHELL_VIEW)) {
2171 g_critical (
2172 "%s is not a subclass of %s",
2173 g_type_name (view_type),
2174 g_type_name (E_TYPE_SHELL_VIEW));
2175 continue;
2176 }
2177
2178 class = g_type_class_ref (view_type);
2179
2180 if (class->label == NULL) {
2181 g_critical (
2182 "Label member not set on %s",
2183 G_OBJECT_CLASS_NAME (class));
2184 continue;
2185 }
2186
2187 tooltip = g_strdup_printf (_("Switch to %s"), class->label);
2188
2189 s_action_name = g_strdup_printf (
2190 E_SHELL_SWITCHER_FORMAT, view_name);
2191
2192 /* Note, we have to set "icon-name" separately because
2193 * gtk_radio_action_new() expects a "stock-id". Sadly,
2194 * GTK+ still distinguishes between the two. */
2195
2196 s_action = GTK_RADIO_ACTION (
2197 e_shell_window_create_switcher_action (
2198 GTK_TYPE_RADIO_ACTION,
2199 class, s_action_name,
2200 tooltip, view_name));
2201 g_object_set (s_action, "value", ii++, NULL);
2202 gtk_radio_action_set_group (s_action, group);
2203 group = gtk_radio_action_get_group (s_action);
2204
2205 /* The first nine views have accelerators Ctrl+(1-9). */
2206 if (ii < 10)
2207 accelerator = g_strdup_printf ("<Control>%d", ii);
2208 else
2209 accelerator = g_strdup ("");
2210
2211 gtk_action_group_add_action_with_accel (
2212 s_action_group, GTK_ACTION (s_action), accelerator);
2213
2214 g_free (accelerator);
2215
2216 gtk_ui_manager_add_ui (
2217 ui_manager, merge_id,
2218 "/main-menu/view-menu/window-menu",
2219 s_action_name, s_action_name,
2220 GTK_UI_MANAGER_AUTO, FALSE);
2221 g_free (s_action_name);
2222
2223 /* Create in new window actions */
2224 n_action_name = g_strdup_printf (
2225 E_SHELL_NEW_WINDOW_FORMAT, view_name);
2226 n_action = e_shell_window_create_switcher_action (
2227 GTK_TYPE_ACTION,
2228 class, n_action_name,
2229 tooltip, view_name);
2230 g_signal_connect (
2231 n_action, "activate",
2232 G_CALLBACK (action_new_view_window_cb), shell_window);
2233 gtk_action_group_add_action (n_action_group, n_action);
2234
2235 e_shell_switcher_add_action (
2236 switcher, GTK_ACTION (s_action), n_action);
2237
2238 g_free (n_action_name);
2239 g_free (tooltip);
2240
2241 g_type_class_unref (class);
2242 }
2243 }
2244
2245 void
2246 e_shell_window_update_view_menu (EShellWindow *shell_window)
2247 {
2248 EShellView *shell_view;
2249 EShellViewClass *shell_view_class;
2250 GtkUIManager *ui_manager;
2251 GtkActionGroup *action_group;
2252 GalViewCollection *view_collection;
2253 GtkRadioAction *radio_action;
2254 GtkAction *action;
2255 GSList *radio_group;
2256 gboolean visible;
2257 const gchar *path;
2258 const gchar *view_id;
2259 const gchar *view_name;
2260 guint merge_id;
2261 gint count, ii;
2262
2263 ui_manager = e_shell_window_get_ui_manager (shell_window);
2264 view_name = e_shell_window_get_active_view (shell_window);
2265 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
2266 g_return_if_fail (shell_view != NULL);
2267
2268 shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
2269 view_collection = shell_view_class->view_collection;
2270 view_id = e_shell_view_get_view_id (shell_view);
2271 g_return_if_fail (view_collection != NULL);
2272
2273 action_group = ACTION_GROUP (GAL_VIEW);
2274 merge_id = shell_window->priv->gal_view_merge_id;
2275
2276 /* Unmerge the previous menu. */
2277 gtk_ui_manager_remove_ui (ui_manager, merge_id);
2278 e_action_group_remove_all_actions (action_group);
2279 gtk_ui_manager_ensure_update (ui_manager);
2280
2281 /* We have a view ID, so forge ahead. */
2282 count = gal_view_collection_get_count (view_collection);
2283 path = "/main-menu/view-menu/gal-view-menu/gal-view-list";
2284
2285 /* Prevent spurious activations. */
2286 action = ACTION (GAL_CUSTOM_VIEW);
2287 g_signal_handlers_block_matched (
2288 action, G_SIGNAL_MATCH_FUNC, 0, 0,
2289 NULL, action_gal_view_cb, NULL);
2290
2291 /* Default to "Custom View", unless we find our view ID. */
2292 radio_action = GTK_RADIO_ACTION (ACTION (GAL_CUSTOM_VIEW));
2293 gtk_radio_action_set_group (radio_action, NULL);
2294 radio_group = gtk_radio_action_get_group (radio_action);
2295 gtk_radio_action_set_current_value (radio_action, -1);
2296
2297 /* Add a menu item for each view collection item. */
2298 for (ii = 0; ii < count; ii++) {
2299 GalViewCollectionItem *item;
2300 gchar *action_name;
2301 gchar *tooltip, *title;
2302
2303 item = gal_view_collection_get_view_item (view_collection, ii);
2304
2305 action_name = g_strdup_printf (
2306 "gal-view-%s-%d", view_name, ii);
2307 title = e_str_without_underscores (item->title);
2308 tooltip = g_strdup_printf (_("Select view: %s"), title);
2309 g_free (title);
2310
2311 radio_action = gtk_radio_action_new (
2312 action_name, item->title, tooltip, NULL, ii);
2313
2314 action = GTK_ACTION (radio_action);
2315 gtk_radio_action_set_group (radio_action, radio_group);
2316 radio_group = gtk_radio_action_get_group (radio_action);
2317
2318 g_object_set_data_full (
2319 G_OBJECT (radio_action), "view-id",
2320 g_strdup (item->id), (GDestroyNotify) g_free);
2321
2322 if (view_id != NULL && strcmp (item->id, view_id) == 0)
2323 gtk_radio_action_set_current_value (radio_action, ii);
2324
2325 gtk_action_group_add_action (action_group, action);
2326
2327 gtk_ui_manager_add_ui (
2328 ui_manager, merge_id,
2329 path, action_name, action_name,
2330 GTK_UI_MANAGER_AUTO, FALSE);
2331
2332 g_free (action_name);
2333 g_free (tooltip);
2334 }
2335
2336 /* Doesn't matter which radio action we check. */
2337 visible = (gtk_radio_action_get_current_value (radio_action) < 0);
2338
2339 action = ACTION (GAL_CUSTOM_VIEW);
2340 gtk_action_set_visible (action, visible);
2341 g_signal_handlers_unblock_matched (
2342 action, G_SIGNAL_MATCH_FUNC, 0, 0,
2343 NULL, action_gal_view_cb, NULL);
2344
2345 action = ACTION (GAL_SAVE_CUSTOM_VIEW);
2346 gtk_action_set_visible (action, visible);
2347 }
2348
2349 void
2350 e_shell_window_update_search_menu (EShellWindow *shell_window)
2351 {
2352 EShellView *shell_view;
2353 EShellViewClass *shell_view_class;
2354 ERuleContext *context;
2355 EFilterRule *rule;
2356 GtkUIManager *ui_manager;
2357 GtkActionGroup *action_group;
2358 const gchar *source;
2359 const gchar *view_name;
2360 gboolean sensitive;
2361 guint merge_id;
2362 gint ii = 0;
2363
2364 g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
2365
2366 ui_manager = e_shell_window_get_ui_manager (shell_window);
2367 view_name = e_shell_window_get_active_view (shell_window);
2368 shell_view = e_shell_window_get_shell_view (shell_window, view_name);
2369
2370 /* Check for a NULL shell view before proceeding. This can
2371 * happen if the initial view name from GSettings is unrecognized.
2372 * Without this we would crash at E_SHELL_VIEW_GET_CLASS(). */
2373 g_return_if_fail (shell_view != NULL);
2374
2375 shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
2376 context = shell_view_class->search_context;
2377
2378 source = E_FILTER_SOURCE_INCOMING;
2379
2380 /* Update sensitivity of search_options action. */
2381 sensitive = (shell_view_class->search_options != NULL);
2382 gtk_action_set_sensitive (ACTION (SEARCH_OPTIONS), sensitive);
2383
2384 /* Add custom rules to the Search menu. */
2385
2386 action_group = ACTION_GROUP (CUSTOM_RULES);
2387 merge_id = shell_window->priv->custom_rule_merge_id;
2388
2389 /* Unmerge the previous menu. */
2390 gtk_ui_manager_remove_ui (ui_manager, merge_id);
2391 e_action_group_remove_all_actions (action_group);
2392 gtk_ui_manager_ensure_update (ui_manager);
2393
2394 rule = e_rule_context_next_rule (context, NULL, source);
2395 while (rule != NULL) {
2396 GtkAction *action;
2397 gchar *action_name;
2398 gchar *action_label;
2399
2400 action_name = g_strdup_printf ("custom-rule-%d", ii++);
2401 if (ii < 10)
2402 action_label = g_strdup_printf (
2403 "_%d. %s", ii, rule->name);
2404 else
2405 action_label = g_strdup (rule->name);
2406
2407 action = gtk_action_new (
2408 action_name, action_label,
2409 _("Execute these search parameters"), NULL);
2410
2411 g_object_set_data_full (
2412 G_OBJECT (action),
2413 "rule", g_object_ref (rule),
2414 (GDestroyNotify) g_object_unref);
2415
2416 g_signal_connect (
2417 action, "activate",
2418 G_CALLBACK (action_custom_rule_cb), shell_window);
2419
2420 gtk_action_group_add_action (action_group, action);
2421
2422 gtk_ui_manager_add_ui (
2423 ui_manager, merge_id,
2424 "/main-menu/search-menu/custom-rules",
2425 action_name, action_name,
2426 GTK_UI_MANAGER_AUTO, FALSE);
2427
2428 g_free (action_name);
2429 g_free (action_label);
2430
2431 rule = e_rule_context_next_rule (context, rule, source);
2432 }
2433 }