From aaf4ce7f85811b4303b9adf8ebd1a8924bcb8173 Mon Sep 17 00:00:00 2001 From: Michael Webster Date: Fri, 17 Sep 2021 09:57:52 -0400 Subject: [PATCH] Add native support for using a bulk renaming tool. This allows the normal method of renaming a file launch a bulk renamer if one is detected (or configured) and multiple files are selected. Ported from nemo. --- libcaja-private/caja-global-preferences.h | 3 + libcaja-private/org.mate.caja.gschema.xml | 5 + src/file-manager/fm-directory-view.c | 117 ++++++++++++++++++++-- 3 files changed, 115 insertions(+), 10 deletions(-) diff --git a/libcaja-private/caja-global-preferences.h b/libcaja-private/caja-global-preferences.h index 832811574..4d978e6e1 100644 --- a/libcaja-private/caja-global-preferences.h +++ b/libcaja-private/caja-global-preferences.h @@ -209,6 +209,9 @@ typedef enum #define CAJA_PREFERENCES_LOCKDOWN_COMMAND_LINE "disable-command-line" #define CAJA_PREFERENCES_DISABLED_EXTENSIONS "disabled-extensions" +/* bulk rename utility */ +#define CAJA_PREFERENCES_BULK_RENAME_TOOL "bulk-rename-tool" + void caja_global_preferences_init (void); char *caja_global_preferences_get_default_folder_viewer_preference_as_iid (void); diff --git a/libcaja-private/org.mate.caja.gschema.xml b/libcaja-private/org.mate.caja.gschema.xml index 399efdc79..17de5838d 100644 --- a/libcaja-private/org.mate.caja.gschema.xml +++ b/libcaja-private/org.mate.caja.gschema.xml @@ -269,6 +269,11 @@ Whether to show desktop notifications If set to true, Caja will show desktop notifications. + + [] + Bulk rename utility + If set, Nautilus will append URIs of selected files and treat the result as a command line for bulk renaming. Bulk rename applications can register themselves in this key by setting the key to a space-separated string of their executable name and any command line options. If the executable name is not set to a full path, it will be searched for in the search path. + diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 7431c9635..c1718089d 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -6421,6 +6421,91 @@ real_action_redo (FMDirectoryView *view) caja_undostack_manager_redo (manager, GTK_WIDGET (view), finish_undoredo_callback); } +static const gchar *known_bulk_renamers[][2] = { + { "bulky", "bulky" }, + { "thunar", "thunar -B" } +}; + +static char * +get_bulk_rename_tool (void) +{ + gchar *bulk_rename_tool = NULL; + gint i; + + for (i = 0; i < G_N_ELEMENTS (known_bulk_renamers); i++) { + gchar *binary = g_find_program_in_path (known_bulk_renamers[i][0]); + if (binary != NULL) { + bulk_rename_tool = g_strdup (known_bulk_renamers[i][1]); + g_free (binary); + break; + } + } + + if (bulk_rename_tool == NULL) { + g_settings_get (caja_preferences, + CAJA_PREFERENCES_BULK_RENAME_TOOL, + "^ay", &bulk_rename_tool); + } + + return g_strstrip (bulk_rename_tool); +} + +static gboolean +have_bulk_rename_tool (void) +{ + gchar *bulk_rename_tool; + gboolean have_tool; + + bulk_rename_tool = get_bulk_rename_tool (); + have_tool = ((bulk_rename_tool != NULL) && (*bulk_rename_tool != '\0')); + g_free (bulk_rename_tool); + + return have_tool; +} + +static void +invoke_external_bulk_rename_utility (FMDirectoryView *view, + GList *selection) +{ + GList *iter; + GString *cmd; + gchar *bulk_rename_tool; + gint i; + + /* assemble command line */ + bulk_rename_tool = get_bulk_rename_tool (); + cmd = g_string_new (bulk_rename_tool); + g_free (bulk_rename_tool); + + for (iter = selection; iter != NULL; iter = iter->next) { + CajaFile *file; + gchar *parameter; + gchar *quoted_parameter; + + file = CAJA_FILE (iter->data); + + parameter = caja_file_get_uri (file); + quoted_parameter = g_shell_quote (parameter); + cmd = g_string_append (cmd, " "); + cmd = g_string_append (cmd, quoted_parameter); + + g_free (parameter); + g_free (quoted_parameter); + } + + // Escape percents + for (i = 0; i < cmd->len; i++) { + if (cmd->str[i] == '%') { + g_string_insert_c (cmd, i++, '%'); + } + } + + /* spawning and error handling */ + caja_launch_application_from_command (gtk_widget_get_screen (GTK_WIDGET (view)), + cmd->str, cmd->str, FALSE, NULL); + g_string_free (cmd, TRUE); +} + static void real_action_rename (FMDirectoryView *view, gboolean select_all) @@ -6432,16 +6517,21 @@ real_action_rename (FMDirectoryView *view, selection = fm_directory_view_get_selection (view); if (selection_not_empty_in_menu_callback (view, selection)) { - CajaFile *file; - - file = CAJA_FILE (selection->data); - - if (!select_all) { + /* If there is more than one file selected, invoke a batch renamer */ + if (selection->next != NULL) { + if (have_bulk_rename_tool ()) { + invoke_external_bulk_rename_utility (view, selection); + } + } else { + CajaFile *file; + file = CAJA_FILE (selection->data); + if (!select_all) { /* directories don't have a file extension, so * they are always pre-selected as a whole */ - select_all = caja_file_is_directory (file); + select_all = caja_file_is_directory (file); + } + EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, file, select_all)); } - EEL_CALL_METHOD (FM_DIRECTORY_VIEW_CLASS, view, start_renaming_file, (view, file, select_all)); } caja_file_list_free (selection); @@ -8915,9 +9005,16 @@ real_update_menus (FMDirectoryView *view) G_GNUC_BEGIN_IGNORE_DEPRECATIONS; action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_RENAME); - gtk_action_set_sensitive (action, - selection_count == 1 && - fm_directory_view_can_rename_file (view, selection->data)); + + /* rename sensitivity depending on selection */ + if (selection_count > 1) { + /* If multiple files are selected, sensitivity depends on whether a bulk renamer is registered. */ + gtk_action_set_sensitive (action, have_bulk_rename_tool ()); + } else { + gtk_action_set_sensitive (action, + selection_count == 1 && + fm_directory_view_can_rename_file (view, selection->data)); + } action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_NEW_FOLDER);