]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-window.c
[libdocument] Do not require GAppInfo to support uris when opening an attachment
[evince.git] / shell / ev-window.c
index b4133ad0f72f504eed3cf9eb802a19bdc4784baa..02a3087784f0d5975d1093288943ac0e32084b5f 100644 (file)
@@ -206,6 +206,9 @@ struct _EvWindowPrivate {
        GtkPrintSettings *print_settings;
        GtkPageSetup     *print_page_setup;
        gboolean          close_after_print;
+#ifdef WITH_GCONF
+       GConfClient *gconf_client;
+#endif
 };
 
 #define EV_WINDOW_GET_PRIVATE(object) \
@@ -215,9 +218,11 @@ struct _EvWindowPrivate {
 #define ZOOM_CONTROL_ACTION    "ViewZoom"
 #define NAVIGATION_ACTION      "Navigation"
 
+#define GCONF_LOCKDOWN_DIR          "/desktop/gnome/lockdown"
 #define GCONF_OVERRIDE_RESTRICTIONS "/apps/evince/override_restrictions"
 #define GCONF_LOCKDOWN_SAVE         "/desktop/gnome/lockdown/disable_save_to_disk"
 #define GCONF_LOCKDOWN_PRINT        "/desktop/gnome/lockdown/disable_printing"
+#define GCONF_LOCKDOWN_PRINT_SETUP  "/desktop/gnome/lockdown/disable_print_setup"
 
 #define PRESENTATION_TIMEOUT 5
 
@@ -227,6 +232,12 @@ struct _EvWindowPrivate {
 #define ATTACHMENTS_SIDEBAR_ID "attachments"
 #define LAYERS_SIDEBAR_ID "layers"
 
+#define EV_PRINT_SETTINGS_FILE  "print-settings"
+#define EV_PRINT_SETTINGS_GROUP "Print Settings"
+#define EV_PAGE_SETUP_GROUP     "Page Setup"
+
+#define EV_TOOLBARS_FILENAME "evince-toolbar.xml"
+
 #define MIN_SCALE 0.05409
 #define MAX_SCALE 4.0
 
@@ -308,7 +319,8 @@ static void     ev_window_load_file_remote              (EvWindow         *ev_wi
 static void     ev_window_media_player_key_pressed      (EvWindow         *window,
                                                         const gchar      *key,
                                                         gpointer          user_data);
-static void     ev_window_save_print_page_setup         (EvWindow         *window);
+
+static guint ev_window_n_copies = 0;
 
 G_DEFINE_TYPE (EvWindow, ev_window, GTK_TYPE_WINDOW)
 
@@ -328,18 +340,15 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
 {
        EvDocument *document = ev_window->priv->document;
        const EvDocumentInfo *info = NULL;
-
        gboolean has_document = FALSE;
        gboolean ok_to_print = TRUE;
+       gboolean ok_to_print_setup = TRUE;
        gboolean ok_to_copy = TRUE;
        gboolean has_properties = TRUE;
        gboolean override_restrictions = TRUE;
        gboolean can_get_text = FALSE;
        gboolean has_pages = FALSE;
        gboolean can_find = FALSE;
-#ifdef WITH_GCONF
-       GConfClient *client;
-#endif
 
        if (document) {
                has_document = TRUE;
@@ -360,10 +369,10 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
        }
 
 #ifdef WITH_GCONF
-       client = gconf_client_get_default ();
-       override_restrictions = gconf_client_get_bool (client, 
-                                                      GCONF_OVERRIDE_RESTRICTIONS, 
-                                                      NULL);
+       if (has_document)
+               override_restrictions = gconf_client_get_bool (ev_window->priv->gconf_client,
+                                                              GCONF_OVERRIDE_RESTRICTIONS,
+                                                              NULL);
 #endif
        if (!override_restrictions && info && info->fields_mask & EV_DOCUMENT_INFO_PERMISSIONS) {
                ok_to_print = (info->permissions & EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT);
@@ -374,21 +383,28 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window)
                ok_to_print = FALSE;
 
 #ifdef WITH_GCONF
-       if (gconf_client_get_bool (client, GCONF_LOCKDOWN_SAVE, NULL)) {
+       if (has_document &&
+           gconf_client_get_bool (ev_window->priv->gconf_client, GCONF_LOCKDOWN_SAVE, NULL)) {
                ok_to_copy = FALSE;
        }
 
-       if (gconf_client_get_bool (client, GCONF_LOCKDOWN_PRINT, NULL)) {
+       if (has_document &&
+           gconf_client_get_bool (ev_window->priv->gconf_client, GCONF_LOCKDOWN_PRINT, NULL)) {
                ok_to_print = FALSE;
        }
 
-       g_object_unref (client);
+       if (has_document &&
+           gconf_client_get_bool (ev_window->priv->gconf_client, GCONF_LOCKDOWN_PRINT_SETUP, NULL)) {
+               ok_to_print_setup = FALSE;
+       }
 #endif
 
        /* File menu */
        ev_window_set_action_sensitive (ev_window, "FileOpenCopy", has_document);
        ev_window_set_action_sensitive (ev_window, "FileSaveAs", has_document && ok_to_copy);
-       ev_window_set_action_sensitive (ev_window, "FilePageSetup", has_pages && ok_to_print);
+#if !GTK_CHECK_VERSION (2, 17, 4)
+       ev_window_set_action_sensitive (ev_window, "FilePageSetup", has_pages && ok_to_print && ok_to_print_setup);
+#endif
        ev_window_set_action_sensitive (ev_window, "FilePrint", has_pages && ok_to_print);
        ev_window_set_action_sensitive (ev_window, "FileProperties", has_document && has_properties);
 
@@ -1149,6 +1165,17 @@ ev_window_refresh_window_thumbnail (EvWindow *ev_window, int rotation)
        ev_job_scheduler_push_job (ev_window->priv->thumbnail_job, EV_JOB_PRIORITY_NONE);
 }
 
+#ifdef WITH_GCONF
+static void
+lockdown_changed (GConfClient *client,
+                 guint        cnxn_id,
+                 GConfEntry  *entry,
+                 EvWindow    *ev_window)
+{
+       ev_window_setup_action_sensitivity (ev_window);
+}
+#endif /* WITH_GCONF */
+
 static gboolean
 ev_window_setup_document (EvWindow *ev_window)
 {
@@ -1164,6 +1191,27 @@ ev_window_setup_document (EvWindow *ev_window)
        ev_window_title_set_document (ev_window->priv->title, document);
        ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri);
 
+#ifdef WITH_GCONF
+       if (!ev_window->priv->gconf_client)
+               ev_window->priv->gconf_client = gconf_client_get_default ();
+       gconf_client_add_dir (ev_window->priv->gconf_client,
+                             GCONF_LOCKDOWN_DIR,
+                             GCONF_CLIENT_PRELOAD_ONELEVEL,
+                             NULL);
+       gconf_client_add_dir (ev_window->priv->gconf_client,
+                             GCONF_OVERRIDE_RESTRICTIONS,
+                             GCONF_CLIENT_PRELOAD_NONE,
+                             NULL);
+       gconf_client_notify_add (ev_window->priv->gconf_client,
+                                GCONF_LOCKDOWN_DIR,
+                                (GConfClientNotifyFunc)lockdown_changed,
+                                ev_window, NULL, NULL);
+       gconf_client_notify_add (ev_window->priv->gconf_client,
+                                GCONF_OVERRIDE_RESTRICTIONS,
+                                (GConfClientNotifyFunc)lockdown_changed,
+                                ev_window, NULL, NULL);
+#endif /* WITH_GCONF */
+
        ev_window_setup_action_sensitivity (ev_window);
 
        if (ev_window->priv->history)
@@ -1701,26 +1749,39 @@ ev_window_load_file_remote (EvWindow *ev_window,
        GFile *target_file;
        
        if (!ev_window->priv->local_uri) {
-               gchar *tmp_name;
-               gchar *base_name;
+               char *base_name, *template;
+                GFile *tmp_file;
+                GError *err = NULL;
 
                /* We'd like to keep extension of source uri since
-                * it helps to resolve some mime types, say cbz */
-               tmp_name = ev_tmp_filename (NULL);
+                * it helps to resolve some mime types, say cbz.
+                 */
                base_name = g_file_get_basename (source_file);
-               ev_window->priv->local_uri = g_strconcat ("file:", tmp_name, "-",
-                                                         base_name, NULL);
+                template = g_strdup_printf ("document.XXXXXX-%s", base_name);
+                g_free (base_name);
+
+                tmp_file = ev_mkstemp_file (template, &err);
+               g_free (template);
+                if (tmp_file == NULL) {
+                        ev_window_error_message (ev_window, err,
+                                                 "%s", _("Failed to load remote file."));
+                        g_error_free (err);
+                        return;
+                }
+
+               ev_window->priv->local_uri = g_file_get_uri (tmp_file);
+               g_object_unref (tmp_file);
+
                ev_job_load_set_uri (EV_JOB_LOAD (ev_window->priv->load_job),
                                     ev_window->priv->local_uri);
-               g_free (base_name);
-               g_free (tmp_name);
        }
 
        ev_window_reset_progress_cancellable (ev_window);
        
        target_file = g_file_new_for_uri (ev_window->priv->local_uri);
        g_file_copy_async (source_file, target_file,
-                          0, G_PRIORITY_DEFAULT,
+                          G_FILE_COPY_OVERWRITE,
+                          G_PRIORITY_DEFAULT,
                           ev_window->priv->progress_cancellable,
                           (GFileProgressCallback)window_open_file_copy_progress_cb,
                           ev_window, 
@@ -2057,7 +2118,7 @@ file_open_dialog_response_cb (GtkWidget *chooser,
 
                ev_application_open_uri_list (EV_APP, uris,
                                              gtk_window_get_screen (GTK_WINDOW (ev_window)),
-                                             GDK_CURRENT_TIME);
+                                             gtk_get_current_event_time ());
 
                g_slist_foreach (uris, (GFunc)g_free, NULL);
                g_slist_free (uris);
@@ -2129,12 +2190,14 @@ ev_window_open_copy_at_dest (EvWindow   *window,
 {
        EvWindow *new_window = EV_WINDOW (ev_window_new ());
 
+       ev_window_n_copies++;
+
        if (window->priv->metadata)
                new_window->priv->metadata = g_object_ref (window->priv->metadata);
        ev_window_open_document (new_window,
                                 window->priv->document,
                                 dest, 0, NULL);
-       gtk_widget_show (GTK_WIDGET (new_window));
+       gtk_window_present (GTK_WINDOW (new_window));
 }
 
 static void
@@ -2157,7 +2220,7 @@ ev_window_cmd_recent_file_activate (GtkAction *action,
        
        ev_application_open_uri_at_dest (EV_APP, uri,
                                         gtk_window_get_screen (GTK_WINDOW (window)),
-                                        NULL, 0, NULL, GDK_CURRENT_TIME);
+                                        NULL, 0, NULL, gtk_get_current_event_time ());
 }
 
 static void
@@ -2167,7 +2230,7 @@ ev_window_open_recent_action_item_activated (EvOpenRecentAction *action,
 {
        ev_application_open_uri_at_dest (EV_APP, uri,
                                         gtk_window_get_screen (GTK_WINDOW (window)),
-                                        NULL, 0, NULL, GDK_CURRENT_TIME);
+                                        NULL, 0, NULL, gtk_get_current_event_time ());
 }
 
 static void
@@ -2592,28 +2655,66 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window)
        gtk_widget_show (fc);
 }
 
-static void
-ev_window_load_print_settings_from_metadata (EvWindow *window)
+static GKeyFile *
+get_print_settings_file (void)
 {
-       gint i;
+       GKeyFile *print_settings_file;
+       gchar    *filename;
+        GError *error = NULL;
 
-       if (!window->priv->metadata)
-               return;
+       print_settings_file = g_key_file_new ();
 
-       /* Load print setting that are specific to the document */
-       for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
-               gchar *value = NULL;
+       filename = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE),
+                                     EV_PRINT_SETTINGS_FILE, NULL);
+        if (!g_key_file_load_from_file (print_settings_file,
+                                        filename,
+                                        G_KEY_FILE_KEEP_COMMENTS |
+                                        G_KEY_FILE_KEEP_TRANSLATIONS,
+                                        &error)) {
 
-               ev_metadata_get_string (window->priv->metadata, document_print_settings[i], &value);
-               gtk_print_settings_set (window->priv->print_settings,
-                                       document_print_settings[i], value);
+                /* Don't warn if the file simply doesn't exist */
+                if (!g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+                       g_warning ("%s", error->message);
+
+                g_error_free (error);
        }
+
+       g_free (filename);
+
+       return print_settings_file;
 }
 
 static void
-ev_window_save_print_settings (EvWindow *window)
+save_print_setting_file (GKeyFile *key_file)
 {
-       gint i;
+       gchar  *filename;
+       gchar  *data;
+       gsize  data_length;
+       GError *error = NULL;
+
+       filename = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE),
+                                    EV_PRINT_SETTINGS_FILE, NULL);
+       data = g_key_file_to_data (key_file, &data_length, NULL);
+       g_file_set_contents (filename, data, data_length, &error);
+       if (error) {
+               g_warning ("Failed to save print settings: %s", error->message);
+               g_error_free (error);
+       }
+       g_free (data);
+       g_free (filename);
+}
+
+static void
+ev_window_save_print_settings (EvWindow         *window,
+                              GtkPrintSettings *print_settings)
+{
+       GKeyFile *key_file;
+       gint      i;
+
+       key_file = get_print_settings_file ();
+       gtk_print_settings_to_key_file (print_settings, key_file, EV_PRINT_SETTINGS_GROUP);
+       save_print_setting_file (key_file);
+       g_key_file_free (key_file);
 
        if (!window->priv->metadata)
                return;
@@ -2622,7 +2723,7 @@ ev_window_save_print_settings (EvWindow *window)
        for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
                const gchar *value;
 
-               value = gtk_print_settings_get (window->priv->print_settings,
+               value = gtk_print_settings_get (print_settings,
                                                document_print_settings[i]);
                ev_metadata_set_string (window->priv->metadata,
                                        document_print_settings[i], value);
@@ -2630,9 +2731,15 @@ ev_window_save_print_settings (EvWindow *window)
 }
 
 static void
-ev_window_save_print_page_setup (EvWindow *window)
+ev_window_save_print_page_setup (EvWindow     *window,
+                                GtkPageSetup *page_setup)
 {
-       GtkPageSetup *page_setup = window->priv->print_page_setup;
+       GKeyFile *key_file;
+
+       key_file = get_print_settings_file ();
+       gtk_page_setup_to_key_file (page_setup, key_file, EV_PAGE_SETUP_GROUP);
+       save_print_setting_file (key_file);
+       g_key_file_free (key_file);
 
        if (!window->priv->metadata)
                return;
@@ -2651,9 +2758,29 @@ ev_window_save_print_page_setup (EvWindow *window)
 }
 
 static void
-ev_window_load_print_page_setup_from_metadata (EvWindow *window)
+ev_window_load_print_settings_from_metadata (EvWindow         *window,
+                                            GtkPrintSettings *print_settings)
+{
+       gint i;
+
+       if (!window->priv->metadata)
+               return;
+
+       /* Load print setting that are specific to the document */
+       for (i = 0; i < G_N_ELEMENTS (document_print_settings); i++) {
+               gchar *value = NULL;
+
+               ev_metadata_get_string (window->priv->metadata,
+                                       document_print_settings[i], &value);
+               gtk_print_settings_set (print_settings,
+                                       document_print_settings[i], value);
+       }
+}
+
+static void
+ev_window_load_print_page_setup_from_metadata (EvWindow     *window,
+                                              GtkPageSetup *page_setup)
 {
-       GtkPageSetup *page_setup = window->priv->print_page_setup;
        gint          int_value;
        gdouble       double_value;
        GtkPaperSize *paper_size = gtk_page_setup_get_paper_size (page_setup);
@@ -2703,6 +2830,30 @@ ev_window_load_print_page_setup_from_metadata (EvWindow *window)
        }
 }
 
+static GtkPrintSettings *
+get_print_settings (GKeyFile *key_file)
+{
+       GtkPrintSettings *print_settings;
+
+       print_settings = g_key_file_has_group (key_file, EV_PRINT_SETTINGS_GROUP) ?
+               gtk_print_settings_new_from_key_file (key_file, EV_PRINT_SETTINGS_GROUP, NULL) :
+               gtk_print_settings_new ();
+
+       return print_settings ? print_settings : gtk_print_settings_new ();
+}
+
+static GtkPageSetup *
+get_print_page_setup (GKeyFile *key_file)
+{
+       GtkPageSetup *page_setup;
+
+       page_setup = g_key_file_has_group (key_file, EV_PAGE_SETUP_GROUP) ?
+               gtk_page_setup_new_from_key_file (key_file, EV_PAGE_SETUP_GROUP, NULL) :
+               gtk_page_setup_new ();
+
+       return page_setup ? page_setup : gtk_page_setup_new ();
+}
+
 static void
 ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup,
                                    EvWindow     *window)
@@ -2711,31 +2862,33 @@ ev_window_print_page_setup_done_cb (GtkPageSetup *page_setup,
        if (!page_setup)
                return;
 
-       if (window->priv->print_page_setup != page_setup) {
-               if (window->priv->print_page_setup)
-                       g_object_unref (window->priv->print_page_setup);
-               window->priv->print_page_setup = g_object_ref (page_setup);
-       }
-       
-       ev_application_set_page_setup (EV_APP, page_setup);
-       ev_window_save_print_page_setup (window);
+       ev_window_save_print_page_setup (window, page_setup);
 }
 
 static void
-ev_window_cmd_file_print_setup (GtkAction *action, EvWindow *ev_window)
+ev_window_cmd_file_print_setup (GtkAction *action,
+                               EvWindow  *ev_window)
 {
-       if (!ev_window->priv->print_page_setup) {
-               ev_window->priv->print_page_setup = gtk_page_setup_copy (
-                       ev_application_get_page_setup (EV_APP));
-               ev_window_load_print_page_setup_from_metadata (ev_window);
-       }
-       
-       gtk_print_run_page_setup_dialog_async (
-               GTK_WINDOW (ev_window),
-               ev_window->priv->print_page_setup,
-               ev_window->priv->print_settings,
-               (GtkPageSetupDoneFunc) ev_window_print_page_setup_done_cb,
-               ev_window);
+       GKeyFile         *print_settings_file;
+       GtkPrintSettings *print_settings;
+       GtkPageSetup     *print_page_setup;
+
+       print_settings_file = get_print_settings_file ();
+
+       print_settings = get_print_settings (print_settings_file);
+       ev_window_load_print_settings_from_metadata (ev_window, print_settings);
+
+       print_page_setup = get_print_page_setup (print_settings_file);
+       ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup);
+
+       gtk_print_run_page_setup_dialog_async (GTK_WINDOW (ev_window),
+                                              print_page_setup,
+                                              print_settings,
+                                              (GtkPageSetupDoneFunc)ev_window_print_page_setup_done_cb,
+                                              ev_window);
+       g_object_unref (print_settings);
+       g_object_unref (print_page_setup);
+       g_key_file_free (print_settings_file);
 }
 
 static void
