gnome-commander r2284 - in branches/gcmd-1-3: . doc/C src src/dialogs



Author: epiotr
Date: Mon Nov 17 22:31:43 2008
New Revision: 2284
URL: http://svn.gnome.org/viewvc/gnome-commander?rev=2284&view=rev

Log:
 Brand new dlg for Advanced Rename Tool

Modified:
   branches/gcmd-1-3/ChangeLog
   branches/gcmd-1-3/TODO
   branches/gcmd-1-3/doc/C/gnome-commander.xml
   branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.cc
   branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.h
   branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.cc
   branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.h
   branches/gcmd-1-3/src/gnome-cmd-data.cc
   branches/gcmd-1-3/src/gnome-cmd-data.h
   branches/gcmd-1-3/src/gnome-cmd-main-win.cc
   branches/gcmd-1-3/src/gnome-cmd-main-win.h
   branches/gcmd-1-3/src/gnome-cmd-user-actions.cc

Modified: branches/gcmd-1-3/TODO
==============================================================================
--- branches/gcmd-1-3/TODO	(original)
+++ branches/gcmd-1-3/TODO	Mon Nov 17 22:31:43 2008
@@ -54,8 +54,6 @@
 
 // Advrename tool
 
-* The advrename dialog should have a feature to convert between upper/lowercase
-* Addressing components of a regexp in the replacement text (\0, \1, ..., \9)
 * Support for file meta tags (icc, *ml, video, ...)
 
 

Modified: branches/gcmd-1-3/doc/C/gnome-commander.xml
==============================================================================
--- branches/gcmd-1-3/doc/C/gnome-commander.xml	(original)
+++ branches/gcmd-1-3/doc/C/gnome-commander.xml	Mon Nov 17 22:31:43 2008
@@ -5519,27 +5519,6 @@
                                 </row>
                                 <row valign="top">
                                     <entry><para></para></entry>
-                                    <entry><para>pat_col_widths<emphasis><subscript>n</subscript></emphasis></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                </row>
-                                <row valign="top">
-                                    <entry><para></para></entry>
-                                    <entry><para>res_col_widths<emphasis><subscript>n</subscript></emphasis></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                </row>
-                                <row valign="top">
-                                    <entry><para></para></entry>
-                                    <entry><para>sep_value</para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                </row>
-                                <row valign="top">
-                                    <entry><para></para></entry>
                                     <entry><para>width</para></entry>
                                     <entry><para></para></entry>
                                     <entry><para></para></entry>
@@ -5547,13 +5526,6 @@
                                 </row>
                                 <row valign="top">
                                     <entry><para></para></entry>
-                                    <entry><para>template_auto_update</para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                    <entry><para></para></entry>
-                                </row>
-                                <row valign="top">
-                                    <entry><para></para></entry>
                                     <entry><para>counter_start</para></entry>
                                     <entry><para></para></entry>
                                     <entry><para></para></entry>

Modified: branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.cc
==============================================================================
--- branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.cc	(original)
+++ branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.cc	Mon Nov 17 22:31:43 2008
@@ -21,23 +21,22 @@
 #include <config.h>
 #include <regex.h>
 #include "gnome-cmd-includes.h"
-#include "gnome-cmd-advrename-dialog.h"
 #include "gnome-cmd-advrename-regex-dialog.h"
+#include "gnome-cmd-advrename-dialog.h"
+#include "gnome-cmd-hintbox.h"
 #include "utils.h"
 
 using namespace std;
 
 
-static void response_callback (GtkDialog *dialog, int response_id, PatternEntry *rx)
+static void response_callback (GtkDialog *dialog, int response_id, GnomeCmdAdvrenameDialog::Regex *rx)
 {
     switch (response_id)
     {
         case GTK_RESPONSE_OK:
-            g_free (rx->from);
-            g_free (rx->to);
-            rx->from = gtk_editable_get_chars (GTK_EDITABLE (lookup_widget (GTK_WIDGET (dialog), "pattern")), 0, -1);
-            rx->to = gtk_editable_get_chars (GTK_EDITABLE (lookup_widget (GTK_WIDGET (dialog), "replace")), 0, -1);
-            rx->case_sens = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (GTK_WIDGET (dialog), "match_case")));
+            rx->assign(gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "pattern"))),
+                       gtk_entry_get_text (GTK_ENTRY (lookup_widget (GTK_WIDGET (dialog), "replace"))),
+                       gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (GTK_WIDGET (dialog), "match_case"))));
             break;
 
         case GTK_RESPONSE_NONE:
@@ -51,7 +50,7 @@
 }
 
 
-gboolean gnome_cmd_advrename_regex_dialog_new (const gchar *title, GtkWindow *parent, PatternEntry *rx)
+gboolean gnome_cmd_advrename_regex_dialog_new (const gchar *title, GtkWindow *parent, GnomeCmdAdvrenameDialog::Regex *rx)
 {
     GtkWidget *dialog = gtk_dialog_new_with_buttons (title, parent,
                                                      GtkDialogFlags (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
@@ -69,7 +68,7 @@
     gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5);
     gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area),6);
 
-    GtkWidget *table, *align, *label, *entry, *check;
+    GtkWidget *table, *align, *label, *entry, *check, *box;
 
     table = gtk_table_new (3, 2, FALSE);
     gtk_container_set_border_width (GTK_CONTAINER (table), 5);
@@ -83,8 +82,7 @@
 
     entry = gtk_entry_new ();
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
-    if (rx->from)
-        gtk_entry_set_text (GTK_ENTRY (entry), rx->from);
+    gtk_entry_set_text (GTK_ENTRY (entry), rx->from.c_str());
     g_object_set_data (G_OBJECT (dialog), "pattern", entry);
     gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
     gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 0, 1);
@@ -95,8 +93,7 @@
 
     entry = gtk_entry_new ();
     gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
-    if (rx->to)
-        gtk_entry_set_text (GTK_ENTRY (entry), rx->to);
+    gtk_entry_set_text (GTK_ENTRY (entry), rx->to.c_str());
     g_object_set_data (G_OBJECT (dialog), "replace", entry);
     gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
     gtk_table_attach_defaults (GTK_TABLE (table), entry, 1, 2, 1, 2);
@@ -107,10 +104,17 @@
 
     check = gtk_check_button_new_with_mnemonic (_("_Match case"));
     g_object_set_data (G_OBJECT (dialog), "match_case", check);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), rx ? rx->case_sens : FALSE);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), rx ? rx->case_sensitive : FALSE);
     gtk_container_add (GTK_CONTAINER (align), check);
 
-    gtk_widget_show_all (table);
+#if !GLIB_CHECK_VERSION (2, 14, 0)
+    box = gnome_cmd_hint_box_new (_("Some regular expressions functionality is disabled. "
+                                    "To enable it's necessary to build GNOME Commander with GLib â 2.14. "
+                                    "Please contact your package maintainer about that."));
+    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), box);
+#endif
+
+    gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
 
     gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
 

Modified: branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.h
==============================================================================
--- branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.h	(original)
+++ branches/gcmd-1-3/src/dialogs/gnome-cmd-advrename-regex-dialog.h	Mon Nov 17 22:31:43 2008
@@ -23,6 +23,6 @@
 
 #include "gnome-cmd-advrename-dialog.h"
 
-gboolean gnome_cmd_advrename_regex_dialog_new (const gchar *title, GtkWindow *parent, PatternEntry *rx);
+gboolean gnome_cmd_advrename_regex_dialog_new (const gchar *title, GtkWindow *parent, GnomeCmdAdvrenameDialog::Regex *rx);
 
 #endif // __GNOME_CMD_ADVRENAME_REGEX_DIALOG_H__

Modified: branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.cc	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.cc	Mon Nov 17 22:31:43 2008
@@ -23,13 +23,15 @@
 #include <regex.h>
 #include <unistd.h>
 #include <errno.h>
+#include <gtk/gtkdialog.h>
+
 #include "gnome-cmd-includes.h"
 #include "gnome-cmd-convert.h"
 #include "gnome-cmd-advrename-dialog.h"
 #include "dialogs/gnome-cmd-advrename-regex-dialog.h"
 #include "gnome-cmd-advrename-lexer.h"
 #include "gnome-cmd-file.h"
-#include "gnome-cmd-clist.h"
+#include "gnome-cmd-treeview.h"
 #include "gnome-cmd-data.h"
 #include "tags/gnome-cmd-tags.h"
 #include "utils.h"
@@ -37,360 +39,342 @@
 using namespace std;
 
 
-// static GdkColor black   = {0,0,0,0};
-// static GdkColor red     = {0,0xffff,0,0};
-
-
-struct RenameEntry
+struct GnomeCmdAdvrenameDialogClass
 {
-    GnomeCmdFile *f;
-    gchar *new_name;
+    GtkDialogClass parent_class;
 };
 
 
-enum {DIR_MENU, FILE_MENU, COUNTER_MENU, DATE_MENU, METATAG_MENU, NUM_MENUS};
-
-
-struct _GnomeCmdAdvrenameDialogPrivate
+struct GnomeCmdAdvrenameDialog::Private
 {
-    GList *files;
-    GList *entries;
-    PatternEntry *sel_entry;
-    GnomeCmdData::AdvrenameDefaults *defaults;
+    GnomeCmdConvertFunc convert_case;
     GnomeCmdConvertFunc trim_blanks;
 
-    gboolean template_has_counters;
+    GtkWidget *template_combo;
+    GtkWidget *template_entry;
 
-    GtkWidget *pat_list;
-    GtkWidget *res_list;
-    GtkWidget *move_up_btn;
-    GtkWidget *move_down_btn;
-    GtkWidget *add_btn;
-    GtkWidget *edit_btn;
-    GtkWidget *remove_btn;
-    GtkWidget *remove_all_btn;
-    GtkWidget *templ_combo;
-    GtkWidget *templ_entry;
-    GtkWidget *trim_combo;
-
-    GtkWidget *menu[NUM_MENUS];
-};
+    gboolean template_has_counters;
 
+    GtkWidget *counter_start_spin;
+    GtkWidget *counter_step_spin;
+    GtkWidget *counter_digits_spin;
+
+    GtkWidget *regex_view;
+
+    GtkWidget *regex_add_button;
+    GtkWidget *regex_edit_button;
+    GtkWidget *regex_remove_button;
+    GtkWidget *regex_remove_all_button;
 
-static GnomeCmdDialogClass *parent_class = NULL;
+    GtkWidget *case_combo;
+    GtkWidget *trim_combo;
 
-guint advrename_dialog_default_pat_column_width[ADVRENAME_DIALOG_PAT_NUM_COLUMNS] = {150, 150, 30};
-guint advrename_dialog_default_res_column_width[ADVRENAME_DIALOG_RES_NUM_COLUMNS] = {200, 200};
+    GtkWidget *files_view;
 
+    enum {DIR_MENU, FILE_MENU, COUNTER_MENU, DATE_MENU, METATAG_MENU, NUM_MENUS};
 
-static void do_test (GnomeCmdAdvrenameDialog *dialog);
+    GtkWidget *menu[NUM_MENUS];
 
+    static GtkItemFactoryEntry dir_items[];
+    static GtkItemFactoryEntry name_items[];
+    static GtkItemFactoryEntry counter_items[];
+    static GtkItemFactoryEntry date_items[];
+    static GtkItemFactoryEntry *items[];
+    static GnomeCmdTag metatags[];
+
+    Private();
+    ~Private();
+
+    GtkWidget *create_placeholder_menu(int menu_type);
+    GtkWidget *create_button_with_menu(gchar *label_text, int menu_type);
+    void insert_tag(const gchar *text);
+
+    static void insert_text_tag(GnomeCmdAdvrenameDialog::Private *priv, guint n, GtkWidget *widget);
+    static void insert_num_tag(GnomeCmdAdvrenameDialog::Private *priv, guint tag, GtkWidget *widget);
+
+    void files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog, GdkEventButton *event=NULL);
+
+    static void on_template_entry_changed(GtkEntry *entry, GnomeCmdAdvrenameDialog *dialog);
+    static void on_menu_button_clicked(GtkButton *widget, GtkWidget *menu);
+
+    static void on_counter_start_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog);
+    static void on_counter_step_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog);
+    static void on_counter_digits_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog);
+
+    static void on_regex_model_row_deleted (GtkTreeModel *treemodel, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog);
+    static void on_regex_add_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog);
+    static void on_regex_edit_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog);
+    static void on_regex_remove_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog);
+    static void on_regex_remove_all_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog);
+    static void on_regex_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog);
+
+    static void on_case_combo_changed (GtkComboBox *combo, GnomeCmdAdvrenameDialog *dialog);
+    static void on_trim_combo_changed (GtkComboBox *combo, GnomeCmdAdvrenameDialog *dialog);
+
+    static void on_files_model_row_deleted (GtkTreeModel *files, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog);
+    static void on_files_view_popup_menu__remove (GtkWidget *menuitem, GtkTreeView *treeview);
+    static void on_files_view_popup_menu__show_properties (GtkWidget *menuitem, GtkTreeView *treeview);
+    static void on_files_view_popup_menu__update_files (GtkWidget *menuitem, GnomeCmdAdvrenameDialog *dialog);
+    static gboolean on_files_view_button_pressed (GtkWidget *treeview, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog);
+    static gboolean on_files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog);
+    static void on_files_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog);
+
+    static gboolean on_dialog_delete (GtkWidget *widget, GdkEvent *event, GnomeCmdAdvrenameDialog *dialog);
+    static void on_dialog_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GnomeCmdAdvrenameDialog *dialog);
+    static void on_dialog_response (GnomeCmdAdvrenameDialog *dialog, int response_id, gpointer data);
+};
 
