]> www.fi.muni.cz Git - evince.git/blob - shell/ev-application.c
Fix window size persistance
[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 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "ev-application.h"
28 #include "ev-utils.h"
29 #include "ev-document-types.h"
30 #include "ev-file-helpers.h"
31
32 #include <glib.h>
33 #include <glib/gi18n.h>
34 #include <glib-object.h>
35 #include <gtk/gtkfilechooserdialog.h>
36 #include <gtk/gtkstock.h>
37 #include <gtk/gtkwidget.h>
38 #include <gtk/gtkmain.h>
39 #include <string.h>
40
41 #ifdef ENABLE_DBUS
42 #include "ev-application-service.h"
43 #include <dbus/dbus-glib-bindings.h>
44 #endif
45
46 G_DEFINE_TYPE (EvApplication, ev_application, G_TYPE_OBJECT);
47
48 #define EV_APPLICATION_GET_PRIVATE(object) \
49         (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_APPLICATION, EvApplicationPrivate))
50
51 #define APPLICATION_SERVICE_NAME "org.gnome.evince.ApplicationService"
52
53 #ifdef ENABLE_DBUS
54 gboolean
55 ev_application_register_service (EvApplication *application)
56 {
57         DBusGConnection *connection;
58         DBusGProxy *driver_proxy;
59         GError *err = NULL;
60         guint request_name_result;
61
62         connection = dbus_g_bus_get (DBUS_BUS_STARTER, &err);
63         if (connection == NULL) {
64                 g_warning ("Service registration failed.");
65                 g_error_free (err);
66
67                 return FALSE;
68         }
69
70         driver_proxy = dbus_g_proxy_new_for_name (connection,
71                                                   DBUS_SERVICE_DBUS,
72                                                   DBUS_PATH_DBUS,
73                                                   DBUS_INTERFACE_DBUS);
74
75         if (!org_freedesktop_DBus_request_name (driver_proxy,
76                                                 APPLICATION_SERVICE_NAME,
77                                                 0, &request_name_result, &err)) {
78                 g_warning ("Service registration failed.");
79                 g_clear_error (&err);
80         }
81
82         if (request_name_result == DBUS_REQUEST_NAME_REPLY_EXISTS) {
83                 return FALSE;
84         }
85
86 #if DBUS_VERSION == 33
87         dbus_g_object_class_install_info (G_OBJECT_GET_CLASS (application),
88                                           &dbus_glib_ev_application_object_info);
89 #else
90         dbus_g_object_type_install_info (EV_TYPE_APPLICATION,
91                                          &dbus_glib_ev_application_object_info);
92 #endif
93
94         dbus_g_connection_register_g_object (connection,
95                                              "/org/gnome/evince/Evince",
96                                              G_OBJECT (application));
97
98         return TRUE;
99 }
100 #endif /* ENABLE_DBUS */
101
102 EvApplication *
103 ev_application_get_instance (void)
104 {
105         static EvApplication *instance;
106
107         if (!instance) {
108                 instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL));
109         }
110
111         return instance;
112 }
113
114 gboolean
115 ev_application_open_window (EvApplication  *application,
116                             guint32         timestamp,
117                             GError        **error)
118 {
119         GtkWidget *new_window = ev_window_new ();
120
121         gtk_widget_show (new_window);
122         
123 #ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME
124         gtk_window_present_with_time (GTK_WINDOW (new_window),
125                                       timestamp);
126 #else
127         gtk_window_present (GTK_WINDOW (new_window));
128 #endif
129
130         return TRUE;
131 }
132
133 static EvWindow *
134 ev_application_get_empty_window (EvApplication *application)
135 {
136         EvWindow *empty_window = NULL;
137         GList *windows = gtk_window_list_toplevels ();
138         GList *l;
139
140         for (l = windows; l != NULL; l = l->next) {
141                 if (EV_IS_WINDOW (l->data)) {
142                         EvWindow *window = EV_WINDOW (l->data);
143
144                         if (ev_window_is_empty (window)) {
145                                 empty_window = window;
146                                 break;
147                         }
148                 }
149         }
150
151         g_list_free (windows);
152         
153         return empty_window;
154 }
155
156 static EvWindow *
157 ev_application_get_uri_window (EvApplication *application, const char *uri)
158 {
159         EvWindow *uri_window = NULL;
160         GList *windows = gtk_window_list_toplevels ();
161         GList *l;
162
163         g_return_val_if_fail (uri != NULL, NULL);
164
165         for (l = windows; l != NULL; l = l->next) {
166                 if (EV_IS_WINDOW (l->data)) {
167                         EvWindow *window = EV_WINDOW (l->data);
168                         const char *window_uri = ev_window_get_uri (window);
169
170                         if (window_uri && strcmp (window_uri, uri) == 0) {
171                                 uri_window = window;
172                                 break;
173                         }
174                 }
175         }
176
177         g_list_free (windows);
178         
179         return uri_window;
180 }
181
182 gboolean
183 ev_application_open_uri (EvApplication  *application,
184                          const char     *uri,
185                          const char     *page_label,
186                          guint           timestamp,
187                          GError        **error)
188 {
189         EvWindow *new_window;
190
191         g_return_val_if_fail (uri != NULL, FALSE);
192
193         new_window = ev_application_get_uri_window (application, uri);
194         if (new_window != NULL) {
195 #ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME
196                 gtk_window_present_with_time (GTK_WINDOW (new_window),
197                                               timestamp);
198 #else
199                 gtk_window_present (GTK_WINDOW (new_window));
200 #endif  
201                 return TRUE;
202         }
203
204         new_window = ev_application_get_empty_window (application);
205
206         if (new_window == NULL) {
207                 new_window = EV_WINDOW (ev_window_new ());
208         }
209
210         /* We need to load uri before showing the window, so
211            we can restore window size without flickering */     
212         ev_window_open_uri (new_window, uri);
213
214         gtk_widget_show (GTK_WIDGET (new_window));
215
216 #ifdef HAVE_GTK_WINDOW_PRESENT_WITH_TIME
217         gtk_window_present_with_time (GTK_WINDOW (new_window),
218                                       timestamp);
219 #else
220         gtk_window_present (GTK_WINDOW (new_window));
221 #endif
222
223         if (page_label != NULL) {
224                 ev_window_open_page_label (new_window, page_label);
225         }
226
227         return TRUE;
228 }
229
230 void
231 ev_application_open_uri_list (EvApplication *application,
232                               GSList        *uri_list,
233                               guint          timestamp)
234 {
235         GSList *l;
236
237         for (l = uri_list; l != NULL; l = l->next) {
238                 ev_application_open_uri (application, (char *)l->data,
239                                          NULL,
240                                          timestamp,
241                                          NULL);
242         }
243 }
244
245 void
246 ev_application_shutdown (EvApplication *application)
247 {
248         if (application->toolbars_model) {
249                 g_object_unref (application->toolbars_model);
250                 g_free (application->toolbars_file);
251                 application->toolbars_model = NULL;
252                 application->toolbars_file = NULL;
253         }
254
255         if (application->recent_model) {
256                 g_object_unref (application->recent_model);
257                 application->recent_model = NULL;
258         }
259
260         g_object_unref (application);
261         gtk_main_quit ();
262 }
263
264 static void
265 ev_application_class_init (EvApplicationClass *ev_application_class)
266 {
267 }
268
269 static void
270 ev_application_init (EvApplication *ev_application)
271 {
272         ev_application->toolbars_model = egg_toolbars_model_new ();
273
274         ev_application->toolbars_file = g_build_filename
275                         (ev_dot_dir (), "evince_toolbar.xml", NULL);
276
277         if (!egg_toolbars_model_load (ev_application->toolbars_model,
278                                       ev_application->toolbars_file)) {
279                 egg_toolbars_model_load (ev_application->toolbars_model,
280                                          DATADIR"/evince-toolbar.xml");
281         }
282
283         egg_toolbars_model_set_flags (ev_application->toolbars_model, 0,
284                                       EGG_TB_MODEL_NOT_REMOVABLE); 
285                                       
286         ev_application->recent_model = egg_recent_model_new (EGG_RECENT_MODEL_SORT_MRU);
287         /* FIXME we should add a mime type filter but current eggrecent
288            has only a varargs style api which does not work well when
289            the list of mime types is dynamic */
290         egg_recent_model_set_limit (ev_application->recent_model, 5);   
291         egg_recent_model_set_filter_groups (ev_application->recent_model,
292                                             "Evince", NULL);
293 }
294
295 EggToolbarsModel *ev_application_get_toolbars_model (EvApplication *application)
296 {
297         return application->toolbars_model;
298 }
299
300 EggRecentModel *ev_application_get_recent_model (EvApplication *application)
301 {
302         return application->recent_model;
303 }
304
305 void ev_application_save_toolbars_model (EvApplication *application)
306 {
307         egg_toolbars_model_save (application->toolbars_model,
308                                  application->toolbars_file, "1.0");
309 }
310
311