diff options
author | Alexandru Pandelea <alexandru.pandelea@gmail.com> | 2016-07-29 15:15:52 +0300 |
---|---|---|
committer | Alexandru Pandelea <alexandru.pandelea@gmail.com> | 2016-07-29 15:21:24 +0300 |
commit | 51206dcb24bf03be7b3c97530ece741caeeeb55f (patch) | |
tree | c7bd181c3a6cc2c529703b8c3b069905b633aca0 | |
parent | 840481fa160c9d496b5f9057d9f73b12387c2bf2 (diff) | |
download | nautilus-51206dcb24bf03be7b3c97530ece741caeeeb55f.tar.gz |
Add format mode
There were added tags as text for the format mode.
-rw-r--r-- | src/nautilus-batch-rename-utilities.c | 417 | ||||
-rw-r--r-- | src/nautilus-batch-rename-utilities.h | 4 | ||||
-rw-r--r-- | src/nautilus-batch-rename.c | 590 | ||||
-rw-r--r-- | src/nautilus-batch-rename.h | 22 | ||||
-rw-r--r-- | src/nautilus-file.c | 2 | ||||
-rw-r--r-- | src/resources/ui/nautilus-batch-rename-dialog.ui | 67 |
6 files changed, 1011 insertions, 91 deletions
diff --git a/src/nautilus-batch-rename-utilities.c b/src/nautilus-batch-rename-utilities.c index da9bc8fe7..6487d49f0 100644 --- a/src/nautilus-batch-rename-utilities.c +++ b/src/nautilus-batch-rename-utilities.c @@ -7,6 +7,7 @@ #include <gtk/gtk.h> #include <string.h> #include <stdarg.h> +#include <eel/eel-vfs-extensions.h> #define MAX_DISPLAY_LEN 40 #define MAX_FILTER_LEN 500 @@ -19,6 +20,15 @@ typedef struct { typedef struct { NautilusBatchRename *dialog; GHashTable *hash_table; + + GList *selection_metadata; + + gboolean have_creation_date; + gboolean have_equipment; + gboolean have_season; + gboolean have_episode_nr; + gboolean have_track_nr; + gboolean have_artist_name; } QueryData; static void cursor_callback (GObject *object, @@ -32,44 +42,6 @@ string_free (gpointer mem) } static GString* -batch_rename_append (gchar *file_name, - gchar *entry_text) -{ - GString *result; - - result = g_string_new (""); - - if (result == NULL) { - g_string_append (result, file_name); - - return result; - } - - g_string_append_printf (result, "%s%s", file_name, entry_text); - - return result; -} - -static GString* -batch_rename_prepend (gchar *file_name, - gchar *entry_text) -{ - GString *result; - - result = g_string_new (""); - - if (result == NULL) { - g_string_append (result, file_name); - - return result; - } - - g_string_append_printf (result, "%s%s", entry_text, file_name); - - return result; -} - -static GString* batch_rename_replace (gchar *string, gchar *substr, gchar *replacement) @@ -108,12 +80,187 @@ batch_rename_replace (gchar *string, g_string_append (new_string, replacement); } + g_strfreev (splitted_string); + return new_string; } +static gchar* +get_metadata (GList *selection_metadata, + gchar *file_name, + gchar *metadata) +{ + GList *l; + FileMetadata *file_metadata; + + for (l = selection_metadata; l != NULL; l = l->next) { + file_metadata = l->data; + if (g_strcmp0 (file_name, file_metadata->file_name->str) == 0) { + if (g_strcmp0 (metadata, "creation_date") == 0 && + file_metadata->creation_date != NULL && + g_strcmp0 (file_metadata->creation_date->str, "")) + return file_metadata->creation_date->str; + + if (g_strcmp0 (metadata, "equipment") == 0 && + file_metadata->equipment != NULL && + g_strcmp0 (file_metadata->equipment->str, "")) + return file_metadata->equipment->str; + + if (g_strcmp0 (metadata, "season") == 0 && + file_metadata->season != NULL && + g_strcmp0 (file_metadata->season->str, "")) + return file_metadata->season->str; + + if (g_strcmp0 (metadata, "episode_nr") == 0 && + file_metadata->episode_nr != NULL && + g_strcmp0 (file_metadata->episode_nr->str, "")) + return file_metadata->episode_nr->str; + + if (g_strcmp0 (metadata, "track_nr") == 0 && + file_metadata->track_nr != NULL && + g_strcmp0 (file_metadata->track_nr->str, "")) + return file_metadata->track_nr->str; + + if (g_strcmp0 (metadata, "artist_name") == 0 && + file_metadata->artist_name != NULL && + g_strcmp0 (file_metadata->artist_name->str, "")) + return file_metadata->artist_name->str; + } + } + + return NULL; +} + +static GString* +batch_rename_format (NautilusFile *file, + GList *tags_list, + GList *selection_metadata, + gint count) +{ + GList *l; + GString *tag, *new_name; + gboolean added_tag; + gint start_offset, end_offset; + g_autofree gchar *file_name, *extension; + gchar *metadata, **splitted_date; + + file_name = nautilus_file_get_display_name (file); + extension = nautilus_file_get_extension (file); + + eel_filename_get_rename_region (file_name, + &start_offset, &end_offset); + new_name = g_string_new (""); + + for (l = tags_list; l != NULL; l = l->next) { + tag = l->data; + added_tag = FALSE; + + if (!added_tag && g_strcmp0 (tag->str, "[Original file name]") == 0) { + new_name = g_string_append_len (new_name, + nautilus_file_get_display_name (file), + end_offset); + added_tag = TRUE; + } + + if (!added_tag && g_strcmp0 (tag->str, "[1, 2, 3]") == 0) { + g_string_append_printf (new_name, "%d", count); + added_tag = TRUE; + } + + if (!added_tag && g_strcmp0 (tag->str, "[01, 02, 03]") == 0) { + if (count < 10) + g_string_append_printf (new_name, "0%d", count); + else + g_string_append_printf (new_name, "%d", count); + added_tag = TRUE; + } + + if (!added_tag && g_strcmp0 (tag->str, "[001, 002, 003]") == 0) { + if (count < 10) + g_string_append_printf (new_name, "00%d", count); + else + if (count < 100) + g_string_append_printf (new_name, "0%d", count); + else + g_string_append_printf (new_name, "%d", count); + added_tag = TRUE; + } + + if (!added_tag && g_strcmp0 (tag->str, "[Camera model]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "equipment"); + + if (metadata != NULL) { + new_name = g_string_append (new_name, metadata); + added_tag = TRUE; + } + } + + if (!added_tag && g_strcmp0 (tag->str, "[Date taken]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "creation_date"); + + if (metadata != NULL) { + splitted_date = g_strsplit (metadata, "T", -1); + + new_name = g_string_append (new_name, splitted_date[0]); + added_tag = TRUE; + + g_strfreev (splitted_date); + } + } + + if (!added_tag && g_strcmp0 (tag->str, "[Season nr]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "season"); + + if (metadata != NULL) { + new_name = g_string_append (new_name, metadata); + added_tag = TRUE; + } + } + + if (!added_tag && g_strcmp0 (tag->str, "[Episode nr]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "episode_nr"); + + if (metadata != NULL) { + new_name = g_string_append (new_name, metadata); + added_tag = TRUE; + } + } + + if (!added_tag && g_strcmp0 (tag->str, "[Track nr]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "track_nr"); + + if (metadata != NULL) { + new_name = g_string_append (new_name, metadata); + added_tag = TRUE; + } + } + + if (!added_tag && g_strcmp0 (tag->str, "[Artist name]") == 0) { + metadata = get_metadata (selection_metadata, file_name, "artist_name"); + + if (metadata != NULL) { + new_name = g_string_append (new_name, metadata); + added_tag = TRUE; + } + } + if (!added_tag) + new_name = g_string_append (new_name, tag->str); + } + + if (g_strcmp0 (new_name->str, "") == 0) + new_name = g_string_append (new_name, file_name); + else + if (extension != NULL) + new_name = g_string_append (new_name, extension); + + return new_name; +} + GList* get_new_names_list (NautilusBatchRenameMode mode, GList *selection, + GList *tags_list, + GList *selection_metadata, gchar *entry_text, gchar *replace_text) { @@ -121,8 +268,10 @@ get_new_names_list (NautilusBatchRenameMode mode, GList *result; GString *file_name; NautilusFile *file; + gint count; result = NULL; + count = 1; file_name = g_string_new (""); for (l = selection; l != NULL; l = l->next) { @@ -131,13 +280,13 @@ get_new_names_list (NautilusBatchRenameMode mode, g_string_append (file_name ,nautilus_file_get_name (file)); /* get the new name here and add it to the list*/ - if (mode == NAUTILUS_BATCH_RENAME_PREPEND) - result = g_list_prepend (result, - batch_rename_prepend (file_name->str, entry_text)); - - if (mode == NAUTILUS_BATCH_RENAME_APPEND) + if (mode == NAUTILUS_BATCH_RENAME_FORMAT) { result = g_list_prepend (result, - batch_rename_append (file_name->str, entry_text)); + batch_rename_format (file, + tags_list, + selection_metadata, + count++)); + } if (mode == NAUTILUS_BATCH_RENAME_REPLACE) result = g_list_prepend (result, @@ -242,7 +391,6 @@ list_has_duplicates (NautilusBatchRename *dialog, for (l1 = new_names; l1 != NULL; l1 = l1->next) { if (g_cancellable_is_cancelled (cancellable)) { - return NULL; g_list_free_full (result, g_free); break; } @@ -286,6 +434,11 @@ list_has_duplicates (NautilusBatchRename *dialog, if (!have_conflict) for (l2 = new_names; l2 != NULL; l2 = l2->next) { file_name3 = l2->data; + + /* thread was interrupted */ + if (file_name3 == NULL) + break; + if (l1 != l2 && g_string_equal (new_name, file_name3)) { result = g_list_prepend (result, strdup (new_name->str)); @@ -422,7 +575,7 @@ nautilus_batch_rename_sort (GList *selection, for (l = selection; l != NULL; l = l->next) { CreateDateElem *elem; - elem = g_malloc (sizeof (CreateDateElem*)); + elem = g_malloc (sizeof (NautilusFile*) + sizeof (gint*)); file = NAUTILUS_FILE (l->data); @@ -471,40 +624,147 @@ cursor_callback (GObject *object, gint *value; QueryData *data; GError *error; + const gchar *file_name; + GList *l; + FileMetadata *metadata; error = NULL; + metadata = NULL; cursor = TRACKER_SPARQL_CURSOR (object); data = user_data; hash_table = data->hash_table; success = tracker_sparql_cursor_next_finish (cursor, result, &error); - if (!success) { g_clear_error (&error); g_clear_object (&cursor); - query_finished (data->dialog, data->hash_table); + + query_finished (data->dialog, data->hash_table, data->selection_metadata); return; } - value = g_malloc (sizeof(int)); - *value = g_hash_table_size (hash_table); + /* creation date used for sorting criteria */ + if (tracker_sparql_cursor_get_string (cursor, 1, NULL) == NULL) { + if (hash_table != NULL) + g_hash_table_destroy (hash_table); + + data->hash_table = NULL; + data->have_creation_date = FALSE; + } else { + if (data->have_creation_date){ + value = g_malloc (sizeof(int)); + *value = g_hash_table_size (hash_table); - g_hash_table_insert (hash_table, + g_hash_table_insert (hash_table, strdup (tracker_sparql_cursor_get_string (cursor, 0, NULL)), value); + } + } + file_name = tracker_sparql_cursor_get_string (cursor, 0, NULL); + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; - if (tracker_sparql_cursor_get_string (cursor, 1, NULL) == NULL) { - g_object_unref (cursor); - g_hash_table_destroy (hash_table); + if (g_strcmp0 (file_name, metadata->file_name->str) == 0) + break; + } + + /* Metadata to be used in file name + * creation date */ + if (data->have_creation_date && tracker_sparql_cursor_get_string (cursor, 1, NULL) == NULL) { + data->have_creation_date = FALSE; + + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; + + g_string_free (metadata->creation_date, TRUE); + metadata->creation_date = NULL; + } + } else { + if (data->have_creation_date) + g_string_append (metadata->creation_date, + tracker_sparql_cursor_get_string (cursor, 1, NULL)); + } + + /* equipment */ + if (data->have_equipment && tracker_sparql_cursor_get_string (cursor, 2, NULL) == NULL) { + data->have_equipment = FALSE; + + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; + + g_string_free (metadata->equipment, TRUE); + metadata->equipment = NULL; + } + } else { + if (data->have_equipment) + g_string_append (metadata->equipment, + tracker_sparql_cursor_get_string (cursor, 2, NULL)); + } + + /* season nr */ + if (data->have_season && tracker_sparql_cursor_get_string (cursor, 3, NULL) == NULL) { + data->have_season = FALSE; - query_finished (data->dialog, NULL); + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; - /* if one file doesn't have the metadata, there's no point in - * continuing the query */ - return ; + g_string_free (metadata->season, TRUE); + metadata->season = NULL; + } + } else { + if (data->have_season) + g_string_append (metadata->season, + tracker_sparql_cursor_get_string (cursor, 3, NULL)); + } + + /* episode nr */ + if (data->have_episode_nr && tracker_sparql_cursor_get_string (cursor, 4, NULL) == NULL) { + data->have_episode_nr = FALSE; + + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; + + g_string_free (metadata->episode_nr, TRUE); + metadata->episode_nr = NULL; + } + } else { + if (data->have_episode_nr) + g_string_append (metadata->episode_nr, + tracker_sparql_cursor_get_string (cursor, 4, NULL)); + } + + /* track number */ + if (data->have_track_nr && tracker_sparql_cursor_get_string (cursor, 5, NULL) == NULL) { + data->have_track_nr = FALSE; + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; + + g_string_free (metadata->track_nr, TRUE); + metadata->track_nr = NULL; + } + } else { + if (data->have_track_nr) + g_string_append (metadata->track_nr, + tracker_sparql_cursor_get_string (cursor, 5, NULL)); + } + + /* artist name */ + if (data->have_artist_name && tracker_sparql_cursor_get_string (cursor, 6, NULL) == NULL) { + data->have_artist_name = FALSE; + + for (l = data->selection_metadata; l != NULL; l = l->next) { + metadata = l->data; + + g_string_free (metadata->artist_name, TRUE); + metadata->artist_name = NULL; + } + } else { + if (data->have_artist_name) + g_string_append (metadata->artist_name, + tracker_sparql_cursor_get_string (cursor, 6, NULL)); } /* Get next */ @@ -533,15 +793,15 @@ query_callback (GObject *object, if (error != NULL) { g_error_free (error); - query_finished (data->dialog, data->hash_table); + query_finished (data->dialog, data->hash_table, data->selection_metadata); } else { cursor_next (data, cursor); } } void -check_creation_date_for_selection (NautilusBatchRename *dialog, - GList *selection) +check_metadata_for_selection (NautilusBatchRename *dialog, + GList *selection) { TrackerSparqlConnection *connection; GString *query; @@ -550,10 +810,17 @@ check_creation_date_for_selection (NautilusBatchRename *dialog, NautilusFile *file; GError *error; QueryData *data; + gchar *file_name; + FileMetadata *metadata; + GList *selection_metadata; error = NULL; + selection_metadata = NULL; - query = g_string_new ("SELECT nfo:fileName(?file) nie:contentCreated(?file) WHERE { ?file a nfo:FileDataObject. "); + query = g_string_new ("SELECT nfo:fileName(?file) nie:contentCreated(?file) " + "nfo:model(nfo:equipment(?file)) nmm:season(?file) nmm:episodeNumber(?file) " + "nmm:trackNumber(?file) nmm:artistName(?file) " + "WHERE { ?file a nfo:FileDataObject. "); g_string_append_printf (query, "FILTER(tracker:uri-is-parent('%s', nie:url(?file))) ", @@ -561,6 +828,7 @@ check_creation_date_for_selection (NautilusBatchRename *dialog, for (l = selection; l != NULL; l = l->next) { file = NAUTILUS_FILE (l->data); + file_name = nautilus_file_get_name (file); if (l == selection) g_string_append_printf (query, @@ -570,6 +838,17 @@ check_creation_date_for_selection (NautilusBatchRename *dialog, g_string_append_printf (query, "|| nfo:fileName(?file) = '%s' ", nautilus_file_get_name (file)); + + metadata = g_malloc (9 * sizeof (GString*)); + metadata->file_name = g_string_new (file_name); + metadata->creation_date = g_string_new (""); + metadata->equipment = g_string_new (""); + metadata->season = g_string_new (""); + metadata->episode_nr = g_string_new (""); + metadata->track_nr = g_string_new (""); + metadata->artist_name = g_string_new (""); + + selection_metadata = g_list_append (selection_metadata, metadata); } g_string_append (query, ")} ORDER BY ASC(nie:contentCreated(?file))"); @@ -586,9 +865,21 @@ check_creation_date_for_selection (NautilusBatchRename *dialog, (GDestroyNotify) g_free, (GDestroyNotify) g_free); - data = g_malloc (sizeof (QueryData*)); + data = g_malloc (sizeof (NautilusBatchRename*) + + sizeof (GHashTable*) + + sizeof (GList*) + + 9 * sizeof (gboolean)); data->hash_table = hash_table; data->dialog = dialog; + data->selection_metadata = selection_metadata; + + data->have_season = TRUE; + data->have_creation_date = TRUE; + data->have_season = TRUE; + data->have_artist_name = TRUE; + data->have_track_nr = TRUE; + data->have_equipment = TRUE; + data->have_episode_nr = TRUE; /* Make an asynchronous query to the store */ tracker_sparql_connection_query_async (connection, diff --git a/src/nautilus-batch-rename-utilities.h b/src/nautilus-batch-rename-utilities.h index 7c51fe65e..f9233e880 100644 --- a/src/nautilus-batch-rename-utilities.h +++ b/src/nautilus-batch-rename-utilities.h @@ -7,6 +7,8 @@ GList* get_new_names_list (NautilusBatchRenameMode mode, GList *selection, + GList *tags_list, + GList *selection_metadata, gchar *entry_text, gchar *replace_text); @@ -40,7 +42,7 @@ gint compare_files_by_first_created (gconstpointer a, gint compare_files_by_last_created (gconstpointer a, gconstpointer b); -void check_creation_date_for_selection (NautilusBatchRename *dialog, +void check_metadata_for_selection (NautilusBatchRename *dialog, GList *selection); gboolean selection_has_single_parent (GList *selection); diff --git a/src/nautilus-batch-rename.c b/src/nautilus-batch-rename.c index 0b3e8795d..befed21bb 100644 --- a/src/nautilus-batch-rename.c +++ b/src/nautilus-batch-rename.c @@ -22,11 +22,13 @@ #include "nautilus-batch-rename-utilities.h" #include <glib/gprintf.h> +#include <glib.h> #include <string.h> #define ADD_TEXT_ENTRY_SIZE 550 #define REPLACE_ENTRY_SIZE 275 #define DIALOG_TITLE_LEN 25 +#define TAG_UNAVAILABLE -2 struct _NautilusBatchRename { @@ -46,6 +48,7 @@ struct _NautilusBatchRename GtkWidget *add_button; GtkWidget *add_popover; GtkWidget *numbering_order_label; + GtkWidget *numbering_label; GtkWidget *scrolled_window; GtkWidget *numbering_order_popover; GtkWidget *numbering_order_button; @@ -66,8 +69,10 @@ struct _NautilusBatchRename GActionGroup *action_group; GMenu *numbering_order_menu; + GMenu *add_tag_menu; GHashTable *create_date; + GList *selection_metadata; /* check if all files in selection have the same parent */ gboolean same_parent; @@ -85,6 +90,17 @@ struct _NautilusBatchRename GtkSizeGroup *size_group1; GtkSizeGroup *size_group2; + + /* starting tag position, -1 if tag is missing and + * -2 if tag can't be added at all */ + gint original_name_tag; + gint numbering_tag; + gint creation_date_tag; + gint equipment_tag; + gint season_tag; + gint episode_nr_tag; + gint track_nr_tag; + gint artist_name_tag; }; static void file_names_widget_entry_on_changed (NautilusBatchRename *dialog); @@ -159,19 +175,319 @@ numbering_order_changed (GSimpleAction *action, file_names_widget_entry_on_changed (dialog); } +static void +add_original_file_name_tag (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + NautilusBatchRename *dialog; + gint *cursor_pos; + + dialog = NAUTILUS_BATCH_RENAME (user_data); + cursor_pos = g_malloc (sizeof (int)); + + g_object_get (dialog->name_entry, "cursor-position", cursor_pos, NULL); + + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Original file name]", + strlen ("[Original file name]"), + cursor_pos); + *cursor_pos += strlen ("[Original file name]"); + + gtk_entry_grab_focus_without_selecting (GTK_ENTRY (dialog->name_entry)); + + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + + g_free (cursor_pos); +} + +static void +disable_action (NautilusBatchRename *dialog, + gchar *action_name) +{ + GAction *action; + + action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + action_name); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); +} + +static void +add_metadata_tag (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + NautilusBatchRename *dialog; + gchar *action_name; + gint *cursor_pos; + + dialog = NAUTILUS_BATCH_RENAME (user_data); + action_name = g_malloc (strlen ("add-numbering-tag-zero")); + cursor_pos = g_malloc (sizeof (int)); + + g_object_get (action, "name", &action_name, NULL); + g_object_get (dialog->name_entry, "cursor-position", cursor_pos, NULL); + + if (g_strrstr (action_name, "creation-date")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Date taken]", + strlen ("[Date taken]"), + cursor_pos); + disable_action (dialog, "add-creation-date-tag"); + } + + if (g_strrstr (action_name, "equipment")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Camera model]", + strlen ("[Camera model]"), + cursor_pos); + disable_action (dialog, "add-equipment-tag"); + } + + if (g_strrstr (action_name, "season")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Season nr]", + strlen ("[Season nr]"), + cursor_pos); + disable_action (dialog, "add-season-tag"); + } + + if (g_strrstr (action_name, "episode")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Episode nr]", + strlen ("[Episode nr]"), + cursor_pos); + disable_action (dialog, "add-episode-tag"); + } + + if (g_strrstr (action_name, "track")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Track nr]", + strlen ("[Track nr]"), + cursor_pos); + disable_action (dialog, "add-track-number-tag"); + } + + if (g_strrstr (action_name, "artist")) { + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[Artist name]", + strlen ("[Artist name]"), + cursor_pos); + disable_action (dialog, "add-artist-name-tag"); + } + + gtk_entry_grab_focus_without_selecting (GTK_ENTRY (dialog->name_entry)); + + g_free (action_name); +} + +static void +add_numbering_tag (GSimpleAction *action, + GVariant *value, + gpointer user_data) +{ + NautilusBatchRename *dialog; + gchar *action_name; + gint *cursor_pos; + GAction *add_numbering_action; + + dialog = NAUTILUS_BATCH_RENAME (user_data); + action_name = g_malloc (strlen ("add-numbering-tag-zero")); + cursor_pos = g_malloc (sizeof (int)); + + g_object_get (action, "name", &action_name, NULL); + g_object_get (dialog->name_entry, "cursor-position", cursor_pos, NULL); + + if (g_strrstr (action_name, "zero")) + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[1, 2, 3]", + strlen ("[1, 2, 3]"), + cursor_pos); + + if (g_strrstr (action_name, "one")) + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[01, 02, 03]", + strlen ("[01, 02, 03]"), + cursor_pos); + + if (g_strrstr (action_name, "two")) + gtk_editable_insert_text (GTK_EDITABLE (dialog->name_entry), + "[001, 002, 003]", + strlen ("[001, 002, 003]"), + cursor_pos); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-zero"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-one"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-two"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + + gtk_entry_grab_focus_without_selecting (GTK_ENTRY (dialog->name_entry)); + + g_free (action_name); +} + const GActionEntry dialog_entries[] = { - { "numbering-order-changed", NULL, "s", "'name-ascending'", numbering_order_changed } + { "numbering-order-changed", NULL, "s", "'name-ascending'", numbering_order_changed }, + { "add-original-file-name-tag", add_original_file_name_tag }, + { "add-numbering-tag-zero", add_numbering_tag }, + { "add-numbering-tag-one", add_numbering_tag }, + { "add-numbering-tag-two", add_numbering_tag }, + { "add-creation-date-tag", add_metadata_tag }, + { "add-equipment-tag", add_metadata_tag }, + { "add-season-tag", add_metadata_tag }, + { "add-episode-tag", add_metadata_tag }, + { "add-video-album-tag", add_metadata_tag }, + { "add-track-number-tag", add_metadata_tag }, + { "add-artist-name-tag", add_metadata_tag }, + { "add-album-title-tag", add_metadata_tag }, + }; +gint compare_int (gconstpointer a, + gconstpointer b) +{ + return *(int*)a - *(int*)b; +} + +static GList* +split_entry_text (NautilusBatchRename *dialog, + gchar *entry_text) +{ + GString *string, *tag; + GArray *tag_positions; + gint tags, i, j; + GList *result = NULL; + + tags = 0; + j = 0; + tag_positions = g_array_new (FALSE, FALSE, sizeof (gint)); + + if (dialog->numbering_tag >= 0) { + g_array_append_val (tag_positions, dialog->numbering_tag); + tags++; + } + + if (dialog->original_name_tag >= 0) { + g_array_append_val (tag_positions, dialog->original_name_tag); + tags++; + } + + if (dialog->creation_date_tag >= 0) { + g_array_append_val (tag_positions, dialog->creation_date_tag); + tags++; + } + + if (dialog->equipment_tag >= 0) { + g_array_append_val (tag_positions, dialog->equipment_tag); + tags++; + } + + if (dialog->season_tag >= 0) { + g_array_append_val (tag_positions, dialog->season_tag); + tags++; + } + + if (dialog->episode_nr_tag >= 0) { + g_array_append_val (tag_positions, dialog->episode_nr_tag); + tags++; + } + + if (dialog->track_nr_tag >= 0) { + g_array_append_val (tag_positions, dialog->track_nr_tag); + tags++; + } + + if (dialog->artist_name_tag >= 0) { + g_array_append_val (tag_positions, dialog->artist_name_tag); + tags++; + } + + g_array_sort (tag_positions, compare_int); + + for (i = 0; i < tags; i++) { + tag = g_string_new (""); + + tag = g_string_append_len (tag, + entry_text + g_array_index (tag_positions, gint, i), + 3); + + string = g_string_new (""); + + string = g_string_append_len (string, + entry_text + j, + g_array_index (tag_positions, gint, i) - j); + + if (g_strcmp0 (string->str, "")) + result = g_list_append (result, string); + + if (g_strcmp0 (tag->str, "[Or") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Original file name]"); + tag = g_string_append (tag, "iginal file name]"); + } + if (g_strcmp0 (tag->str, "[1,") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[1, 2, 3]"); + tag = g_string_append (tag, " 2, 3]"); + } + if (g_strcmp0 (tag->str, "[01") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[01, 02, 03]"); + tag = g_string_append (tag, ", 02, 03]"); + } + if (g_strcmp0 (tag->str, "[00") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[001, 002, 003]"); + tag = g_string_append (tag, "1, 002, 003]"); + } + if (g_strcmp0 (tag->str, "[Da") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Date taken]"); + tag = g_string_append (tag, "te taken]"); + } + if (g_strcmp0 (tag->str, "[Ca") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Camera model]"); + tag = g_string_append (tag, "mera model]"); + } + if (g_strcmp0 (tag->str, "[Se") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Season nr]"); + tag = g_string_append (tag, "ason nr]"); + } + if (g_strcmp0 (tag->str, "[Ep") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Episode nr]"); + tag = g_string_append (tag, "isode nr]"); + } + if (g_strcmp0 (tag->str, "[Tr") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Track nr]"); + tag = g_string_append (tag, "ack nr]"); + } + if (g_strcmp0 (tag->str, "[Ar") == 0) { + j = g_array_index (tag_positions, gint, i) + strlen ("[Artist name]"); + tag = g_string_append (tag, "tist name]"); + } + result = g_list_append (result, tag); + } + string = g_string_new (""); + string = g_string_append (string, entry_text + j); + + if (g_strcmp0 (string->str, "")) + result = g_list_append (result, string); + + g_array_free (tag_positions, TRUE); + return result; +} + static GList* batch_rename_get_new_names (NautilusBatchRename *dialog) { GList *result = NULL; - GList *selection; + GList *selection, *tags_list; g_autofree gchar *entry_text; g_autofree gchar *replace_text; selection = dialog->selection; + tags_list = NULL; if (dialog->mode == NAUTILUS_BATCH_RENAME_REPLACE) entry_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->find_entry))); @@ -180,10 +496,30 @@ batch_rename_get_new_names (NautilusBatchRename *dialog) replace_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->replace_entry))); - result = get_new_names_list (dialog->mode, selection, entry_text, replace_text); + if (dialog->mode == NAUTILUS_BATCH_RENAME_REPLACE) { + result = get_new_names_list (dialog->mode, + selection, + NULL, + NULL, + entry_text, + replace_text); + } else { + /* get list of tags and regular text */ + tags_list = split_entry_text (dialog, entry_text); + + result = get_new_names_list (dialog->mode, + selection, + tags_list, + dialog->selection_metadata, + entry_text, + replace_text); + } result = g_list_reverse (result); + if (tags_list != NULL) + g_list_free_full (tags_list, string_free); + return result; } @@ -581,6 +917,139 @@ list_has_duplicates_async (NautilusBatchRename *dialog, g_object_unref (dialog->task); } +static gint +check_tag (NautilusBatchRename *dialog, + gchar *tag_name, + gchar *action_name, + gint old_position) +{ + GString *entry_text; + GAction *action; + gint position; + + entry_text = g_string_new (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry))); + position = old_position; + + if (g_strrstr (entry_text->str, tag_name) && old_position == -1) { + action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + action_name); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + } + + if (g_strrstr (entry_text->str, tag_name) == NULL && old_position >= 0) { + action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + action_name); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), TRUE); + + position = -1; + } + + if (g_strrstr (entry_text->str, tag_name)) { + position = g_strrstr (entry_text->str, tag_name) - entry_text->str; + } + + g_string_free (entry_text, TRUE); + + return position; +} + +static void +check_numbering_tags (NautilusBatchRename *dialog) +{ + GString *entry_text; + GAction *add_numbering_action; + + entry_text = g_string_new (gtk_entry_get_text (GTK_ENTRY (dialog->name_entry))); + + if ((g_strrstr (entry_text->str, "[1, 2, 3]") || + g_strrstr (entry_text->str, "[01, 02, 03]") || + g_strrstr (entry_text->str, "[001, 002, 003]")) && + dialog->numbering_tag == -1) { + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-zero"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-one"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-two"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), FALSE); + } + if (g_strrstr (entry_text->str, "[1, 2, 3]") == NULL && + g_strrstr (entry_text->str, "[01, 02, 03]") == NULL && + g_strrstr (entry_text->str, "[001, 002, 003]") == NULL && + dialog->numbering_tag >= 0) { + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-zero"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), TRUE); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-one"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), TRUE); + + add_numbering_action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-numbering-tag-two"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (add_numbering_action), TRUE); + + dialog->numbering_tag = -1; + } + + if (g_strrstr (entry_text->str, "[1, 2, 3]")) { + dialog->numbering_tag = g_strrstr (entry_text->str, "[1, 2, 3]") - entry_text->str; + } + + if (g_strrstr (entry_text->str, "[01, 02, 03]")) { + dialog->numbering_tag = g_strrstr (entry_text->str, "[01, 02, 03]") - entry_text->str; + } + if (g_strrstr (entry_text->str, "[001, 002, 003]")) { + dialog->numbering_tag = g_strrstr (entry_text->str, "[001, 002, 003]") - entry_text->str; + } + g_string_free (entry_text, TRUE); +} + +static void +update_tags (NautilusBatchRename *dialog) +{ + dialog->original_name_tag = check_tag (dialog, + "[Original file name]", + "add-original-file-name-tag", + dialog->original_name_tag); + if (dialog->creation_date_tag != TAG_UNAVAILABLE) + dialog->creation_date_tag = check_tag (dialog, + "[Date taken]", + "add-creation-date-tag", + dialog->creation_date_tag); + if (dialog->equipment_tag != TAG_UNAVAILABLE) + dialog->equipment_tag = check_tag (dialog, + "[Camera model]", + "add-equipment-tag", + dialog->equipment_tag); + if (dialog->season_tag != TAG_UNAVAILABLE) + dialog->season_tag = check_tag (dialog, + "[Season nr]", + "add-season-tag", + dialog->season_tag); + if (dialog->episode_nr_tag != TAG_UNAVAILABLE) + dialog->episode_nr_tag = check_tag (dialog, + "[Episode nr]", + "add-episode-tag", + dialog->episode_nr_tag); + if (dialog->track_nr_tag != TAG_UNAVAILABLE) + dialog->track_nr_tag = check_tag (dialog, + "[Track nr]", + "add-track-number-tag", + dialog->track_nr_tag); + if (dialog->artist_name_tag != TAG_UNAVAILABLE) + dialog->artist_name_tag = check_tag (dialog, + "[Artist name]", + "add-artist-name-tag", + dialog->artist_name_tag); + + check_numbering_tags (dialog); +} + static void file_names_widget_entry_on_changed (NautilusBatchRename *dialog) { @@ -598,6 +1067,16 @@ file_names_widget_entry_on_changed (NautilusBatchRename *dialog) if (dialog->new_names != NULL) g_list_free_full (dialog->new_names, string_free); + update_tags (dialog); + + if (dialog->numbering_tag == -1) { + gtk_label_set_label (GTK_LABEL (dialog->numbering_label), ""); + gtk_widget_hide (dialog->numbering_order_button); + } else { + gtk_label_set_label (GTK_LABEL (dialog->numbering_label), "Automatic Numbering Order"); + gtk_widget_show (dialog->numbering_order_button); + } + dialog->new_names = batch_rename_get_new_names (dialog); dialog->checked_parents = 0; @@ -639,22 +1118,16 @@ batch_rename_mode_changed (NautilusBatchRename *dialog) if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->format_mode_button))) { gtk_stack_set_visible_child_name (GTK_STACK (dialog->mode_stack), "format"); - dialog->mode = NAUTILUS_BATCH_RENAME_PREPEND; - - gtk_entry_set_text (GTK_ENTRY (dialog->name_entry), - gtk_entry_get_text (GTK_ENTRY (dialog->find_entry))); + dialog->mode = NAUTILUS_BATCH_RENAME_FORMAT; - gtk_widget_grab_focus (dialog->name_entry); + gtk_entry_grab_focus_without_selecting (GTK_ENTRY (dialog->name_entry)); } else { gtk_stack_set_visible_child_name (GTK_STACK (dialog->mode_stack), "replace"); dialog->mode = NAUTILUS_BATCH_RENAME_REPLACE; - gtk_entry_set_text (GTK_ENTRY (dialog->find_entry), - gtk_entry_get_text ( GTK_ENTRY (dialog->name_entry))); - - gtk_widget_grab_focus (dialog->find_entry); + gtk_entry_grab_focus_without_selecting (GTK_ENTRY (dialog->find_entry)); } /* update display text */ @@ -694,10 +1167,11 @@ numbering_order_popover_closed (NautilusBatchRename *dialog) void query_finished (NautilusBatchRename *dialog, - GHashTable *hash_table) + GHashTable *hash_table, + GList *selection_metadata) { - GMenuItem *first_created; - GMenuItem *last_created; + GMenuItem *first_created, *last_created; + FileMetadata *metadata; /* for files with no metadata */ if (hash_table != NULL && g_hash_table_size (hash_table) == 0) @@ -724,11 +1198,58 @@ query_finished (NautilusBatchRename *dialog, g_menu_append_item (dialog->numbering_order_menu, last_created); } + + dialog->selection_metadata = selection_metadata; + metadata = selection_metadata->data; + + if (metadata->creation_date == NULL || g_strcmp0 (metadata->creation_date->str, "") == 0) { + disable_action (dialog, "add-creation-date-tag"); + dialog->creation_date_tag = TAG_UNAVAILABLE; + } else { + dialog->creation_date_tag = -1; + } + + if (metadata->equipment == NULL || g_strcmp0 (metadata->equipment->str, "") == 0) { + disable_action (dialog, "add-equipment-tag"); + dialog->equipment_tag = TAG_UNAVAILABLE; + } else { + dialog->equipment_tag = -1; + } + + if (metadata->season == NULL || g_strcmp0 (metadata->season->str, "") == 0) { + disable_action (dialog, "add-season-tag"); + dialog->season_tag = TAG_UNAVAILABLE; + } else { + dialog->creation_date_tag = -1; + } + + if (metadata->episode_nr == NULL || g_strcmp0 (metadata->episode_nr->str, "") == 0) { + disable_action (dialog, "add-episode-tag"); + dialog->episode_nr_tag = TAG_UNAVAILABLE; + } else { + dialog->episode_nr_tag = -1; + } + + if (metadata->track_nr == NULL || g_strcmp0 (metadata->track_nr->str, "") == 0) { + disable_action (dialog, "add-track-number-tag"); + dialog->track_nr_tag = TAG_UNAVAILABLE; + } else { + dialog->track_nr_tag = -1; + } + + if (metadata->artist_name == NULL || g_strcmp0 (metadata->artist_name->str, "") == 0) { + disable_action (dialog, "add-artist-name-tag"); + dialog->artist_name_tag = TAG_UNAVAILABLE; + } else { + dialog->artist_name_tag = -1; + } } static void nautilus_batch_rename_initialize_actions (NautilusBatchRename *dialog) { + GAction *action; + dialog->action_group = G_ACTION_GROUP (g_simple_action_group_new ()); g_action_map_add_action_entries (G_ACTION_MAP (dialog->action_group), @@ -739,16 +1260,42 @@ nautilus_batch_rename_initialize_actions (NautilusBatchRename *dialog) "dialog", G_ACTION_GROUP (dialog->action_group)); - check_creation_date_for_selection (dialog, dialog->selection); + action = g_action_map_lookup_action (G_ACTION_MAP (dialog->action_group), + "add-original-file-name-tag"); + g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE); + + check_metadata_for_selection (dialog, dialog->selection); } static void nautilus_batch_rename_finalize (GObject *object) { NautilusBatchRename *dialog; + GList *l; dialog = NAUTILUS_BATCH_RENAME (object); + for (l = dialog->selection_metadata; l != NULL; l = l->next) { + FileMetadata *metadata; + + metadata = l->data; + + if (metadata->file_name != NULL) + g_string_free (metadata->file_name, TRUE); + if (metadata->creation_date != NULL) + g_string_free (metadata->creation_date, TRUE); + if (metadata->equipment != NULL) + g_string_free (metadata->equipment, TRUE); + if (metadata->season != NULL) + g_string_free (metadata->season, TRUE); + if (metadata->episode_nr != NULL) + g_string_free (metadata->episode_nr, TRUE); + if (metadata->track_nr != NULL) + g_string_free (metadata->track_nr, TRUE); + if (metadata->artist_name != NULL) + g_string_free (metadata->artist_name, TRUE); + } + if (dialog->create_date != NULL) g_hash_table_destroy (dialog->create_date); @@ -796,6 +1343,8 @@ nautilus_batch_rename_class_init (NautilusBatchRenameClass *klass) gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, conflict_label); gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, conflict_up); gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, conflict_down); + gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, add_tag_menu); + gtk_widget_class_bind_template_child (widget_class, NautilusBatchRename, numbering_label); gtk_widget_class_bind_template_callback (widget_class, file_names_widget_entry_on_changed); gtk_widget_class_bind_template_callback (widget_class, file_names_widget_on_activate); @@ -861,11 +1410,14 @@ nautilus_batch_rename_init (NautilusBatchRename *self) self, NULL); - self->mode = NAUTILUS_BATCH_RENAME_PREPEND; + self->mode = NAUTILUS_BATCH_RENAME_FORMAT; gtk_popover_bind_model (GTK_POPOVER (self->numbering_order_popover), G_MENU_MODEL (self->numbering_order_menu), NULL); + gtk_popover_bind_model (GTK_POPOVER (self->add_popover), + G_MENU_MODEL (self->add_tag_menu), + NULL); gtk_label_set_ellipsize (GTK_LABEL (self->conflict_label), PANGO_ELLIPSIZE_END); @@ -874,4 +1426,8 @@ nautilus_batch_rename_init (NautilusBatchRename *self) self->listbox_rows = NULL; self->checking_conflicts = FALSE; + + self->original_name_tag = 0; + self->numbering_tag = -1; + gtk_entry_set_text (GTK_ENTRY (self->name_entry),"[Original file name]"); }
\ No newline at end of file diff --git a/src/nautilus-batch-rename.h b/src/nautilus-batch-rename.h index 219848976..7ce187dd5 100644 --- a/src/nautilus-batch-rename.h +++ b/src/nautilus-batch-rename.h @@ -25,6 +25,22 @@ typedef enum { LAST_CREATED = 5, } SortingMode; +typedef struct { + GString *file_name; + + /* Photo */ + GString *creation_date; + GString *equipment; + + /* Video */ + GString *season; + GString *episode_nr; + + /* Music */ + GString *track_nr; + GString *artist_name; +} FileMetadata; + #define NAUTILUS_TYPE_BATCH_RENAME (nautilus_batch_rename_get_type()) G_DECLARE_FINAL_TYPE (NautilusBatchRename, nautilus_batch_rename, NAUTILUS, BATCH_RENAME, GtkDialog); @@ -34,12 +50,16 @@ GtkWidget* nautilus_batch_rename_new (GList *selecti NautilusWindow *window); void query_finished (NautilusBatchRename *dialog, - GHashTable *hash_table); + GHashTable *hash_table, + GList *selection_metadata); void check_conflict_for_file (NautilusBatchRename *dialog, NautilusDirectory *directory, GList *files); +gint compare_int (gconstpointer a, + gconstpointer b); + G_END_DECLS #endif
\ No newline at end of file diff --git a/src/nautilus-file.c b/src/nautilus-file.c index 928b90bf9..1b1d07a14 100644 --- a/src/nautilus-file.c +++ b/src/nautilus-file.c @@ -1703,6 +1703,8 @@ change_selection_callback (gpointer user_data) data = user_data; nautilus_directory_emit_change_selection (data->directory, data->files); + g_free (data); + return FALSE; } diff --git a/src/resources/ui/nautilus-batch-rename-dialog.ui b/src/resources/ui/nautilus-batch-rename-dialog.ui index e38e42c69..022a585e4 100644 --- a/src/resources/ui/nautilus-batch-rename-dialog.ui +++ b/src/resources/ui/nautilus-batch-rename-dialog.ui @@ -148,10 +148,11 @@ </packing> </child> <child> - <object class="GtkLabel" id="numbering_order"> + <object class="GtkLabel" id="numbering_label"> <property name="visible">True</property> <property name="label" translatable="yes">Automatic Numbering Order</property> <property name="can_focus">False</property> + <property name="height-request">35</property> <property name="sensitive">False</property> </object> <packing> @@ -370,18 +371,66 @@ </object> </child> </template> + <menu id="add_tag_menu"> + <section> + <attribute name="label" translatable="yes">Automatic Numbers</attribute> + <item> + <attribute name="label" translatable="yes">1, 2, 3, 4</attribute> + <attribute name="action">dialog.add-numbering-tag-zero</attribute> + </item> + <item> + <attribute name="label" translatable="yes">01, 02, 03, 04</attribute> + <attribute name="action">dialog.add-numbering-tag-one</attribute> + </item> + <item> + <attribute name="label" translatable="yes">001, 002, 003, 004</attribute> + <attribute name="action">dialog.add-numbering-tag-two</attribute> + </item> + </section> + <section> + <attribute name="label" translatable="yes">Metadata</attribute> + <item> + <attribute name="label" translatable="yes">Date Taken</attribute> + <attribute name="action">dialog.add-creation-date-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Camera Model</attribute> + <attribute name="action">dialog.add-equipment-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Season Number</attribute> + <attribute name="action">dialog.add-season-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Episode Number</attribute> + <attribute name="action">dialog.add-episode-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Track Number</attribute> + <attribute name="action">dialog.add-track-number-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + <item> + <attribute name="label" translatable="yes">Artist Name</attribute> + <attribute name="action">dialog.add-artist-name-tag</attribute> + <attribute name="hidden-when">action-disabled</attribute> + </item> + </section> + <section> + <item> + <attribute name="label" translatable="yes">Original File Name</attribute> + <attribute name="action">dialog.add-original-file-name-tag</attribute> + </item> + </section> + </menu> <object class="GtkPopover" id="add_popover"> <property name="position">bottom</property> <property name="relative-to">add_button</property> <signal name="closed" handler="add_popover_closed" swapped="yes" /> - <child> - <object class="GtkLabel"> - <property name="visible">True</property> - <property name="label" translatable="yes">label for testing purpose</property> - <property name="can_focus">False</property> - <property name="sensitive">True</property> - </object> - </child> </object> <object class="GtkImage" id="done_image"> <property name="visible">True</property> |