-inline void insert_tag (GnomeCmdAdvrenameDialog *dialog, const gchar *text)
-{
-    GtkEditable *editable = (GtkEditable *) dialog->priv->templ_entry;
-    gint pos = gtk_editable_get_position (editable);
 
-    gtk_editable_insert_text (editable, text, strlen(text), &pos);
-    gtk_editable_set_position (editable, pos);
-    gtk_widget_grab_focus ((GtkWidget *) editable);
-    gtk_editable_select_region (editable, pos, pos);
-}
+GtkItemFactoryEntry GnomeCmdAdvrenameDialog::Private::dir_items[] =
+    {{_("/Grandparent"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 0},
+     {_("/Parent"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 1}};
+
+GtkItemFactoryEntry GnomeCmdAdvrenameDialog::Private::name_items[] =
+    {{_("/File name"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 2},
+     {_("/File name without extension"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 3},
+     {_("/File extension"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 4}};
+
+GtkItemFactoryEntry GnomeCmdAdvrenameDialog::Private::counter_items[] =
+    {{_("/Counter"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 5},
+     {_("/Counter (width)"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 6},
+     {_("/Hexadecimal random number (width)"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 7}};
+
+GtkItemFactoryEntry GnomeCmdAdvrenameDialog::Private::date_items[] =
+    {{_("/Date/<locale>"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 8},
+     {_("/Date/yyyy-mm-dd"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 9},
+     {_("/Date/yy-mm-dd"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 10},
+     {_("/Date/yy.mm.dd"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 11},
+     {_("/Date/yymmdd"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 12},
+     {_("/Date/dd.mm.yy"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 13},
+     {_("/Date/mm-dd-yy"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 14},
+     {_("/Date/yyyy"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 15},
+     {_("/Date/yy"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 16},
+     {_("/Date/mm"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 17},
+     {_("/Date/mmm"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 18},
+     {_("/Date/dd"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 19},
+     {_("/Time/<locale>"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 20},
+     {_("/Time/HH.MM.SS"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 21},
+     {_("/Time/HH-MM-SS"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 22},
+     {_("/Time/HHMMSS"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 23},
+     {_("/Time/HH"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 24},
+     {_("/Time/MM"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 25},
+     {_("/Time/SS"), NULL, (GtkItemFactoryCallback) GnomeCmdAdvrenameDialog::Private::insert_text_tag, 26}};
+
+GtkItemFactoryEntry *GnomeCmdAdvrenameDialog::Private::items[] = {dir_items, name_items, counter_items, date_items};
+
+GnomeCmdTag GnomeCmdAdvrenameDialog::Private::metatags[] =
+    {TAG_FILE_NAME, TAG_FILE_PATH,
+     TAG_FILE_LINK,
+     TAG_FILE_SIZE,
+     TAG_FILE_MODIFIED, TAG_FILE_ACCESSED,
+     TAG_FILE_PERMISSIONS,
+     TAG_FILE_FORMAT,
+     TAG_FILE_PUBLISHER, TAG_FILE_DESCRIPTION, TAG_FILE_KEYWORDS, TAG_FILE_RANK,
+
+     TAG_AUDIO_ALBUMARTIST, TAG_AUDIO_ALBUMGAIN, TAG_AUDIO_ALBUMPEAKGAIN,
+     TAG_AUDIO_ALBUMTRACKCOUNT, TAG_AUDIO_ALBUM, TAG_AUDIO_ARTIST, TAG_AUDIO_BITRATE,
+     TAG_AUDIO_CHANNELS, TAG_AUDIO_CODECVERSION, TAG_AUDIO_CODEC, TAG_AUDIO_COMMENT,
+     TAG_AUDIO_COVERALBUMTHUMBNAILPATH, TAG_AUDIO_DISCNO,
+     TAG_AUDIO_DURATION, TAG_AUDIO_DURATIONMMSS,
+     TAG_AUDIO_GENRE, TAG_AUDIO_ISNEW, TAG_AUDIO_ISRC, TAG_AUDIO_LASTPLAY, TAG_AUDIO_LYRICS,
+     TAG_AUDIO_MBALBUMARTISTID, TAG_AUDIO_MBALBUMID, TAG_AUDIO_MBARTISTID,
+     TAG_AUDIO_MBTRACKID, TAG_AUDIO_PERFORMER, TAG_AUDIO_PLAYCOUNT,
+     TAG_AUDIO_RELEASEDATE, TAG_AUDIO_SAMPLERATE, TAG_AUDIO_TITLE, TAG_AUDIO_TRACKGAIN,
+     TAG_AUDIO_TRACKNO, TAG_AUDIO_TRACKPEAKGAIN, TAG_AUDIO_YEAR,
+     TAG_AUDIO_MPEG_CHANNELMODE, TAG_AUDIO_MPEG_LAYER, TAG_AUDIO_MPEG_VERSION,
+
+     TAG_DOC_AUTHOR, TAG_DOC_CREATOR, TAG_DOC_TITLE,
+     TAG_DOC_SUBJECT, TAG_DOC_DESCRIPTION,
+     TAG_DOC_CATEGORY, TAG_DOC_KEYWORDS, TAG_DOC_REVISIONCOUNT,
+     TAG_DOC_PAGECOUNT, TAG_DOC_PARAGRAPHCOUNT, TAG_DOC_LINECOUNT,
+     TAG_DOC_WORDCOUNT, TAG_DOC_BYTECOUNT,
+     TAG_DOC_CELLCOUNT, TAG_DOC_CHARACTERCOUNT,
+     TAG_DOC_CODEPAGE, TAG_DOC_COMMENTS, TAG_DOC_COMPANY,
+     TAG_DOC_DATECREATED, TAG_DOC_DATEMODIFIED,
+     TAG_DOC_DICTIONARY,
+     TAG_DOC_EDITINGDURATION, TAG_DOC_GENERATOR,
+     TAG_DOC_HIDDENSLIDECOUNT,
+     TAG_DOC_IMAGECOUNT, TAG_DOC_INITIALCREATOR,
+     TAG_DOC_LANGUAGE,
+     TAG_DOC_LASTPRINTED, TAG_DOC_LASTSAVEDBY,
+     TAG_DOC_LOCALESYSTEMDEFAULT, TAG_DOC_MMCLIPCOUNT,
+     TAG_DOC_MANAGER, TAG_DOC_NOTECOUNT, TAG_DOC_OBJECTCOUNT,
+     TAG_DOC_PRESENTATIONFORMAT, TAG_DOC_PRINTDATE,
+     TAG_DOC_PRINTEDBY, TAG_DOC_SCALE, TAG_DOC_SECURITY,
+     TAG_DOC_SLIDECOUNT, TAG_DOC_SPREADSHEETCOUNT,
+     TAG_DOC_TABLECOUNT, TAG_DOC_TEMPLATE,
+     TAG_DOC_CASESENSITIVE, TAG_DOC_LINKSDIRTY,
+
+     TAG_IMAGE_ALBUM, TAG_IMAGE_MAKE, TAG_IMAGE_MODEL,
+     TAG_IMAGE_COMMENTS, TAG_IMAGE_COPYRIGHT, TAG_IMAGE_CREATOR,
+     TAG_IMAGE_DATE, TAG_IMAGE_DESCRIPTION, TAG_IMAGE_EXPOSUREPROGRAM,
+     TAG_IMAGE_EXPOSURETIME, TAG_IMAGE_FLASH, TAG_IMAGE_FNUMBER,
+     TAG_IMAGE_FOCALLENGTH, TAG_IMAGE_HEIGHT, TAG_IMAGE_ISOSPEED,
+     TAG_IMAGE_KEYWORDS, TAG_IMAGE_METERINGMODE, TAG_IMAGE_ORIENTATION,
+     TAG_IMAGE_SOFTWARE, TAG_IMAGE_TITLE, TAG_IMAGE_WHITEBALANCE,
+     TAG_IMAGE_WIDTH,
+
+     TAG_NONE,
+
+     TAG_ID3_BAND,
+     TAG_ID3_CONTENTTYPE,
+     TAG_ID3_ALBUMSORTORDER, TAG_ID3_AUDIOCRYPTO,
+     TAG_ID3_AUDIOSEEKPOINT,
+     TAG_ID3_BPM, TAG_ID3_BUFFERSIZE, TAG_ID3_CDID,
+     TAG_ID3_COMMERCIAL, TAG_ID3_COMPOSER, TAG_ID3_CONDUCTOR,
+     TAG_ID3_CONTENTGROUP, TAG_ID3_CONTENTTYPE,
+     TAG_ID3_COPYRIGHT,
+     TAG_ID3_CRYPTOREG, TAG_ID3_DATE,
+     TAG_ID3_EMPHASIS, TAG_ID3_ENCODEDBY,
+     TAG_ID3_ENCODERSETTINGS, TAG_ID3_ENCODINGTIME, TAG_ID3_EQUALIZATION,
+     TAG_ID3_EQUALIZATION2, TAG_ID3_EVENTTIMING, TAG_ID3_FILEOWNER,
+     TAG_ID3_FILETYPE, TAG_ID3_FRAMES, TAG_ID3_GENERALOBJECT,
+     TAG_ID3_GROUPINGREG, TAG_ID3_INITIALKEY,
+     TAG_ID3_INVOLVEDPEOPLE, TAG_ID3_INVOLVEDPEOPLE2,
+     TAG_ID3_LANGUAGE, TAG_ID3_LINKEDINFO,
+     TAG_ID3_LYRICIST, TAG_ID3_MEDIATYPE, TAG_ID3_MIXARTIST,
+     TAG_ID3_MOOD,
+     TAG_ID3_MPEGLOOKUP,
+     TAG_ID3_MUSICIANCREDITLIST,
+     TAG_ID3_NETRADIOOWNER, TAG_ID3_NETRADIOSTATION,
+     TAG_ID3_ORIGALBUM, TAG_ID3_ORIGARTIST, TAG_ID3_ORIGFILENAME,
+     TAG_ID3_ORIGLYRICIST, TAG_ID3_ORIGRELEASETIME, TAG_ID3_ORIGYEAR,
+     TAG_ID3_OWNERSHIP, TAG_ID3_PARTINSET, TAG_ID3_PERFORMERSORTORDER,
+     TAG_ID3_PICTURE, TAG_ID3_PLAYCOUNTER, TAG_ID3_PLAYLISTDELAY,
+     TAG_ID3_POPULARIMETER, TAG_ID3_POSITIONSYNC, TAG_ID3_PRIVATE,
+     TAG_ID3_PRODUCEDNOTICE, TAG_ID3_PUBLISHER, TAG_ID3_RECORDINGDATES,
+     TAG_ID3_RECORDINGTIME, TAG_ID3_RELEASETIME, TAG_ID3_REVERB,
+     TAG_ID3_SETSUBTITLE, TAG_ID3_SIGNATURE,
+     TAG_ID3_SIZE, TAG_ID3_SONGLEN, TAG_ID3_SUBTITLE, TAG_ID3_SYNCEDLYRICS,
+     TAG_ID3_SYNCEDTEMPO, TAG_ID3_TAGGINGTIME, TAG_ID3_TERMSOFUSE,
+     TAG_ID3_TIME, TAG_ID3_TITLESORTORDER,
+     TAG_ID3_UNIQUEFILEID, TAG_ID3_UNSYNCEDLYRICS, TAG_ID3_USERTEXT,
+     TAG_ID3_VOLUMEADJ, TAG_ID3_VOLUMEADJ2, TAG_ID3_WWWARTIST,
+     TAG_ID3_WWWAUDIOFILE, TAG_ID3_WWWAUDIOSOURCE, TAG_ID3_WWWCOMMERCIALINFO,
+     TAG_ID3_WWWCOPYRIGHT, TAG_ID3_WWWPAYMENT, TAG_ID3_WWWPUBLISHER,
+     TAG_ID3_WWWRADIOPAGE, TAG_ID3_WWWUSER,
+
+     TAG_VORBIS_CONTACT, TAG_VORBIS_DESCRIPTION,
+     TAG_VORBIS_LICENSE, TAG_VORBIS_LOCATION,
+     TAG_VORBIS_MAXBITRATE, TAG_VORBIS_MINBITRATE,
+     TAG_VORBIS_NOMINALBITRATE, TAG_VORBIS_ORGANIZATION,
+     TAG_VORBIS_VENDOR, TAG_VORBIS_VERSION,
+
+     TAG_EXIF_COPYRIGHT, TAG_EXIF_DATETIME,
+     TAG_EXIF_EXPOSUREBIASVALUE, TAG_EXIF_EXPOSUREMODE, TAG_EXIF_EXPOSUREPROGRAM,
+     TAG_EXIF_FLASH, TAG_EXIF_FLASHENERGY,
+     TAG_EXIF_FNUMBER, TAG_EXIF_FOCALLENGTH,
+     TAG_EXIF_ISOSPEEDRATINGS, TAG_EXIF_MAXAPERTUREVALUE,
+     TAG_EXIF_METERINGMODE, TAG_EXIF_SHUTTERSPEEDVALUE, TAG_EXIF_WHITEBALANCE,
+     TAG_EXIF_PIXELXDIMENSION, TAG_EXIF_PIXELYDIMENSION,
+     TAG_EXIF_XRESOLUTION, TAG_EXIF_YRESOLUTION,
+     TAG_EXIF_IMAGELENGTH, TAG_EXIF_IMAGEWIDTH,
+     TAG_EXIF_CUSTOMRENDERED, TAG_EXIF_COLORSPACE,
+     TAG_EXIF_DOCUMENTNAME, TAG_EXIF_USERCOMMENT,
+
+     TAG_EXIF_APERTUREVALUE, TAG_EXIF_ARTIST, TAG_EXIF_BATTERYLEVEL,
+     TAG_EXIF_BITSPERSAMPLE, TAG_EXIF_BRIGHTNESSVALUE,
+     TAG_EXIF_CFAPATTERN, TAG_EXIF_COMPONENTSCONFIGURATION,
+     TAG_EXIF_COMPRESSEDBITSPERPIXEL, TAG_EXIF_COMPRESSION, TAG_EXIF_CONTRAST,
+     TAG_EXIF_DATETIMEDIGITIZED, TAG_EXIF_DATETIMEORIGINAL,
+     TAG_EXIF_DEVICESETTINGDESCRIPTION, TAG_EXIF_DIGITALZOOMRATIO,
+     TAG_EXIF_EXIFVERSION,
+     TAG_EXIF_EXPOSUREINDEX,
+     TAG_EXIF_EXPOSURETIME, TAG_EXIF_FILESOURCE,
+     TAG_EXIF_FILLORDER,
+     TAG_EXIF_FLASHPIXVERSION,
+     TAG_EXIF_FOCALLENGTHIN35MMFILM, TAG_EXIF_FOCALPLANERESOLUTIONUNIT,
+     TAG_EXIF_FOCALPLANEXRESOLUTION, TAG_EXIF_FOCALPLANEYRESOLUTION,
+     TAG_EXIF_GAINCONTROL, TAG_EXIF_GAMMA, TAG_EXIF_GPSALTITUDE,
+     TAG_EXIF_GPSLATITUDE, TAG_EXIF_GPSLONGITUDE,
+     TAG_EXIF_GPSVERSIONID, TAG_EXIF_IMAGEDESCRIPTION, TAG_EXIF_IMAGEUNIQUEID,
+     TAG_EXIF_INTERCOLORPROFILE, TAG_EXIF_INTEROPERABILITYINDEX, TAG_EXIF_INTEROPERABILITYVERSION,
+     TAG_EXIF_IPTCNAA, TAG_EXIF_JPEGINTERCHANGEFORMAT,
+     TAG_EXIF_JPEGINTERCHANGEFORMATLENGTH, TAG_EXIF_LIGHTSOURCE,
+     TAG_EXIF_MAKE, TAG_EXIF_MAKERNOTE,
+     TAG_EXIF_METERINGMODE, TAG_EXIF_MODEL, TAG_EXIF_NEWCFAPATTERN,
+     TAG_EXIF_NEWSUBFILETYPE, TAG_EXIF_OECF, TAG_EXIF_ORIENTATION,
+     TAG_EXIF_PHOTOMETRICINTERPRETATION, TAG_EXIF_PLANARCONFIGURATION,
+     TAG_EXIF_PRIMARYCHROMATICITIES, TAG_EXIF_REFERENCEBLACKWHITE,
+     TAG_EXIF_RELATEDIMAGEFILEFORMAT, TAG_EXIF_RELATEDIMAGELENGTH,
+     TAG_EXIF_RELATEDIMAGEWIDTH, TAG_EXIF_RELATEDSOUNDFILE, TAG_EXIF_RESOLUTIONUNIT,
+     TAG_EXIF_ROWSPERSTRIP, TAG_EXIF_SAMPLESPERPIXEL, TAG_EXIF_SATURATION,
+     TAG_EXIF_SCENECAPTURETYPE, TAG_EXIF_SCENETYPE, TAG_EXIF_SENSINGMETHOD,
+     TAG_EXIF_SHARPNESS, TAG_EXIF_SHUTTERSPEEDVALUE, TAG_EXIF_SOFTWARE,
+     TAG_EXIF_SPATIALFREQUENCYRESPONSE, TAG_EXIF_SPECTRALSENSITIVITY,
+     TAG_EXIF_STRIPBYTECOUNTS, TAG_EXIF_STRIPOFFSETS,
+     TAG_EXIF_SUBJECTAREA, TAG_EXIF_SUBJECTDISTANCE, TAG_EXIF_SUBJECTDISTANCERANGE,
+     TAG_EXIF_SUBJECTLOCATION, TAG_EXIF_SUBSECTIME, TAG_EXIF_SUBSECTIMEDIGITIZED,
+     TAG_EXIF_SUBSECTIMEORIGINAL, TAG_EXIF_TIFFEPSTANDARDID, TAG_EXIF_TRANSFERFUNCTION,
+     TAG_EXIF_TRANSFERRANGE, TAG_EXIF_WHITEPOINT,
+     TAG_EXIF_YCBCRCOEFFICIENTS, TAG_EXIF_YCBCRPOSITIONING,
+     TAG_EXIF_YCBCRSUBSAMPLING,
+
+     TAG_IPTC_BYLINE, TAG_IPTC_BYLINETITLE, TAG_IPTC_CAPTION, TAG_IPTC_HEADLINE,
+     TAG_IPTC_SUBLOCATION, TAG_IPTC_CITY, TAG_IPTC_PROVINCE,
+     TAG_IPTC_COUNTRYCODE, TAG_IPTC_COUNTRYNAME,
+     TAG_IPTC_CONTACT, TAG_IPTC_COPYRIGHTNOTICE, TAG_IPTC_CREDIT,
+     TAG_IPTC_KEYWORDS,
+     TAG_IPTC_DIGITALCREATIONDATE, TAG_IPTC_DIGITALCREATIONTIME,
+     TAG_IPTC_IMAGEORIENTATION,
+     TAG_IPTC_SPECIALINSTRUCTIONS, TAG_IPTC_URGENCY,
+
+     TAG_IPTC_ACTIONADVISED, TAG_IPTC_ARMID, TAG_IPTC_ARMVERSION,
+     TAG_IPTC_AUDIODURATION, TAG_IPTC_AUDIOOUTCUE, TAG_IPTC_AUDIOSAMPLINGRATE,
+     TAG_IPTC_AUDIOSAMPLINGRES, TAG_IPTC_AUDIOTYPE,
+     TAG_IPTC_CATEGORY, TAG_IPTC_CHARACTERSET, TAG_IPTC_CONFIRMEDDATASIZE,
+     TAG_IPTC_CONTENTLOCCODE, TAG_IPTC_CONTENTLOCNAME,
+     TAG_IPTC_DATECREATED, TAG_IPTC_DATESENT,
+     TAG_IPTC_DESTINATION, TAG_IPTC_EDITORIALUPDATE, TAG_IPTC_EDITSTATUS,
+     TAG_IPTC_ENVELOPENUM, TAG_IPTC_ENVELOPEPRIORITY, TAG_IPTC_EXPIRATIONDATE,
+     TAG_IPTC_EXPIRATIONTIME, TAG_IPTC_FILEFORMAT, TAG_IPTC_FILEVERSION,
+     TAG_IPTC_FIXTUREID, TAG_IPTC_IMAGETYPE, TAG_IPTC_LANGUAGEID,
+     TAG_IPTC_MAXOBJECTSIZE, TAG_IPTC_MAXSUBFILESIZE, TAG_IPTC_MODELVERSION,
+     TAG_IPTC_OBJECTATTRIBUTE, TAG_IPTC_OBJECTCYCLE, TAG_IPTC_OBJECTNAME,
+     TAG_IPTC_OBJECTSIZEANNOUNCED, TAG_IPTC_OBJECTTYPE, TAG_IPTC_ORIGINATINGPROGRAM,
+     TAG_IPTC_ORIGTRANSREF, TAG_IPTC_PREVIEWDATA, TAG_IPTC_PREVIEWFORMAT,
+     TAG_IPTC_PREVIEWFORMATVER, TAG_IPTC_PRODUCTID, TAG_IPTC_PROGRAMVERSION,
+     TAG_IPTC_PROVINCE, TAG_IPTC_RASTERIZEDCAPTION, TAG_IPTC_RECORDVERSION,
+     TAG_IPTC_REFERENCEDATE, TAG_IPTC_REFERENCENUMBER, TAG_IPTC_REFERENCESERVICE,
+     TAG_IPTC_RELEASEDATE, TAG_IPTC_RELEASETIME, TAG_IPTC_SERVICEID,
+     TAG_IPTC_SIZEMODE, TAG_IPTC_SOURCE, TAG_IPTC_SUBFILE, TAG_IPTC_SUBJECTREFERENCE,
+     TAG_IPTC_SUPPLCATEGORY, TAG_IPTC_TIMECREATED, TAG_IPTC_TIMESENT, TAG_IPTC_UNO,
+     TAG_IPTC_URGENCY, TAG_IPTC_WRITEREDITOR,
+
+     TAG_PDF_PAGESIZE, TAG_PDF_PAGEWIDTH, TAG_PDF_PAGEHEIGHT,
+     TAG_PDF_VERSION, TAG_PDF_PRODUCER,
+     TAG_PDF_EMBEDDEDFILES,
+     TAG_PDF_OPTIMIZED,
+     TAG_PDF_PRINTING,
+     TAG_PDF_HIRESPRINTING,
+     TAG_PDF_COPYING,
+     TAG_PDF_MODIFYING,
+     TAG_PDF_DOCASSEMBLY,
+     TAG_PDF_COMMENTING,
+     TAG_PDF_FORMFILLING,
+     TAG_PDF_ACCESSIBILITYSUPPORT
+    };
 
 
-static void insert_text_tag (gpointer data, guint n, GtkWidget *widget)
+inline GnomeCmdAdvrenameDialog::Private::Private()
 {
-    static const gchar *placeholder[] = {"$g",
-                                         "$p",
-                                         "$N",
-                                         "$n",
-                                         "$e",
-                                         "$c",
-                                         "$c(2)",
-                                         "$x(8)",
-                                         "%x",
-                                         "%Y-%m-%d",
-                                         "%y-%m-%d",
-                                         "%y.%m.%d",
-                                         "%y%m%d",
-                                         "%d.%m.%y",
-                                         "%m-%d-%y",
-                                         "%Y",
-                                         "%y",
-                                         "%m",
-                                         "%b",
-                                         "%d",
-                                         "%X",
-                                         "%H.%M.%S",
-                                         "%H-%M-%S",
-                                         "%H%M%S",
-                                         "%H",
-                                         "%M",
-                                         "%S"};
-
-    g_return_if_fail (n < G_N_ELEMENTS(placeholder));
-
-    insert_tag ((GnomeCmdAdvrenameDialog *) data, placeholder[n]);
+    convert_case = gcmd_convert_unchanged;
+    trim_blanks = gcmd_convert_strip;
+    template_has_counters = FALSE;
 }
 
 
-static void insert_num_tag (gpointer data, guint tag, GtkWidget *widget)
+inline GnomeCmdAdvrenameDialog::Private::~Private()
 {
-    gchar *s = g_strdup_printf ("$T(%s)", gcmd_tags_get_name((GnomeCmdTag) tag));
-    insert_tag ((GnomeCmdAdvrenameDialog *) data, s);
-    g_free (s);
 }
 
 
-static void on_menu_button_clicked(GtkButton *widget, gpointer data)
+inline GtkWidget *GnomeCmdAdvrenameDialog::Private::create_placeholder_menu(int menu_type)
 {
-    GtkWidget *menu = (GtkWidget *) data;
-    GdkEventButton *event = (GdkEventButton *) gtk_get_current_event();
-
-    if (event == NULL)
-        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time());
-    else
-        if (event->button == 1)
-            gtk_menu_popup (GTK_MENU(menu), NULL, NULL, NULL, NULL, event->button, event->time);
-}
-
-
-static GtkWidget *create_placeholder_menu(GnomeCmdAdvrenameDialog *dialog, int menu_type)
-{
-    GtkItemFactoryEntry dir_items[] =     {{_("/Grandparent"), NULL, (GtkItemFactoryCallback) insert_text_tag, 0},
-                                           {_("/Parent"), NULL, (GtkItemFactoryCallback) insert_text_tag, 1}};
-
-    GtkItemFactoryEntry name_items[] =    {{_("/File name"), NULL, (GtkItemFactoryCallback) insert_text_tag, 2},
-                                           {_("/File name without extension"), NULL, (GtkItemFactoryCallback) insert_text_tag, 3},
-                                           {_("/File extension"), NULL, (GtkItemFactoryCallback) insert_text_tag, 4}};
-
-    GtkItemFactoryEntry counter_items[] = {{_("/Counter"), NULL, (GtkItemFactoryCallback) insert_text_tag, 5},
-                                           {_("/Counter (width)"), NULL, (GtkItemFactoryCallback) insert_text_tag, 6},
-                                           {_("/Hexadecimal random number (width)"), NULL, (GtkItemFactoryCallback) insert_text_tag, 7}};
-
-    GtkItemFactoryEntry date_items[] =    {{_("/Date/<locale>"), NULL, (GtkItemFactoryCallback) insert_text_tag, 8},
-                                           {_("/Date/yyyy-mm-dd"), NULL, (GtkItemFactoryCallback) insert_text_tag, 9},
-                                           {_("/Date/yy-mm-dd"), NULL, (GtkItemFactoryCallback) insert_text_tag, 10},
-                                           {_("/Date/yy.mm.dd"), NULL, (GtkItemFactoryCallback) insert_text_tag, 11},
-                                           {_("/Date/yymmdd"), NULL, (GtkItemFactoryCallback) insert_text_tag, 12},
-                                           {_("/Date/dd.mm.yy"), NULL, (GtkItemFactoryCallback) insert_text_tag, 13},
-                                           {_("/Date/mm-dd-yy"), NULL, (GtkItemFactoryCallback) insert_text_tag, 14},
-                                           {_("/Date/yyyy"), NULL, (GtkItemFactoryCallback) insert_text_tag, 15},
-                                           {_("/Date/yy"), NULL, (GtkItemFactoryCallback) insert_text_tag, 16},
-                                           {_("/Date/mm"), NULL, (GtkItemFactoryCallback) insert_text_tag, 17},
-                                           {_("/Date/mmm"), NULL, (GtkItemFactoryCallback) insert_text_tag, 18},
-                                           {_("/Date/dd"), NULL, (GtkItemFactoryCallback) insert_text_tag, 19},
-                                           {_("/Time/<locale>"), NULL, (GtkItemFactoryCallback) insert_text_tag, 20},
-                                           {_("/Time/HH.MM.SS"), NULL, (GtkItemFactoryCallback) insert_text_tag, 21},
-                                           {_("/Time/HH-MM-SS"), NULL, (GtkItemFactoryCallback) insert_text_tag, 22},
-                                           {_("/Time/HHMMSS"), NULL, (GtkItemFactoryCallback) insert_text_tag, 23},
-                                           {_("/Time/HH"), NULL, (GtkItemFactoryCallback) insert_text_tag, 24},
-                                           {_("/Time/MM"), NULL, (GtkItemFactoryCallback) insert_text_tag, 25},
-                                           {_("/Time/SS"), NULL, (GtkItemFactoryCallback) insert_text_tag, 26}};
-
-    static GnomeCmdTag metatags[] = {
-                                     TAG_FILE_NAME, TAG_FILE_PATH,
-                                     TAG_FILE_LINK,
-                                     TAG_FILE_SIZE,
-                                     TAG_FILE_MODIFIED, TAG_FILE_ACCESSED,
-                                     TAG_FILE_PERMISSIONS,
-                                     TAG_FILE_FORMAT,
-                                     TAG_FILE_PUBLISHER, TAG_FILE_DESCRIPTION, TAG_FILE_KEYWORDS, TAG_FILE_RANK,
-
-                                     TAG_AUDIO_ALBUMARTIST, TAG_AUDIO_ALBUMGAIN, TAG_AUDIO_ALBUMPEAKGAIN,
-                                     TAG_AUDIO_ALBUMTRACKCOUNT, TAG_AUDIO_ALBUM, TAG_AUDIO_ARTIST, TAG_AUDIO_BITRATE,
-                                     TAG_AUDIO_CHANNELS, TAG_AUDIO_CODECVERSION, TAG_AUDIO_CODEC, TAG_AUDIO_COMMENT,
-                                     TAG_AUDIO_COVERALBUMTHUMBNAILPATH, TAG_AUDIO_DISCNO,
-                                     TAG_AUDIO_DURATION, TAG_AUDIO_DURATIONMMSS,
-                                     TAG_AUDIO_GENRE, TAG_AUDIO_ISNEW, TAG_AUDIO_ISRC, TAG_AUDIO_LASTPLAY, TAG_AUDIO_LYRICS,
-                                     TAG_AUDIO_MBALBUMARTISTID, TAG_AUDIO_MBALBUMID, TAG_AUDIO_MBARTISTID,
-                                     TAG_AUDIO_MBTRACKID, TAG_AUDIO_PERFORMER, TAG_AUDIO_PLAYCOUNT,
-                                     TAG_AUDIO_RELEASEDATE, TAG_AUDIO_SAMPLERATE, TAG_AUDIO_TITLE, TAG_AUDIO_TRACKGAIN,
-                                     TAG_AUDIO_TRACKNO, TAG_AUDIO_TRACKPEAKGAIN, TAG_AUDIO_YEAR,
-                                     TAG_AUDIO_MPEG_CHANNELMODE, TAG_AUDIO_MPEG_LAYER, TAG_AUDIO_MPEG_VERSION,
-
-                                     TAG_DOC_AUTHOR, TAG_DOC_CREATOR, TAG_DOC_TITLE,
-                                     TAG_DOC_SUBJECT, TAG_DOC_DESCRIPTION,
-                                     TAG_DOC_CATEGORY, TAG_DOC_KEYWORDS, TAG_DOC_REVISIONCOUNT,
-                                     TAG_DOC_PAGECOUNT, TAG_DOC_PARAGRAPHCOUNT, TAG_DOC_LINECOUNT,
-                                     TAG_DOC_WORDCOUNT, TAG_DOC_BYTECOUNT,
-                                     TAG_DOC_CELLCOUNT, TAG_DOC_CHARACTERCOUNT,
-                                     TAG_DOC_CODEPAGE, TAG_DOC_COMMENTS, TAG_DOC_COMPANY,
-                                     TAG_DOC_DATECREATED, TAG_DOC_DATEMODIFIED,
-                                     TAG_DOC_DICTIONARY,
-                                     TAG_DOC_EDITINGDURATION, TAG_DOC_GENERATOR,
-                                     TAG_DOC_HIDDENSLIDECOUNT,
-                                     TAG_DOC_IMAGECOUNT, TAG_DOC_INITIALCREATOR,
-                                     TAG_DOC_LANGUAGE,
-                                     TAG_DOC_LASTPRINTED, TAG_DOC_LASTSAVEDBY,
-                                     TAG_DOC_LOCALESYSTEMDEFAULT, TAG_DOC_MMCLIPCOUNT,
-                                     TAG_DOC_MANAGER, TAG_DOC_NOTECOUNT, TAG_DOC_OBJECTCOUNT,
-                                     TAG_DOC_PRESENTATIONFORMAT, TAG_DOC_PRINTDATE,
-                                     TAG_DOC_PRINTEDBY, TAG_DOC_SCALE, TAG_DOC_SECURITY,
-                                     TAG_DOC_SLIDECOUNT, TAG_DOC_SPREADSHEETCOUNT,
-                                     TAG_DOC_TABLECOUNT, TAG_DOC_TEMPLATE,
-                                     TAG_DOC_CASESENSITIVE, TAG_DOC_LINKSDIRTY,
-
-                                     TAG_IMAGE_ALBUM, TAG_IMAGE_MAKE, TAG_IMAGE_MODEL,
-                                     TAG_IMAGE_COMMENTS, TAG_IMAGE_COPYRIGHT, TAG_IMAGE_CREATOR,
-                                     TAG_IMAGE_DATE, TAG_IMAGE_DESCRIPTION, TAG_IMAGE_EXPOSUREPROGRAM,
-                                     TAG_IMAGE_EXPOSURETIME, TAG_IMAGE_FLASH, TAG_IMAGE_FNUMBER,
-                                     TAG_IMAGE_FOCALLENGTH, TAG_IMAGE_HEIGHT, TAG_IMAGE_ISOSPEED,
-                                     TAG_IMAGE_KEYWORDS, TAG_IMAGE_METERINGMODE, TAG_IMAGE_ORIENTATION,
-                                     TAG_IMAGE_SOFTWARE, TAG_IMAGE_TITLE, TAG_IMAGE_WHITEBALANCE,
-                                     TAG_IMAGE_WIDTH,
-
-                                     TAG_NONE,
-
-                                     TAG_ID3_BAND,
-                                     TAG_ID3_CONTENTTYPE,
-                                     TAG_ID3_ALBUMSORTORDER, TAG_ID3_AUDIOCRYPTO,
-                                     TAG_ID3_AUDIOSEEKPOINT,
-                                     TAG_ID3_BPM, TAG_ID3_BUFFERSIZE, TAG_ID3_CDID,
-                                     TAG_ID3_COMMERCIAL, TAG_ID3_COMPOSER, TAG_ID3_CONDUCTOR,
-                                     TAG_ID3_CONTENTGROUP, TAG_ID3_CONTENTTYPE,
-                                     TAG_ID3_COPYRIGHT,
-                                     TAG_ID3_CRYPTOREG, TAG_ID3_DATE,
-                                     TAG_ID3_EMPHASIS, TAG_ID3_ENCODEDBY,
-                                     TAG_ID3_ENCODERSETTINGS, TAG_ID3_ENCODINGTIME, TAG_ID3_EQUALIZATION,
-                                     TAG_ID3_EQUALIZATION2, TAG_ID3_EVENTTIMING, TAG_ID3_FILEOWNER,
-                                     TAG_ID3_FILETYPE, TAG_ID3_FRAMES, TAG_ID3_GENERALOBJECT,
-                                     TAG_ID3_GROUPINGREG, TAG_ID3_INITIALKEY,
-                                     TAG_ID3_INVOLVEDPEOPLE, TAG_ID3_INVOLVEDPEOPLE2,
-                                     TAG_ID3_LANGUAGE, TAG_ID3_LINKEDINFO,
-                                     TAG_ID3_LYRICIST, TAG_ID3_MEDIATYPE, TAG_ID3_MIXARTIST,
-                                     TAG_ID3_MOOD,
-                                     TAG_ID3_MPEGLOOKUP,
-                                     TAG_ID3_MUSICIANCREDITLIST,
-                                     TAG_ID3_NETRADIOOWNER, TAG_ID3_NETRADIOSTATION,
-                                     TAG_ID3_ORIGALBUM, TAG_ID3_ORIGARTIST, TAG_ID3_ORIGFILENAME,
-                                     TAG_ID3_ORIGLYRICIST, TAG_ID3_ORIGRELEASETIME, TAG_ID3_ORIGYEAR,
-                                     TAG_ID3_OWNERSHIP, TAG_ID3_PARTINSET, TAG_ID3_PERFORMERSORTORDER,
-                                     TAG_ID3_PICTURE, TAG_ID3_PLAYCOUNTER, TAG_ID3_PLAYLISTDELAY,
-                                     TAG_ID3_POPULARIMETER, TAG_ID3_POSITIONSYNC, TAG_ID3_PRIVATE,
-                                     TAG_ID3_PRODUCEDNOTICE, TAG_ID3_PUBLISHER, TAG_ID3_RECORDINGDATES,
-                                     TAG_ID3_RECORDINGTIME, TAG_ID3_RELEASETIME, TAG_ID3_REVERB,
-                                     TAG_ID3_SETSUBTITLE, TAG_ID3_SIGNATURE,
-                                     TAG_ID3_SIZE, TAG_ID3_SONGLEN, TAG_ID3_SUBTITLE, TAG_ID3_SYNCEDLYRICS,
-                                     TAG_ID3_SYNCEDTEMPO, TAG_ID3_TAGGINGTIME, TAG_ID3_TERMSOFUSE,
-                                     TAG_ID3_TIME, TAG_ID3_TITLESORTORDER,
-                                     TAG_ID3_UNIQUEFILEID, TAG_ID3_UNSYNCEDLYRICS, TAG_ID3_USERTEXT,
-                                     TAG_ID3_VOLUMEADJ, TAG_ID3_VOLUMEADJ2, TAG_ID3_WWWARTIST,
-                                     TAG_ID3_WWWAUDIOFILE, TAG_ID3_WWWAUDIOSOURCE, TAG_ID3_WWWCOMMERCIALINFO,
-                                     TAG_ID3_WWWCOPYRIGHT, TAG_ID3_WWWPAYMENT, TAG_ID3_WWWPUBLISHER,
-                                     TAG_ID3_WWWRADIOPAGE, TAG_ID3_WWWUSER,
-
-                                     TAG_VORBIS_CONTACT, TAG_VORBIS_DESCRIPTION,
-                                     TAG_VORBIS_LICENSE, TAG_VORBIS_LOCATION,
-                                     TAG_VORBIS_MAXBITRATE, TAG_VORBIS_MINBITRATE,
-                                     TAG_VORBIS_NOMINALBITRATE, TAG_VORBIS_ORGANIZATION,
-                                     TAG_VORBIS_VENDOR, TAG_VORBIS_VERSION,
-
-                                     TAG_EXIF_COPYRIGHT, TAG_EXIF_DATETIME,
-                                     TAG_EXIF_EXPOSUREBIASVALUE, TAG_EXIF_EXPOSUREMODE, TAG_EXIF_EXPOSUREPROGRAM,
-                                     TAG_EXIF_FLASH, TAG_EXIF_FLASHENERGY,
-                                     TAG_EXIF_FNUMBER, TAG_EXIF_FOCALLENGTH,
-                                     TAG_EXIF_ISOSPEEDRATINGS, TAG_EXIF_MAXAPERTUREVALUE,
-                                     TAG_EXIF_METERINGMODE, TAG_EXIF_SHUTTERSPEEDVALUE, TAG_EXIF_WHITEBALANCE,
-                                     TAG_EXIF_PIXELXDIMENSION, TAG_EXIF_PIXELYDIMENSION,
-                                     TAG_EXIF_XRESOLUTION, TAG_EXIF_YRESOLUTION,
-                                     TAG_EXIF_IMAGELENGTH, TAG_EXIF_IMAGEWIDTH,
-                                     TAG_EXIF_CUSTOMRENDERED, TAG_EXIF_COLORSPACE,
-                                     TAG_EXIF_DOCUMENTNAME, TAG_EXIF_USERCOMMENT,
-
-                                     TAG_EXIF_APERTUREVALUE, TAG_EXIF_ARTIST, TAG_EXIF_BATTERYLEVEL,
-                                     TAG_EXIF_BITSPERSAMPLE, TAG_EXIF_BRIGHTNESSVALUE,
-                                     TAG_EXIF_CFAPATTERN, TAG_EXIF_COMPONENTSCONFIGURATION,
-                                     TAG_EXIF_COMPRESSEDBITSPERPIXEL, TAG_EXIF_COMPRESSION, TAG_EXIF_CONTRAST,
-                                     TAG_EXIF_DATETIMEDIGITIZED, TAG_EXIF_DATETIMEORIGINAL,
-                                     TAG_EXIF_DEVICESETTINGDESCRIPTION, TAG_EXIF_DIGITALZOOMRATIO,
-                                     TAG_EXIF_EXIFVERSION,
-                                     TAG_EXIF_EXPOSUREINDEX,
-                                     TAG_EXIF_EXPOSURETIME, TAG_EXIF_FILESOURCE,
-                                     TAG_EXIF_FILLORDER,
-                                     TAG_EXIF_FLASHPIXVERSION,
-                                     TAG_EXIF_FOCALLENGTHIN35MMFILM, TAG_EXIF_FOCALPLANERESOLUTIONUNIT,
-                                     TAG_EXIF_FOCALPLANEXRESOLUTION, TAG_EXIF_FOCALPLANEYRESOLUTION,
-                                     TAG_EXIF_GAINCONTROL, TAG_EXIF_GAMMA, TAG_EXIF_GPSALTITUDE,
-                                     TAG_EXIF_GPSLATITUDE, TAG_EXIF_GPSLONGITUDE,
-                                     TAG_EXIF_GPSVERSIONID, TAG_EXIF_IMAGEDESCRIPTION, TAG_EXIF_IMAGEUNIQUEID,
-                                     TAG_EXIF_INTERCOLORPROFILE, TAG_EXIF_INTEROPERABILITYINDEX, TAG_EXIF_INTEROPERABILITYVERSION,
-                                     TAG_EXIF_IPTCNAA, TAG_EXIF_JPEGINTERCHANGEFORMAT,
-                                     TAG_EXIF_JPEGINTERCHANGEFORMATLENGTH, TAG_EXIF_LIGHTSOURCE,
-                                     TAG_EXIF_MAKE, TAG_EXIF_MAKERNOTE,
-                                     TAG_EXIF_METERINGMODE, TAG_EXIF_MODEL, TAG_EXIF_NEWCFAPATTERN,
-                                     TAG_EXIF_NEWSUBFILETYPE, TAG_EXIF_OECF, TAG_EXIF_ORIENTATION,
-                                     TAG_EXIF_PHOTOMETRICINTERPRETATION, TAG_EXIF_PLANARCONFIGURATION,
-                                     TAG_EXIF_PRIMARYCHROMATICITIES, TAG_EXIF_REFERENCEBLACKWHITE,
-                                     TAG_EXIF_RELATEDIMAGEFILEFORMAT, TAG_EXIF_RELATEDIMAGELENGTH,
-                                     TAG_EXIF_RELATEDIMAGEWIDTH, TAG_EXIF_RELATEDSOUNDFILE, TAG_EXIF_RESOLUTIONUNIT,
-                                     TAG_EXIF_ROWSPERSTRIP, TAG_EXIF_SAMPLESPERPIXEL, TAG_EXIF_SATURATION,
-                                     TAG_EXIF_SCENECAPTURETYPE, TAG_EXIF_SCENETYPE, TAG_EXIF_SENSINGMETHOD,
-                                     TAG_EXIF_SHARPNESS, TAG_EXIF_SHUTTERSPEEDVALUE, TAG_EXIF_SOFTWARE,
-                                     TAG_EXIF_SPATIALFREQUENCYRESPONSE, TAG_EXIF_SPECTRALSENSITIVITY,
-                                     TAG_EXIF_STRIPBYTECOUNTS, TAG_EXIF_STRIPOFFSETS,
-                                     TAG_EXIF_SUBJECTAREA, TAG_EXIF_SUBJECTDISTANCE, TAG_EXIF_SUBJECTDISTANCERANGE,
-                                     TAG_EXIF_SUBJECTLOCATION, TAG_EXIF_SUBSECTIME, TAG_EXIF_SUBSECTIMEDIGITIZED,
-                                     TAG_EXIF_SUBSECTIMEORIGINAL, TAG_EXIF_TIFFEPSTANDARDID, TAG_EXIF_TRANSFERFUNCTION,
-                                     TAG_EXIF_TRANSFERRANGE, TAG_EXIF_WHITEPOINT,
-                                     TAG_EXIF_YCBCRCOEFFICIENTS, TAG_EXIF_YCBCRPOSITIONING,
-                                     TAG_EXIF_YCBCRSUBSAMPLING,
-
-                                     TAG_IPTC_BYLINE, TAG_IPTC_BYLINETITLE, TAG_IPTC_CAPTION, TAG_IPTC_HEADLINE,
-                                     TAG_IPTC_SUBLOCATION, TAG_IPTC_CITY, TAG_IPTC_PROVINCE,
-                                     TAG_IPTC_COUNTRYCODE, TAG_IPTC_COUNTRYNAME,
-                                     TAG_IPTC_CONTACT, TAG_IPTC_COPYRIGHTNOTICE, TAG_IPTC_CREDIT,
-                                     TAG_IPTC_KEYWORDS,
-                                     TAG_IPTC_DIGITALCREATIONDATE, TAG_IPTC_DIGITALCREATIONTIME,
-                                     TAG_IPTC_IMAGEORIENTATION,
-                                     TAG_IPTC_SPECIALINSTRUCTIONS, TAG_IPTC_URGENCY,
-
-                                     TAG_IPTC_ACTIONADVISED, TAG_IPTC_ARMID, TAG_IPTC_ARMVERSION,
-                                     TAG_IPTC_AUDIODURATION, TAG_IPTC_AUDIOOUTCUE, TAG_IPTC_AUDIOSAMPLINGRATE,
-                                     TAG_IPTC_AUDIOSAMPLINGRES, TAG_IPTC_AUDIOTYPE,
-                                     TAG_IPTC_CATEGORY, TAG_IPTC_CHARACTERSET, TAG_IPTC_CONFIRMEDDATASIZE,
-                                     TAG_IPTC_CONTENTLOCCODE, TAG_IPTC_CONTENTLOCNAME,
-                                     TAG_IPTC_DATECREATED, TAG_IPTC_DATESENT,
-                                     TAG_IPTC_DESTINATION, TAG_IPTC_EDITORIALUPDATE, TAG_IPTC_EDITSTATUS,
-                                     TAG_IPTC_ENVELOPENUM, TAG_IPTC_ENVELOPEPRIORITY, TAG_IPTC_EXPIRATIONDATE,
-                                     TAG_IPTC_EXPIRATIONTIME, TAG_IPTC_FILEFORMAT, TAG_IPTC_FILEVERSION,
-                                     TAG_IPTC_FIXTUREID, TAG_IPTC_IMAGETYPE, TAG_IPTC_LANGUAGEID,
-                                     TAG_IPTC_MAXOBJECTSIZE, TAG_IPTC_MAXSUBFILESIZE, TAG_IPTC_MODELVERSION,
-                                     TAG_IPTC_OBJECTATTRIBUTE, TAG_IPTC_OBJECTCYCLE, TAG_IPTC_OBJECTNAME,
-                                     TAG_IPTC_OBJECTSIZEANNOUNCED, TAG_IPTC_OBJECTTYPE, TAG_IPTC_ORIGINATINGPROGRAM,
-                                     TAG_IPTC_ORIGTRANSREF, TAG_IPTC_PREVIEWDATA, TAG_IPTC_PREVIEWFORMAT,
-                                     TAG_IPTC_PREVIEWFORMATVER, TAG_IPTC_PRODUCTID, TAG_IPTC_PROGRAMVERSION,
-                                     TAG_IPTC_PROVINCE, TAG_IPTC_RASTERIZEDCAPTION, TAG_IPTC_RECORDVERSION,
-                                     TAG_IPTC_REFERENCEDATE, TAG_IPTC_REFERENCENUMBER, TAG_IPTC_REFERENCESERVICE,
-                                     TAG_IPTC_RELEASEDATE, TAG_IPTC_RELEASETIME, TAG_IPTC_SERVICEID,
-                                     TAG_IPTC_SIZEMODE, TAG_IPTC_SOURCE, TAG_IPTC_SUBFILE, TAG_IPTC_SUBJECTREFERENCE,
-                                     TAG_IPTC_SUPPLCATEGORY, TAG_IPTC_TIMECREATED, TAG_IPTC_TIMESENT, TAG_IPTC_UNO,
-                                     TAG_IPTC_URGENCY, TAG_IPTC_WRITEREDITOR,
-
-                                     TAG_PDF_PAGESIZE, TAG_PDF_PAGEWIDTH, TAG_PDF_PAGEHEIGHT,
-                                     TAG_PDF_VERSION, TAG_PDF_PRODUCER,
-                                     TAG_PDF_EMBEDDEDFILES,
-                                     TAG_PDF_OPTIMIZED,
-                                     TAG_PDF_PRINTING,
-                                     TAG_PDF_HIRESPRINTING,
-                                     TAG_PDF_COPYING,
-                                     TAG_PDF_MODIFYING,
-                                     TAG_PDF_DOCASSEMBLY,
-                                     TAG_PDF_COMMENTING,
-                                     TAG_PDF_FORMFILLING,
-                                     TAG_PDF_ACCESSIBILITYSUPPORT
-                                    };
-
-    GtkItemFactoryEntry *items[] = {dir_items,
-                                    name_items,
-                                    counter_items,
-                                    date_items};
-
     static guint items_size[] = {G_N_ELEMENTS(dir_items),
                                  G_N_ELEMENTS(name_items),
                                  G_N_ELEMENTS(counter_items),
                                  G_N_ELEMENTS(date_items)};
-
     switch (menu_type)
     {
         case DIR_MENU:
@@ -400,7 +384,7 @@
             {
                 GtkItemFactory *ifac = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
 
-                gtk_item_factory_create_items (ifac, items_size[menu_type], items[menu_type], dialog);
+                gtk_item_factory_create_items (ifac, items_size[menu_type], items[menu_type], this);
 
                 return gtk_item_factory_get_widget (ifac, "<main>");
             }
@@ -432,7 +416,7 @@
 
                 GtkItemFactory *ifac = gtk_item_factory_new (GTK_TYPE_MENU, "<main>", NULL);
 
-                gtk_item_factory_create_items (ifac, G_N_ELEMENTS(metatags), items, dialog);
+                gtk_item_factory_create_items (ifac, G_N_ELEMENTS(metatags), items, this);
 
                 for (guint i=0; i<G_N_ELEMENTS(metatags); ++i)
                     g_free (items[i].path);
@@ -448,7 +432,7 @@
 }
 
 
-static GtkWidget *create_button_with_menu (GnomeCmdAdvrenameDialog *dialog, gchar *label_text, int menu_type)
+inline GtkWidget *GnomeCmdAdvrenameDialog::Private::create_button_with_menu(gchar *label_text, int menu_type)
 {
     GtkWidget *arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE);
     GtkWidget *label = gtk_label_new (label_text);
@@ -460,10 +444,10 @@
     GtkWidget *button = gtk_button_new ();
     gtk_container_add (GTK_CONTAINER (button), hbox);
 
-    dialog->priv->menu[menu_type] = create_placeholder_menu (dialog, menu_type);
+    menu[menu_type] = create_placeholder_menu(menu_type);
 
     gtk_widget_set_events (button, GDK_BUTTON_PRESS_MASK);
-    g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (on_menu_button_clicked), dialog->priv->menu[menu_type]);
+    g_signal_connect (G_OBJECT(button), "clicked", G_CALLBACK (on_menu_button_clicked), menu[menu_type]);
 
     gtk_widget_show_all(button);
 
@@ -471,826 +455,1041 @@
 }
 
 
-inline void free_data (GnomeCmdAdvrenameDialog *dialog)
+inline void GnomeCmdAdvrenameDialog::Private::insert_tag(const gchar *text)
 {
-    gnome_cmd_file_list_free (dialog->priv->files);
-
-    for (GList *tmp = dialog->priv->entries; tmp; tmp = tmp->next)
-    {
-        RenameEntry *entry = (RenameEntry *) tmp->data;
-        g_free (entry->new_name);
-        g_free (entry);
-    }
-    g_list_free (dialog->priv->entries);
+    GtkEditable *editable = (GtkEditable *) template_entry;
+    gint pos = gtk_editable_get_position (editable);
 
-    g_free (dialog->priv);
-    dialog->priv = NULL;
+    gtk_editable_insert_text (editable, text, strlen(text), &pos);
+    gtk_editable_set_position (editable, pos);
+    gtk_widget_grab_focus ((GtkWidget *) editable);
+    gtk_editable_select_region (editable, pos, pos);
 }
 
 
-inline void format_entry (PatternEntry *entry, gchar **text)
+void GnomeCmdAdvrenameDialog::Private::insert_text_tag(GnomeCmdAdvrenameDialog::Private *priv, guint n, GtkWidget *widget)
 {
-    text[0] = entry->from;
-    text[1] = entry->to;
-    text[2] = entry->case_sens ? _("Yes") : _("No");
-    text[3] = NULL;
-}
+    static const gchar *placeholder[] = {"$g",          //  0
+                                         "$p",          //  1
+                                         "$N",          //  2
+                                         "$n",          //  3
+                                         "$e",          //  4
+                                         "$c",          //  5
+                                         "$c(2)",       //  6
+                                         "$x(8)",       //  7
+                                         "%x",          //  8
+                                         "%Y-%m-%d",    //  9
+                                         "%y-%m-%d",    // 10
+                                         "%y.%m.%d",    // 11
+                                         "%y%m%d",      // 12
+                                         "%d.%m.%y",    // 13
+                                         "%m-%d-%y",    // 14
+                                         "%Y",          // 15
+                                         "%y",          // 16
+                                         "%m",          // 17
+                                         "%b",          // 18
+                                         "%d",          // 19
+                                         "%X",          // 20
+                                         "%H.%M.%S",    // 21
+                                         "%H-%M-%S",    // 22
+                                         "%H%M%S",      // 23
+                                         "%H",          // 24
+                                         "%M",          // 25
+                                         "%S"};         // 26
 
+    g_return_if_fail (n < G_N_ELEMENTS(placeholder));
 
-inline RenameEntry *rename_entry_new ()
-{
-    return g_new0 (RenameEntry, 1);
+    priv->insert_tag(placeholder[n]);
 }
 
 
-inline PatternEntry *get_pattern_entry_from_row (GnomeCmdAdvrenameDialog *dialog, gint row)
+void GnomeCmdAdvrenameDialog::Private::insert_num_tag(GnomeCmdAdvrenameDialog::Private *priv, guint tag, GtkWidget *widget)
 {
-    return (PatternEntry *) gtk_clist_get_row_data (GTK_CLIST (dialog->priv->pat_list), row);
+    gchar *s = g_strdup_printf ("$T(%s)", gcmd_tags_get_name((GnomeCmdTag) tag));
+    priv->insert_tag(s);
+    g_free (s);
 }
 
 
-inline gint get_row_from_rename_entry (GnomeCmdAdvrenameDialog *dialog, RenameEntry *entry)
+void GnomeCmdAdvrenameDialog::Private::on_menu_button_clicked(GtkButton *widget, GtkWidget *menu)
 {
-    return gtk_clist_find_row_from_data (GTK_CLIST (dialog->priv->res_list), entry);
+    GdkEventButton *event = (GdkEventButton *) gtk_get_current_event();
+
+    if (event == NULL)
+        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, gtk_get_current_event_time());
+    else
+        if (event->button == 1)
+            gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, event->button, event->time);
 }
 
 
-inline void add_rename_entry (GnomeCmdAdvrenameDialog *dialog, GnomeCmdFile *f)
-{
-    gint row;
-    gchar *text[4],
-          *fname = get_utf8 (f->info->name);
-    RenameEntry *entry = rename_entry_new ();
+inline GtkTreeModel *create_and_fill_regex_model (GnomeCmdData::AdvrenameDefaults &defaults);
+inline GtkWidget *create_regex_view ();
 
-    entry->f = f;
+inline GtkTreeModel *create_files_model ();
+inline GtkWidget *create_files_view ();
 
-    text[0] = fname;
-    text[1] = NULL;
-    text[2] = NULL;
-    text[3] = NULL;
 
-    row = gtk_clist_append (GTK_CLIST (dialog->priv->res_list), text);
-    gtk_clist_set_row_data (GTK_CLIST (dialog->priv->res_list), row, entry);
-    dialog->priv->entries = g_list_append (dialog->priv->entries, entry);
+inline gboolean model_is_empty (GtkTreeModel *tree_model)
+{
+    GtkTreeIter iter;
 
-    g_free (fname);
+    return !gtk_tree_model_get_iter_first (tree_model, &iter);
 }
 
 
-inline void update_move_buttons (GnomeCmdAdvrenameDialog *dialog, int row)
-{
-    if (row == 0)
-    {
-        gtk_widget_set_sensitive (dialog->priv->move_up_btn, FALSE);
-        gtk_widget_set_sensitive (dialog->priv->move_down_btn, g_list_length (dialog->priv->defaults->patterns) > 1);
-    }
-    else
-        if (row == g_list_length (dialog->priv->defaults->patterns) - 1)
-        {
-            gtk_widget_set_sensitive (dialog->priv->move_down_btn, FALSE);
-            gtk_widget_set_sensitive (dialog->priv->move_up_btn, g_list_length (dialog->priv->defaults->patterns) > 1);
-        }
-        else
-        {
-            gtk_widget_set_sensitive (dialog->priv->move_up_btn, TRUE);
-            gtk_widget_set_sensitive (dialog->priv->move_down_btn, TRUE);
-        }
-}
+G_DEFINE_TYPE (GnomeCmdAdvrenameDialog, gnome_cmd_advrename_dialog, GTK_TYPE_DIALOG)
 
 
-inline void update_remove_all_button (GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_template_entry_changed(GtkEntry *entry, GnomeCmdAdvrenameDialog *dialog)
 {
-    gtk_widget_set_sensitive (dialog->priv->remove_all_btn, dialog->priv->defaults->patterns != NULL);
+    gnome_cmd_advrename_parse_template (gtk_entry_get_text (GTK_ENTRY (dialog->priv->template_entry)), dialog->priv->template_has_counters);
+    dialog->update_new_filenames();
 }
 
 
-inline void add_pattern_entry (GnomeCmdAdvrenameDialog *dialog, PatternEntry *entry)
+void GnomeCmdAdvrenameDialog::Private::on_counter_start_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog)
 {
-    gint row;
-    gchar *text[4];
-
-    if (!entry) return;
+    dialog->defaults.counter_start = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
+    if (dialog->priv->template_has_counters)
+        dialog->update_new_filenames();
+}
 
-    format_entry (entry, text);
 
-    row = gtk_clist_append (GTK_CLIST (dialog->priv->pat_list), text);
-    //gtk_clist_set_foreground (GTK_CLIST (dialog->priv->pat_list), row, entry->malformed_pattern ? &red : &black);
-    gtk_clist_set_row_data (GTK_CLIST (dialog->priv->pat_list), row, entry);
-    update_move_buttons (dialog, GTK_CLIST (dialog->priv->pat_list)->focus_row);
+void GnomeCmdAdvrenameDialog::Private::on_counter_step_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog)
+{
+    dialog->defaults.counter_increment = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
+    if (dialog->priv->template_has_counters)
+        dialog->update_new_filenames();
 }
 
 
-inline gchar *update_entry (PatternEntry *entry, GnomeCmdStringDialog *string_dialog, const gchar **values)
+void GnomeCmdAdvrenameDialog::Private::on_counter_digits_spin_value_changed (GtkWidget *spin, GnomeCmdAdvrenameDialog *dialog)
 {
-    if (!values[0])
-        return g_strdup (_("Invalid source pattern"));
-
-    GtkWidget *case_check = lookup_widget (GTK_WIDGET (string_dialog), "case_check");
+    dialog->defaults.counter_precision = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin));
+    if (dialog->priv->template_has_counters)
+        dialog->update_new_filenames();
+}
 
-    g_free (entry->from);
-    g_free (entry->to);
-    entry->from = g_strdup (values[0]);
-    entry->to = g_strdup (values[1]);
-    entry->case_sens = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (case_check));
 
-    return NULL;
+void GnomeCmdAdvrenameDialog::Private::on_regex_model_row_deleted (GtkTreeModel *treemodel, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog)
+{
+    dialog->update_new_filenames();
 }
 
 
-static gchar *apply_one_pattern (gchar *in, PatternEntry *entry, int eflags)
+void GnomeCmdAdvrenameDialog::Private::on_regex_add_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
 {
-    regex_t re_exp;
-    regmatch_t re_match_info;
-    gchar *out = NULL;
-
-    if (!in || !entry) return NULL;
+    Regex *rx = new Regex;
 
-    if (regcomp (&re_exp, entry->from, (entry->case_sens ? REG_EXTENDED : REG_EXTENDED|REG_ICASE)) != 0)
-        entry->malformed_pattern = TRUE;
-    else
+    if (gnome_cmd_advrename_regex_dialog_new (_("Add Rule"), GTK_WINDOW (dialog), rx))
     {
-        if (regexec (&re_exp, in, 1, &re_match_info, eflags) == 0)
-        {
-            if (strcmp (entry->from, "$") == 0)
-                out = g_strconcat (in, entry->to, NULL);
-            else
-                if (strcmp (entry->from, "^") == 0)
-                    out = g_strconcat (entry->to, in, NULL);
-                else
-                {
-                    gint match_size = re_match_info.rm_eo - re_match_info.rm_so;
+        GtkTreeIter i;
 
-                    if (match_size)
-                    {
-                        gchar **v;
-                        gchar *match = (gchar *) g_malloc (match_size+1);
-                        gchar *tail;
-
-                        g_utf8_strncpy (match, in+re_match_info.rm_so, match_size);
-                        match[match_size] = '\0';
-                        v = g_strsplit (in, match, 2);
-                        tail = apply_one_pattern (v[1], entry, eflags|REG_NOTBOL|REG_NOTEOL);
-                        out = g_strjoin (NULL, v[0], entry->to, tail, NULL);
-                        g_free (tail);
-                        g_free (match);
-                        g_strfreev (v);
-                    }
-                }
-        }
+        gtk_list_store_append (GTK_LIST_STORE (dialog->defaults.regexes), &i);
+        gtk_list_store_set (GTK_LIST_STORE (dialog->defaults.regexes), &i,
+                            COL_REGEX, rx,
+                            COL_MALFORMED_REGEX, !*rx,
+                            COL_PATTERN, rx->from.c_str(),
+                            COL_REPLACE, rx->to.c_str(),
+                            COL_MATCH_CASE, rx->case_sensitive ? _("Yes") : _("No"),
+                            -1);
+
+        dialog->update_new_filenames();
+
+        gtk_widget_set_sensitive (dialog->priv->regex_edit_button, TRUE);
+        gtk_widget_set_sensitive (dialog->priv->regex_remove_button, TRUE);
+        gtk_widget_set_sensitive (dialog->priv->regex_remove_all_button, TRUE);
     }
-
-    regfree (&re_exp);
-
-    return out ? out : g_strdup (in);
+    else
+        delete rx;
 }
 
 
-inline gchar *create_new_name (const gchar *name, GList *patterns)
+void GnomeCmdAdvrenameDialog::Private::on_regex_edit_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
 {
-    gchar *new_name = g_strdup (name);
+    GtkTreeView *tree_view = GTK_TREE_VIEW (dialog->priv->regex_view);
+    GtkTreeIter i;
 
-    for (; patterns; patterns = patterns->next)
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (tree_view), NULL, &i))
     {
-        PatternEntry *entry = (PatternEntry *) patterns->data;
+        Regex *rx = NULL;
 
-        gchar *tmp = new_name;
+        gtk_tree_model_get (dialog->defaults.regexes, &i, COL_REGEX, &rx, -1);
 
-        new_name = apply_one_pattern (tmp, entry, 0);
+        if (gnome_cmd_advrename_regex_dialog_new (_("Edit Rule"), GTK_WINDOW (dialog), rx))
+        {
+            gtk_list_store_set (GTK_LIST_STORE (dialog->defaults.regexes), &i,
+                                COL_REGEX, rx,
+                                COL_MALFORMED_REGEX, !*rx,
+                                COL_PATTERN, rx->from.c_str(),
+                                COL_REPLACE, rx->to.c_str(),
+                                COL_MATCH_CASE, rx->case_sensitive ? _("Yes") : _("No"),
+                                -1);
 
-        g_free (tmp);
+            dialog->update_new_filenames();
+        }
     }
-
-    return new_name;
 }
 
 
-inline void update_new_names (GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_regex_remove_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
 {
-    const gchar *templ_string = gtk_entry_get_text (GTK_ENTRY (dialog->priv->templ_entry));
+    GtkTreeView *tree_view = GTK_TREE_VIEW (dialog->priv->regex_view);
+    GtkTreeIter i;
 
-    gnome_cmd_advrename_reset_counter (dialog->priv->defaults->counter_start, dialog->priv->defaults->counter_precision, dialog->priv->defaults->counter_increment);
-    gnome_cmd_advrename_parse_template (templ_string, dialog->priv->template_has_counters);
-
-    for (GList *tmp = dialog->priv->entries; tmp; tmp = tmp->next)
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (tree_view), NULL, &i))
     {
-        gchar fname[256];
-        RenameEntry *entry = (RenameEntry *) tmp->data;
-        GList *patterns = dialog->priv->defaults->patterns;
+        Regex *rx = NULL;
 
-        gnome_cmd_advrename_gen_fname (fname, sizeof (fname), entry->f);
+        gtk_tree_model_get (dialog->defaults.regexes, &i, COL_REGEX, &rx, -1);
+        gtk_list_store_remove (GTK_LIST_STORE (dialog->defaults.regexes), &i);
+        delete rx;
 
-        entry->new_name = dialog->priv->trim_blanks (create_new_name (fname, patterns));
+        if (model_is_empty (dialog->defaults.regexes))
+        {
+            gtk_widget_set_sensitive (dialog->priv->regex_edit_button, FALSE);
+            gtk_widget_set_sensitive (dialog->priv->regex_remove_button, FALSE);
+            gtk_widget_set_sensitive (dialog->priv->regex_remove_all_button, FALSE);
+        }
     }
 }
 
 
-inline void redisplay_new_names (GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_regex_remove_all_btn_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
 {
-    for (GList *tmp = dialog->priv->entries; tmp; tmp = tmp->next)
+    GtkTreeIter i;
+
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (dialog->defaults.regexes, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (dialog->defaults.regexes, &i))
     {
-        RenameEntry *entry = (RenameEntry *) tmp->data;
+        Regex *rx = NULL;
 
-        gtk_clist_set_text (GTK_CLIST (dialog->priv->res_list),
-                            get_row_from_rename_entry (dialog, entry),
-                            1,
-                            entry->new_name);
+        gtk_tree_model_get (dialog->defaults.regexes, &i, COL_REGEX, &rx, -1);
+        delete rx;
     }
-}
 
+    g_signal_handlers_block_by_func (dialog->defaults.regexes, gpointer (on_regex_model_row_deleted), dialog);
+    gtk_list_store_clear (GTK_LIST_STORE (dialog->defaults.regexes));
+    g_signal_handlers_unblock_by_func (dialog->defaults.regexes, gpointer (on_regex_model_row_deleted), dialog);
 
-inline void change_names (GnomeCmdAdvrenameDialog *dialog)
-{
-    for (GList *tmp = dialog->priv->entries; tmp; tmp = tmp->next)
-    {
-        RenameEntry *entry = (RenameEntry *) tmp->data;
+    dialog->update_new_filenames();
 
-        if (strcmp (entry->f->info->name, entry->new_name) != 0)
-            gnome_cmd_file_rename (entry->f, entry->new_name);
-    }
+    gtk_widget_set_sensitive (dialog->priv->regex_edit_button, FALSE);
+    gtk_widget_set_sensitive (dialog->priv->regex_remove_button, FALSE);
+    gtk_widget_set_sensitive (dialog->priv->regex_remove_all_button, FALSE);
 }
 
 
-static void on_rule_add (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_regex_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog)
 {
-    PatternEntry *entry = g_new0 (PatternEntry, 1);
-
-    if (gnome_cmd_advrename_regex_dialog_new (_("New Rule"), GTK_WINDOW (dialog), entry))
-    {
-        add_pattern_entry (dialog, entry);
-        dialog->priv->defaults->patterns = g_list_append (dialog->priv->defaults->patterns, entry);
-        update_remove_all_button (dialog);
-        do_test (dialog);
-    }
-    else
-        g_free (entry);
+    on_regex_edit_btn_clicked (NULL, dialog);
 }
 
 
-static void on_rule_edit (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_case_combo_changed (GtkComboBox *combo, GnomeCmdAdvrenameDialog *dialog)
 {
-    GtkWidget *pat_list = dialog->priv->pat_list;
-    gint row = GTK_CLIST (pat_list)->focus_row;
-    PatternEntry *entry = (PatternEntry *) g_list_nth_data (dialog->priv->defaults->patterns, row);
-
-    g_return_if_fail (entry != NULL);
-
-    if (gnome_cmd_advrename_regex_dialog_new (_("Edit Rule"), GTK_WINDOW (dialog), entry))
+    switch (gtk_combo_box_get_active (combo))
     {
-        gchar *text[4];
+        case 0: dialog->priv->convert_case = gcmd_convert_unchanged; break;
+        case 1: dialog->priv->convert_case = gcmd_convert_lowercase; break;
+        case 2: dialog->priv->convert_case = gcmd_convert_uppercase; break;
+        case 3: dialog->priv->convert_case = gcmd_convert_sentence_case; break;
+        case 4: dialog->priv->convert_case = gcmd_convert_initial_caps; break;
+        case 5: dialog->priv->convert_case = gcmd_convert_toggle_case; break;
 
-        format_entry (entry, text);
-        //gtk_clist_set_foreground (GTK_CLIST (pat_list), row, entry->malformed_pattern ? &red : &black);
-        gtk_clist_set_text (GTK_CLIST (pat_list), row, 0, text[0]);
-        gtk_clist_set_text (GTK_CLIST (pat_list), row, 1, text[1]);
-        gtk_clist_set_text (GTK_CLIST (pat_list), row, 2, text[2]);
-        gtk_clist_set_text (GTK_CLIST (pat_list), row, 3, text[3]);
-        update_remove_all_button (dialog);
-        do_test (dialog);
+        default:
+            return;
     }
+
+    dialog->update_new_filenames();
 }
 
 
-static void on_rule_remove (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_trim_combo_changed (GtkComboBox *combo, GnomeCmdAdvrenameDialog *dialog)
 {
-    GtkWidget *pat_list = dialog->priv->pat_list;
-    PatternEntry *entry = get_pattern_entry_from_row (dialog, GTK_CLIST (pat_list)->focus_row);
-
-    if (entry)
+    switch (gtk_combo_box_get_active (combo))
     {
-        dialog->priv->defaults->patterns = g_list_remove (dialog->priv->defaults->patterns, entry);
-        gtk_clist_remove (GTK_CLIST (pat_list), GTK_CLIST (pat_list)->focus_row);
-        update_remove_all_button (dialog);
-        do_test (dialog);
+        case 0: dialog->priv->trim_blanks = gcmd_convert_unchanged; break;
+        case 1: dialog->priv->trim_blanks = gcmd_convert_ltrim; break;
+        case 2: dialog->priv->trim_blanks = gcmd_convert_rtrim; break;
+        case 3: dialog->priv->trim_blanks = gcmd_convert_strip; break;
+
+        default:
+            return;
     }
+
+    dialog->update_new_filenames();
 }
 
 
-static void on_rule_remove_all (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_files_model_row_deleted (GtkTreeModel *files, GtkTreePath *path, GnomeCmdAdvrenameDialog *dialog)
 {
-    gtk_clist_clear (GTK_CLIST (dialog->priv->pat_list));
-    g_list_free (dialog->priv->defaults->patterns);
-    dialog->priv->defaults->patterns = NULL;
-    update_remove_all_button (dialog);
-    do_test (dialog);
+    if (dialog->priv->template_has_counters)
+        dialog->update_new_filenames();
 }
 
 
-static void on_pat_list_scroll_vertical (GtkCList *clist, GtkScrollType scroll_type, gfloat position, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__remove (GtkWidget *menuitem, GtkTreeView *treeview)
 {
-    gtk_clist_select_row (clist, clist->focus_row, 0);
-}
+    GtkTreeIter iter;
 
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter))
+    {
+        GtkTreeModel *model = gtk_tree_view_get_model (treeview);
 
-static void on_rule_selected (GtkCList *list, gint row, gint column, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog)
-{
-    gtk_widget_set_sensitive (dialog->priv->remove_btn, TRUE);
-    gtk_widget_set_sensitive (dialog->priv->edit_btn, TRUE);
-    update_move_buttons (dialog, row);
-    dialog->priv->sel_entry = (PatternEntry *) g_list_nth_data (dialog->priv->defaults->patterns, row);
-}
+        GnomeCmdFile *f;
 
+        gtk_tree_model_get (model, &iter, COL_FILE, &f, -1);
+        gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
 
-static void on_rule_unselected (GtkCList *list, gint row, gint column, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog)
-{
-    gtk_widget_set_sensitive (dialog->priv->remove_btn, FALSE);
-    gtk_widget_set_sensitive (dialog->priv->edit_btn, FALSE);
-    gtk_widget_set_sensitive (dialog->priv->move_up_btn, FALSE);
-    gtk_widget_set_sensitive (dialog->priv->move_down_btn, FALSE);
-    dialog->priv->sel_entry = NULL;
+        gnome_cmd_file_unref (f);
+    }
 }
 
 
-static void on_rule_move_up (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__show_properties (GtkWidget *menuitem, GtkTreeView *treeview)
 {
-    GtkCList *clist = GTK_CLIST (dialog->priv->pat_list);
+    GtkTreeIter iter;
 
-    if (clist->focus_row >= 1)
+    if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), NULL, &iter))
     {
-        gtk_clist_row_move (clist, clist->focus_row, clist->focus_row-1);
-        update_move_buttons (dialog, clist->focus_row);
-        do_test (dialog);
+        GtkTreeModel *model = gtk_tree_view_get_model (treeview);
+        GnomeCmdFile *f;
+
+        gtk_tree_model_get (model, &iter, COL_FILE, &f, -1);
+
+        if (f)
+            gnome_cmd_file_show_properties (f);
     }
 }
 
 
-static void on_rule_move_down (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu__update_files (GtkWidget *menuitem, GnomeCmdAdvrenameDialog *dialog)
 {
-    GtkCList *clist = GTK_CLIST (dialog->priv->pat_list);
+    GtkTreeIter i;
+    GnomeCmdFile *f;
 
-    if (clist->focus_row >= 0)
+    //  re-read file attributes, as they could be changed...
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (dialog->files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (dialog->files, &i))
     {
-        gtk_clist_row_move (clist, clist->focus_row, clist->focus_row+1);
-        update_move_buttons (dialog, clist->focus_row);
-        do_test (dialog);
+        gtk_tree_model_get (dialog->files, &i,
+                            COL_FILE, &f,
+                            -1);
+
+        gtk_list_store_set (GTK_LIST_STORE (dialog->files), &i,
+                            COL_NAME, gnome_cmd_file_get_name (f),
+                            COL_SIZE, gnome_cmd_file_get_size (f),
+                            COL_DATE, gnome_cmd_file_get_mdate (f, FALSE),
+                            COL_RENAME_FAILED, FALSE,
+                            -1);
     }
+
+    gnome_cmd_advrename_parse_template (gtk_entry_get_text (GTK_ENTRY (dialog->priv->template_entry)), dialog->priv->template_has_counters);
+    dialog->update_new_filenames();
 }
 
 
-static void on_rule_moved (GtkCList *clist, gint arg1, gint arg2, GnomeCmdAdvrenameDialog *dialog)
+inline void GnomeCmdAdvrenameDialog::Private::files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog, GdkEventButton *event)
 {
-    GList *pats = dialog->priv->defaults->patterns;
+    GtkWidget *menu = gtk_menu_new ();
+    GtkWidget *menuitem;
+
+    menuitem = gtk_menu_item_new_with_label (_("Remove from file list"));
+    g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__remove), treeview);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
-    if (!pats
-        || MAX (arg1, arg2) >= g_list_length (pats)
-        || MIN (arg1, arg2) < 0
-        || arg1 == arg2)
-        return;
+    menuitem = gtk_menu_item_new_with_label (_("File properties"));
+    g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__show_properties), treeview);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
-    gpointer data = g_list_nth_data (pats, arg1);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), gtk_separator_menu_item_new ());
 
-    pats = g_list_remove (pats, data);
-    pats = g_list_insert (pats, data, arg2);
+    menuitem = gtk_menu_item_new_with_label (_("Update file list"));
+    g_signal_connect (menuitem, "activate", G_CALLBACK (on_files_view_popup_menu__update_files), dialog);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
 
-    dialog->priv->defaults->patterns =  pats;
+    gtk_widget_show_all (menu);
+    gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
+                    (event != NULL) ? event->button : 0, gdk_event_get_time ((GdkEvent*) event));
 }
 
 
-inline void save_settings (GnomeCmdAdvrenameDialog *dialog)
+gboolean GnomeCmdAdvrenameDialog::Private::on_files_view_button_pressed (GtkWidget *treeview, GdkEventButton *event, GnomeCmdAdvrenameDialog *dialog)
 {
-    const gchar *template_string = gtk_entry_get_text (GTK_ENTRY (dialog->priv->templ_entry));
+    if (event->type==GDK_BUTTON_PRESS && event->button==3)
+    {
+        // optional: select row if no row is selected or only one other row is selected
+        // (will only do something if you set a tree selection mode
+        // as described later in the tutorial)
+        if (1)
+        {
+            GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+            if (gtk_tree_selection_count_selected_rows (selection) <= 1)
+            {
+                GtkTreePath *path;
+
+                if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (treeview),
+                                                   (gint) event->x, (gint) event->y,
+                                                   &path,
+                                                   NULL, NULL, NULL))
+                {
+                    gtk_tree_selection_unselect_all (selection);
+                    gtk_tree_selection_select_path (selection, path);
+                    gtk_tree_path_free (path);
+                }
+            }
+        }
+        dialog->priv->files_view_popup_menu (treeview, dialog, event);
+
+        return TRUE;
+    }
 
-    dialog->priv->defaults->templates->add(g_strdup (template_string));
+    return FALSE;
 }
 
 
-static void on_ok (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+gboolean GnomeCmdAdvrenameDialog::Private::on_files_view_popup_menu (GtkWidget *treeview, GnomeCmdAdvrenameDialog *dialog)
 {
-    update_new_names (dialog);
-    change_names (dialog);
+    dialog->priv->files_view_popup_menu (treeview, dialog);
 
-    save_settings (dialog);
-    free_data (dialog);
-    gtk_widget_destroy (GTK_WIDGET (dialog));
+    return TRUE;
 }
 
 
-static void on_cancel (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_files_view_row_activated (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *col, GnomeCmdAdvrenameDialog *dialog)
 {
-    save_settings (dialog);
-    free_data (dialog);
-    gtk_widget_destroy (GTK_WIDGET (dialog));
+    on_files_view_popup_menu__show_properties (NULL, view);
 }
 
 
-static void on_reset (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+gboolean GnomeCmdAdvrenameDialog::Private::on_dialog_delete (GtkWidget *widget, GdkEvent *event, GnomeCmdAdvrenameDialog *dialog)
 {
-    gtk_entry_set_text (GTK_ENTRY (dialog->priv->templ_entry), "$N");
-    on_rule_remove_all (NULL, dialog);
-    dialog->priv->defaults->counter_start = 1;
-    dialog->priv->defaults->counter_precision = 1;
-    dialog->priv->defaults->counter_increment = 1;
-    gtk_option_menu_set_history (GTK_OPTION_MENU (dialog->priv->trim_combo), 3);
+    return event->type==GDK_DELETE;
 }
 
 
-static void on_help (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
+void GnomeCmdAdvrenameDialog::Private::on_dialog_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GnomeCmdAdvrenameDialog *dialog)
 {
-    gnome_cmd_help_display ("gnome-commander.xml", "gnome-commander-advanced-rename");
+    dialog->defaults.width  = allocation->width;
+    dialog->defaults.height = allocation->height;
 }
 
 
-static gboolean on_dialog_keypress (GnomeCmdAdvrenameDialog *dialog, GdkEventKey *event)
+void GnomeCmdAdvrenameDialog::Private::on_dialog_response (GnomeCmdAdvrenameDialog *dialog, int response_id, gpointer unused)
 {
-    if (event->keyval == GDK_Escape)
+    GtkTreeIter i;
+
+    switch (response_id)
     {
-        gtk_widget_destroy (GTK_WIDGET (dialog));
-        return TRUE;
-    }
+        case GTK_RESPONSE_OK:
+        case GTK_RESPONSE_APPLY:
+            for (gboolean valid_iter=gtk_tree_model_get_iter_first (dialog->files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (dialog->files, &i))
+            {
+                GnomeCmdFile *f;
+                gchar *new_name;
 
-    return FALSE;
-}
+                gtk_tree_model_get (dialog->files, &i,
+                                    COL_FILE, &f,
+                                    COL_NEW_NAME, &new_name,
+                                    -1);
 
+                GnomeVFSResult result = GNOME_VFS_OK;
 
-inline void do_test (GnomeCmdAdvrenameDialog *dialog)
-{
-    update_new_names (dialog);
-    redisplay_new_names (dialog);
-}
+                if (strcmp (f->info->name, new_name) != 0)
+                    result = gnome_cmd_file_rename (f, new_name);
 
+                gtk_list_store_set (GTK_LIST_STORE (dialog->files), &i,
+                                    COL_NAME, gnome_cmd_file_get_name (f),
+                                    COL_RENAME_FAILED, result!=GNOME_VFS_OK,
+                                    -1);
 
-static void on_templ_entry_changed (GtkEntry *entry, GnomeCmdAdvrenameDialog *dialog)
-{
-    if (dialog->priv->defaults->auto_update)
-        do_test (dialog);
+                g_free (new_name);
+            }
+            dialog->update_new_filenames();
+            dialog->defaults.templates->add(gtk_entry_get_text (GTK_ENTRY (dialog->priv->template_entry)));
+            break;
+
+
+        case GTK_RESPONSE_NONE:
+        case GTK_RESPONSE_DELETE_EVENT:
+        case GTK_RESPONSE_CANCEL:
+        case GTK_RESPONSE_CLOSE:
+            dialog->defaults.templates->add(gtk_entry_get_text (GTK_ENTRY (dialog->priv->template_entry)));
+            gtk_widget_hide (*dialog);
+            dialog->unset();
+            g_signal_stop_emission_by_name (dialog, "response");        //  FIXME:  ???
+            break;
+
+        case GTK_RESPONSE_HELP:
+            gnome_cmd_help_display ("gnome-commander.xml", "gnome-commander-advanced-rename");
+            g_signal_stop_emission_by_name (dialog, "response");
+            break;
+
+        case GCMD_RESPONSE_RESET:
+            gtk_entry_set_text (GTK_ENTRY (dialog->priv->template_entry), "$N");
+            gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->counter_start_spin), 1);
+            gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->counter_step_spin), 1);
+            gtk_spin_button_set_value (GTK_SPIN_BUTTON (dialog->priv->counter_digits_spin), 1);
+            gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->case_combo), 0);
+            gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->trim_combo), 3);
+            on_regex_remove_all_btn_clicked (NULL, dialog);
+            break;
+
+        default :
+            g_assert_not_reached ();
+    }
 }
 
 
-static gboolean on_templ_entry_keypress (GtkEntry *entry, GdkEventKey *event, GnomeCmdAdvrenameDialog *dialog)
+static void gnome_cmd_advrename_dialog_init (GnomeCmdAdvrenameDialog *dialog)
 {
-    if (event->keyval == GDK_Return)
+    dialog->priv = new GnomeCmdAdvrenameDialog::Private;
+
+    gtk_window_set_title (*dialog, _("Advanced Rename Tool"));
+    gtk_window_set_resizable (*dialog, TRUE);
+    gtk_dialog_set_has_separator (*dialog, FALSE);
+    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+    gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2);
+
+    GtkWidget *align;
+    GtkWidget *label;
+    GtkWidget *table;
+    GtkWidget *combo;
+    GtkWidget *hbox;
+    GtkWidget *vbox;
+    GtkWidget *bbox;
+    GtkWidget *spin;
+    GtkWidget *button;
+
+    gchar *str;
+
+    vbox = gtk_vbox_new (FALSE, 6);
+    gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), vbox, TRUE, TRUE, 0);
+
+    hbox = gtk_hbox_new (FALSE, 18);
+    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+    // Template
     {
-        do_test (dialog);
-        return TRUE;
-    }
+        GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+        gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
 
-    return FALSE;
-}
+        str = g_strdup_printf ("<b>%s</b>", _("_Template"));
+        label = gtk_label_new_with_mnemonic (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+        align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 0);
+        gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
 
