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/caja-file-management-properties.c b/src/caja-file-management-properties.c index 5a4368a7f..9e4a8827b 100644 --- a/src/caja-file-management-properties.c +++ b/src/caja-file-management-properties.c @@ -77,6 +77,8 @@ /* int enums */ #define CAJA_FILE_MANAGEMENT_PROPERTIES_THUMBNAIL_LIMIT_WIDGET "preview_image_size_combobox" +#define CAJA_FILE_MANAGEMENT_PROPERTIES_BULK_RENAME_WIDGET "bulk_rename_entry" + static const char * const default_view_values[] = { "icon-view", @@ -939,6 +941,17 @@ bind_builder_bool_inverted (GtkBuilder *builder, "active", G_SETTINGS_BIND_INVERT_BOOLEAN); } +static void +bind_builder_string_entry (GtkBuilder *builder, + GSettings *settings, + const char *widget_name, + const char *prefs) +{ + g_settings_bind (settings, prefs, + gtk_builder_get_object (builder, widget_name), + "text", G_SETTINGS_BIND_DEFAULT); +} + static gboolean enum_get_mapping (GValue *value, GVariant *variant, @@ -1136,6 +1149,9 @@ caja_file_management_properties_dialog_setup (GtkBuilder *builder, GtkWindow *wi bind_builder_bool (builder, caja_preferences, CAJA_FILE_MANAGEMENT_PROPERTIES_TRASH_DELETE_WIDGET, CAJA_PREFERENCES_ENABLE_DELETE); + bind_builder_string_entry (builder, caja_preferences, + CAJA_FILE_MANAGEMENT_PROPERTIES_BULK_RENAME_WIDGET, + CAJA_PREFERENCES_BULK_RENAME_TOOL); bind_builder_bool (builder, caja_preferences, CAJA_FILE_MANAGEMENT_PROPERTIES_SHOW_HIDDEN_WIDGET, CAJA_PREFERENCES_SHOW_HIDDEN_FILES); diff --git a/src/caja-file-management-properties.ui b/src/caja-file-management-properties.ui index 3207c800a..ed44c28e3 100644 --- a/src/caja-file-management-properties.ui +++ b/src/caja-file-management-properties.ui @@ -1161,6 +1161,83 @@ 2 + + + True + False + vertical + 6 + + + True + False + <b>Bulk Rename</b> + True + 0 + + + False + False + 0 + + + + + True + False + vertical + + + True + False + 10 + + + True + False + Command to invoke when renaming multiple items: + 0 + + + False + True + 0 + + + + + True + True + True + + + + False + True + 1 + + + + + False + True + 0 + + + + + False + True + 1 + + + + + False + True + 3 + + 1 diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 7431c9635..ac936b651 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -6421,6 +6421,66 @@ real_action_redo (FMDirectoryView *view) caja_undostack_manager_redo (manager, GTK_WIDGET (view), finish_undoredo_callback); } +static char * +get_bulk_rename_tool (void) +{ + char *bulk_rename_tool; + 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) +{ + char *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) +{ + GString *cmd; + char *parameter; + char *quoted_parameter; + char *bulk_rename_tool; + GList *walk; + CajaFile *file; + + /* assemble command line */ + bulk_rename_tool = get_bulk_rename_tool (); + cmd = g_string_new (bulk_rename_tool); + g_free (bulk_rename_tool); + for (walk = selection; walk; walk = walk->next) { + file = walk->data; + parameter = caja_file_get_uri (file); + quoted_parameter = g_shell_quote (parameter); + g_free (parameter); + cmd = g_string_append (cmd, " "); + cmd = g_string_append (cmd, quoted_parameter); + g_free (quoted_parameter); + } + + guint i = 0; + + // Escape percents + for (i = 0; i < strlen(cmd->str); 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 +6492,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 +8980,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);