[nautilus] files-view: add optional menu item for creating links



commit 0eef08686f520caf3700bff4f9b371fa780dba88
Author: Razvan Chitu <razvan ch95 gmail com>
Date:   Tue Dec 22 14:56:20 2015 +0200

    files-view: add optional menu item for creating links
    
    The menu item for creating links was removed in previous versions of nautilus
    since it exposes a concept of the file system that is not really clear.
    However, we don't have a working solution yet for the use cases that creating
    links is a workaround, so we didn't remove the functionality altogether.
    
    We were allowing link creation with a shortcut and with the middle button while
    performing a drag and drop operation. However, some users would need to use a
    context menu action instead of a drag and drop operation, which usually is less
    convenient and prone to errors.
    
    Since this is demanded, implement the menu action for it and add a gsetting
    preference to show it in the context menu for those users who like to have it
    there.
    
    Also the new implementation uses the code that is already used for other
    operations, improving the implementation compared to the previous one.
    
    In an upcoming patch we add the UI for the preference dialog.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=745575

 data/org.gnome.nautilus.gschema.xml                |    5 +
 libnautilus-private/nautilus-clipboard-monitor.c   |   10 +++
 libnautilus-private/nautilus-clipboard-monitor.h   |    1 +
 src/nautilus-files-view.c                          |   84 +++++++++++++++++--
 .../ui/nautilus-files-view-context-menus.ui        |    7 ++
 5 files changed, 98 insertions(+), 9 deletions(-)
---
diff --git a/data/org.gnome.nautilus.gschema.xml b/data/org.gnome.nautilus.gschema.xml
index 9aece59..bf03e03 100644
--- a/data/org.gnome.nautilus.gschema.xml
+++ b/data/org.gnome.nautilus.gschema.xml
@@ -81,6 +81,11 @@
       <summary>Whether to show a context menu item to delete permanently</summary>
       <description>If set to true Nautilus will show a delete permanently context menu item to bypass the 
trash.</description>
     </key>
+    <key type="b" name="show-create-link">
+      <default>false</default>
+      <summary>Whether to show a context menu item to create links from copied files</summary>
+      <description>If set to true Nautilus will show a create link context menu item to create links from 
the copied files</description>
+    </key>
     <key type="b" name="confirm-trash">
       <default>true</default>
       <summary>Whether to ask for confirmation when deleting files, or emptying Trash</summary>
diff --git a/libnautilus-private/nautilus-clipboard-monitor.c 
b/libnautilus-private/nautilus-clipboard-monitor.c
index 9ae66f6..891401a 100644
--- a/libnautilus-private/nautilus-clipboard-monitor.c
+++ b/libnautilus-private/nautilus-clipboard-monitor.c
@@ -205,6 +205,16 @@ nautilus_clipboard_monitor_get_clipboard_info (NautilusClipboardMonitor *monitor
        return monitor->details->info;
 }
 
+gboolean
+nautilus_clipboard_monitor_is_cut (NautilusClipboardMonitor *monitor)
+{
+       NautilusClipboardInfo *info;
+
+       info = nautilus_clipboard_monitor_get_clipboard_info (monitor);
+
+       return info != NULL ? info->cut : FALSE;
+}
+
 void
 nautilus_clear_clipboard_callback (GtkClipboard *clipboard,
                                    gpointer      user_data)
diff --git a/libnautilus-private/nautilus-clipboard-monitor.h 
b/libnautilus-private/nautilus-clipboard-monitor.h
index 8aa4788..7d1e6fa 100644
--- a/libnautilus-private/nautilus-clipboard-monitor.h
+++ b/libnautilus-private/nautilus-clipboard-monitor.h
@@ -65,6 +65,7 @@ NautilusClipboardMonitor *   nautilus_clipboard_monitor_get (void);
 void nautilus_clipboard_monitor_set_clipboard_info (NautilusClipboardMonitor *monitor,
                                                     NautilusClipboardInfo *info);
 NautilusClipboardInfo * nautilus_clipboard_monitor_get_clipboard_info (NautilusClipboardMonitor *monitor);