+        {
+            GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+            gtk_container_add (GTK_CONTAINER (align), vbox);
 
-static void on_trim_combo_changed (GtkOptionMenu *optmenu, GnomeCmdAdvrenameDialog *dialog)
-{
-    switch (gtk_option_menu_get_history (optmenu))
+            dialog->priv->template_combo = combo = gtk_combo_box_entry_new_text ();
+            dialog->priv->template_entry = gtk_bin_get_child (GTK_BIN (dialog->priv->template_combo));
+            gtk_entry_set_activates_default (GTK_ENTRY (dialog->priv->template_entry), TRUE);
+            gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+            gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0);
+
+            GtkWidget *bbox = gtk_hbutton_box_new ();
+            gtk_box_pack_start (GTK_BOX (vbox), bbox, TRUE, FALSE, 0);
+
+            gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+            gtk_box_set_spacing (GTK_BOX (bbox), 6);
+            gtk_box_pack_start (GTK_BOX (bbox), dialog->priv->create_button_with_menu (_("Directory"), GnomeCmdAdvrenameDialog::Private::DIR_MENU), FALSE, FALSE, 0);
+            gtk_box_pack_start (GTK_BOX (bbox), dialog->priv->create_button_with_menu (_("File"), GnomeCmdAdvrenameDialog::Private::FILE_MENU), FALSE, FALSE, 0);
+            gtk_box_pack_start (GTK_BOX (bbox), dialog->priv->create_button_with_menu (_("Counter"), GnomeCmdAdvrenameDialog::Private::COUNTER_MENU), FALSE, FALSE, 0);
+            gtk_box_pack_start (GTK_BOX (bbox), dialog->priv->create_button_with_menu (_("Date"), GnomeCmdAdvrenameDialog::Private::DATE_MENU), FALSE, FALSE, 0);
+            gtk_box_pack_start (GTK_BOX (bbox), dialog->priv->create_button_with_menu (_("Metatag"), GnomeCmdAdvrenameDialog::Private::METATAG_MENU), FALSE, FALSE, 0);
+        }
+    }
+
+
+    // Counter
     {
-        case 0: dialog->priv->trim_blanks = gcmd_convert_unchanged; break;
-        case 1: dialog->priv->trim_blanks = gcmd_convert_ltrim; break;
-        case 2: dialog->priv->trim_blanks = gcmd_convert_rtrim; break;
-        case 3: dialog->priv->trim_blanks = gcmd_convert_strip; break;
+        GtkWidget *vbox = gtk_vbox_new (FALSE, 6);
+        gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
+
+        str = g_strdup_printf ("<b>%s</b>", _("Counter"));
+        label = gtk_label_new_with_mnemonic (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+        align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 0, 12, 0);
+        gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+        table = gtk_table_new (3, 2, FALSE);
+        gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+        gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+        gtk_container_add (GTK_CONTAINER (align), table);
+
+        label = gtk_label_new_with_mnemonic (_("_Start:"));
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        dialog->priv->counter_start_spin = spin = gtk_spin_button_new_with_range (0, 1000000, 1);
+        gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
+        gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 0, 1);
+        gtk_table_attach_defaults (GTK_TABLE (table), spin, 1, 2, 0, 1);
+
+        label = gtk_label_new_with_mnemonic (_("Ste_p:"));
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        dialog->priv->counter_step_spin = spin = gtk_spin_button_new_with_range (-1000, 1000, 1);
+        gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
+        gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 1, 2);
+        gtk_table_attach_defaults (GTK_TABLE (table), spin, 1, 2, 1, 2);
+
+        label = gtk_label_new_with_mnemonic (_("Di_gits:"));
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        dialog->priv->counter_digits_spin = spin = gtk_spin_button_new_with_range (1, 16, 1);
+        gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
+        gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 2, 3);
+        gtk_table_attach_defaults (GTK_TABLE (table), spin, 1, 2, 2, 3);
     }
 