@@ -2791,20 +2944,20 @@ ev_window_print_operation_done (EvPrintOperation       *op,
                                EvWindow               *ev_window)
 {
        gint n_jobs;
-       
+
        switch (result) {
        case GTK_PRINT_OPERATION_RESULT_APPLY: {
                GtkPrintSettings *print_settings;
-               
+
                print_settings = ev_print_operation_get_print_settings (op);
-               if (ev_window->priv->print_settings != print_settings) {
-                       if (ev_window->priv->print_settings)
-                               g_object_unref (ev_window->priv->print_settings);
-                       ev_window->priv->print_settings = g_object_ref (print_settings);
+               ev_window_save_print_settings (ev_window, print_settings);
+
+               if (ev_print_operation_get_embed_page_setup (op)) {
+                       GtkPageSetup *page_setup;
+
+                       page_setup = ev_print_operation_get_default_page_setup (op);
+                       ev_window_save_print_page_setup (ev_window, page_setup);
                }
-               
-               ev_application_set_print_settings (EV_APP, print_settings);
-               ev_window_save_print_settings (ev_window);
        }
 
                break;
@@ -2908,19 +3061,12 @@ static void
 ev_window_print_operation_begin_print (EvPrintOperation *op,
                                       EvWindow         *ev_window)
 {
-       GtkPrintSettings *print_settings;
-       
        if (!ev_window->priv->print_queue)
                ev_window->priv->print_queue = g_queue_new ();
 
        g_queue_push_head (ev_window->priv->print_queue, op);
        ev_window_print_update_pending_jobs_message (ev_window,
                                                     g_queue_get_length (ev_window->priv->print_queue));
-       
-       if (ev_window->priv->print_settings)
-               g_object_unref (ev_window->priv->print_settings);
-       print_settings = ev_print_operation_get_print_settings (op);
-       ev_window->priv->print_settings = g_object_ref (print_settings);
 }
 
 void
@@ -2929,6 +3075,9 @@ ev_window_print_range (EvWindow *ev_window,
                       gint      last_page)
 {
        EvPrintOperation *op;
+       GKeyFile         *print_settings_file;
+       GtkPrintSettings *print_settings;
+       GtkPageSetup     *print_page_setup;
        gint              current_page;
        gint              document_last_page;
 
@@ -2957,17 +3106,13 @@ ev_window_print_range (EvWindow *ev_window,
        current_page = ev_document_model_get_page (ev_window->priv->model);
        document_last_page = ev_document_get_n_pages (ev_window->priv->document);
 
-       if (!ev_window->priv->print_settings) {
-               ev_window->priv->print_settings = gtk_print_settings_copy (
-                       ev_application_get_print_settings (EV_APP));
-               ev_window_load_print_settings_from_metadata (ev_window);
-       }
+       print_settings_file = get_print_settings_file ();
 
-       if (!ev_window->priv->print_page_setup) {
-               ev_window->priv->print_page_setup = gtk_page_setup_copy (
-                       ev_application_get_page_setup (EV_APP));
-               ev_window_load_print_page_setup_from_metadata (ev_window);
-       }
+       print_settings = get_print_settings (print_settings_file);
+       ev_window_load_print_settings_from_metadata (ev_window, print_settings);
+
+       print_page_setup = get_print_page_setup (print_settings_file);
+       ev_window_load_print_page_setup_from_metadata (ev_window, print_page_setup);
 
        if (first_page != 1 || last_page != document_last_page) {
                GtkPageRange range;
@@ -2975,17 +3120,28 @@ ev_window_print_range (EvWindow *ev_window,
                /* Ranges in GtkPrint are 0 - N */
                range.start = first_page - 1;
                range.end = last_page - 1;
-               
-               gtk_print_settings_set_print_pages (ev_window->priv->print_settings,
+
+               gtk_print_settings_set_print_pages (print_settings,
                                                    GTK_PRINT_PAGES_RANGES);
-               gtk_print_settings_set_page_ranges (ev_window->priv->print_settings,
+               gtk_print_settings_set_page_ranges (print_settings,
                                                    &range, 1);
        }
 
        ev_print_operation_set_job_name (op, gtk_window_get_title (GTK_WINDOW (ev_window)));
        ev_print_operation_set_current_page (op, current_page);
-       ev_print_operation_set_print_settings (op, ev_window->priv->print_settings);
-       ev_print_operation_set_default_page_setup (op, ev_window->priv->print_page_setup);
+       ev_print_operation_set_print_settings (op, print_settings);
+       ev_print_operation_set_default_page_setup (op, print_page_setup);
+#ifdef WITH_GCONF
+       ev_print_operation_set_embed_page_setup (op, !gconf_client_get_bool (ev_window->priv->gconf_client,
+                                                                            GCONF_LOCKDOWN_PRINT_SETUP,
+                                                                            NULL));
+#else
+       ev_print_operation_set_embed_page_setup (op, TRUE);
+#endif
+
+       g_object_unref (print_settings);
+       g_object_unref (print_page_setup);
+       g_key_file_free (print_settings_file);
 
        ev_print_operation_run (op, GTK_WINDOW (ev_window));
 }
@@ -3693,42 +3849,54 @@ ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window)
 }
 
 static void
-ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog, gint response, gpointer data)
+ev_window_cmd_edit_toolbar_cb (GtkDialog *dialog,
+                              gint       response,
+                              EvWindow  *ev_window)
 {
-       EvWindow *ev_window = EV_WINDOW (data);
-        egg_editable_toolbar_set_edit_mode
-                       (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), FALSE);
-       ev_application_save_toolbars_model (EV_APP);
+       EggEditableToolbar *toolbar;
+       gchar              *toolbars_file;
+
+       toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar);
+        egg_editable_toolbar_set_edit_mode (toolbar, FALSE);
+
+       toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, TRUE),
+                                         "evince_toolbar.xml", NULL);
+       egg_toolbars_model_save_toolbars (egg_editable_toolbar_get_model (toolbar),
+                                         toolbars_file, "1.0");
+       g_free (toolbars_file);
+
         gtk_widget_destroy (GTK_WIDGET (dialog));
 }
 
 static void
 ev_window_cmd_edit_toolbar (GtkAction *action, EvWindow *ev_window)
 {
-       GtkWidget *dialog;
-       GtkWidget *editor;
+       GtkWidget          *dialog;
+       GtkWidget          *editor;
+       EggEditableToolbar *toolbar;
 
        dialog = gtk_dialog_new_with_buttons (_("Toolbar Editor"),
-                                             GTK_WINDOW (ev_window), 
-                                             GTK_DIALOG_DESTROY_WITH_PARENT, 
+                                             GTK_WINDOW (ev_window),
+                                             GTK_DIALOG_DESTROY_WITH_PARENT,
                                              GTK_STOCK_CLOSE,
-                                             GTK_RESPONSE_CLOSE, 
+                                             GTK_RESPONSE_CLOSE,
                                              NULL);
        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
        gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)), 5);
        gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
        gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
        gtk_window_set_default_size (GTK_WINDOW (dialog), 500, 400);