+gboolean nautilus_clipboard_monitor_is_cut (NautilusClipboardMonitor *monitor);
 void nautilus_clipboard_monitor_emit_changed (void);
 
 void nautilus_clear_clipboard_callback (GtkClipboard *clipboard,
diff --git a/src/nautilus-files-view.c b/src/nautilus-files-view.c
index 1a78425..1efeb5e 100644
--- a/src/nautilus-files-view.c
+++ b/src/nautilus-files-view.c
@@ -2402,24 +2402,23 @@ action_open_item_new_window (GSimpleAction *action,
 }
 
 static void
-paste_clipboard_data (NautilusFilesView *view,
-                      GtkSelectionData  *selection_data,
-                      char              *destination_uri)
+handle_clipboard_data (NautilusFilesView *view,
+                       GtkSelectionData  *selection_data,
+                       char              *destination_uri,
+                       GdkDragAction      action)
 {
-        gboolean cut;
         GList *item_uris;
 
-        cut = FALSE;
-        item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, &cut,
+        item_uris = nautilus_clipboard_get_uri_list_from_selection_data (selection_data, NULL,
                                                                          copied_files_atom);
 
         if (item_uris != NULL && destination_uri != NULL) {
                 nautilus_files_view_move_copy_items (view, item_uris, NULL, destination_uri,
-                                               cut ? GDK_ACTION_MOVE : GDK_ACTION_COPY,
-                                               0, 0);
+                                                     action,
+                                                     0, 0);
 
                 /* If items are cut then remove from clipboard */
-                if (cut) {
+                if (action == GDK_ACTION_MOVE) {
                         gtk_clipboard_clear (nautilus_clipboard_get (GTK_WIDGET (view)));
                 }
 
@@ -2428,6 +2427,19 @@ paste_clipboard_data (NautilusFilesView *view,
 }
 
 static void
+paste_clipboard_data (NautilusFilesView *view,
+                      GtkSelectionData  *selection_data,
+                      char              *destination_uri)
+{
+        GdkDragAction action;
+
+        action = nautilus_clipboard_monitor_is_cut (nautilus_clipboard_monitor_get ()) ?
+                GDK_ACTION_MOVE : GDK_ACTION_COPY;
+
+        handle_clipboard_data (view, selection_data, destination_uri, action);
+}
+
+static void
 paste_clipboard_received_callback (GtkClipboard     *clipboard,
                                    GtkSelectionData *selection_data,
                                    gpointer          data)
@@ -2467,6 +2479,45 @@ action_paste_files (GSimpleAction *action,
 }
 
 static void
+create_links_clipboard_received_callback (GtkClipboard     *clipboard,
+                                          GtkSelectionData *selection_data,
+                                          gpointer          data)
+{
+        NautilusFilesView *view;
+        char *view_uri;
+
+        view = NAUTILUS_FILES_VIEW (data);
+
+        view_uri = nautilus_files_view_get_backing_uri (view);
+
+        if (view->details->slot != NULL) {
+                handle_clipboard_data (view, selection_data, view_uri, GDK_ACTION_LINK);
+        }
+
+        g_free (view_uri);
+
+        g_object_unref (view);
+}
+
+static void
+action_create_links (GSimpleAction *action,
+                     GVariant      *state,
+                     gpointer       user_data)
+{
+        NautilusFilesView *view;
+
+        g_assert (NAUTILUS_IS_FILES_VIEW (user_data));
+
+        view = NAUTILUS_FILES_VIEW (user_data);
+
+        g_object_ref (view);
+        gtk_clipboard_request_contents (nautilus_clipboard_get (GTK_WIDGET (view)),
+                                        copied_files_atom,
+                                        create_links_clipboard_received_callback,
+                                        view);
+}
+
+static void
 click_policy_changed_callback (gpointer callback_data)
 {
         NautilusFilesView *view;
@@ -5876,6 +5927,7 @@ const GActionEntry view_entries[] = {
         { "new-folder", action_new_folder },
         { "select-all", action_select_all },
         { "paste", action_paste_files },
+        { "create-link", action_create_links },
         { "new-document" },
         /* Selection menu */
         { "scripts" },
@@ -6164,6 +6216,7 @@ real_update_actions_state (NautilusFilesView *view)
         gboolean can_move_files;
         gboolean can_trash_files;
         gboolean can_copy_files;
+        gboolean can_link_files;
         gboolean can_paste_files_into;
         gboolean show_app, show_run;
         gboolean item_opens_in_view;
@@ -6179,6 +6232,7 @@ real_update_actions_state (NautilusFilesView *view)
         gboolean show_stop;
         gboolean show_detect_media;
         gboolean settings_show_delete_permanently;
+        gboolean settings_show_create_link;
         GDriveStartStopType start_stop_type;
 
         view_action_group = view->details->view_action_group;
@@ -6208,6 +6262,9 @@ real_update_actions_state (NautilusFilesView *view)
                 !selection_contains_desktop_or_home_dir;
         can_copy_files = selection_count != 0
                 && !selection_contains_special_link;
+        can_link_files = (!nautilus_clipboard_monitor_is_cut (nautilus_clipboard_monitor_get ()) &&
+                          !selection_contains_recent &&
+                          !is_read_only);
         can_move_files = can_delete_files && !selection_contains_recent;
         can_paste_files_into = (!selection_contains_recent &&
                                 selection_count == 1 &&
@@ -6215,6 +6272,8 @@ real_update_actions_state (NautilusFilesView *view)
         show_properties = !NAUTILUS_IS_DESKTOP_CANVAS_VIEW (view) || selection_count > 0;
          settings_show_delete_permanently = g_settings_get_boolean (nautilus_preferences,
                                                                     
NAUTILUS_PREFERENCES_SHOW_DELETE_PERMANENTLY);
+         settings_show_create_link = g_settings_get_boolean (nautilus_preferences,
+                                                             NAUTILUS_PREFERENCES_SHOW_CREATE_LINK);
 
         /* Right click actions */
         /* Selection menu actions */
@@ -6425,6 +6484,12 @@ real_update_actions_state (NautilusFilesView *view)
                                      !is_read_only && !selection_contains_recent);
 
         action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
+                                             "create-link");
+        g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                                     can_link_files &&
+                                     settings_show_create_link);
+
+        action = g_action_map_lookup_action (G_ACTION_MAP (view_action_group),
                                              "paste-into");
         g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
                                      !selection_is_read_only && !selection_contains_recent &&
@@ -8150,6 +8215,7 @@ nautilus_files_view_init (NautilusFilesView *view)
         /* Background menu */
         nautilus_application_add_accelerator (app, "view.select-all", "<control>a");
         nautilus_application_add_accelerator (app, "view.paste", "<control>v");
+        nautilus_application_add_accelerator (app, "view.create-link", "<control>m");
         /* Selection menu */
         gtk_application_set_accels_for_action (GTK_APPLICATION (app),
                                                "view.open-with-default-application", open_accels);
diff --git a/src/resources/ui/nautilus-files-view-context-menus.ui 
b/src/resources/ui/nautilus-files-view-context-menus.ui
index 238ac38..b60ab1f 100644
--- a/src/resources/ui/nautilus-files-view-context-menus.ui
+++ b/src/resources/ui/nautilus-files-view-context-menus.ui
@@ -19,6 +19,13 @@
     </section>
     <section>
       <item>
+        <attribute name="label" translatable="yes">Create _Link</attribute>
+        <attribute name="action">view.create-link</attribute>
+        <attribute name="hidden-when">action-disabled</attribute>
+      </item>
+    </section>
+    <section>
+      <item>
         <attribute name="label" translatable="yes">Select _All</attribute>
         <attribute name="action">view.select-all</attribute>
       </item>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]