-    do_test (dialog);
-}
 
+    // Regex
+    {
+        str = g_strdup_printf ("<b>%s</b>", _("Regex replacing"));
+        label = gtk_label_new (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+        align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 18, 12, 0);
+        gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+
+        table = gtk_table_new (2, 1, FALSE);
+        gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+        gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+        gtk_container_add (GTK_CONTAINER (align), table);
+
+        GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+        gtk_table_attach (GTK_TABLE (table), scrolled_window, 0, 1, 0, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), GTK_FILL, 0, 0);
+
+        dialog->priv->regex_view = create_regex_view ();
+        gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->priv->regex_view);
+
+        bbox = gtk_vbutton_box_new ();
+        gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+        gtk_box_set_spacing (GTK_BOX (bbox), 12);
+        gtk_table_attach (GTK_TABLE (table), bbox, 1, 2, 0, 1, GTK_FILL, GTK_FILL, 0, 0);
+
+        dialog->priv->regex_add_button = button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+        gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+
+        dialog->priv->regex_edit_button = button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+        gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
 
-static gboolean on_template_options_ok (GnomeCmdStringDialog *string_dialog, const gchar **values, GnomeCmdAdvrenameDialog *dialog)
-{
-    guint start, precision, inc;
+        dialog->priv->regex_remove_button = button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+        gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
 
-    if (sscanf (values[0], "%u", &start) != 1)
-        return TRUE;
+        dialog->priv->regex_remove_all_button = button = gtk_button_new_with_mnemonic ("Remove A_ll");
+        gtk_box_pack_start (GTK_BOX (bbox), button, FALSE, FALSE, 0);
+    }
 
