]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
Update all window copies of the same document when requesting a remote open_uri
[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
24 #include <config.h>
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
37 #ifdef WITH_SMCLIENT
38 #include "eggsmclient.h"
39 #endif
40
41 #include "ev-application.h"
42 #include "ev-document-factory.h"
43 #include "ev-file-helpers.h"
44 #include "ev-utils.h"
45 #include "ev-stock-icons.h"
46
47 #ifdef ENABLE_DBUS
48 #include "ev-media-player-keys.h"
49 #endif /* ENABLE_DBUS */
50
51 #ifdef ENABLE_DBUS
52 #include <dbus/dbus-glib-bindings.h>
53 static gboolean ev_application_open_uri (EvApplication  *application,
54                                          const char     *uri,
55                                          GHashTable     *args,
56                                          guint           timestamp,
57                                          GError        **error);
58 #include "ev-application-service.h"
59 #endif
60
61 static void ev_application_save_print_settings (EvApplication *application);
62
63 struct _EvApplication {
64         GObject base_instance;
65
66         gchar *uri;
67
68         gchar *dot_dir;
69         gchar *data_dir;
70         gchar *accel_map_file;
71         gchar *toolbars_file;
72
73 #ifdef ENABLE_DBUS
74         DBusGConnection *connection;
75         EvMediaPlayerKeys *keys;
76 #endif
77
78         EggToolbarsModel *toolbars_model;
79
80         TotemScrsaver *scr_saver;
81
82 #ifdef WITH_SMCLIENT
83         EggSMClient *smclient;
84 #endif
85
86         gchar *filechooser_open_uri;
87         gchar *filechooser_save_uri;
88
89         GtkPrintSettings *print_settings;
90         GtkPageSetup     *page_setup;
91         GKeyFile         *print_settings_file;
92 };
93
94 struct _EvApplicationClass {
95         GObjectClass base_class;
96 };
97
98 static EvApplication *instance;
99
100 G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT);
101
102 #ifdef ENABLE_DBUS
103 #define APPLICATION_DBUS_OBJECT_PATH "/org/gnome/evince/Evince"
104 #define APPLICATION_DBUS_INTERFACE   "org.gnome.evince.Application"
105 #endif
106
107 #define EV_PRINT_SETTINGS_FILE "print-settings"
108 #define EV_PRINT_SETTINGS_GROUP "Print Settings"
109 #define EV_PAGE_SETUP_GROUP "Page Setup"
110
111 /**
112  * ev_application_get_instance:
113  *
114  * Checks for #EvApplication instance, if it doesn't exist it does create it.
115  *
116  * Returns: an instance of the #EvApplication data.
117  */
118 EvApplication *
119 ev_application_get_instance (void)
120 {
121         if (!instance) {
122                 instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL));
123         }
124
125         return instance;
126 }
127
128 /* Session */
129 gboolean
130 ev_application_load_session (EvApplication *application)
131 {
132         GKeyFile *state_file;
133         gchar    *uri;
134
135 #ifdef WITH_SMCLIENT
136         if (egg_sm_client_is_resumed (application->smclient)) {
137                 state_file = egg_sm_client_get_state_file (application->smclient);
138                 if (!state_file)
139                         return FALSE;
140         } else
141 #endif /* WITH_SMCLIENT */
142                 return FALSE;
143
144         uri = g_key_file_get_string (state_file, "Evince", "uri", NULL);
145         if (!uri)
146                 return FALSE;
147
148         ev_application_open_uri_at_dest (application, uri,
149                                          gdk_screen_get_default (),
150                                          NULL, 0, NULL,
151                                          GDK_CURRENT_TIME);
152         g_free (uri);
153         g_key_file_free (state_file);
154
155         return TRUE;
156 }
157
158 #ifdef WITH_SMCLIENT
159
160 static void
161 smclient_save_state_cb (EggSMClient   *client,
162                         GKeyFile      *state_file,
163                         EvApplication *application)
164 {
165         if (!application->uri)
166                 return;
167
168         g_key_file_set_string (state_file, "Evince", "uri", application->uri);
169 }
170
171 static void
172 smclient_quit_cb (EggSMClient   *client,
173                   EvApplication *application)
174 {
175         ev_application_shutdown (application);
176 }
177 #endif /* WITH_SMCLIENT */
178
179 static void
180 ev_application_init_session (EvApplication *application)
181 {
182 #ifdef WITH_SMCLIENT
183         application->smclient = egg_sm_client_get ();
184         g_signal_connect (application->smclient, "save_state",
185                           G_CALLBACK (smclient_save_state_cb),
186                           application);
187         g_signal_connect (application->smclient, "quit",
188                           G_CALLBACK (smclient_quit_cb),
189                           application);
190 #endif
191 }
192
193 /**
194  * ev_display_open_if_needed:
195  * @name: the name of the display to be open if it's needed.
196  *
197  * Search among all the open displays if any of them have the same name as the
198  * passed name. If the display isn't found it tries the open it.
199  *
200  * Returns: a #GdkDisplay of the display with the passed name.
201  */
202 static GdkDisplay *
203 ev_display_open_if_needed (const gchar *name)
204 {
205         GSList     *displays;
206         GSList     *l;
207         GdkDisplay *display = NULL;
208
209         displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
210
211         for (l = displays; l != NULL; l = l->next) {
212                 const gchar *display_name = gdk_display_get_name ((GdkDisplay *) l->data);
213
214                 if (g_ascii_strcasecmp (display_name, name) == 0) {
215                         display = l->data;
216                         break;
217                 }
218         }
219
220         g_slist_free (displays);
221
222         return display != NULL ? display : gdk_display_open (name);
223 }
224
225 /**
226  * get_screen_from_args:
227  * @args: a #GHashTable with data passed to the application.
228  *
229  * Looks for the screen in the display available in the hash table passed to the
230  * application. If the display isn't opened, it's opened and the #GdkScreen
231  * assigned to the screen in that display returned.
232  *
233  * Returns: the #GdkScreen assigned to the screen on the display indicated by
234  *          the data on the #GHashTable.
235  */
236 static GdkScreen *
237 get_screen_from_args (GHashTable *args)
238 {
239         GValue     *value = NULL;
240         GdkDisplay *display = NULL;
241         GdkScreen  *screen = NULL;
242
243         g_assert (args != NULL);
244         
245         value = g_hash_table_lookup (args, "display");
246         if (value) {
247                 const gchar *display_name;
248                 
249                 display_name = g_value_get_string (value);
250                 display = ev_display_open_if_needed (display_name);
251         }
252         
253         value = g_hash_table_lookup (args, "screen");
254         if (value) {
255                 gint screen_number;
256                 
257                 screen_number = g_value_get_int (value);
258                 screen = gdk_display_get_screen (display, screen_number);
259         }
260
261         return screen;
262 }
263
264 /**
265  * get_window_run_mode_from_args:
266  * @args: a #GHashTable with data passed to the application.
267  *
268  * It does look if the mode option has been passed from command line, using it
269  * as the window run mode, otherwise the run mode will be the normal mode.
270  *
271  * Returns: The window run mode passed from command line or
272  *          EV_WINDOW_MODE_NORMAL in other case.
273  */
274 static EvWindowRunMode
275 get_window_run_mode_from_args (GHashTable *args)
276 {
277         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
278         GValue          *value = NULL;
279
280         g_assert (args != NULL);
281
282         value = g_hash_table_lookup (args, "mode");
283         if (value) {
284                 mode = g_value_get_uint (value);
285         }
286
287         return mode;
288 }
289
290 /**
291  * get_destination_from_args:
292  * @args: a #GHashTable with data passed to the application.
293  *
294  * It does look for the page-label argument parsed from the command line and
295  * if it does exist, it returns an #EvLinkDest.
296  *
297  * Returns: An #EvLinkDest to page-label if it has been passed from the command
298  *          line, NULL in other case.
299  */
300 static EvLinkDest *
301 get_destination_from_args (GHashTable *args)
302 {
303         EvLinkDest *dest = NULL;
304         GValue     *value = NULL;
305         
306         g_assert (args != NULL);
307         
308         value = g_hash_table_lookup (args, "page-label");
309         if (value) {
310                 const gchar *page_label;
311
312                 page_label = g_value_get_string (value);
313                 dest = ev_link_dest_new_page_label (page_label);
314         }
315
316         return dest;
317 }
318
319 static const gchar *
320 get_find_string_from_args (GHashTable *args)
321 {
322         GValue *value = NULL;
323
324         g_assert (args != NULL);
325
326         value = g_hash_table_lookup (args, "find-string");
327         
328         return value ? g_value_get_string (value) : NULL;
329 }
330
331 static void
332 value_free (GValue *value)
333 {
334         g_value_unset (value);
335         g_free (value);
336 }
337
338 static GHashTable *
339 build_args (GdkScreen      *screen,
340             EvLinkDest     *dest,
341             EvWindowRunMode mode,
342             const gchar    *search_string)
343 {
344         GHashTable  *args;
345         GValue      *value;
346         GdkDisplay  *display;
347         const gchar *display_name;
348         gint         screen_number;
349
350         args = g_hash_table_new_full (g_str_hash,
351                                       g_str_equal,
352                                       (GDestroyNotify)g_free,
353                                       (GDestroyNotify)value_free);
354
355         /* Display */
356         display = gdk_screen_get_display (screen);
357         display_name = gdk_display_get_name (display);
358         value = g_new0 (GValue, 1);
359         g_value_init (value, G_TYPE_STRING);
360         g_value_set_string (value, display_name);
361         g_hash_table_insert (args, g_strdup ("display"), value);
362
363         /* Screen */
364         screen_number = gdk_screen_get_number (screen);
365         value = g_new0 (GValue, 1);
366         g_value_init (value, G_TYPE_INT);
367         g_value_set_int (value, screen_number);
368         g_hash_table_insert (args, g_strdup ("screen"), value);
369
370         /* Page label */
371         if (dest) {
372                 value = g_new0 (GValue, 1);
373                 g_value_init (value, G_TYPE_STRING);
374                 g_value_set_string (value, ev_link_dest_get_page_label (dest));
375
376                 g_hash_table_insert (args, g_strdup ("page-label"), value);
377         }
378
379         /* Find string */
380         if (search_string) {
381                 value = g_new0 (GValue, 1);
382                 g_value_init (value, G_TYPE_STRING);
383                 g_value_set_string (value, search_string);
384
385                 g_hash_table_insert (args, g_strdup ("find-string"), value);
386         }
387
388         /* Mode */
389         if (mode != EV_WINDOW_MODE_NORMAL) {
390                 value = g_new0 (GValue, 1);
391                 g_value_init (value, G_TYPE_UINT);
392                 g_value_set_uint (value, mode);
393
394                 g_hash_table_insert (args, g_strdup ("mode"), value);
395         }
396
397         return args;
398 }
399
400 static void
401 child_setup (gpointer user_data)
402 {
403         gchar *startup_id;
404
405         startup_id = g_strdup_printf ("_TIME%lu",
406                                       (unsigned long)GPOINTER_TO_INT (user_data));
407         g_setenv ("DESKTOP_STARTUP_ID", startup_id, TRUE);
408         g_free (startup_id);
409 }
410
411 static void
412 ev_spawn (const char     *uri,
413           GdkScreen      *screen,
414           EvLinkDest     *dest,
415           EvWindowRunMode mode,
416           const gchar    *search_string,
417           guint           timestamp)
418 {
419         gchar   *argv[6];
420         guint    arg = 0;
421         gint     i;
422         gboolean res;
423         GError  *error = NULL;
424
425         argv[arg++] = g_build_filename (BINDIR, "evince", NULL);
426
427         /* Page label */
428         if (dest) {
429                 const gchar *page_label;
430
431                 page_label = ev_link_dest_get_page_label (dest);
432                 if (page_label)
433                         argv[arg++] = g_strdup_printf ("--page-label=%s", page_label);
434                 else
435                         argv[arg++] = g_strdup_printf ("--page-label=%d",
436                                                        ev_link_dest_get_page (dest));
437         }
438
439         /* Find string */
440         if (search_string) {
441                 argv[arg++] = g_strdup_printf ("--find=%s", search_string);
442         }
443
444         /* Mode */
445         switch (mode) {
446         case EV_WINDOW_MODE_FULLSCREEN:
447                 argv[arg++] = g_strdup ("-f");
448                 break;
449         case EV_WINDOW_MODE_PRESENTATION:
450                 argv[arg++] = g_strdup ("-s");
451                 break;
452         default:
453                 break;
454         }
455
456         argv[arg++] = (gchar *)uri;
457         argv[arg] = NULL;
458
459         res = gdk_spawn_on_screen (screen, NULL /* wd */, argv, NULL /* env */,
460                                    0,
461                                    child_setup,
462                                    GINT_TO_POINTER(timestamp),
463                                    NULL, &error);
464         if (!res) {
465                 g_warning ("Error launching evince %s: %s\n", uri, error->message);
466                 g_error_free (error);
467         }
468
469         for (i = 0; i < arg - 1; i++) {
470                 g_free (argv[i]);
471         }
472 }
473
474 static GList *
475 ev_application_get_windows (EvApplication *application)
476 {
477         GList *l, *toplevels;
478         GList *windows = NULL;
479
480         toplevels = gtk_window_list_toplevels ();
481
482         for (l = toplevels; l != NULL; l = l->next) {
483                 if (EV_IS_WINDOW (l->data)) {
484                         windows = g_list_append (windows, l->data);
485                 }
486         }
487
488         g_list_free (toplevels);
489
490         return windows;
491 }
492
493 static EvWindow *
494 ev_application_get_empty_window (EvApplication *application,
495                                  GdkScreen     *screen)
496 {
497         EvWindow *empty_window = NULL;
498         GList    *windows = ev_application_get_windows (application);
499         GList    *l;
500
501         for (l = windows; l != NULL; l = l->next) {
502                 EvWindow *window = EV_WINDOW (l->data);
503
504                 if (ev_window_is_empty (window) &&
505                     gtk_window_get_screen (GTK_WINDOW (window)) == screen) {
506                         empty_window = window;
507                         break;
508                 }
509         }
510
511         g_list_free (windows);
512
513         return empty_window;
514 }
515
516
517 #ifdef ENABLE_DBUS
518 static gboolean
519 ev_application_register_uri (EvApplication *application,
520                              const gchar   *uri,
521                              GHashTable    *args,
522                              guint          timestamp)
523 {
524         DBusGProxy *proxy;
525         gchar      *owner;
526         gboolean    retval = TRUE;
527         GError     *error = NULL;
528
529         if (!application->connection)
530                 return TRUE;
531
532         proxy = dbus_g_proxy_new_for_name (application->connection,
533                                            "org.gnome.evince.Daemon",
534                                            "/org/gnome/evince/Daemon",
535                                            "org.gnome.evince.Daemon");
536         if (!dbus_g_proxy_call (proxy, "RegisterDocument", &error,
537                                 G_TYPE_STRING, uri,
538                                 G_TYPE_INVALID,
539                                 G_TYPE_STRING, &owner,
540                                 G_TYPE_INVALID)) {
541                 g_warning ("Error registering document: %s\n", error->message);
542                 g_error_free (error);
543                 g_object_unref (proxy);
544
545                 return TRUE;
546         }
547         g_object_unref (proxy);
548
549         if (*owner == ':') {
550                 /* Already registered */
551                 proxy = dbus_g_proxy_new_for_name_owner (application->connection,
552                                                          owner,
553                                                          APPLICATION_DBUS_OBJECT_PATH,
554                                                          APPLICATION_DBUS_INTERFACE,
555                                                          &error);
556                 if (proxy) {
557                         if (!dbus_g_proxy_call (proxy, "OpenURI", &error,
558                                                 G_TYPE_STRING, uri,
559                                                 dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), args,
560                                                 G_TYPE_UINT, timestamp,
561                                                 G_TYPE_INVALID,
562                                                 G_TYPE_INVALID)) {
563                                 g_warning ("%s", error->message);
564                                 g_error_free (error);
565                         }
566                         g_object_unref (proxy);
567                 } else {
568                         g_warning ("Error creating proxy: %s\n", error->message);
569                         g_error_free (error);
570                 }
571
572                 /* Do not continue opening this document */
573                 retval = FALSE;
574         }
575
576         g_free (owner);
577
578         return retval;
579 }
580
581 static void
582 ev_application_unregister_uri (EvApplication *application,
583                                const gchar   *uri)
584 {
585         DBusGProxy *proxy;
586         GError     *error = NULL;
587
588         if (!application->connection)
589                 return;
590
591         proxy = dbus_g_proxy_new_for_name (application->connection,
592                                            "org.gnome.evince.Daemon",
593                                            "/org/gnome/evince/Daemon",
594                                            "org.gnome.evince.Daemon");
595         if (!dbus_g_proxy_call (proxy, "UnregisterDocument", &error,
596                                 G_TYPE_STRING, uri,
597                                 G_TYPE_INVALID,
598                                 G_TYPE_INVALID)) {
599                 g_warning ("Error unregistering document: %s\n", error->message);
600                 g_error_free (error);
601         }
602
603         g_object_unref (proxy);
604 }
605 #endif /* ENABLE_DBUS */
606
607 static void
608 ev_application_open_uri_in_window (EvApplication  *application,
609                                    const char     *uri,
610                                    EvWindow       *ev_window,
611                                    GdkScreen      *screen,
612                                    EvLinkDest     *dest,
613                                    EvWindowRunMode mode,
614                                    const gchar    *search_string,
615                                    guint           timestamp)
616 {
617         if (screen) {
618                 ev_stock_icons_set_screen (screen);
619                 gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
620         }
621
622         /* We need to load uri before showing the window, so
623            we can restore window size without flickering */
624         ev_window_open_uri (ev_window, uri, dest, mode, search_string);
625
626         if (!GTK_WIDGET_REALIZED (GTK_WIDGET (ev_window)))
627                 gtk_widget_realize (GTK_WIDGET (ev_window));
628
629 #ifdef GDK_WINDOWING_X11
630         if (timestamp <= 0)
631                 timestamp = gdk_x11_get_server_time (GTK_WIDGET (ev_window)->window);
632         gdk_x11_window_set_user_time (GTK_WIDGET (ev_window)->window, timestamp);
633
634         ev_document_fc_mutex_lock ();
635         gtk_window_present (GTK_WINDOW (ev_window));
636         ev_document_fc_mutex_unlock ();
637 #else
638         ev_document_fc_mutex_lock ();
639         gtk_window_present_with_time (GTK_WINDOW (ev_window), timestamp);
640         ev_document_fc_mutex_unlock ();
641 #endif /* GDK_WINDOWING_X11 */
642 }
643
644 /**
645  * ev_application_open_uri_at_dest:
646  * @application: The instance of the application.
647  * @uri: The uri to be opened.
648  * @screen: Thee screen where the link will be shown.
649  * @dest: The #EvLinkDest of the document.
650  * @mode: The run mode of the window.
651  * @timestamp: Current time value.
652  */
653 void
654 ev_application_open_uri_at_dest (EvApplication  *application,
655                                  const char     *uri,
656                                  GdkScreen      *screen,
657                                  EvLinkDest     *dest,
658                                  EvWindowRunMode mode,
659                                  const gchar    *search_string,
660                                  guint           timestamp)
661 {
662         EvWindow *ev_window;
663
664         g_return_if_fail (uri != NULL);
665
666         if (application->uri && strcmp (application->uri, uri) != 0) {
667                 /* spawn a new evince process */
668                 ev_spawn (uri, screen, dest, mode, search_string, timestamp);
669                 return;
670         } else {
671 #ifdef ENABLE_DBUS
672                 GHashTable *args = build_args (screen, dest, mode, search_string);
673                 gboolean    ret;
674
675                 /* Register the uri or send OpenURI to
676                  * remote instance if already registered
677                  */
678                 ret = ev_application_register_uri (application, uri, args, timestamp);
679                 g_hash_table_destroy (args);
680                 if (!ret)
681                         return;
682 #endif /* ENABLE_DBUS */
683
684                 ev_window = ev_application_get_empty_window (application, screen);
685                 if (!ev_window)
686                         ev_window = EV_WINDOW (ev_window_new ());
687         }
688
689         application->uri = g_strdup (uri);
690
691         ev_application_open_uri_in_window (application, uri, ev_window,
692                                            screen, dest, mode,
693                                            search_string,
694                                            timestamp);
695 }
696
697 /**
698  * ev_application_open_window:
699  * @application: The instance of the application.
700  * @timestamp: Current time value.
701  *
702  * Creates a new window
703  */
704 void
705 ev_application_open_window (EvApplication *application,
706                             GdkScreen     *screen,
707                             guint32        timestamp)
708 {
709         GtkWidget *new_window = ev_window_new ();
710
711         if (screen) {
712                 ev_stock_icons_set_screen (screen);
713                 gtk_window_set_screen (GTK_WINDOW (new_window), screen);
714         }
715
716         if (!GTK_WIDGET_REALIZED (new_window))
717                 gtk_widget_realize (new_window);
718
719 #ifdef GDK_WINDOWING_X11
720         if (timestamp <= 0)
721                 timestamp = gdk_x11_get_server_time (new_window->window);
722         gdk_x11_window_set_user_time (new_window->window, timestamp);
723
724         gtk_window_present (GTK_WINDOW (new_window));
725 #else
726         gtk_window_present_with_time (GTK_WINDOW (new_window), timestamp);
727 #endif /* GDK_WINDOWING_X11 */
728 }
729
730 /**
731  * ev_application_open_uri:
732  * @application: The instance of the application.
733  * @uri: The uri to be opened
734  * @args: A #GHashTable with the arguments data.
735  * @timestamp: Current time value.
736  * @error: The #GError facility.
737  */
738 static gboolean
739 ev_application_open_uri (EvApplication  *application,
740                          const char     *uri,
741                          GHashTable     *args,
742                          guint           timestamp,
743                          GError        **error)
744 {
745         GList           *windows, *l;
746         EvLinkDest      *dest = NULL;
747         EvWindowRunMode  mode = EV_WINDOW_MODE_NORMAL;
748         const gchar     *search_string = NULL;
749         GdkScreen       *screen = NULL;
750
751         g_assert (application->uri != NULL);
752
753         /* FIXME: we don't need uri anymore,
754          * maybe this method should be renamed
755          * as reload, refresh or something like that
756          */
757         if (!application->uri || strcmp (application->uri, uri)) {
758                 g_warning ("Invalid uri: %s, expected %s\n",
759                            uri, application->uri);
760                 return TRUE;
761         }
762
763         if (args) {
764                 screen = get_screen_from_args (args);
765                 dest = get_destination_from_args (args);
766                 mode = get_window_run_mode_from_args (args);
767                 search_string = get_find_string_from_args (args);
768         }
769
770         windows = ev_application_get_windows (application);
771         for (l = windows; l != NULL; l = g_list_next (l)) {
772                 EvWindow *ev_window = EV_WINDOW (l->data);
773
774                 ev_application_open_uri_in_window (application, uri, ev_window,
775                                                    screen, dest, mode,
776                                                    search_string,
777                                                    timestamp);
778         }
779         g_list_free (windows);
780
781         if (dest)
782                 g_object_unref (dest);
783
784         return TRUE;
785 }
786
787 void
788 ev_application_open_uri_list (EvApplication *application,
789                               GSList        *uri_list,
790                               GdkScreen     *screen,
791                               guint          timestamp)
792 {
793         GSList *l;
794
795         for (l = uri_list; l != NULL; l = l->next) {
796                 ev_application_open_uri_at_dest (application, (char *)l->data,
797                                                  screen, NULL, 0, NULL,
798                                                  timestamp);
799         }
800 }
801
802 void
803 ev_application_shutdown (EvApplication *application)
804 {
805         if (application->uri) {
806 #ifdef ENABLE_DBUS
807                 ev_application_unregister_uri (application,
808                                                application->uri);
809 #endif
810                 g_free (application->uri);
811                 application->uri = NULL;
812         }
813
814         if (application->accel_map_file) {
815                 gtk_accel_map_save (application->accel_map_file);
816                 g_free (application->accel_map_file);
817                 application->accel_map_file = NULL;
818         }
819         
820         if (application->toolbars_model) {
821                 g_object_unref (application->toolbars_model);
822                 g_free (application->toolbars_file);
823                 application->toolbars_model = NULL;
824                 application->toolbars_file = NULL;
825         }
826
827         ev_application_save_print_settings (application);
828         
829         if (application->print_settings_file) {
830                 g_key_file_free (application->print_settings_file);
831                 application->print_settings_file = NULL;
832         }
833
834         if (application->print_settings) {
835                 g_object_unref (application->print_settings);
836                 application->print_settings = NULL;
837         }
838
839         if (application->page_setup) {
840                 g_object_unref (application->page_setup);
841                 application->page_setup = NULL;
842         }
843
844 #ifdef ENABLE_DBUS
845         if (application->keys) {
846                 g_object_unref (application->keys);
847                 application->keys = NULL;
848         }
849 #endif /* ENABLE_DBUS */
850         
851         g_free (application->dot_dir);
852         application->dot_dir = NULL;
853         g_free (application->data_dir);
854         application->data_dir = NULL;
855         g_free (application->filechooser_open_uri);
856         application->filechooser_open_uri = NULL;
857         g_free (application->filechooser_save_uri);
858         application->filechooser_save_uri = NULL;
859
860         g_object_unref (application);
861         instance = NULL;
862         
863         gtk_main_quit ();
864 }
865
866 static void
867 ev_application_class_init (EvApplicationClass *ev_application_class)
868 {
869 #ifdef ENABLE_DBUS
870         dbus_g_object_type_install_info (EV_TYPE_APPLICATION,
871                                          &dbus_glib_ev_application_object_info);
872 #endif
873 }
874
875 static void
876 ev_application_init (EvApplication *ev_application)
877 {
878         gint i;
879         const gchar *home_dir;
880         gchar *toolbar_path;
881         GError *error = NULL;
882
883         ev_application->dot_dir = g_build_filename (g_get_home_dir (),
884                                                     ".gnome2",
885                                                     "evince",
886                                                     NULL);
887
888         /* FIXME: why make this fatal? */
889         if (!ev_dir_ensure_exists (ev_application->dot_dir, 0700))
890                 exit (1);
891
892 #ifdef G_OS_WIN32
893 {
894         gchar *dir;
895
896         dir = g_win32_get_package_installation_directory_of_module (NULL);
897         ev_application->data_dir = g_build_filename (dir, "share", "evince", NULL);
898         g_free (dir);
899 }
900 #else
901         ev_application->data_dir = g_strdup (DATADIR);
902 #endif
903
904         ev_application_init_session (ev_application);
905
906         home_dir = g_get_home_dir ();
907         if (home_dir) {
908                 ev_application->accel_map_file = g_build_filename (home_dir,
909                                                                    ".gnome2",
910                                                                    "accels",
911                                                                    "evince",
912                                                                    NULL);
913                 gtk_accel_map_load (ev_application->accel_map_file);
914         }
915         
916         ev_application->toolbars_model = egg_toolbars_model_new ();
917
918         ev_application->toolbars_file = g_build_filename
919                         (ev_application->dot_dir, "evince_toolbar.xml", NULL);
920
921         toolbar_path = g_build_filename (ev_application->data_dir,
922                                          "evince-toolbar.xml", NULL);
923         egg_toolbars_model_load_names (ev_application->toolbars_model,
924                                        toolbar_path);
925
926         if (!egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
927                                                ev_application->toolbars_file)) {
928                 egg_toolbars_model_load_toolbars (ev_application->toolbars_model,
929                                                   toolbar_path);
930         }
931         g_free (toolbar_path);
932
933         /* Open item doesn't exist anymore,
934          * convert it to OpenRecent for compatibility
935          */
936         for (i = 0; i < egg_toolbars_model_n_items (ev_application->toolbars_model, 0); i++) {
937                 const gchar *item;
938                 
939                 item = egg_toolbars_model_item_nth (ev_application->toolbars_model, 0, i);
940                 if (g_ascii_strcasecmp (item, "FileOpen") == 0) {
941                         egg_toolbars_model_remove_item (ev_application->toolbars_model, 0, i);
942                         egg_toolbars_model_add_item (ev_application->toolbars_model, 0, i,
943                                                      "FileOpenRecent");
944                         ev_application_save_toolbars_model (ev_application);
945                         break;
946                 }
947         }
948
949         egg_toolbars_model_set_flags (ev_application->toolbars_model, 0,
950                                       EGG_TB_MODEL_NOT_REMOVABLE);
951
952 #ifdef ENABLE_DBUS
953         ev_application->connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error);
954         if (ev_application->connection) {
955                 dbus_g_connection_register_g_object (ev_application->connection,
956                                                      APPLICATION_DBUS_OBJECT_PATH,
957                                                      G_OBJECT (ev_application));
958                 ev_application->scr_saver = totem_scrsaver_new (ev_application->connection);
959         } else {
960                 g_warning ("Error connection to DBus: %s\n", error->message);
961                 g_error_free (error);
962         }
963         ev_application->keys = ev_media_player_keys_new ();
964 #endif /* ENABLE_DBUS */
965 }
966
967 gboolean
968 ev_application_has_window (EvApplication *application)
969 {
970         GList   *windows = ev_application_get_windows (application);
971         gboolean retval = windows != NULL;
972
973         g_list_free (windows);
974
975         return retval;
976 }
977
978 const gchar *
979 ev_application_get_uri (EvApplication *application)
980 {
981         return application->uri;
982 }
983
984 /**
985  * ev_application_get_media_keys:
986  * @application: The instance of the application.
987  *
988  * It gives you access to the media player keys handler object.
989  *
990  * Returns: A #EvMediaPlayerKeys.
991  */
992 GObject *
993 ev_application_get_media_keys (EvApplication *application)
994 {
995 #ifdef ENABLE_DBUS
996         return G_OBJECT (application->keys);
997 #else
998         return NULL;
999 #endif /* ENABLE_DBUS */
1000 }
1001
1002 EggToolbarsModel *
1003 ev_application_get_toolbars_model (EvApplication *application)
1004 {
1005         return application->toolbars_model;
1006 }
1007
1008 void
1009 ev_application_save_toolbars_model (EvApplication *application)
1010 {
1011         egg_toolbars_model_save_toolbars (application->toolbars_model,
1012                                           application->toolbars_file, "1.0");
1013 }
1014
1015 void
1016 ev_application_set_filechooser_uri (EvApplication       *application,
1017                                     GtkFileChooserAction action,
1018                                     const gchar         *uri)
1019 {
1020         if (action == GTK_FILE_CHOOSER_ACTION_OPEN) {
1021                 g_free (application->filechooser_open_uri);
1022                 application->filechooser_open_uri = g_strdup (uri);
1023         } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
1024                 g_free (application->filechooser_save_uri);
1025                 application->filechooser_save_uri = g_strdup (uri);
1026         }
1027 }
1028
1029 const gchar *
1030 ev_application_get_filechooser_uri (EvApplication       *application,
1031                                     GtkFileChooserAction action)
1032 {
1033         if (action == GTK_FILE_CHOOSER_ACTION_OPEN) {
1034                 if (application->filechooser_open_uri)
1035                         return application->filechooser_open_uri;
1036         } else if (action == GTK_FILE_CHOOSER_ACTION_SAVE) {
1037                 if (application->filechooser_save_uri)
1038                         return application->filechooser_save_uri;
1039         }
1040
1041         return NULL;
1042 }
1043
1044 void
1045 ev_application_screensaver_enable (EvApplication *application)
1046 {
1047         if (application->scr_saver)
1048                 totem_scrsaver_enable (application->scr_saver); 
1049 }
1050
1051 void
1052 ev_application_screensaver_disable (EvApplication *application)
1053 {
1054         if (application->scr_saver)
1055                 totem_scrsaver_disable (application->scr_saver);        
1056 }
1057
1058 static GKeyFile *
1059 ev_application_get_print_settings_file (EvApplication *application)
1060 {
1061         gchar *filename;
1062         
1063         if (application->print_settings_file)
1064                 return application->print_settings_file;
1065
1066         application->print_settings_file = g_key_file_new ();
1067         
1068         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
1069         if (g_file_test (filename, G_FILE_TEST_IS_REGULAR)) {
1070                 GError *error = NULL;
1071
1072                 g_key_file_load_from_file (application->print_settings_file,
1073                                            filename,
1074                                            G_KEY_FILE_KEEP_COMMENTS |
1075                                            G_KEY_FILE_KEEP_TRANSLATIONS,
1076                                            &error);
1077                 if (error) {
1078                         g_warning ("%s", error->message);
1079                         g_error_free (error);
1080                 }
1081         }
1082         g_free (filename);
1083
1084         return application->print_settings_file;
1085 }
1086
1087 static void
1088 ev_application_save_print_settings (EvApplication *application)
1089 {
1090         GKeyFile *key_file;
1091         gchar    *filename;
1092         gchar    *data;
1093         gssize    data_length;
1094         GError   *error = NULL;
1095
1096         if (!application->print_settings && !application->page_setup)
1097                 return;
1098         
1099         key_file = ev_application_get_print_settings_file (application);
1100         if (application->print_settings)
1101                 gtk_print_settings_to_key_file (application->print_settings,
1102                                                 key_file,
1103                                                 EV_PRINT_SETTINGS_GROUP);
1104         if (application->page_setup)
1105                 gtk_page_setup_to_key_file (application->page_setup,
1106                                             key_file,
1107                                             EV_PAGE_SETUP_GROUP);
1108         
1109         filename = g_build_filename (ev_application_get_dot_dir (application), EV_PRINT_SETTINGS_FILE, NULL);
1110         data = g_key_file_to_data (key_file, (gsize *)&data_length, NULL);
1111         g_file_set_contents (filename, data, data_length, &error);
1112         if (error) {
1113                 g_warning ("%s", error->message);
1114                 g_error_free (error);
1115         }
1116         g_free (data);
1117         g_free (filename);
1118 }
1119
1120 GtkPrintSettings *
1121 ev_application_get_print_settings (EvApplication *application)
1122 {
1123         GKeyFile         *key_file;
1124         GtkPrintSettings *print_settings;
1125         
1126         if (application->print_settings)
1127                 return application->print_settings;
1128
1129         key_file = ev_application_get_print_settings_file (application);
1130         print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ? 
1131                 gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) :
1132                 gtk_print_settings_new ();
1133
1134         application->print_settings = print_settings ? print_settings : gtk_print_settings_new ();
1135
1136         return application->print_settings;
1137 }
1138
1139 void
1140 ev_application_set_print_settings (EvApplication    *application,
1141                                    GtkPrintSettings *settings)
1142 {
1143         GKeyFile *key_file;
1144         
1145         g_return_if_fail (GTK_IS_PRINT_SETTINGS (settings));
1146         
1147         if (settings == application->print_settings)
1148                 return;
1149
1150         key_file = ev_application_get_print_settings_file (application);
1151         
1152         if (application->print_settings)
1153                 g_object_unref (application->print_settings);
1154         
1155         application->print_settings = g_object_ref (settings);
1156         gtk_print_settings_to_key_file (settings, key_file, EV_PRINT_SETTINGS_GROUP);
1157 }
1158
1159 GtkPageSetup *
1160 ev_application_get_page_setup (EvApplication *application)
1161 {
1162         GKeyFile     *key_file;
1163         GtkPageSetup *page_setup;
1164         
1165         if (application->page_setup)
1166                 return application->page_setup;
1167
1168         key_file = ev_application_get_print_settings_file (application);
1169         page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ? 
1170                 gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) :
1171                 gtk_page_setup_new ();
1172
1173         application->page_setup = page_setup ? page_setup : gtk_page_setup_new ();
1174
1175         return application->page_setup;
1176 }
1177
1178 void
1179 ev_application_set_page_setup (EvApplication *application,
1180                                GtkPageSetup  *page_setup)
1181 {
1182         GKeyFile *key_file;
1183         
1184         g_return_if_fail (GTK_IS_PAGE_SETUP (page_setup));
1185         
1186         if (page_setup == application->page_setup)
1187                 return;
1188
1189         key_file = ev_application_get_print_settings_file (application);
1190         
1191         if (application->page_setup)
1192                 g_object_unref (application->page_setup);
1193         
1194         application->page_setup = g_object_ref (page_setup);
1195         gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP);
1196 }
1197
1198 const gchar *
1199 ev_application_get_dot_dir (EvApplication   *application)
1200 {
1201         return application->dot_dir;
1202 }
1203
1204 const gchar *
1205 ev_application_get_data_dir (EvApplication   *application)
1206 {
1207         return application->data_dir;
1208 }