]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
Include gdkx.h only with X11. See bug #339172.
[evince.git] / shell / ev-application.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Martin Kretzschmar
4  *
5  *  Author:
6  *    Martin Kretzschmar <martink@gnome.org>
7  *
8  * Evince is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * Evince is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21  */
22
23 #include <config.h>
24
25 #include <stdlib.h>
26 #include <string.h>
27
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <gtk/gtk.h>
31 #ifdef GDK_WINDOWING_X11
32 #include <gdk/gdkx.h>
33 #endif
34
35 #include "totem-scrsaver.h"
36 #include "eggsmclient.h"
37
38 #include "ev-application.h"
39 #include "ev-document-factory.h"
40 #include "ev-file-helpers.h"
41 #include "ev-metadata-manager.h"
42 #include "ev-utils.h"
43
44 #ifdef ENABLE_DBUS
45 #include "ev-media-player-keys.h"
46 #endif /* ENABLE_DBUS */
47
48 #ifdef ENABLE_DBUS
49 #include <dbus/dbus-glib-bindings.h>
50 #include "ev-application-service.h"
51 #endif
52
53 static void ev_application_add_icon_path_for_screen (GdkScreen     *screen);
54 static void ev_application_save_print_settings      (EvApplication *application);
55
56 struct _EvApplication {
57         GObject base_instance;
58
59         gchar *dot_dir;
60         gchar *accel_map_file;
61         gchar *toolbars_file;
62
63         EggToolbarsModel *toolbars_model;
64
65         TotemScrsaver *scr_saver;
66
67         EggSMClient *smclient;
68
69         gchar *last_chooser_uri;
70
71 #ifdef ENABLE_DBUS
72         EvMediaPlayerKeys *keys;
73 #endif /* ENABLE_DBUS */
74
75         GtkPrintSettings *print_settings;
76         GtkPageSetup     *page_setup;
77         GKeyFile         *print_settings_file;
78 };
79
80 struct _EvApplicationClass {
81         GObjectClass base_class;
82 };
83
84 static EvApplication *instance;
85
86 G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT);
87
88 #define APPLICATION_SERVICE_NAME "org.gnome.evince.ApplicationService"
89
90 #define EV_PRINT_SETTINGS_FILE "print-settings"
91 #define EV_PRINT_SETTINGS_GROUP "Print Settings"
92 #define EV_PAGE_SETUP_GROUP "Page Setup"
93
94 #ifdef ENABLE_DBUS
95 gboolean
96 ev_application_register_service (EvApplication *application)
97 {
98         static DBusGConnection *connection = NULL;
99         DBusGProxy *driver_proxy;
100         GError *err = NULL;
101         guint request_name_result;
102
103         if (connection) {
104                 g_warning ("Service already registered.");
105                 return FALSE;
106         }
107         
108         connection = dbus_g_bus_get (DBUS_BUS_STARTER, &err);
109         if (connection == NULL) {
110                 g_warning ("Service registration failed.");
111                 g_error_free (err);
112
113                 return FALSE;
114         }
115
116         driver_proxy = dbus_g_proxy_new_for_name (connection,
117                                                   DBUS_SERVICE_DBUS,
118                                                   DBUS_PATH_DBUS,
119                                                   DBUS_INTERFACE_DBUS);
120
121         if (!org_freedesktop_DBus_request_name (driver_proxy,
122                                                 APPLICATION_SERVICE_NAME,
123                                                 DBUS_NAME_FLAG_DO_NOT_QUEUE,
124                                                 &request_name_result, &err)) {
125                 g_warning ("Service registration failed.");
126                 g_clear_error (&err);
127         }
128
129         g_object_unref (driver_proxy);
130         
131         if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS) {
132                 return FALSE;
133         }
134
135         dbus_g_object_type_install_info (EV_TYPE_APPLICATION,
136                                          &dbus_glib_ev_application_object_info);
137         dbus_g_connection_register_g_object (connection,
138                                              "/org/gnome/evince/Evince",
139                                              G_OBJECT (application));
140         
141         application->scr_saver = totem_scrsaver_new (connection);
142
143         ev_metadata_manager_init ();
144
145         return TRUE;
146 }
147 #endif /* ENABLE_DBUS */
148
149 /**
150  * ev_application_get_instance:
151  *
152  * Checks for #EvApplication instance, if it doesn't exist it does create it.
153  *
154  * Returns: an instance of the #EvApplication data.
155  */
156 EvApplication *
157 ev_application_get_instance (void)
158 {
159         if (!instance) {
160                 instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL));
161         }
162
163         return instance;
164 }
165
166 /* Session */
167 gboolean
168 ev_application_load_session (EvApplication *application)
169 {
170         GKeyFile *state_file;
171         gchar   **uri_list;
172         
173         if (!egg_sm_client_is_resumed (application->smclient))
174                 return FALSE;
175
176         state_file = egg_sm_client_get_state_file (application->smclient);
177         if (!state_file)
178                 return FALSE;
179
180         uri_list = g_key_file_get_string_list (state_file,
181                                                "Evince",
182                                                "documents",
183                                                NULL, NULL);
184         if (uri_list) {
185                 gint i;
186
187                 for (i = 0; uri_list[i]; i++) {
188                         if (g_ascii_strcasecmp (uri_list[i], "empty-window") == 0)
189                                 ev_application_open_window (application, NULL, GDK_CURRENT_TIME, NULL);
190                         else
191                                 ev_application_open_uri (application, uri_list[i], NULL, GDK_CURRENT_TIME, NULL);
192                 }
193                 g_strfreev (uri_list);
194         }
195         g_key_file_free (state_file);
196
197         return TRUE;
198 }
199
200 static void
201 smclient_save_state_cb (EggSMClient   *client,
202                         GKeyFile      *state_file,
203                         EvApplication *application)
204 {
205         GList *windows, *l;
206         gint i;
207         const gchar **uri_list;
208         const gchar *empty = "empty-window";
209
210         windows = ev_application_get_windows (application);
211         if (!windows)
212                 return;
213
214         uri_list = g_new (const gchar *, g_list_length (windows));
215         for (l = windows, i = 0; l != NULL; l = g_list_next (l), i++) {
216                 EvWindow *window = EV_WINDOW (l->data);
217
218                 if (ev_window_is_empty (window))
219                         uri_list[i] = empty;
220                 else
221                         uri_list[i] = ev_window_get_uri (window);
222         }
223         g_key_file_set_string_list (state_file,
224                                     "Evince",
225                                     "documents", 
226                                     (const char **)uri_list,
227                                     i);
228         g_free (uri_list);
229 }
230
231 static void
232 smclient_quit_cb (EggSMClient   *client,
233                   EvApplication *application)
234 {
235         ev_application_shutdown (application);
236 }
237
238 static void
239 ev_application_init_session (EvApplication *application)
240 {
241         application->smclient = egg_sm_client_get ();
242         g_signal_connect (application->smclient, "save_state",
243                           G_CALLBACK (smclient_save_state_cb),
244                           application);
245         g_signal_connect (application->smclient, "quit",
246                           G_CALLBACK (smclient_quit_cb),
247                           application);
248 }
249
250 /**
251  * ev_display_open_if_needed:
252  * @name: the name of the display to be open if it's needed.
253  *
254  * Search among all the open displays if any of them have the same name as the
255  * passed name. If the display isn't found it tries the open it.
256  *
257  * Returns: a #GdkDisplay of the display with the passed name.
258  */
259 static GdkDisplay *
260 ev_display_open_if_needed (const gchar *name)
261 {
262         GSList     *displays;
263         GSList     *l;
264         GdkDisplay *display = NULL;
265
266         displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
267
268         for (l = displays; l != NULL; l = l->next) {
269                 const gchar *display_name = gdk_display_get_name ((GdkDisplay *) l->data);
270
271                 if (g_ascii_strcasecmp (display_name, name) == 0) {
272                         display = l->data;
273                         break;
274                 }
275         }
276
277         g_slist_free (displays);
278
279         return display != NULL ? display : gdk_display_open (name);
280 }
281
282 /**
283  * get_screen_from_args:
284  * @args: a #GHashTable with data passed to the application.
285  *
286  * Looks for the screen in the display available in the hash table passed to the
287  * application. If the display isn't opened, it's opened and the #GdkScreen
288  * assigned to the screen in that display returned.
289  *
290  * Returns: the #GdkScreen assigned to the screen on the display indicated by
291  *          the data on the #GHashTable.
292  */
293 static GdkScreen *
294 get_screen_from_args (GHashTable *args)
295 {
296         GValue     *value = NULL;
297         GdkDisplay *display = NULL;
298         GdkScreen  *screen = NULL;
299
300         g_assert (args != NULL);
301         
302         value = g_hash_table_lookup (args, "display");
303         if (value) {
304                 const gchar *display_name;
305                 
306                 display_name = g_value_get_string (value);
307                 display = ev_display_open_if_needed (display_name);
308         }
309         
310         value = g_hash_table_lookup (args, "screen");
311         if (value) {
312                 gint screen_number;
313                 
314                 screen_number = g_value_get_int (value);
315                 screen = gdk_display_get_screen (display, screen_number);
316         }
317
318         return screen;
319 }
320
321 /**
322  * get_window_run_mode_from_args:
323  * @args: a #GHashTable with data passed to the application.
324  *
325  * It does look if the mode option has been passed from command line, using it
326  * as the window run mode, otherwise the run mode will be the normal mode.
327  *
328  * Returns: The window run mode passed from command line or
329  *          EV_WINDOW_MODE_NORMAL in other case.
330  */
331 static EvWindowRunMode
332 get_window_run_mode_from_args (GHashTable *args)
333 {
334         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
335         GValue          *value = NULL;
336
337         g_assert (args != NULL);
338
339         value = g_hash_table_lookup (args, "mode");
340         if (value) {
341                 mode = g_value_get_uint (value);
342         }
343
344         return mode;
345 }
346
347 /**
348  * get_destination_from_args:
349  * @args: a #GHashTable with data passed to the application.
350  *
351  * It does look for the page-label argument parsed from the command line and
352  * if it does exist, it returns an #EvLinkDest.
353  *
354  * Returns: An #EvLinkDest to page-label if it has been passed from the command
355  *          line, NULL in other case.
356  */
357 static EvLinkDest *
358 get_destination_from_args (GHashTable *args)
359 {
360         EvLinkDest *dest = NULL;
361         GValue     *value = NULL;
362         
363         g_assert (args != NULL);
364         
365         value = g_hash_table_lookup (args, "page-label");
366         if (value) {
367                 const gchar *page_label;
368
369                 page_label = g_value_get_string (value);
370                 dest = ev_link_dest_new_page_label (page_label);
371         }
372
373         return dest;
374 }
375
376 static const gchar *
377 get_find_string_from_args (GHashTable *args)
378 {
379         GValue *value = NULL;
380
381         g_assert (args != NULL);
382
383         value = g_hash_table_lookup (args, "find-string");
384         
385         return value ? g_value_get_string (value) : NULL;
386 }
387
388 /**
389  * get_unlink_temp_file_from_args:
390  * @args: a #GHashTable with data passed to the application.
391  *
392  * It does look if the unlink-temp-file option has been passed from the command
393  * line returning it's boolean representation, otherwise it does return %FALSE.
394  *
395  * Returns: the boolean representation of the unlink-temp-file value or %FALSE
396  *          in other case.
397  */
398 static gboolean
399 get_unlink_temp_file_from_args (GHashTable *args)
400 {
401         gboolean unlink_temp_file = FALSE;
402         GValue  *value = NULL;
403
404         g_assert (args != NULL);
405
406         value = g_hash_table_lookup (args, "unlink-temp-file");
407         if (value) {
408                 unlink_temp_file = g_value_get_boolean (value);
409         }
410         
411         return unlink_temp_file;
412 }
413
414 static const gchar *
415 get_print_settings_from_args (GHashTable *args)
416 {
417         const gchar *print_settings = NULL;
418         GValue      *value = NULL;
419
420         g_assert (args != NULL);
421
422         value = g_hash_table_lookup (args, "print-settings");
423         if (value) {
424                 print_settings = g_value_get_string (value);
425         }
426
427         return print_settings;
428 }
429
430 /**
431  * ev_application_open_window:
432  * @application: The instance of the application.
433  * @args: A #GHashTable with the arguments data.
434  * @timestamp: Current time value.
435  * @error: The #GError facility.
436  * 
437  * Creates a new window and if the args are available, it's not NULL, it gets
438  * the screen from them and assigns the just created window to it. At last it
439  * does show it.
440  *
441  * Returns: %TRUE.
442  */
443 gboolean
444 ev_application_open_window (EvApplication  *application,
445                             GHashTable     *args,
446                             guint32         timestamp,
447                             GError        **error)
448 {
449         GtkWidget *new_window = ev_window_new ();
450         GdkScreen *screen = NULL;
451
452         if (args) {
453                 screen = get_screen_from_args (args);
454         }
455         
456         if (screen) {
457                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
458         }
459         ev_application_add_icon_path_for_screen (screen);
460
461         if (!GTK_WIDGET_REALIZED (new_window))
462                 gtk_widget_realize (new_window);
463         
464 #ifdef GDK_WINDOWING_X11
465         if (timestamp <= 0)
466                 timestamp = gdk_x11_get_server_time (GTK_WIDGET (new_window)->window);
467         gdk_x11_window_set_user_time (GTK_WIDGET (new_window)->window, timestamp);
468         
469         gtk_window_present (GTK_WINDOW (new_window));
470 #else
471         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
472 #endif /* GDK_WINDOWING_X11 */
473
474         return TRUE;
475 }
476
477 /**
478  * ev_application_get_empty_window:
479  * @application: The instance of the application.
480  * @screen: The screen where the empty window will be search.
481  *
482  * It does look if there is any empty window in the indicated screen.
483  *
484  * Returns: The first empty #EvWindow in the passed #GdkScreen or NULL in other
485  *          case.
486  */
487 static EvWindow *
488 ev_application_get_empty_window (EvApplication *application,
489                                  GdkScreen     *screen)
490 {
491         EvWindow *empty_window = NULL;
492         GList *windows = ev_application_get_windows (application);
493         GList *l;
494
495         for (l = windows; l != NULL; l = l->next) {
496                 EvWindow *window = EV_WINDOW (l->data);
497
498                 if (ev_window_is_empty (window) &&
499                     gtk_window_get_screen (GTK_WINDOW (window)) == screen) {
500                         empty_window = window;
501                         break;
502                 }
503         }
504
505         g_list_free (windows);
506         
507         return empty_window;
508 }
509
510 /**
511  * ev_application_get_uri_window:
512  * @application: The instance of the application.
513  * @uri: The uri to be opened.
514  *
515  * It looks in the list of the windows for the one with the document represented
516  * by the passed uri on it. If the window is empty or the document isn't present
517  * on any window, it will return NULL.
518  *
519  * Returns: The #EvWindow where the document represented by the passed uri is
520  *          shown, NULL in other case.
521  */
522 static EvWindow *
523 ev_application_get_uri_window (EvApplication *application, const char *uri)
524 {
525         EvWindow *uri_window = NULL;
526         GList *windows = gtk_window_list_toplevels ();
527         GList *l;
528
529         g_return_val_if_fail (uri != NULL, NULL);
530
531         for (l = windows; l != NULL; l = l->next) {
532                 if (EV_IS_WINDOW (l->data)) {
533                         EvWindow *window = EV_WINDOW (l->data);
534                         const char *window_uri = ev_window_get_uri (window);
535
536                         if (window_uri && strcmp (window_uri, uri) == 0 && !ev_window_is_empty (window)) {
537                                 uri_window = window;
538                                 break;
539                         }
540                 }
541         }
542
543         g_list_free (windows);
544         
545         return uri_window;
546 }
547
548 static void
549 ev_application_add_icon_path_for_screen (GdkScreen *screen)
550 {
551         GtkIconTheme *icon_theme;
552
553         icon_theme = screen ? gtk_icon_theme_get_for_screen (screen) : gtk_icon_theme_get_default ();
554         if (icon_theme) {
555                 gchar **path = NULL;
556                 gint    n_paths;
557                 gint    i;
558                 gchar  *ev_icons_path;
559
560                 /* GtkIconTheme will then look in Evince custom hicolor dir
561                  * for icons as well as the standard search paths
562                  */
563                 ev_icons_path = g_build_filename (DATADIR, "icons", NULL);
564                 gtk_icon_theme_get_search_path (icon_theme, &path, &n_paths);
565                 for (i = n_paths - 1; i >= 0; i--) {
566                         if (g_ascii_strcasecmp (ev_icons_path, path[i]) == 0)
567                                 break;
568                 }
569
570                 if (i < 0)
571                         gtk_icon_theme_append_search_path (icon_theme,
572                                                            ev_icons_path);
573
574                 g_free (ev_icons_path);
575                 g_strfreev (path);
576         }       
577 }
578
579 /**
580  * ev_application_open_uri_at_dest:
581  * @application: The instance of the application.
582  * @uri: The uri to be opened.
583  * @screen: Thee screen where the link will be shown.
584  * @dest: The #EvLinkDest of the document.
585  * @mode: The run mode of the window.
586  * @unlink_temp_file: The unlink_temp_file option value.
587  * @timestamp: Current time value.
588  */
589 void
590 ev_application_open_uri_at_dest (EvApplication  *application,
591                                  const char     *uri,
592                                  GdkScreen      *screen,
593                                  EvLinkDest     *dest,
594                                  EvWindowRunMode mode,
595                                  const gchar    *search_string,
596                                  gboolean        unlink_temp_file,
597                                  const gchar    *print_settings, 
598                                  guint           timestamp)
599 {
600         EvWindow *new_window;
601
602         g_return_if_fail (uri != NULL);
603         
604         ev_application_add_icon_path_for_screen (screen);
605
606         new_window = ev_application_get_uri_window (application, uri);
607         
608         if (new_window == NULL) {
609                 new_window = ev_application_get_empty_window (application, screen);
610         }
611
612         if (new_window == NULL) {
613                 new_window = EV_WINDOW (ev_window_new ());
614         }
615
616         if (screen)
617                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
618
619         /* We need to load uri before showing the window, so
620            we can restore window size without flickering */     
621         ev_window_open_uri (new_window, uri, dest, mode, search_string, 
622                             unlink_temp_file, print_settings);
623
624         if (!GTK_WIDGET_REALIZED (GTK_WIDGET (new_window)))
625                 gtk_widget_realize (GTK_WIDGET (new_window));
626
627 #ifdef GDK_WINDOWING_X11
628         if (timestamp <= 0)
629                 timestamp = gdk_x11_get_server_time (GTK_WIDGET (new_window)->window);
630         gdk_x11_window_set_user_time (GTK_WIDGET (new_window)->window, timestamp);
631
632         ev_document_fc_mutex_lock ();
633         gtk_window_present (GTK_WINDOW (new_window));
634         ev_document_fc_mutex_unlock ();
635 #else
636         ev_document_fc_mutex_lock ();
637         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
638         ev_document_fc_mutex_unlock ();
639 #endif /* GDK_WINDOWING_X11 */
640 }
641
642 /**
643  * ev_application_open_uri:
644  * @application: The instance of the application.
645  * @uri: The uri to be opened
646  * @args: A #GHashTable with the arguments data.
647  * @timestamp: Current time value.
648  * @error: The #GError facility.
649  */
650 gboolean
651 ev_application_open_uri (EvApplication  *application,
652                          const char     *uri,
653                          GHashTable     *args,
654                          guint           timestamp,
655                          GError        **error)
656 {
657         EvLinkDest      *dest = NULL;
658         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
659         const gchar     *search_string = NULL;
660         gboolean         unlink_temp_file = FALSE;
661         const gchar     *print_settings = NULL;
662         GdkScreen       *screen = NULL;
663
664         if (args) {
665                 screen = get_screen_from_args (args);
666                 dest = get_destination_from_args (args);
667                 mode = get_window_run_mode_from_args (args);
668                 search_string = get_find_string_from_args (args);
669                 unlink_temp_file = (mode == EV_WINDOW_MODE_PREVIEW &&
670                                     get_unlink_temp_file_from_args (args));
671                 print_settings = get_print_settings_from_args (args);
672         }
673         
674         ev_application_open_uri_at_dest (application, uri, screen,
675                                          dest, mode, search_string,
676                                          unlink_temp_file,
677                                          print_settings, timestamp);
678
679         if (dest)
680                 g_object_unref (dest);
681
682         return TRUE;
683 }
684
685 void
686 ev_application_open_uri_list (EvApplication *application,
687                               GSList        *uri_list,
688                               GdkScreen     *screen,
689                               guint          timestamp)
690 {
691         GSList *l;
692
693         for (l = uri_list; l != NULL; l = l->next) {
694                 ev_application_open_uri_at_dest (application, (char *)l->data,
695                                                  screen, NULL, 0, NULL,
696                                                  FALSE, NULL, timestamp);
697         }
698 }
699
700 void
701 ev_application_shutdown (EvApplication *application)
702 {
703         if (application->accel_map_file) {
704                 gtk_accel_map_save (application->accel_map_file);
705                 g_free (application->accel_map_file);
706                 application->accel_map_file = NULL;
707         }
708         
709         if (application->toolbars_model) {
710                 g_object_unref (application->toolbars_model);
711                 g_free (application->toolbars_file);
712                 application->toolbars_model = NULL;
713                 application->toolbars_file = NULL;
714         }
715
716         ev_application_save_print_settings (application);
717         
718         if (application->print_settings_file) {
719                 g_key_file_free (application->print_settings_file);
720                 application->print_settings_file = NULL;
721         }
722
723         if (application->print_settings) {
724                 g_object_unref (application->print_settings);
725                 application->print_settings = NULL;
726         }
727
728         if (application->page_setup) {
729                 g_object_unref (application->page_setup);
730                 application->page_setup = NULL;
731         }
732
733 #ifdef ENABLE_DBUS
734         if (application->keys) {
735                 g_object_unref (application->keys);
736                 application->keys = NULL;
737         }
738 #endif /* ENABLE_DBUS */
739         
740         ev_metadata_manager_shutdown ();
741
742         g_free (application->dot_dir);
743         application->dot_dir = NULL;
744         g_free (application->last_chooser_uri);
745         application->last_chooser_uri = NULL;
746
747         g_object_unref (application);
748         instance = NULL;
749         
750         gtk_main_quit ();
751 }
752
753 static void
754 ev_application_class_init (EvApplicationClass *ev_application_class)
755 {
756 }
757
758 static void
759 ev_application_init (EvApplication *ev_application)
760 {
761         gint i;
762         const gchar *home_dir;
763         
764         ev_application_init_session (ev_application);
765
766         ev_application->dot_dir = g_build_filename (g_get_home_dir (),
767                                                     ".gnome2",
768                                                     "evince",
769                                                     NULL);
770
771         /* FIXME: why make this fatal? */
772         if (!ev_dir_ensure_exists (ev_application->dot_dir, 0700))
773                 exit (1);
774
775         home_dir = g_get_home_dir ();
776         if (home_dir) {
777                 ev_application->accel_map_file = g_build_filename (home_dir,
778                                                                    ".gnome2",
779                                                                    "accels"
780                                                                    "evince",
781                                                                    NULL);
782                 gtk_accel_map_load (ev_application->accel_map_file);
783         }
784         
785         ev_application->toolbars_model = egg_toolbars_model_new ();
786
787         ev_application->toolbars_file = g_build_filename
788                         (ev_application->dot_dir, "evince_toolbar.xml", NULL);
789
790         egg_toolbars_model_load_names (ev_application->toolbars_model,
791                                        DATADIR "/evince-toolbar.xml");
792
793         if (!egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
794                                                ev_application->toolbars_file)) {
795                 egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
796                                                   DATADIR"/evince-toolbar.xml");
797         }
798
799         /* Open item doesn't exist anymore,
800          * convert it to OpenRecent for compatibility
801          */
802         for (i = 0; i < egg_toolbars_model_n_items (ev_application->toolbars_model, 0); i++) {
803                 const gchar *item;
804                 
805                 item = egg_toolbars_model_item_nth (ev_application->toolbars_model, 0, i);
806                 if (g_ascii_strcasecmp (item, "FileOpen") == 0) {
807                         egg_toolbars_model_remove_item (ev_application->toolbars_model, 0, i);
808                         egg_toolbars_model_add_item (ev_application->toolbars_model, 0, i,
809                                                      "FileOpenRecent");
810                         ev_application_save_toolbars_model (ev_application);
811                         break;
812                 }
813         }
814
815         egg_toolbars_model_set_flags (ev_application->toolbars_model, 0,
816                                       EGG_TB_MODEL_NOT_REMOVABLE);
817
818 #ifdef ENABLE_DBUS
819         ev_application->keys = ev_media_player_keys_new ();
820 #endif /* ENABLE_DBUS */
821 }
822
823 /**
824  * ev_application_get_windows:
825  * @application: The instance of the application.
826  *
827  * It creates a list of the top level windows.
828  *
829  * Returns: A #GList of the top level windows.
830  */
831 GList *
832 ev_application_get_windows (EvApplication *application)
833 {
834         GList *l, *toplevels;
835         GList *windows = NULL;
836
837         toplevels = gtk_window_list_toplevels ();
838
839         for (l = toplevels; l != NULL; l = l->next) {
840                 if (EV_IS_WINDOW (l->data)) {
841                         windows = g_list_append (windows, l->data);
842                 }
843         }
844
845         g_list_free (toplevels);
846
847         return windows;
848 }
849
850 /**
851  * ev_application_get_media_keys:
852  * @application: The instance of the application.
853  *
854  * It gives you access to the media player keys handler object.
855  *
856  * Returns: A #EvMediaPlayerKeys.
857  */
858 GObject *
859 ev_application_get_media_keys (EvApplication *application)
860 {
861 #ifdef ENABLE_DBUS
862         return G_OBJECT (application->keys);
863 #else
864         return NULL;
865 #endif /* ENABLE_DBUS */
866 }
867
868 EggToolbarsModel *
869 ev_application_get_toolbars_model (EvApplication *application)
870 {
871         return application->toolbars_model;
872 }
873
874 void
875 ev_application_save_toolbars_model (EvApplication *application)
876 {
877         egg_toolbars_model_save_toolbars (application->toolbars_model,
878                                           application->toolbars_file, "1.0");
879 }
880
881 void
882 ev_application_set_chooser_uri (EvApplication *application, const gchar *uri)
883 {
884         g_free (application->last_chooser_uri);
885         application->last_chooser_uri = g_strdup (uri);
886 }
887
888 const gchar *
889 ev_application_get_chooser_uri (EvApplication *application)
890 {
891         return application->last_chooser_uri;
892 }
893
894 void
895 ev_application_screensaver_enable (EvApplication *application)
896 {
897         if (application->scr_saver)
898                 totem_scrsaver_enable (application->scr_saver); 
899 }
900
901 void
902 ev_application_screensaver_disable (EvApplication *application)
903 {
904         if (application->scr_saver)
905                 totem_scrsaver_disable (application->scr_saver);        
906 }
907
908 static GKeyFile *
909 ev_application_get_print_settings_file (EvApplication *application)
910 {
911         gchar *filename;
912         
913         if (application->print_settings_file)
914                 return application->print_settings_file;
915
916         application->print_settings_file = g_key_file_new ();
917         
918         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
919         if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
920                 GError *error = NULL;
921
922                 g_key_file_load_from_file (application->print_settings_file,
923                                            filename,
924                                            G_KEY_FILE_KEEP_COMMENTS |
925                                            G_KEY_FILE_KEEP_TRANSLATIONS,
926                                            &error);
927                 if (error) {
928                         g_warning ("%s", error->message);
929                         g_error_free (error);
930                 }
931         }
932         g_free (filename);
933
934         return application->print_settings_file;
935 }
936
937 static void
938 ev_application_save_print_settings (EvApplication *application)
939 {
940         GKeyFile *key_file;
941         gchar    *filename;
942         gchar    *data;
943         gssize    data_length;
944         GError   *error = NULL;
945
946         if (!application->print_settings && !application->page_setup)
947                 return;
948         
949         key_file = ev_application_get_print_settings_file (application);
950         if (application->print_settings)
951                 gtk_print_settings_to_key_file (application->print_settings,
952                                                 key_file,
953                                                 EV_PRINT_SETTINGS_GROUP);
954         if (application->page_setup)
955                 gtk_page_setup_to_key_file (application->page_setup,
956                                             key_file,
957                                             EV_PAGE_SETUP_GROUP);
958         
959         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
960         data = g_key_file_to_data (key_file, (gsize *)&data_length, NULL);
961         g_file_set_contents (filename, data, data_length, &error);
962         if (error) {
963                 g_warning ("%s", error->message);
964                 g_error_free (error);
965         }
966         g_free (data);
967         g_free (filename);
968 }
969
970 GtkPrintSettings *
971 ev_application_get_print_settings (EvApplication *application)
972 {
973         GKeyFile         *key_file;
974         GtkPrintSettings *print_settings;
975         
976         if (application->print_settings)
977                 return application->print_settings;
978
979         key_file = ev_application_get_print_settings_file (application);
980         print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ? 
981                 gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) :
982                 gtk_print_settings_new ();
983
984         application->print_settings = print_settings ? print_settings : gtk_print_settings_new ();
985
986         return application->print_settings;
987 }
988
989 void
990 ev_application_set_print_settings (EvApplication    *application,
991                                    GtkPrintSettings *settings)
992 {
993         GKeyFile *key_file;
994         
995         g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings));
996         
997         if (settings == application->print_settings)
998                 return;
999
1000         key_file = ev_application_get_print_settings_file (application);
1001         
1002         if (application->print_settings)
1003                 g_object_unref (application->print_settings);
1004         
1005         application->print_settings = g_object_ref (settings);
1006         gtk_print_settings_to_key_file (settings, key_file, EV_PRINT_SETTINGS_GROUP);
1007 }
1008
1009 GtkPageSetup *
1010 ev_application_get_page_setup (EvApplication *application)
1011 {
1012         GKeyFile     *key_file;
1013         GtkPageSetup *page_setup;
1014         
1015         if (application->page_setup)
1016                 return application->page_setup;
1017
1018         key_file = ev_application_get_print_settings_file (application);
1019         page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ? 
1020                 gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) :
1021                 gtk_page_setup_new ();
1022
1023         application->page_setup = page_setup ? page_setup : gtk_page_setup_new ();
1024
1025         return application->page_setup;
1026 }
1027
1028 void
1029 ev_application_set_page_setup (EvApplication *application,
1030                                GtkPageSetup  *page_setup)
1031 {
1032         GKeyFile *key_file;
1033         
1034         g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
1035         
1036         if (page_setup == application->page_setup)
1037                 return;
1038
1039         key_file = ev_application_get_print_settings_file (application);
1040         
1041         if (application->page_setup)
1042                 g_object_unref (application->page_setup);
1043         
1044         application->page_setup = g_object_ref (page_setup);
1045         gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP);
1046 }
1047
1048 const gchar *
1049 ev_application_get_dot_dir (EvApplication   *application)
1050 {
1051         return application->dot_dir;
1052 }