-         
+
+       toolbar = EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar);
        editor = egg_toolbar_editor_new (ev_window->priv->ui_manager,
-                                        ev_application_get_toolbars_model (EV_APP));
+                                        egg_editable_toolbar_get_model (toolbar));
+
        gtk_container_set_border_width (GTK_CONTAINER (editor), 5);
        gtk_box_set_spacing (GTK_BOX (EGG_TOOLBAR_EDITOR (editor)), 5);
-             
+
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), editor);
 
-       egg_editable_toolbar_set_edit_mode
-               (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar), TRUE);
+       egg_editable_toolbar_set_edit_mode (toolbar, TRUE);
 
        g_signal_connect (dialog, "response",
                          G_CALLBACK (ev_window_cmd_edit_toolbar_cb),
@@ -3835,7 +4003,7 @@ ev_window_cmd_help_contents (GtkAction *action, EvWindow *ev_window)
 
        gtk_show_uri (gtk_window_get_screen (GTK_WINDOW (ev_window)),
                      "ghelp:evince",
-                     GDK_CURRENT_TIME,
+                     gtk_get_current_event_time (),
                      &error);
        if (error) {
                ev_window_error_message (ev_window, error, 
@@ -4549,15 +4717,13 @@ ev_window_drag_data_received (GtkWidget        *widget,
 static void
 ev_window_finalize (GObject *object)
 {
-       GList *windows = ev_application_get_windows (EV_APP);
+       G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
 
-       if (windows == NULL) {
+       if (ev_window_n_copies == 0) {
                ev_application_shutdown (EV_APP);
        } else {
-               g_list_free (windows);
+               ev_window_n_copies--;
        }
-       
-       G_OBJECT_CLASS (ev_window_parent_class)->finalize (object);
 }
 
 static void
@@ -4582,7 +4748,14 @@ ev_window_dispose (GObject *object)
                g_source_remove (priv->setup_document_idle);
                priv->setup_document_idle = 0;
        }
-       
+
+#ifdef WITH_GCONF
+       if (priv->gconf_client) {
+               g_object_unref (priv->gconf_client);
+               priv->gconf_client = NULL;
+       }
+#endif
+
        if (priv->monitor) {
                g_object_unref (priv->monitor);
                priv->monitor = NULL;
@@ -4683,16 +4856,6 @@ ev_window_dispose (GObject *object)
        
        ev_window_close_dialogs (window);
 
-       if (window->priv->print_settings) {
-               g_object_unref (window->priv->print_settings);
-               window->priv->print_settings = NULL;
-       }
-
-       if (window->priv->print_page_setup) {
-               g_object_unref (window->priv->print_page_setup);
-               window->priv->print_page_setup = NULL;
-       }
-
        if (priv->link) {
                g_object_unref (priv->link);
                priv->link = NULL;
@@ -4941,6 +5104,10 @@ static const GtkActionEntry entries[] = {
           G_CALLBACK (ev_window_cmd_scroll_forward) },
         { "ShiftReturn", NULL, "", "<shift>Return", NULL,
           G_CALLBACK (ev_window_cmd_scroll_backward) },
+       { "p", GTK_STOCK_GO_UP, "", "p", NULL,
+         G_CALLBACK (ev_window_cmd_go_previous_page) },
+       { "n", GTK_STOCK_GO_DOWN, "", "n", NULL,
+         G_CALLBACK (ev_window_cmd_go_next_page) },
         { "Plus", GTK_STOCK_ZOOM_IN, NULL, "plus", NULL,
           G_CALLBACK (ev_window_cmd_view_zoom_in) },
         { "CtrlEqual", GTK_STOCK_ZOOM_IN, NULL, "<control>equal", NULL,
@@ -5308,7 +5475,8 @@ launch_action (EvWindow *window, EvLinkAction *action)
        context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ());
        gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context),
                                           gtk_window_get_screen (GTK_WINDOW (window)));
-       gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), GDK_CURRENT_TIME);
+       gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context),
+                                              gtk_get_current_event_time ());
        
        file_list.data = file;
        if (!g_app_info_launch (app_info, &file_list, context, &error)) {
@@ -5320,6 +5488,7 @@ launch_action (EvWindow *window, EvLinkAction *action)
        
        g_object_unref (app_info);
        g_object_unref (file);
+        /* FIXMEchpe: unref launch context? */
 
        /* According to the PDF spec filename can be an executable. I'm not sure
           allowing to launch executables is a good idea though. -- marco */
@@ -5337,7 +5506,7 @@ launch_external_uri (EvWindow *window, EvLinkAction *action)
        gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context),
                                           gtk_window_get_screen (GTK_WINDOW (window)));
        gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context),
