]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
8ce0899033ab2b0e89b534aca2df1e03add32675
[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 #include "ev-stock-icons.h"
44
45 #ifdef ENABLE_DBUS
46 #include "ev-media-player-keys.h"
47 #endif /* ENABLE_DBUS */
48
49 #ifdef ENABLE_DBUS
50 #include <dbus/dbus-glib-bindings.h>
51 #include "ev-application-service.h"
52 #endif
53
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                 ev_stock_icons_add_icons_path_for_screen (screen);
458                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
459         }
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 /**
549  * ev_application_open_uri_at_dest:
550  * @application: The instance of the application.
551  * @uri: The uri to be opened.
552  * @screen: Thee screen where the link will be shown.
553  * @dest: The #EvLinkDest of the document.
554  * @mode: The run mode of the window.
555  * @unlink_temp_file: The unlink_temp_file option value.
556  * @timestamp: Current time value.
557  */
558 void
559 ev_application_open_uri_at_dest (EvApplication  *application,
560                                  const char     *uri,
561                                  GdkScreen      *screen,
562                                  EvLinkDest     *dest,
563                                  EvWindowRunMode mode,
564                                  const gchar    *search_string,
565                                  gboolean        unlink_temp_file,
566                                  const gchar    *print_settings, 
567                                  guint           timestamp)
568 {
569         EvWindow *new_window;
570
571         g_return_if_fail (uri != NULL);
572         
573         new_window = ev_application_get_uri_window (application, uri);
574         
575         if (new_window == NULL) {
576                 new_window = ev_application_get_empty_window (application, screen);
577         }
578
579         if (new_window == NULL) {
580                 new_window = EV_WINDOW (ev_window_new ());
581         }
582
583         if (screen) {
584                 ev_stock_icons_add_icons_path_for_screen (screen);
585                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
586         }
587
588         /* We need to load uri before showing the window, so
589            we can restore window size without flickering */     
590         ev_window_open_uri (new_window, uri, dest, mode, search_string, 
591                             unlink_temp_file, print_settings);
592
593         if (!GTK_WIDGET_REALIZED (GTK_WIDGET (new_window)))
594                 gtk_widget_realize (GTK_WIDGET (new_window));
595
596 #ifdef GDK_WINDOWING_X11
597         if (timestamp <= 0)
598                 timestamp = gdk_x11_get_server_time (GTK_WIDGET (new_window)->window);
599         gdk_x11_window_set_user_time (GTK_WIDGET (new_window)->window, timestamp);
600
601         ev_document_fc_mutex_lock ();
602         gtk_window_present (GTK_WINDOW (new_window));
603         ev_document_fc_mutex_unlock ();
604 #else
605         ev_document_fc_mutex_lock ();
606         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
607         ev_document_fc_mutex_unlock ();
608 #endif /* GDK_WINDOWING_X11 */
609 }
610
611 /**
612  * ev_application_open_uri:
613  * @application: The instance of the application.
614  * @uri: The uri to be opened
615  * @args: A #GHashTable with the arguments data.
616  * @timestamp: Current time value.
617  * @error: The #GError facility.
618  */
619 gboolean
620 ev_application_open_uri (EvApplication  *application,
621                          const char     *uri,
622                          GHashTable     *args,
623                          guint           timestamp,
624                          GError        **error)
625 {
626         EvLinkDest      *dest = NULL;
627         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
628         const gchar     *search_string = NULL;
629         gboolean         unlink_temp_file = FALSE;
630         const gchar     *print_settings = NULL;
631         GdkScreen       *screen = NULL;
632
633         if (args) {
634                 screen = get_screen_from_args (args);
635                 dest = get_destination_from_args (args);
636                 mode = get_window_run_mode_from_args (args);
637                 search_string = get_find_string_from_args (args);
638                 unlink_temp_file = (mode == EV_WINDOW_MODE_PREVIEW &&
639                                     get_unlink_temp_file_from_args (args));
640                 print_settings = get_print_settings_from_args (args);
641         }
642         
643         ev_application_open_uri_at_dest (application, uri, screen,
644                                          dest, mode, search_string,
645                                          unlink_temp_file,
646                                          print_settings, timestamp);
647
648         if (dest)
649                 g_object_unref (dest);
650
651         return TRUE;
652 }
653
654 void
655 ev_application_open_uri_list (EvApplication *application,
656                               GSList        *uri_list,
657                               GdkScreen     *screen,
658                               guint          timestamp)
659 {
660         GSList *l;
661
662         for (l = uri_list; l != NULL; l = l->next) {
663                 ev_application_open_uri_at_dest (application, (char *)l->data,
664                                                  screen, NULL, 0, NULL,
665                                                  FALSE, NULL, timestamp);
666         }
667 }
668
669 void
670 ev_application_shutdown (EvApplication *application)
671 {
672         if (application->accel_map_file) {
673                 gtk_accel_map_save (application->accel_map_file);
674                 g_free (application->accel_map_file);
675                 application->accel_map_file = NULL;
676         }
677         
678         if (application->toolbars_model) {
679                 g_object_unref (application->toolbars_model);
680                 g_free (application->toolbars_file);
681                 application->toolbars_model = NULL;
682                 application->toolbars_file = NULL;
683         }
684
685         ev_application_save_print_settings (application);
686         
687         if (application->print_settings_file) {
688                 g_key_file_free (application->print_settings_file);
689                 application->print_settings_file = NULL;
690         }
691
692         if (application->print_settings) {
693                 g_object_unref (application->print_settings);
694                 application->print_settings = NULL;
695         }
696
697         if (application->page_setup) {
698                 g_object_unref (application->page_setup);
699                 application->page_setup = NULL;
700         }
701
702 #ifdef ENABLE_DBUS
703         if (application->keys) {
704                 g_object_unref (application->keys);
705                 application->keys = NULL;
706         }
707 #endif /* ENABLE_DBUS */
708         
709         ev_metadata_manager_shutdown ();
710
711         g_free (application->dot_dir);
712         application->dot_dir = NULL;
713         g_free (application->last_chooser_uri);
714         application->last_chooser_uri = NULL;
715
716         g_object_unref (application);
717         instance = NULL;
718         
719         gtk_main_quit ();
720 }
721
722 static void
723 ev_application_class_init (EvApplicationClass *ev_application_class)
724 {
725 }
726
727 static void
728 ev_application_init (EvApplication *ev_application)
729 {
730         gint i;
731         const gchar *home_dir;
732         
733         ev_application_init_session (ev_application);
734
735         ev_application->dot_dir = g_build_filename (g_get_home_dir (),
736                                                     ".gnome2",
737                                                     "evince",
738                                                     NULL);
739
740         /* FIXME: why make this fatal? */
741         if (!ev_dir_ensure_exists (ev_application->dot_dir, 0700))
742                 exit (1);
743
744         home_dir = g_get_home_dir ();
745         if (home_dir) {
746                 ev_application->accel_map_file = g_build_filename (home_dir,
747                                                                    ".gnome2",
748                                                                    "accels",
749                                                                    "evince",
750                                                                    NULL);
751                 gtk_accel_map_load (ev_application->accel_map_file);
752         }
753         
754         ev_application->toolbars_model = egg_toolbars_model_new ();
755
756         ev_application->toolbars_file = g_build_filename
757                         (ev_application->dot_dir, "evince_toolbar.xml", NULL);
758
759         egg_toolbars_model_load_names (ev_application->toolbars_model,
760                                        DATADIR "/evince-toolbar.xml");
761
762         if (!egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
763                                                ev_application->toolbars_file)) {
764                 egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
765                                                   DATADIR"/evince-toolbar.xml");
766         }
767
768         /* Open item doesn't exist anymore,
769          * convert it to OpenRecent for compatibility
770          */
771         for (i = 0; i < egg_toolbars_model_n_items (ev_application->toolbars_model, 0); i++) {
772                 const gchar *item;
773                 
774                 item = egg_toolbars_model_item_nth (ev_application->toolbars_model, 0, i);
775                 if (g_ascii_strcasecmp (item, "FileOpen") == 0) {
776                         egg_toolbars_model_remove_item (ev_application->toolbars_model, 0, i);
777                         egg_toolbars_model_add_item (ev_application->toolbars_model, 0, i,
778                                                      "FileOpenRecent");
779                         ev_application_save_toolbars_model (ev_application);
780                         break;
781                 }
782         }
783
784         egg_toolbars_model_set_flags (ev_application->toolbars_model, 0,
785                                       EGG_TB_MODEL_NOT_REMOVABLE);
786
787 #ifdef ENABLE_DBUS
788         ev_application->keys = ev_media_player_keys_new ();
789 #endif /* ENABLE_DBUS */
790 }
791
792 /**
793  * ev_application_get_windows:
794  * @application: The instance of the application.
795  *
796  * It creates a list of the top level windows.
797  *
798  * Returns: A #GList of the top level windows.
799  */
800 GList *
801 ev_application_get_windows (EvApplication *application)
802 {
803         GList *l, *toplevels;
804         GList *windows = NULL;
805
806         toplevels = gtk_window_list_toplevels ();
807
808         for (l = toplevels; l != NULL; l = l->next) {
809                 if (EV_IS_WINDOW (l->data)) {
810                         windows = g_list_append (windows, l->data);
811                 }
812         }
813
814         g_list_free (toplevels);
815
816         return windows;
817 }
818
819 /**
820  * ev_application_get_media_keys:
821  * @application: The instance of the application.
822  *
823  * It gives you access to the media player keys handler object.
824  *
825  * Returns: A #EvMediaPlayerKeys.
826  */
827 GObject *
828 ev_application_get_media_keys (EvApplication *application)
829 {
830 #ifdef ENABLE_DBUS
831         return G_OBJECT (application->keys);
832 #else
833         return NULL;
834 #endif /* ENABLE_DBUS */
835 }
836
837 EggToolbarsModel *
838 ev_application_get_toolbars_model (EvApplication *application)
839 {
840         return application->toolbars_model;
841 }
842
843 void
844 ev_application_save_toolbars_model (EvApplication *application)
845 {
846         egg_toolbars_model_save_toolbars (application->toolbars_model,
847                                           application->toolbars_file, "1.0");
848 }
849
850 void
851 ev_application_set_chooser_uri (EvApplication *application, const gchar *uri)
852 {
853         g_free (application->last_chooser_uri);
854         application->last_chooser_uri = g_strdup (uri);
855 }
856
857 const gchar *
858 ev_application_get_chooser_uri (EvApplication *application)
859 {
860         return application->last_chooser_uri;
861 }
862
863 void
864 ev_application_screensaver_enable (EvApplication *application)
865 {
866         if (application->scr_saver)
867                 totem_scrsaver_enable (application->scr_saver); 
868 }
869
870 void
871 ev_application_screensaver_disable (EvApplication *application)
872 {
873         if (application->scr_saver)
874                 totem_scrsaver_disable (application->scr_saver);        
875 }
876
877 static GKeyFile *
878 ev_application_get_print_settings_file (EvApplication *application)
879 {
880         gchar *filename;
881         
882         if (application->print_settings_file)
883                 return application->print_settings_file;
884
885         application->print_settings_file = g_key_file_new ();
886         
887         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
888         if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
889                 GError *error = NULL;
890
891                 g_key_file_load_from_file (application->print_settings_file,
892                                            filename,
893                                            G_KEY_FILE_KEEP_COMMENTS |
894                                            G_KEY_FILE_KEEP_TRANSLATIONS,
895                                            &error);
896                 if (error) {
897                         g_warning ("%s", error->message);
898                         g_error_free (error);
899                 }
900         }
901         g_free (filename);
902
903         return application->print_settings_file;
904 }
905
906 static void
907 ev_application_save_print_settings (EvApplication *application)
908 {
909         GKeyFile *key_file;
910         gchar    *filename;
911         gchar    *data;
912         gssize    data_length;
913         GError   *error = NULL;
914
915         if (!application->print_settings && !application->page_setup)
916                 return;
917         
918         key_file = ev_application_get_print_settings_file (application);
919         if (application->print_settings)
920                 gtk_print_settings_to_key_file (application->print_settings,
921                                                 key_file,
922                                                 EV_PRINT_SETTINGS_GROUP);
923         if (application->page_setup)
924                 gtk_page_setup_to_key_file (application->page_setup,
925                                             key_file,
926                                             EV_PAGE_SETUP_GROUP);
927         
928         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
929         data = g_key_file_to_data (key_file, (gsize *)&data_length, NULL);
930         g_file_set_contents (filename, data, data_length, &error);
931         if (error) {
932                 g_warning ("%s", error->message);
933                 g_error_free (error);
934         }
935         g_free (data);
936         g_free (filename);
937 }
938
939 GtkPrintSettings *
940 ev_application_get_print_settings (EvApplication *application)
941 {
942         GKeyFile         *key_file;
943         GtkPrintSettings *print_settings;
944         
945         if (application->print_settings)
946                 return application->print_settings;
947
948         key_file = ev_application_get_print_settings_file (application);
949         print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ? 
950                 gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) :
951                 gtk_print_settings_new ();
952
953         application->print_settings = print_settings ? print_settings : gtk_print_settings_new ();
954
955         return application->print_settings;
956 }
957
958 void
959 ev_application_set_print_settings (EvApplication    *application,
960                                    GtkPrintSettings *settings)
961 {
962         GKeyFile *key_file;
963         
964         g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings));
965         
966         if (settings == application->print_settings)
967                 return;
968
969         key_file = ev_application_get_print_settings_file (application);
970         
971         if (application->print_settings)
972                 g_object_unref (application->print_settings);
973         
974         application->print_settings = g_object_ref (settings);
975         gtk_print_settings_to_key_file (settings, key_file, EV_PRINT_SETTINGS_GROUP);
976 }
977
978 GtkPageSetup *
979 ev_application_get_page_setup (EvApplication *application)
980 {
981         GKeyFile     *key_file;
982         GtkPageSetup *page_setup;
983         
984         if (application->page_setup)
985                 return application->page_setup;
986
987         key_file = ev_application_get_print_settings_file (application);
988         page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ? 
989                 gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) :
990                 gtk_page_setup_new ();
991
992         application->page_setup = page_setup ? page_setup : gtk_page_setup_new ();
993
994         return application->page_setup;
995 }
996
997 void
998 ev_application_set_page_setup (EvApplication *application,
999                                GtkPageSetup  *page_setup)
1000 {
1001         GKeyFile *key_file;
1002         
1003         g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
1004         
1005         if (page_setup == application->page_setup)
1006                 return;
1007
1008         key_file = ev_application_get_print_settings_file (application);
1009         
1010         if (application->page_setup)
1011                 g_object_unref (application->page_setup);
1012         
1013         application->page_setup = g_object_ref (page_setup);
1014         gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP);
1015 }
1016
1017 const gchar *
1018 ev_application_get_dot_dir (EvApplication   *application)
1019 {
1020         return application->dot_dir;
1021 }