Skip to content

Commit

Permalink
Add native support for using a bulk renaming tool.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mtwebster committed Sep 17, 2021
1 parent 651bded commit 9a1f998
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 10 deletions.
3 changes: 3 additions & 0 deletions libcaja-private/caja-global-preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
5 changes: 5 additions & 0 deletions libcaja-private/org.mate.caja.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@
<summary>Whether to show desktop notifications</summary>
<description>If set to true, Caja will show desktop notifications.</description>
</key>
<key type="ay" name="bulk-rename-tool">
<default>[]</default>
<summary>Bulk rename utility</summary>
<description>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.</description>
</key>
</schema>

<schema id="org.mate.caja.icon-view" path="/org/mate/caja/icon-view/" gettext-domain="caja">
Expand Down
113 changes: 103 additions & 10 deletions src/file-manager/fm-directory-view.c
Original file line number Diff line number Diff line change
Expand Up @@ -6421,6 +6421,87 @@ 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)
{
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)
Expand All @@ -6432,16 +6513,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);
Expand Down Expand Up @@ -8915,9 +9001,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);
Expand Down

0 comments on commit 9a1f998

Please sign in to comment.