-                                             GDK_CURRENT_TIME);
+                                             gtk_get_current_event_time ());
 
        if (!g_strstr_len (uri, strlen (uri), "://") &&
            !g_str_has_prefix (uri, "mailto:")) {
@@ -5345,10 +5514,10 @@ launch_external_uri (EvWindow *window, EvLinkAction *action)
                
                /* Not a valid uri, assuming it's http */
                http = g_strdup_printf ("http://%s", uri);
-               ret = g_app_info_launch_default_for_uri (http, NULL, &error);
+               ret = g_app_info_launch_default_for_uri (http, context, &error);
                g_free (http);
        } else {
-               ret = g_app_info_launch_default_for_uri (uri, NULL, &error);
+               ret = g_app_info_launch_default_for_uri (uri, context, &error);
        }
        
        if (ret == FALSE) {
@@ -5356,6 +5525,8 @@ launch_external_uri (EvWindow *window, EvLinkAction *action)
                                         "%s", _("Unable to open external link"));
                g_error_free (error);
        }
+
+        /* FIXMEchpe: unref launch context? */
 }
 
 static void
@@ -5375,7 +5546,7 @@ open_remote_link (EvWindow *window, EvLinkAction *action)
                                         ev_link_action_get_dest (action),
                                         0,
                                         NULL, 