-    if (sscanf (values[1], "%u", &inc) != 1)
-        return TRUE;
 
-    if (sscanf (values[2], "%u", &precision) != 1)
-        return TRUE;
+    align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+    gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 18, 0, 0);
+    gtk_box_pack_start (GTK_BOX (vbox), align, FALSE, FALSE, 0);
+    hbox = gtk_hbox_new (FALSE, 12);
+    gtk_container_add (GTK_CONTAINER (align), hbox);
 
-    dialog->priv->defaults->counter_start = start;
-    dialog->priv->defaults->counter_increment = inc;
-    dialog->priv->defaults->counter_precision = precision;
-    dialog->priv->defaults->auto_update = gtk_toggle_button_get_active (
-        GTK_TOGGLE_BUTTON (lookup_widget (GTK_WIDGET (string_dialog), "auto-update-check")));
+    // Case conversion & blank triming
+    {
+        str = g_strdup_printf ("<b>%s</b>", _("Case"));
+        label = gtk_label_new_with_mnemonic (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+        dialog->priv->case_combo = combo = gtk_combo_box_new_text ();
+        gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+
+        gchar *case_modes[] = {
+                                _("<unchanged>"),
+                                _("lowercase"),
+                                _("UPPERCASE"),
+                                NULL,
+                                _("Sentence case"),       //  FIXME
+                                _("Initial Caps"),        //  FIXME
+                                _("tOGGLE cASE"),         //  FIXME
+                                NULL
+                              };
+
+        for (gchar **items=case_modes; *items; ++items)
+            gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _(*items));
+
+        gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+
+
+        str = g_strdup_printf ("<b>%s</b>", _("Trim blanks"));
+        label = gtk_label_new_with_mnemonic (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+        dialog->priv->trim_combo = combo = gtk_combo_box_new_text ();
+        gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo);
+
+        gchar *trim_modes[] = {
+                                  _("<none>"),
+                                  _("leading"),
+                                  _("trailing"),
+                                  _("leading and trailing"),
+                                  NULL
+                              };
 
-    do_test (dialog);
+        for (gchar **items=trim_modes; *items; ++items)
+            gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _(*items));
 
