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 configured and multiple files are selected.

Ported from nemo.
  • Loading branch information
mtwebster committed Jun 25, 2021
1 parent 2c823ef commit 579a893
Show file tree
Hide file tree
Showing 5 changed files with 183 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
16 changes: 16 additions & 0 deletions src/caja-file-management-properties.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
77 changes: 77 additions & 0 deletions src/caja-file-management-properties.ui
Original file line number Diff line number Diff line change
Expand Up @@ -1161,6 +1161,83 @@
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox33">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label11">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">&lt;b&gt;Bulk Rename&lt;/b&gt;</property>
<property name="use-markup">True</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox35">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="spacing">10</property>
<child>
<object class="GtkLabel" id="label13">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Command to invoke when renaming multiple items:</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="bulk_rename_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="invisible-char">●</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
</object>
<packing>
<property name="position">1</property>
Expand Down
92 changes: 82 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,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)
Expand 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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 579a893

Please sign in to comment.