-                                        GDK_CURRENT_TIME);
+                                        gtk_get_current_event_time ());
 
        g_free (uri);
 }
@@ -5542,7 +5713,9 @@ image_save_dialog_response_cb (GtkWidget *fc,
        if (is_native) {
                filename = g_file_get_path (target_file);
        } else {
-               filename = ev_tmp_filename ("saveimage");
+                /* Create a temporary local file to save to */
+                if (ev_mkstemp ("saveimage.XXXXXX", &filename, &error) == -1)
+                        goto has_error;
        }
 
        ev_document_doc_mutex_lock ();
@@ -5555,6 +5728,7 @@ image_save_dialog_response_cb (GtkWidget *fc,
        g_free (file_format);
        g_object_unref (pixbuf);
        
+    has_error:
        if (error) {
                ev_window_error_message (ev_window, error, 
                                         "%s", _("The image could not be saved."));
@@ -5652,7 +5826,7 @@ ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
                
                attachment = (EvAttachment *) l->data;
                
-               ev_attachment_open (attachment, screen, GDK_CURRENT_TIME, &error);
+               ev_attachment_open (attachment, screen, gtk_get_current_event_time (), &error);
 
                if (error) {
                        ev_window_error_message (window, error, 
@@ -5687,7 +5861,7 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
        
        for (l = ev_window->priv->attach_list; l && l->data; l = g_list_next (l)) {
                EvAttachment *attachment;
-               GFile        *save_to;
+               GFile        *save_to = NULL;
                GError       *error = NULL;
                
                attachment = (EvAttachment *) l->data;
@@ -5695,15 +5869,17 @@ attachment_save_dialog_response_cb (GtkWidget *fc,
                if (is_native) {
                        if (is_dir) {
                                save_to = g_file_get_child (target_file,
+                                    /* FIXMEchpe: file name encoding! */
                                                            ev_attachment_get_name (attachment));
                        } else {
                                save_to = g_object_ref (target_file);
                        }
                } else {
-                       save_to = ev_tmp_file_get ("saveattachment");
+                       save_to = ev_mkstemp_file ("saveattachment.XXXXXX", &error);
                }
 
-               ev_attachment_save (attachment, save_to, &error);
+                if (save_to)
+                        ev_attachment_save (attachment, save_to, &error);
                
                if (error) {
                        ev_window_error_message (ev_window, error, 
@@ -5809,6 +5985,52 @@ ev_window_media_player_key_pressed (EvWindow    *window,
        }
 }
 
+static EggToolbarsModel *
+get_toolbars_model (void)
+{
+       EggToolbarsModel *toolbars_model;
+       gchar            *toolbars_file;
+       gchar            *toolbars_path;
+       gint              i;
+
+       toolbars_model = egg_toolbars_model_new ();
+
+       toolbars_file = g_build_filename (ev_application_get_dot_dir (EV_APP, FALSE),
+                                         "evince_toolbar.xml", NULL);
+       toolbars_path = g_build_filename (ev_application_get_data_dir (EV_APP),
+                                        "evince-toolbar.xml", NULL);
+       egg_toolbars_model_load_names (toolbars_model, toolbars_path);
+
+       if (!egg_toolbars_model_load_toolbars (toolbars_model, toolbars_file)) {
+               egg_toolbars_model_load_toolbars (toolbars_model, toolbars_path);
+                goto skip_conversion;
+       }
+
+       /* Open item doesn't exist anymore,
+        * convert it to OpenRecent for compatibility
+        */
+       for (i = 0; i < egg_toolbars_model_n_items (toolbars_model, 0); i++) {
+               const gchar *item;
+
+               item = egg_toolbars_model_item_nth (toolbars_model, 0, i);
+               if (g_ascii_strcasecmp (item, "FileOpen") == 0) {
+                       egg_toolbars_model_remove_item (toolbars_model, 0, i);
+                       egg_toolbars_model_add_item (toolbars_model, 0, i,
+                                                    "FileOpenRecent");
+                       egg_toolbars_model_save_toolbars (toolbars_model, toolbars_file, "1.0");
+                       break;
+               }
+       }
+
+    skip_conversion:
+       g_free (toolbars_file);
+       g_free (toolbars_path);
+
+       egg_toolbars_model_set_flags (toolbars_model, 0, EGG_TB_MODEL_NOT_REMOVABLE);
+
+       return toolbars_model;
+}
+
 static void
 ev_window_init (EvWindow *ev_window)
 {
@@ -5816,6 +6038,7 @@ ev_window_init (EvWindow *ev_window)
        GtkAccelGroup *accel_group;
        GError *error = NULL;
        GtkWidget *sidebar_widget;
+       EggToolbarsModel *toolbars_model;
        GObject *mpkeys;
        gchar *ui_path;
        gdouble dpi;
@@ -5884,7 +6107,17 @@ ev_window_init (EvWindow *ev_window)
                g_error_free (error);
        }
        g_free (ui_path);
-       
+
+#if GTK_CHECK_VERSION (2, 17, 4)
+       {
+               GtkAction *action;
+
+               action = gtk_action_group_get_action (ev_window->priv->action_group,
+                                                     "FilePageSetup");
+               g_object_set (action, "visible", FALSE, "sensitive", FALSE, NULL);
+       }
+#endif
+
        ev_window->priv->recent_manager = gtk_recent_manager_get_default ();
        ev_window->priv->recent_action_group = NULL;
        ev_window->priv->recent_ui_id = 0;
@@ -5900,12 +6133,14 @@ ev_window_init (EvWindow *ev_window)
                            ev_window->priv->menubar,
                            FALSE, FALSE, 0);
 
-       ev_window->priv->toolbar = GTK_WIDGET 
-         (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
-                        "ui-manager", ev_window->priv->ui_manager,
-                        "popup-path", "/ToolbarPopup",
-                        "model", ev_application_get_toolbars_model (EV_APP),
-                        NULL));
+       toolbars_model = get_toolbars_model ();
+       ev_window->priv->toolbar = GTK_WIDGET
+               (g_object_new (EGG_TYPE_EDITABLE_TOOLBAR,
+                              "ui-manager", ev_window->priv->ui_manager,
+                              "popup-path", "/ToolbarPopup",
+                              "model", toolbars_model,
+                              NULL));
+       g_object_unref (toolbars_model);
 
        egg_editable_toolbar_show (EGG_EDITABLE_TOOLBAR (ev_window->priv->toolbar),
                                   "DefaultToolBar");