-    return TRUE;
-}
+        gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
+    }
 
+    // Results
+    {
+        str = g_strdup_printf ("<b>%s</b>", _("Results"));
+        label = gtk_label_new_with_mnemonic (str);
+        g_free (str);
+
+        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
+        gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+        gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+        align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+        gtk_alignment_set_padding (GTK_ALIGNMENT (align), 0, 6, 12, 0);
+        gtk_container_add (GTK_CONTAINER (vbox), align);
+
+        GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+        gtk_container_add (GTK_CONTAINER (align), scrolled_window);
 
-static void on_template_options_clicked (GtkButton *button, GnomeCmdAdvrenameDialog *dialog)
-{
-    const gchar *labels[] = {
-        _("Counter start value:"),
-        _("Counter increment:"),
-        _("Counter minimum digit count:")
-    };
-    gchar *s;
+        dialog->priv->files_view = create_files_view ();
+        gtk_container_add (GTK_CONTAINER (scrolled_window), dialog->priv->files_view);
 
-    GtkWidget *dlg = gnome_cmd_string_dialog_new (_("Template Options"), labels, 3,
-                                                  (GnomeCmdStringDialogCallback) on_template_options_ok, dialog);
-    gtk_widget_ref (dlg);
-
-    GtkWidget *check = create_check (GTK_WIDGET (dlg), _("Auto-update when the template is entered"), "auto-update-check");
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), dialog->priv->defaults->auto_update);
-    gnome_cmd_dialog_add_category (GNOME_CMD_DIALOG (dlg), check);
+        GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->files_view));
+        gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+    }
 
-    s = g_strdup_printf ("%d", dialog->priv->defaults->counter_start);
-    gnome_cmd_string_dialog_set_value (GNOME_CMD_STRING_DIALOG (dlg), 0, s);
-    g_free (s);
-    s = g_strdup_printf ("%d", dialog->priv->defaults->counter_increment);
-    gnome_cmd_string_dialog_set_value (GNOME_CMD_STRING_DIALOG (dlg), 1, s);
-    g_free (s);
-    s = g_strdup_printf ("%d", dialog->priv->defaults->counter_precision);
-    gnome_cmd_string_dialog_set_value (GNOME_CMD_STRING_DIALOG (dlg), 2, s);
-    g_free (s);
+    gtk_dialog_add_buttons (*dialog,
+                            GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+                            _("Reset"), GnomeCmdAdvrenameDialog::GCMD_RESPONSE_RESET,
+                            GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+                            GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
+                            NULL);
 
-    gtk_widget_show (dlg);
+    gtk_dialog_set_default_response (*dialog, GTK_RESPONSE_APPLY);
 }
 
 
-static void on_res_list_column_resize (GtkCList *clist, gint column, gint width, GnomeCmdAdvrenameDialog *dialog)
+static void gnome_cmd_advrename_dialog_finalize (GObject *object)
 {
-    advrename_dialog_default_res_column_width[column] = width;
+    GnomeCmdAdvrenameDialog *dialog = GNOME_CMD_ADVRENAME_DIALOG (object);
+
+    delete dialog->priv;
+
+    G_OBJECT_CLASS (gnome_cmd_advrename_dialog_parent_class)->finalize (object);
 }
 
 
-static void on_pat_list_column_resize (GtkCList *clist, gint column, gint width, GnomeCmdAdvrenameDialog *dialog)
+static void gnome_cmd_advrename_dialog_class_init (GnomeCmdAdvrenameDialogClass *klass)
 {
-    advrename_dialog_default_pat_column_width[column] = width;
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = gnome_cmd_advrename_dialog_finalize;
 }
 
 
-static void on_dialog_size_allocate (GtkWidget *widget, GtkAllocation *allocation, GnomeCmdAdvrenameDialog *dialog)
+inline GtkWidget *create_regex_view ()
 {
-    dialog->priv->defaults->width  = allocation->width;
-    dialog->priv->defaults->height = allocation->height;
-}
+    GtkWidget *view = gtk_tree_view_new ();
 
+    g_object_set (view,
+                  "rules-hint", TRUE,
+                  "reorderable", TRUE,
+                  NULL);
 
-/*******************************
- * Gtk class implementation
- *******************************/
+    GtkCellRenderer *renderer = NULL;
+    GtkTreeViewColumn *col = NULL;
 
-static void destroy (GtkObject *object)
-{
-    GnomeCmdAdvrenameDialog *dialog = GNOME_CMD_ADVRENAME_DIALOG (object);
+    GtkTooltips *tips = gtk_tooltips_new ();
 
-    g_free (dialog->priv);
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_PATTERN, _("Search for"));
+    g_object_set (renderer, "foreground", "red", NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_MALFORMED_REGEX);
+    gtk_tooltips_set_tip (tips, col->button, _("Regex pattern"), NULL);
 
-    if (GTK_OBJECT_CLASS (parent_class)->destroy)
-        (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_REPLACE, _("Replace with"));
+    g_object_set (renderer, "foreground", "red", NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_MALFORMED_REGEX);
+    gtk_tooltips_set_tip (tips, col->button, _("Replacement"), NULL);
 
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_MATCH_CASE, _("Match case"));
+    g_object_set (renderer, "foreground", "red", NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_MALFORMED_REGEX);
+    gtk_tooltips_set_tip (tips, col->button, _("Case sensitive matching"), NULL);
 
-static void map (GtkWidget *widget)
-{
-    if (GTK_WIDGET_CLASS (parent_class)->map != NULL)
-        GTK_WIDGET_CLASS (parent_class)->map (widget);
+    g_object_set (renderer,
+                  "xalign", 0.0,
+                  NULL);
+
+    return view;
 }
 
 
-static void class_init (GnomeCmdAdvrenameDialogClass *klass)
+inline GtkTreeModel *create_files_model ()
 {
-    GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
-    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+    GtkListStore *store = gtk_list_store_new (GnomeCmdAdvrenameDialog::NUM_FILE_COLS,
+                                              G_TYPE_POINTER,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_STRING,
+                                              G_TYPE_BOOLEAN);
 
-    parent_class = (GnomeCmdDialogClass *) gtk_type_class (gnome_cmd_dialog_get_type ());
-    object_class->destroy = destroy;
-    widget_class->map = ::map;
+    return GTK_TREE_MODEL (store);
 }
 
 
