From d7836989512d27a12c8300fca843bc97995cf65e Mon Sep 17 00:00:00 2001 From: raveit65 Date: Sat, 7 May 2016 18:02:03 +0200 Subject: shell: Store and restore current folder when opening or saving file Remember the folder last used to open or save a document, attachment or image. taken from: https://git.gnome.org/browse/evince/commit/shell/ev-window.c?h=gnome-3-6&id=f6137df22503d88a76cc69f622919ec7bd3582d7 shell: Fix potential read-after-free in gsettings use It's not valid to use '&' with g_settings_get(). https://bugzilla.gnome.org/show_bug.cgi?id=723737 taken from: https://git.gnome.org/browse/evince/commit/?id=41ce0e1 ev-window: Don't crash when trying to save a copy We can not free both folder_uri and parent_uri. If parent_uri is non-NULL then it will point to the same location as folder_uri. Also, parent_uri is now unused so we can just remove it. https://bugzilla.gnome.org/show_bug.cgi?id=727536 taken from: https://git.gnome.org/browse/evince/commit/?id=3850ff5 --- data/org.mate.Atril.gschema.xml | 8 +++ shell/ev-window.c | 144 +++++++++++++++++++++++++++++++--------- 2 files changed, 120 insertions(+), 32 deletions(-) diff --git a/data/org.mate.Atril.gschema.xml b/data/org.mate.Atril.gschema.xml index d73069ae..04195a33 100644 --- a/data/org.mate.Atril.gschema.xml +++ b/data/org.mate.Atril.gschema.xml @@ -17,6 +17,14 @@ Automatically reload then document The document is automatically reloaded on file change. + + nothing + The URI of the directory last used to open or save a document + + + nothing + The URI of the directory last used to save a picture + diff --git a/shell/ev-window.c b/shell/ev-window.c index 78063ba2..f046f7af 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -254,6 +254,8 @@ struct _EvWindowPrivate { #define GS_SCHEMA_NAME "org.mate.Atril" #define GS_OVERRIDE_RESTRICTIONS "override-restrictions" #define GS_AUTO_RELOAD "auto-reload" +#define GS_LAST_DOCUMENT_DIRECTORY "document-directory" +#define GS_LAST_PICTURES_DIRECTORY "pictures-directory" #define SIDEBAR_DEFAULT_SIZE 132 #define LINKS_SIDEBAR_ID "links" @@ -1479,6 +1481,22 @@ lockdown_changed (GSettings *settings, ev_window_setup_action_sensitivity (ev_window); } +static GSettings * +ev_window_ensure_settings (EvWindow *ev_window) +{ + EvWindowPrivate *priv = ev_window->priv; + + if (priv->settings != NULL) + return priv->settings; + + priv->settings = g_settings_new (GS_SCHEMA_NAME); + g_signal_connect (priv->settings, + "changed::"GS_OVERRIDE_RESTRICTIONS, + G_CALLBACK (override_restrictions_changed), + ev_window); + return priv->settings; +} + static gboolean ev_window_setup_document (EvWindow *ev_window) { @@ -1494,13 +1512,7 @@ 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); - if (!ev_window->priv->settings) { - ev_window->priv->settings = g_settings_new (GS_SCHEMA_NAME); - g_signal_connect (ev_window->priv->settings, - "changed::"GS_OVERRIDE_RESTRICTIONS, - G_CALLBACK (override_restrictions_changed), - ev_window); - } + ev_window_ensure_settings (ev_window); #ifdef WITH_MATEDESKTOP if (mate_gsettings_schema_exists (MATE_LOCKDOWN_SCHEMA)) { @@ -2474,6 +2486,75 @@ ev_window_reload_document (EvWindow *ev_window, } } +static const gchar * +get_settings_key_for_directory (GUserDirectory directory) +{ + switch (directory) { + case G_USER_DIRECTORY_PICTURES: + return GS_LAST_PICTURES_DIRECTORY; + case G_USER_DIRECTORY_DOCUMENTS: + default: + return GS_LAST_DOCUMENT_DIRECTORY; + } +} + +static void +ev_window_file_chooser_restore_folder (EvWindow *window, + GtkFileChooser *file_chooser, + const gchar *uri, + GUserDirectory directory) +{ + const gchar *dir; + gchar *folder_uri; + + g_settings_get (ev_window_ensure_settings (window), + get_settings_key_for_directory (directory), + "ms", &folder_uri); + if (folder_uri == NULL && uri != NULL) { + GFile *file, *parent; + + file = g_file_new_for_uri (uri); + parent = g_file_get_parent (file); + g_object_unref (file); + if (parent) { + folder_uri = g_file_get_uri (parent); + g_object_unref (parent); + } + } + + if (folder_uri) { + gtk_file_chooser_set_current_folder_uri (file_chooser, folder_uri); + } else { + dir = g_get_user_special_dir (directory); + gtk_file_chooser_set_current_folder (file_chooser, + dir ? dir : g_get_home_dir ()); + } + + g_free (folder_uri); +} + +static void +ev_window_file_chooser_save_folder (EvWindow *window, + GtkFileChooser *file_chooser, + GUserDirectory directory) +{ + gchar *uri, *folder; + + folder = gtk_file_chooser_get_current_folder (file_chooser); + if (g_strcmp0 (folder, g_get_user_special_dir (directory)) == 0) { + /* Store 'nothing' if the folder is the default one */ + uri = NULL; + } else { + uri = gtk_file_chooser_get_current_folder_uri (file_chooser); + } + g_free (folder); + + g_settings_set (ev_window_ensure_settings (window), + get_settings_key_for_directory (directory), + "ms", uri); + g_free (uri); +} + static void file_open_dialog_response_cb (GtkWidget *chooser, gint response_id, @@ -2482,6 +2563,9 @@ file_open_dialog_response_cb (GtkWidget *chooser, if (response_id == GTK_RESPONSE_OK) { GSList *uris; + ev_window_file_chooser_save_folder (ev_window, GTK_FILE_CHOOSER (chooser), + G_USER_DIRECTORY_DOCUMENTS); + uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (chooser)); ev_application_open_uri_list (EV_APP, uris, @@ -2500,8 +2584,6 @@ static void ev_window_cmd_file_open (GtkAction *action, EvWindow *window) { GtkWidget *chooser; - const gchar *default_uri = NULL; - gchar *parent_uri = NULL; chooser = gtk_file_chooser_dialog_new (_("Open Document"), GTK_WINDOW (window), @@ -2515,29 +2597,8 @@ ev_window_cmd_file_open (GtkAction *action, EvWindow *window) gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE); gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), FALSE); - if (window->priv->uri) { - GFile *file, *parent; - - file = g_file_new_for_uri (window->priv->uri); - parent = g_file_get_parent (file); - if (parent) { - parent_uri = g_file_get_uri (parent); - default_uri = parent_uri; - g_object_unref (parent); - } - g_object_unref (file); - } - - if (default_uri) { - gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (chooser), default_uri); - } else { - const gchar *folder; - - folder = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); - gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (chooser), - folder ? folder : g_get_home_dir ()); - } - g_free (parent_uri); + ev_window_file_chooser_restore_folder (window, GTK_FILE_CHOOSER (chooser), + NULL, G_USER_DIRECTORY_DOCUMENTS); g_signal_connect (chooser, "response", G_CALLBACK (file_open_dialog_response_cb), @@ -2971,6 +3032,9 @@ file_save_dialog_response_cb (GtkWidget *fc, return; } + ev_window_file_chooser_save_folder (ev_window, GTK_FILE_CHOOSER (fc), + G_USER_DIRECTORY_DOCUMENTS); + uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); /* FIXME: remote copy should be done here rather than in the save job, @@ -3020,6 +3084,10 @@ ev_window_cmd_save_as (GtkAction *action, EvWindow *ev_window) g_object_unref (file); g_free (base_name); + ev_window_file_chooser_restore_folder (ev_window, GTK_FILE_CHOOSER (fc), + ev_window->priv->uri, + G_USER_DIRECTORY_DOCUMENTS); + g_signal_connect (fc, "response", G_CALLBACK (file_save_dialog_response_cb), ev_window); @@ -6753,6 +6821,9 @@ image_save_dialog_response_cb (GtkWidget *fc, return; } + ev_window_file_chooser_save_folder (ev_window, GTK_FILE_CHOOSER (fc), + G_USER_DIRECTORY_PICTURES); + uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (fc)); format = g_object_get_data (G_OBJECT (filter), "pixbuf-format"); @@ -6855,6 +6926,9 @@ ev_view_popup_cmd_save_image_as (GtkAction *action, EvWindow *window) gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (fc), TRUE); file_chooser_dialog_add_writable_pixbuf_formats (GTK_FILE_CHOOSER (fc)); + + ev_window_file_chooser_restore_folder (window, GTK_FILE_CHOOSER (fc), NULL, + G_USER_DIRECTORY_PICTURES); g_signal_connect (fc, "response", G_CALLBACK (image_save_dialog_response_cb), @@ -6990,6 +7064,9 @@ attachment_save_dialog_response_cb (GtkWidget *fc, return; } + ev_window_file_chooser_save_folder (ev_window, GTK_FILE_CHOOSER (fc), + G_USER_DIRECTORY_DOCUMENTS); + uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (fc)); target_file = g_file_new_for_uri (uri); g_object_get (G_OBJECT (fc), "action", &fc_action, NULL); @@ -7086,6 +7163,9 @@ ev_attachment_popup_cmd_save_attachment_as (GtkAction *action, EvWindow *window) gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (fc), ev_attachment_get_name (attachment)); + ev_window_file_chooser_restore_folder (window, GTK_FILE_CHOOSER (fc), NULL, + G_USER_DIRECTORY_DOCUMENTS); + g_signal_connect (fc, "response", G_CALLBACK (attachment_save_dialog_response_cb), window); -- cgit v1.2.1