[nautilus/wip/alexpandelea/batchRename] Add format mode



commit 51206dcb24bf03be7b3c97530ece741caeeeb55f
Author: Alexandru Pandelea <alexandru pandelea gmail com>
Date:   Fri Jul 29 15:15:52 2016 +0300

    Add format mode
    
    There were added tags as text for the format mode.

 src/nautilus-batch-rename-utilities.c            |  417 +++++++++++++---
 src/nautilus-batch-rename-utilities.h            |    4 +-
 src/nautilus-batch-rename.c                      |  590 +++++++++++++++++++++-
 src/nautilus-batch-rename.h                      |   22 +-
 src/nautilus-file.c                              |    2 +
 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 da9bc8f..6487d49 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 7c51fe6..f9233e8 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 0b3e879..befed21 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 2198489..7ce187d 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 928b90b..1b1d07a 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 e38e42c..022a585 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>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]