-static void init (GnomeCmdAdvrenameDialog *in_dialog)
+inline GtkWidget *create_files_view ()
 {
-    GtkWidget *hbox, *vbox;
-    GtkWidget *sw;
-    GtkWidget *bbox;
-    GtkWidget *btn;
-    GtkWidget *cat;
-    GtkWidget *table;
-    GtkWidget *optmenu;
-    GtkWidget *label;
+    GtkWidget *view = gtk_tree_view_new ();
 
-    gchar *trim_modes[] = {
-                              _("<none>"),
-                              _("leading"),
-                              _("trailing"),
-                              _("leading and trailing"),
-                              NULL
-                          };
-
-    in_dialog->priv = g_new0 (GnomeCmdAdvrenameDialogPrivate, 1);
-
-    in_dialog->priv->entries = NULL;
-    in_dialog->priv->sel_entry = NULL;
-    in_dialog->priv->defaults = gnome_cmd_data.advrename_defaults;
-
-    GtkAccelGroup *accel_group = gtk_accel_group_new ();
-
-    GtkWidget *dialog = GTK_WIDGET (in_dialog);
-    gtk_object_set_data (GTK_OBJECT (dialog), "dialog", dialog);
-    gtk_window_set_title (GTK_WINDOW (dialog), _("Advanced Rename Tool"));
-    gtk_window_set_default_size (GTK_WINDOW (dialog),
-                                 in_dialog->priv->defaults->width,
-                                 in_dialog->priv->defaults->height);
-    gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE);
-    gtk_window_set_policy (GTK_WINDOW (dialog), FALSE, TRUE, FALSE);
-    gtk_signal_connect (GTK_OBJECT (dialog), "size-allocate", GTK_SIGNAL_FUNC (on_dialog_size_allocate), dialog);
-
-
-    // Template stuff
-    table = create_table (dialog, 2, 2);
-    cat = create_category (dialog, table, _("Template"));
-    gnome_cmd_dialog_add_category (GNOME_CMD_DIALOG (dialog), cat);
-
-    in_dialog->priv->templ_combo = create_combo (dialog);
-    gtk_combo_set_case_sensitive (GTK_COMBO (in_dialog->priv->templ_combo), TRUE);
-    in_dialog->priv->templ_entry = GTK_COMBO (in_dialog->priv->templ_combo)->entry;
-    gtk_signal_connect (GTK_OBJECT (in_dialog->priv->templ_entry),
-                        "key-press-event", GTK_SIGNAL_FUNC (on_templ_entry_keypress),
-                        dialog);
-    gtk_signal_connect (GTK_OBJECT (in_dialog->priv->templ_entry),
-                        "changed", GTK_SIGNAL_FUNC (on_templ_entry_changed),
-                        dialog);
-    gtk_table_attach (GTK_TABLE (table), in_dialog->priv->templ_combo, 0, 1, 0, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
-    if (in_dialog->priv->defaults->templates->ents)
-        gtk_combo_set_popdown_strings (GTK_COMBO (in_dialog->priv->templ_combo), in_dialog->priv->defaults->templates->ents);
-    else
-        gtk_entry_set_text (GTK_ENTRY (in_dialog->priv->templ_entry), "$N");
+    g_object_set (view,
+                  "rules-hint", TRUE,
+                  "reorderable", TRUE,
+                  "enable-search", TRUE,
+                  "search-column", GnomeCmdAdvrenameDialog::COL_NAME,
+                  NULL);
 
-    bbox = create_vbuttonbox (dialog);
-    table_add (table, bbox, 1, 0, GTK_FILL);
-    gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+    GtkCellRenderer *renderer = NULL;
+    GtkTreeViewColumn *col = NULL;
 
-    btn = create_button (dialog, _("O_ptions..."), GTK_SIGNAL_FUNC (on_template_options_clicked));
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
+    GtkTooltips *tips = gtk_tooltips_new ();
 
-    bbox = create_hbuttonbox (dialog);
-    table_add (table, bbox, 0, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL));
-    gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_NAME, _("Old name"));
+    g_object_set (renderer, "foreground", "DarkGray", "style", PANGO_STYLE_ITALIC, NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tooltips_set_tip (tips, col->button, _("Current file name"), NULL);
 
-    btn = create_button_with_menu (in_dialog, _("Directory"), DIR_MENU);
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_NEW_NAME, _("New name"));
+    g_object_set (renderer, "foreground", "DarkGray", "style", PANGO_STYLE_ITALIC, NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tooltips_set_tip (tips, col->button, _("New file name"), NULL);
 
-    btn = create_button_with_menu (in_dialog, _("File"), FILE_MENU);
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), renderer, GnomeCmdAdvrenameDialog::COL_SIZE, _("Size"));
+    g_object_set (renderer, "xalign", 1.0, "foreground", "DarkGray", "style", PANGO_STYLE_ITALIC, NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tooltips_set_tip (tips, col->button, _("File size"), NULL);
 
-    btn = create_button_with_menu (in_dialog, _("Counter"), COUNTER_MENU);
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
+    col = gnome_cmd_treeview_create_new_text_column (GTK_TREE_VIEW (view), GnomeCmdAdvrenameDialog::COL_DATE, _("Date"));
+    g_object_set (renderer, "foreground", "DarkGray", "style", PANGO_STYLE_ITALIC, NULL);
+    gtk_tree_view_column_add_attribute (col, renderer, "foreground-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tree_view_column_add_attribute (col, renderer, "style-set", GnomeCmdAdvrenameDialog::COL_RENAME_FAILED);
+    gtk_tooltips_set_tip (tips, col->button, _("File modification date"), NULL);
 
-    btn = create_button_with_menu (in_dialog, _("Date"), DATE_MENU);
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
+    return view;
+}
 
-    btn = create_button_with_menu (in_dialog, _("Metatag"), METATAG_MENU);
-    gtk_container_add (GTK_CONTAINER (bbox), btn);
 
-    // Regex stuff
-    table = create_table (dialog, 2, 2);
-    cat = create_category (dialog, table, _("Regex replacing"));
-    gnome_cmd_dialog_add_category (GNOME_CMD_DIALOG (dialog), cat);
+void GnomeCmdAdvrenameDialog::update_new_filenames()
+{
+    gnome_cmd_advrename_reset_counter (defaults.counter_start, defaults.counter_precision, defaults.counter_increment);
 
-    sw = create_clist (dialog, "pat_list", 3, 16, GTK_SIGNAL_FUNC (on_rule_selected), GTK_SIGNAL_FUNC (on_rule_moved));
-    gtk_table_attach (GTK_TABLE (table), sw, 0, 1, 0, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), (GtkAttachOptions) (GTK_EXPAND|GTK_FILL), 0, 0);
-    create_clist_column (sw, 0, advrename_dialog_default_pat_column_width[0], _("Replace this"));
-    create_clist_column (sw, 1, advrename_dialog_default_pat_column_width[1], _("With this"));
-    create_clist_column (sw, 2, advrename_dialog_default_pat_column_width[2], _("Case sensitive"));
+    char buff[256];
+    GtkTreeIter i;
 
-    in_dialog->priv->pat_list = lookup_widget (GTK_WIDGET (sw), "pat_list");
-    gtk_signal_connect (GTK_OBJECT (in_dialog->priv->pat_list),
-                        "unselect-row",
-                        GTK_SIGNAL_FUNC (on_rule_unselected),
-                        dialog);
+    vector<Regex *> rx;
 
-    bbox = create_hbuttonbox (dialog);
-    table_add (table, bbox, 0, 1, (GtkAttachOptions) (GTK_EXPAND|GTK_FILL));
-    gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (defaults.regexes, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (defaults.regexes, &i))
+    {
+        Regex *r;
 
-    in_dialog->priv->add_btn = create_stock_button (dialog, GTK_STOCK_ADD, GTK_SIGNAL_FUNC (on_rule_add));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->add_btn);
+        gtk_tree_model_get (defaults.regexes, &i,
+                            COL_REGEX, &r,
+                            -1);
+        if (r && *r)                            //  ignore regex pattern if it can't be retrieved or if it is malformed
+            rx.push_back(r);
+    }
 
-    in_dialog->priv->edit_btn = create_stock_button (dialog, GTK_STOCK_EDIT, GTK_SIGNAL_FUNC (on_rule_edit));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->edit_btn);
-    gtk_widget_set_sensitive (GTK_WIDGET (in_dialog->priv->edit_btn), FALSE);
+#if !GLIB_CHECK_VERSION (2, 14, 0)
+    vector<pair<int,int> > match;
+#endif
 
-    in_dialog->priv->remove_btn = create_stock_button (dialog, GTK_STOCK_REMOVE, GTK_SIGNAL_FUNC (on_rule_remove));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->remove_btn);
-    gtk_widget_set_sensitive (GTK_WIDGET (in_dialog->priv->remove_btn), FALSE);
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (files, &i))
+    {
+        GnomeCmdFile *f;
 
-    in_dialog->priv->remove_all_btn = create_button (dialog, _("Remove A_ll"), GTK_SIGNAL_FUNC (on_rule_remove_all));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->remove_all_btn);
-    if (!in_dialog->priv->defaults->patterns)
-        gtk_widget_set_sensitive (GTK_WIDGET (in_dialog->priv->remove_all_btn), FALSE);
+        gtk_tree_model_get (files, &i,
+                            COL_FILE, &f,
+                            -1);
+        if (!f)
+            continue;
 
-    bbox = create_vbuttonbox (dialog);
-    table_add (table, bbox, 1, 0, GTK_FILL);
-    gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START);
+        gnome_cmd_advrename_gen_fname (buff, sizeof(buff), f);
 
-    in_dialog->priv->move_up_btn = create_stock_button (dialog, GNOME_STOCK_BUTTON_UP, GTK_SIGNAL_FUNC (on_rule_move_up));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->move_up_btn);
-    gtk_widget_set_sensitive (GTK_WIDGET (in_dialog->priv->move_up_btn), FALSE);
+        gchar *fname = g_strdup (buff);
 
-    in_dialog->priv->move_down_btn = create_stock_button (dialog, GNOME_STOCK_BUTTON_DOWN, GTK_SIGNAL_FUNC (on_rule_move_down));
-    gtk_container_add (GTK_CONTAINER (bbox), in_dialog->priv->move_down_btn);
-    gtk_widget_set_sensitive (GTK_WIDGET (in_dialog->priv->move_down_btn), FALSE);
+        for (vector<Regex *>::iterator j=rx.begin(); j!=rx.end(); ++j)
+        {
+            Regex *&r = *j;
 
+            gchar *prev_fname = fname;
 
-    // Trim blanks stuff
-    hbox = create_hbox (dialog, FALSE, 12);
-    gnome_cmd_dialog_add_category (GNOME_CMD_DIALOG (dialog), hbox);
+#if GLIB_CHECK_VERSION (2, 14, 0)
+            fname = r->replace(prev_fname);
+#else
+            match.clear();
 
-    gchar *str = g_strdup_printf ("<b>%s</b>", _("Trim _blanks"));
-    label = gtk_label_new_with_mnemonic (str);
-    g_free (str);
+            for (gchar *s=prev_fname; *s && r->match(s); s+=r->end())
+                if (r->length()>0)
+                    match.push_back(make_pair(r->start(), r->end()));
 
-    gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
-    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-    gtk_widget_show (label);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+            gchar *src = prev_fname;
+            gchar *dest = fname = (gchar *) g_malloc (strlen(prev_fname) + match.size()*r->to.size() + 1);    // allocate new fname big enough to hold all data
 
-    in_dialog->priv->trim_combo = optmenu = create_option_menu (dialog, trim_modes);
-    gtk_label_set_mnemonic_widget (GTK_LABEL (label), optmenu);
-    gtk_box_pack_start (GTK_BOX (hbox), optmenu, FALSE, FALSE, 0);
-    gtk_signal_connect (GTK_OBJECT (optmenu), "changed", GTK_SIGNAL_FUNC (on_trim_combo_changed), dialog);
-    gtk_option_menu_set_history (GTK_OPTION_MENU (in_dialog->priv->trim_combo), 3);
+            for (vector<pair<int,int> >::const_iterator i=match.begin(); i!=match.end(); ++i)
+            {
+                memcpy(dest, src, i->first);
+                dest += i->first;
+                src += i->second;
+                memcpy(dest, r->to.c_str(), r->to.size());
+                dest += r->to.size();
+            }
 
+            strcpy(dest, src);
+#endif
+            g_free (prev_fname);
+        }
 
-    // Result list stuff
-    vbox = create_vbox (dialog, FALSE, 0);
-    cat = create_category (dialog, vbox, _("Result"));
-    gnome_cmd_dialog_add_expanding_category (GNOME_CMD_DIALOG (dialog), cat);
+        fname = priv->trim_blanks (priv->convert_case (fname));
+        gtk_list_store_set (GTK_LIST_STORE (files), &i,
+                            COL_NEW_NAME, fname,
+                            -1);
+        g_free (fname);
+    }
+}
 
-    sw = create_clist (dialog, "res_list", 2, 16, NULL, NULL);
-    gtk_container_add (GTK_CONTAINER (vbox), sw);
-    create_clist_column (sw, 0, advrename_dialog_default_res_column_width[0], _("Current file names"));
-    create_clist_column (sw, 1, advrename_dialog_default_res_column_width[1], _("New file names"));
-    in_dialog->priv->res_list = lookup_widget (GTK_WIDGET (sw), "res_list");
 
+GnomeCmdAdvrenameDialog::GnomeCmdAdvrenameDialog(GnomeCmdData::AdvrenameDefaults &cfg): defaults(cfg)
+{
+    gtk_window_set_default_size (*this, defaults.width, defaults.height);
 
-    // Dialog stuff
-    gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), GNOME_STOCK_BUTTON_HELP, GTK_SIGNAL_FUNC (on_help), dialog);
-    gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), _("Reset"), GTK_SIGNAL_FUNC (on_reset), dialog);
-    gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), GNOME_STOCK_BUTTON_CANCEL, GTK_SIGNAL_FUNC (on_cancel), dialog);
-    gnome_cmd_dialog_add_button (GNOME_CMD_DIALOG (dialog), GNOME_STOCK_BUTTON_OK, GTK_SIGNAL_FUNC (on_ok), dialog);
+    // Template
+    for (GList *i=defaults.templates->ents; i; i=i->next)
+        gtk_combo_box_append_text (GTK_COMBO_BOX (priv->template_combo), (const gchar *) i->data);
 
-    gtk_widget_grab_focus (in_dialog->priv->pat_list);
-    gtk_window_add_accel_group (GTK_WINDOW (dialog), accel_group);
+    if (defaults.templates->ents)
+        gtk_entry_set_text (GTK_ENTRY (priv->template_entry), (const gchar *) defaults.templates->ents->data);
+    else
+        gtk_entry_set_text (GTK_ENTRY (priv->template_entry), "$N");
 
-    for (GList *tmp = in_dialog->priv->defaults->patterns; tmp; tmp = tmp->next)
-    {
-        PatternEntry *entry = (PatternEntry *) tmp->data;
-        add_pattern_entry (in_dialog, entry);
-    }
+    gtk_editable_set_position (GTK_EDITABLE (priv->template_entry), -1);
+    gtk_widget_grab_focus (priv->template_entry);
+    gtk_entry_select_region (GTK_ENTRY (priv->template_entry), -1, -1);
 
-    gtk_signal_connect (GTK_OBJECT (dialog), "key-press-event", GTK_SIGNAL_FUNC (on_dialog_keypress), dialog);
-    gtk_signal_connect_after (GTK_OBJECT (in_dialog->priv->pat_list),
-                              "scroll-vertical",
-                              GTK_SIGNAL_FUNC (on_pat_list_scroll_vertical),
-                              dialog);
-    gtk_signal_connect_after (GTK_OBJECT (in_dialog->priv->pat_list),
-                              "resize-column",
-                              GTK_SIGNAL_FUNC (on_pat_list_column_resize),
-                              dialog);
-    gtk_signal_connect_after (GTK_OBJECT (in_dialog->priv->res_list),
-                              "resize-column",
-                              GTK_SIGNAL_FUNC (on_res_list_column_resize),
-                              dialog);
+    g_signal_connect (priv->template_combo, "changed", G_CALLBACK (Private::on_template_entry_changed), this);
 
-    if (in_dialog->priv->defaults->patterns)
-        gtk_clist_select_row (GTK_CLIST (in_dialog->priv->pat_list), 0, 0);
-}
+    // Counter
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->counter_start_spin), defaults.counter_start);
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->counter_step_spin), defaults.counter_increment);
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->counter_digits_spin), defaults.counter_precision);
+    g_signal_connect (priv->counter_start_spin, "value-changed", G_CALLBACK (Private::on_counter_start_spin_value_changed), this);
+    g_signal_connect (priv->counter_step_spin, "value-changed", G_CALLBACK (Private::on_counter_step_spin_value_changed), this);
+    g_signal_connect (priv->counter_digits_spin, "value-changed", G_CALLBACK (Private::on_counter_digits_spin_value_changed), this);
 
+    // Regex
+    gtk_tree_view_set_model (GTK_TREE_VIEW (priv->regex_view), defaults.regexes);
 
-/***********************************
- * Public functions
- ***********************************/
+    g_signal_connect (defaults.regexes, "row-deleted", G_CALLBACK (Private::on_regex_model_row_deleted), this);
+    g_signal_connect (priv->regex_view, "row-activated", G_CALLBACK (Private::on_regex_view_row_activated), this);
+    g_signal_connect (priv->regex_add_button, "clicked", G_CALLBACK (Private::on_regex_add_btn_clicked), this);
+    g_signal_connect (priv->regex_edit_button, "clicked", G_CALLBACK (Private::on_regex_edit_btn_clicked), this);
+    g_signal_connect (priv->regex_remove_button, "clicked", G_CALLBACK (Private::on_regex_remove_btn_clicked), this);
+    g_signal_connect (priv->regex_remove_all_button, "clicked", G_CALLBACK (Private::on_regex_remove_all_btn_clicked), this);
 
-GtkWidget *gnome_cmd_advrename_dialog_new (GList *files)
-{
-    GnomeCmdAdvrenameDialog *dialog = (GnomeCmdAdvrenameDialog *) gtk_type_new (gnome_cmd_advrename_dialog_get_type ());
+    // Case conversion & blank triming
+    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->case_combo), 0);
+    gtk_combo_box_set_active (GTK_COMBO_BOX (priv->trim_combo), 3);
+    g_signal_connect (priv->case_combo, "changed", G_CALLBACK (Private::on_case_combo_changed), this);
+    g_signal_connect (priv->trim_combo, "changed", G_CALLBACK (Private::on_trim_combo_changed), this);
+
+    // Results
+    files = create_files_model ();
+
+    g_signal_connect (files, "row-deleted", G_CALLBACK (Private::on_files_model_row_deleted), this);
+    g_signal_connect (priv->files_view, "button-press-event", G_CALLBACK (Private::on_files_view_button_pressed), this);
+    g_signal_connect (priv->files_view, "popup-menu", G_CALLBACK (Private::on_files_view_popup_menu), this);
+    g_signal_connect (priv->files_view, "row-activated", G_CALLBACK (Private::on_files_view_row_activated), this);
+
+    g_signal_connect (this, "delete-event", G_CALLBACK (Private::on_dialog_delete), this);
+    g_signal_connect (this, "size-allocate", G_CALLBACK (Private::on_dialog_size_allocate), this);
+    g_signal_connect (this, "response", G_CALLBACK (Private::on_dialog_response), this);
+
+    gnome_cmd_advrename_parse_template (gtk_entry_get_text (GTK_ENTRY (priv->template_entry)), priv->template_has_counters);
+}
 
-    dialog->priv->files = gnome_cmd_file_list_copy (files);
 
-    for (GList *tmp = dialog->priv->files; tmp; tmp = tmp->next)
+void GnomeCmdAdvrenameDialog::set(GList *file_list)
+{
+    for (GtkTreeIter iter; file_list; file_list=file_list->next)
     {
-        GnomeCmdFile *finfo = (GnomeCmdFile *) tmp->data;
-        if (strcmp (finfo->info->name, "..") != 0)
-            add_rename_entry (dialog, finfo);
+        GnomeCmdFile *f = (GnomeCmdFile *) file_list->data;
+
+        gtk_list_store_append (GTK_LIST_STORE (files), &iter);
+        gtk_list_store_set (GTK_LIST_STORE (files), &iter,
+                            COL_FILE, gnome_cmd_file_ref (f),
+                            COL_NAME, gnome_cmd_file_get_name (f),
+                            COL_SIZE, gnome_cmd_file_get_size (f),
+                            COL_DATE, gnome_cmd_file_get_mdate (f, FALSE),
+                            -1);
     }
 
-    do_test (dialog);
+    gtk_tree_view_set_model (GTK_TREE_VIEW (priv->files_view), files);
+    // g_object_unref (files);          // destroy model automatically with view
 
-    return GTK_WIDGET (dialog);
+    update_new_filenames();
 }
 
 
-GtkType gnome_cmd_advrename_dialog_get_type ()
+void GnomeCmdAdvrenameDialog::unset()
 {
-    static GtkType dlg_type = 0;
+    gtk_tree_view_set_model (GTK_TREE_VIEW (priv->files_view), NULL);       // unset the model
 
-    if (dlg_type == 0)
+    GnomeCmdFile *f;
+    GtkTreeIter i;
+
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (files, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (files, &i))
     {
-        GtkTypeInfo dlg_info =
-        {
-            "GnomeCmdAdvrenameDialog",
-            sizeof (GnomeCmdAdvrenameDialog),
-            sizeof (GnomeCmdAdvrenameDialogClass),
-            (GtkClassInitFunc) class_init,
-            (GtkObjectInitFunc) init,
-            /* reserved_1 */ NULL,
-            /* reserved_2 */ NULL,
-            (GtkClassInitFunc) NULL
-        };
+        gtk_tree_model_get (files, &i,
+                            COL_FILE, &f,
+                            -1);
 
-        dlg_type = gtk_type_unique (gnome_cmd_dialog_get_type (), &dlg_info);
+        gnome_cmd_file_unref (f);
     }
-    return dlg_type;
+
+    g_signal_handlers_block_by_func (files, gpointer (Private::on_files_model_row_deleted), this);
+    gtk_list_store_clear (GTK_LIST_STORE (files));
+    g_signal_handlers_unblock_by_func (files, gpointer (Private::on_files_model_row_deleted), this);
 }

Modified: branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.h
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.h	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-advrename-dialog.h	Mon Nov 17 22:31:43 2008
@@ -21,48 +21,130 @@
 #ifndef __GNOME_CMD_ADVRENAME_DIALOG_H__
 #define __GNOME_CMD_ADVRENAME_DIALOG_H__
 
-#define GNOME_CMD_ADVRENAME_DIALOG(obj) \
-    GTK_CHECK_CAST (obj, gnome_cmd_advrename_dialog_get_type (), GnomeCmdAdvrenameDialog)
-#define GNOME_CMD_ADVRENAME_DIALOG_CLASS(klass) \
-    GTK_CHECK_CLASS_CAST (klass, gnome_cmd_advrename_dialog_get_type (), GnomeCmdAdvrenameDialogClass)
-#define GNOME_CMD_IS_ADVRENAME_DIALOG(obj) \
-    GTK_CHECK_TYPE (obj, gnome_cmd_advrename_dialog_get_type ())
 
+#if !GLIB_CHECK_VERSION (2, 14, 0)
+#include <regex.h>
+#endif
 
-typedef struct _GnomeCmdAdvrenameDialog GnomeCmdAdvrenameDialog;
-typedef struct _GnomeCmdAdvrenameDialogPrivate GnomeCmdAdvrenameDialogPrivate;
-typedef struct _GnomeCmdAdvrenameDialogClass GnomeCmdAdvrenameDialogClass;
+#include "gnome-cmd-data.h"
+#include "gnome-cmd-file-list.h"
 
+#define GNOME_CMD_TYPE_ADVRENAME_DIALOG         (gnome_cmd_advrename_dialog_get_type())
+#define GNOME_CMD_ADVRENAME_DIALOG(obj)         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_CMD_TYPE_ADVRENAME_DIALOG, GnomeCmdAdvrenameDialog))
+#define GNOME_CMD_ADVRENAME_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_CMD_TYPE_ADVRENAME_DIALOG, GnomeCmdAdvrenameDialogClass))
+#define GNOME_CMD_IS_ADVRENAME_DIALOG(obj)      (G_TYPE_INSTANCE_CHECK_TYPE ((obj), GNOME_CMD_TYPE_ADVRENAME_DIALOG)
 
-typedef struct
-{
-    gchar *from;
-    gchar *to;
-    gboolean case_sens;
-    gboolean malformed_pattern;
-} PatternEntry;
+
+GType gnome_cmd_advrename_dialog_get_type ();
 
 
-struct _GnomeCmdAdvrenameDialog
+struct GnomeCmdAdvrenameDialog
 {
-    GnomeCmdDialog parent;
-    GnomeCmdAdvrenameDialogPrivate *priv;
-};
+    GtkDialog parent;
 
+    class Private;
 
-struct _GnomeCmdAdvrenameDialogClass
-{
-    GnomeCmdDialogClass parent_class;
-};
+    Private *priv;
+
+    operator GtkWidget * ()             {  return GTK_WIDGET (this);  }
+    operator GtkWindow * ()             {  return GTK_WINDOW (this);  }
+    operator GtkDialog * ()             {  return GTK_DIALOG (this);  }
+
+    void *operator new (size_t size)    {  return g_object_new (GNOME_CMD_TYPE_ADVRENAME_DIALOG, NULL);  }
+    void operator delete (void *p)      {  g_free (p);  }
+
+    enum {GCMD_RESPONSE_RESET=123};
+
+    enum {COL_REGEX, COL_MALFORMED_REGEX, COL_PATTERN, COL_REPLACE, COL_MATCH_CASE, NUM_REGEX_COLS};
+    enum {COL_FILE, COL_NAME, COL_NEW_NAME, COL_SIZE, COL_DATE, COL_RENAME_FAILED, NUM_FILE_COLS};
+
+    GnomeCmdData::AdvrenameDefaults &defaults;
+
+    GtkTreeModel *files;
 
-#define ADVRENAME_DIALOG_PAT_NUM_COLUMNS 3
-#define ADVRENAME_DIALOG_RES_NUM_COLUMNS 2
+    class Regex
+    {
+#if GLIB_CHECK_VERSION (2, 14, 0)
+        GRegex *re;
+#else
+        regex_t re;
+        regmatch_t pmatch;
+#endif
+        gboolean malformed_pattern;
 
-extern guint advrename_dialog_default_pat_column_width[ADVRENAME_DIALOG_PAT_NUM_COLUMNS];
-extern guint advrename_dialog_default_res_column_width[ADVRENAME_DIALOG_RES_NUM_COLUMNS];
+      public:
 
-GtkWidget *gnome_cmd_advrename_dialog_new (GList *files);
+        std::string from;
+        std::string to;
+        gboolean case_sensitive;
 
-GtkType gnome_cmd_advrename_dialog_get_type ();
+        Regex(): malformed_pattern(TRUE), case_sensitive(FALSE)                                  {}
+        Regex(const gchar *pattern, const gchar *replacement, gboolean case_sensitive);
+        ~Regex();
+
+        void assign(const gchar *pattern, const gchar *replacement, gboolean case_sensitive);
+#if GLIB_CHECK_VERSION (2, 14, 0)
+        gchar *replace(const gchar *s)              {  return g_regex_replace (re, s, -1, 0, to.c_str(), G_REGEX_MATCH_NOTEMPTY, NULL);  }
+#else
+        gboolean match(const gchar *s)              {  return regexec(&re, s, 1, &pmatch, 0)==0;  }
+        int start() const                           {  return pmatch.rm_so;                       }
+        int end() const                             {  return pmatch.rm_eo;                       }
+        int length() const                          {  return end() - start();                    }
+#endif
+
+        operator gboolean ()                        {  return !malformed_pattern;                 }
+    };
+
+    GnomeCmdAdvrenameDialog(GnomeCmdData::AdvrenameDefaults &defaults);
+    ~GnomeCmdAdvrenameDialog();
+
+    void set(GList *files);
+    void unset();
+    void update_new_filenames();
+};
+
+inline GnomeCmdAdvrenameDialog::Regex::Regex(const gchar *pattern, const gchar *replacement, gboolean sensitive=FALSE): case_sensitive(sensitive)
+{
+    if (pattern)  from = pattern;
+    if (replacement)  to = replacement;
+#if GLIB_CHECK_VERSION (2, 14, 0)
+    GError *error = NULL;
+    re = g_regex_new (pattern, GRegexCompileFlags(case_sensitive ? G_REGEX_OPTIMIZE : G_REGEX_OPTIMIZE | G_REGEX_CASELESS), G_REGEX_MATCH_NOTEMPTY, &error);
+    malformed_pattern = !pattern || !*pattern || error;
+    if (error)  g_error_free (error);
+#else
+    memset(&pmatch, 0, sizeof(pmatch));
+    malformed_pattern = !pattern || !*pattern || regcomp(&re, pattern, (case_sensitive ? REG_EXTENDED : REG_EXTENDED|REG_ICASE))!=0;
+#endif
+}
+
+inline GnomeCmdAdvrenameDialog::Regex::~Regex()
+{
+#if GLIB_CHECK_VERSION (2, 14, 0)
+    g_regex_unref (re);
+#else
+    if (!malformed_pattern)  regfree(&re);
+#endif
+}
+
+inline void GnomeCmdAdvrenameDialog::Regex::assign(const gchar *pattern, const gchar *replacement, gboolean sensitive=FALSE)
+{
+    from.clear();
+    to.clear();
+    case_sensitive = sensitive;
+    if (pattern)  from = pattern;
+    if (replacement)  to = replacement;
+#if GLIB_CHECK_VERSION (2, 14, 0)
+    g_regex_unref (re);
+    GError *error = NULL;
+    re = g_regex_new (pattern, GRegexCompileFlags(case_sensitive ? G_REGEX_OPTIMIZE : G_REGEX_OPTIMIZE | G_REGEX_CASELESS), G_REGEX_MATCH_NOTEMPTY, &error);
+    malformed_pattern = !pattern || !*pattern || error;
+    if (error)  g_error_free (error);
+#else
+    if (!malformed_pattern)  regfree(&re);
+    memset(&pmatch, 0, sizeof(pmatch));
+    malformed_pattern = !pattern || !*pattern || regcomp(&re, pattern, (case_sensitive ? REG_EXTENDED : REG_EXTENDED|REG_ICASE))!=0;
+#endif
+}
 
 #endif // __GNOME_CMD_ADVRENAME_DIALOG_H__

Modified: branches/gcmd-1-3/src/gnome-cmd-data.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-data.cc	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-data.cc	Mon Nov 17 22:31:43 2008
@@ -825,25 +825,30 @@
 
 inline void GnomeCmdData::save_rename_history()
 {
-    GList *from=NULL;
-    GList *to=NULL;
-    GList *csens=NULL;
+    GList *from = NULL;
+    GList *to = NULL;
+    GList *csens = NULL;
 
-    for (GList *tmp = advrename_defaults->patterns; tmp; tmp = tmp->next)
+    GtkTreeIter i;
+
+    for (gboolean valid_iter=gtk_tree_model_get_iter_first (advrename_defaults->regexes, &i); valid_iter; valid_iter=gtk_tree_model_iter_next (advrename_defaults->regexes, &i))
     {
-        PatternEntry *entry = (PatternEntry *) tmp->data;
-        from = g_list_append (from, entry->from);
-        to = g_list_append (to, entry->to);
-        csens = g_list_append (csens, (gpointer) (entry->case_sens ? "T" : "F"));
+        GnomeCmdAdvrenameDialog::Regex *rx;
+
+        gtk_tree_model_get (advrename_defaults->regexes, &i,
+                            GnomeCmdAdvrenameDialog::COL_REGEX, &rx,
+                            -1);
+        if (!rx)
+            continue;
+
+        from = g_list_append (from, const_cast <char *> (rx->from.c_str()));
+        to = g_list_append (to, const_cast <char *> (rx->to.c_str()));
+        csens = g_list_append (csens, (gpointer) (rx->case_sensitive ? "T" : "F"));
     }
 
-    gnome_cmd_data_set_int ("/advrename/template_auto_update", advrename_defaults->auto_update);
     gnome_cmd_data_set_int ("/advrename/width", advrename_defaults->width);
     gnome_cmd_data_set_int ("/advrename/height", advrename_defaults->height);
 
-    gnome_cmd_data_set_uint_array ("/advrename/pat_col_widths%d", advrename_dialog_default_pat_column_width, ADVRENAME_DIALOG_PAT_NUM_COLUMNS);
-    gnome_cmd_data_set_uint_array ("/advrename/res_col_widths%d", advrename_dialog_default_res_column_width, ADVRENAME_DIALOG_RES_NUM_COLUMNS);
-
     gnome_cmd_data_set_int ("/template-history/size", g_list_length (advrename_defaults->templates->ents));
     gnome_cmd_data_set_string_history ("/template-history/template%d", advrename_defaults->templates->ents);
 
@@ -851,7 +856,7 @@
     gnome_cmd_data_set_int ("/advrename/counter_precision", advrename_defaults->counter_precision);
     gnome_cmd_data_set_int ("/advrename/counter_increment", advrename_defaults->counter_increment);
 
-    gnome_cmd_data_set_int ("/rename-history/size", g_list_length (advrename_defaults->patterns));
+    gnome_cmd_data_set_int ("/rename-history/size", g_list_length (from));
     gnome_cmd_data_set_string_history ("/rename-history/from%d", from);
     gnome_cmd_data_set_string_history ("/rename-history/to%d", to);
     gnome_cmd_data_set_string_history ("/rename-history/csens%d", csens);
@@ -970,21 +975,12 @@
 {
     gint size;
     GList *from=NULL, *to=NULL, *csens=NULL;
-    GList *tmp_from, *tmp_to, *tmp_csens;
 
     advrename_defaults = g_new0 (AdvrenameDefaults, 1);
 
-    advrename_defaults->auto_update = gnome_cmd_data_get_int ("/advrename/template_auto_update", TRUE);
     advrename_defaults->width = gnome_cmd_data_get_int ("/advrename/width", 450);
     advrename_defaults->height = gnome_cmd_data_get_int ("/advrename/height", 400);
 
-    load_uint_array ("/advrename/pat_col_widths%d",
-                     advrename_dialog_default_pat_column_width,
-                     ADVRENAME_DIALOG_PAT_NUM_COLUMNS);
-    load_uint_array ("/advrename/res_col_widths%d",
-                     advrename_dialog_default_res_column_width,
-                     ADVRENAME_DIALOG_RES_NUM_COLUMNS);
-
     size = gnome_cmd_data_get_int ("/template-history/size", 0);
     GList *templates = load_string_history ("/template-history/template%d", size);
 
@@ -996,26 +992,36 @@
     advrename_defaults->counter_precision = gnome_cmd_data_get_int ("/advrename/counter_precision", 1);
     advrename_defaults->counter_increment = gnome_cmd_data_get_int ("/advrename/counter_increment", 1);
 
-    advrename_defaults->patterns = NULL;
     size = gnome_cmd_data_get_int ("/rename-history/size", 0);
 
-    tmp_from = from = load_string_history ("/rename-history/from%d", size);
-    tmp_to = to = load_string_history ("/rename-history/to%d", size);
-    tmp_csens = csens = load_string_history ("/rename-history/csens%d", size);
+    GList *tmp_from = from = load_string_history ("/rename-history/from%d", size);
+    GList *tmp_to = to = load_string_history ("/rename-history/to%d", size);
+    GList *tmp_csens = csens = load_string_history ("/rename-history/csens%d", size);
+
+    advrename_defaults->regexes = GTK_TREE_MODEL (gtk_list_store_new (GnomeCmdAdvrenameDialog::NUM_REGEX_COLS,
+                                                                      G_TYPE_POINTER,
+                                                                      G_TYPE_BOOLEAN,
+                                                                      G_TYPE_STRING,
+                                                                      G_TYPE_STRING,
+                                                                      G_TYPE_STRING));
 
-    while (tmp_from && size > 0)
+    for (GtkTreeIter iter; tmp_from && size > 0; --size)
     {
-        PatternEntry *entry = g_new0 (PatternEntry, 1);
-        entry->from = (gchar *) tmp_from->data;
-        entry->to = (gchar *) tmp_to->data;
-        entry->case_sens = ((gchar *) tmp_csens->data)[0] == 'T';
+        GnomeCmdAdvrenameDialog::Regex *rx = new GnomeCmdAdvrenameDialog::Regex((gchar *) tmp_from->data,
+                                                                                  (gchar *) tmp_to->data,
+                                                                                  *((gchar *) tmp_csens->data)=='T');
+        gtk_list_store_append (GTK_LIST_STORE (advrename_defaults->regexes), &iter);
+        gtk_list_store_set (GTK_LIST_STORE (advrename_defaults->regexes), &iter,
+                            GnomeCmdAdvrenameDialog::COL_REGEX, rx,
+                            GnomeCmdAdvrenameDialog::COL_MALFORMED_REGEX, !*rx,
+                            GnomeCmdAdvrenameDialog::COL_PATTERN, rx->from.c_str(),
+                            GnomeCmdAdvrenameDialog::COL_REPLACE, rx->to.c_str(),
+                            GnomeCmdAdvrenameDialog::COL_MATCH_CASE, rx->case_sensitive ? _("Yes") : _("No"),
+                            -1);
 
         tmp_from = tmp_from->next;
         tmp_to = tmp_to->next;
         tmp_csens = tmp_csens->next;
-
-        advrename_defaults->patterns = g_list_append (advrename_defaults->patterns, entry);
-        size--;
     }
 
     g_list_free (from);

Modified: branches/gcmd-1-3/src/gnome-cmd-data.h
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-data.h	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-data.h	Mon Nov 17 22:31:43 2008
@@ -50,12 +50,12 @@
 
     struct AdvrenameDefaults
     {
-        GList *patterns;
         History *templates;
+        GtkTreeModel *regexes;
+
         guint counter_start;
         guint counter_precision;
-        guint counter_increment;
-        gboolean auto_update;
+        gint counter_increment;
         gint width, height;
         gint pat_col_widths;
         gint res_col_widths;

Modified: branches/gcmd-1-3/src/gnome-cmd-main-win.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-main-win.cc	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-main-win.cc	Mon Nov 17 22:31:43 2008
@@ -714,6 +714,9 @@
     if (con_home == gnome_cmd_dir_get_connection (dir))
         gnome_cmd_data_set_start_dir (RIGHT, gnome_cmd_file_get_path (GNOME_CMD_FILE (dir)));
 
+    if (main_win->advrename_dlg)
+        gtk_widget_destroy (*main_win->advrename_dlg);
+
     gtk_main_quit ();
 }
 
@@ -754,6 +757,7 @@
      */
     main_win = GNOME_CMD_MAIN_WIN (mw);
 
+    mw->advrename_dlg = NULL;
     mw->priv = g_new0 (GnomeCmdMainWinPrivate, 1);
     mw->priv->current_fs = LEFT;
     mw->priv->accel_group = gtk_accel_group_new ();

Modified: branches/gcmd-1-3/src/gnome-cmd-main-win.h
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-main-win.h	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-main-win.h	Mon Nov 17 22:31:43 2008
@@ -33,12 +33,14 @@
 typedef struct _GnomeCmdMainWinClass GnomeCmdMainWinClass;
 
 #include "gnome-cmd-file-selector.h"
+#include "gnome-cmd-advrename-dialog.h"
 #include "gnome-cmd-cmdline.h"
 #include "plugin_manager.h"
 
 struct _GnomeCmdMainWin
 {
     GnomeApp parent;
+    GnomeCmdAdvrenameDialog *advrename_dlg;
     GnomeCmdMainWinPrivate *priv;
 };
 

Modified: branches/gcmd-1-3/src/gnome-cmd-user-actions.cc
==============================================================================
--- branches/gcmd-1-3/src/gnome-cmd-user-actions.cc	(original)
+++ branches/gcmd-1-3/src/gnome-cmd-user-actions.cc	Mon Nov 17 22:31:43 2008
@@ -742,10 +742,19 @@
     {
         files = get_fl (ACTIVE)->sort_selection(files);
 
-        GtkWidget *dialog = gnome_cmd_advrename_dialog_new (files);
-
-        gtk_widget_ref (dialog);
-        gtk_widget_show (dialog);
+        if (!main_win->advrename_dlg)
+        {
+            main_win->advrename_dlg = new GnomeCmdAdvrenameDialog(*gnome_cmd_data.advrename_defaults);
+            // gtk_widget_ref (*main_win->advrename_dlg);      //  FIXME:  ???
+            main_win->advrename_dlg->set(files);
+            gtk_widget_show_all (*main_win->advrename_dlg);
+        }
+        else
+        {
+            main_win->advrename_dlg->set(files);
+            gtk_widget_show (*main_win->advrename_dlg);
+            // gdk_window_raise (GTK_WIDGET (main_win->advrename_dlg)->window);     //  FIXME:  bring dlg to top ???
+        }
 
         g_list_free (files);
     }



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