[gthumb/ext: 55/79] Implemented the rename series command
- From: Paolo Bacchilega <paobac src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gthumb/ext: 55/79] Implemented the rename series command
- Date: Sun, 2 Aug 2009 20:30:43 +0000 (UTC)
commit 38d437ac2bf8d13e0d2851db231cb5d30dbfac50
Author: Paolo Bacchilega <paobac src gnome org>
Date: Sun Jul 19 18:35:09 2009 +0200
Implemented the rename series command
configure.ac | 3 +
data/ui/overwrite-dialog.ui | 342 +++++++++++++
extensions/Makefile.am | 2 +-
extensions/file_manager/actions.c | 11 +-
extensions/file_manager/actions.h | 1 -
extensions/file_manager/callbacks.c | 6 -
extensions/list_tools/actions.c | 4 +-
extensions/list_tools/actions.h | 2 +-
extensions/list_tools/callbacks.c | 2 +-
extensions/list_tools/gth-script-editor-dialog.c | 4 +-
extensions/list_tools/gth-script.c | 14 +-
extensions/rename_series/Makefile.am | 36 ++
extensions/rename_series/actions.c | 43 ++
extensions/rename_series/actions.h | 32 ++
extensions/rename_series/callbacks.c | 163 +++++++
extensions/rename_series/callbacks.h | 35 ++
extensions/rename_series/data/Makefile.am | 2 +
extensions/rename_series/data/ui/Makefile.am | 5 +
extensions/rename_series/data/ui/rename-series.ui | 514 ++++++++++++++++++++
extensions/rename_series/dlg-rename-series.c | 491 +++++++++++++++++++
extensions/rename_series/dlg-rename-series.h | 31 ++
extensions/rename_series/gth-rename-task.c | 308 ++++++++++++
extensions/rename_series/gth-rename-task.h | 57 +++
extensions/rename_series/main.c | 56 +++
.../rename_series/rename_series.extension.in.in | 10 +
extensions/search/gth-search-editor-dialog.c | 4 +-
gthumb/Makefile.am | 2 +
gthumb/dlg-extensions.c | 33 +-
gthumb/gio-utils.c | 61 +++-
gthumb/gio-utils.h | 7 +
gthumb/gth-browser.c | 13 +-
gthumb/gth-browser.h | 1 +
gthumb/gth-edit-metadata-dialog.c | 102 ++--
gthumb/gth-filter-editor-dialog.c | 42 +-
gthumb/gth-overwrite-dialog.c | 288 +++++++++++
gthumb/gth-overwrite-dialog.h | 69 +++
gthumb/gth-progress-dialog.c | 4 +-
gthumb/gtk-utils.c | 34 +-
38 files changed, 2694 insertions(+), 140 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 41941c8..6ff9387 100644
--- a/configure.ac
+++ b/configure.ac
@@ -238,6 +238,9 @@ extensions/image_viewer/data/ui/Makefile
extensions/list_tools/Makefile
extensions/list_tools/data/Makefile
extensions/list_tools/data/ui/Makefile
+extensions/rename_series/Makefile
+extensions/rename_series/data/Makefile
+extensions/rename_series/data/ui/Makefile
extensions/search/Makefile
extensions/search/data/Makefile
extensions/search/data/ui/Makefile
diff --git a/data/ui/overwrite-dialog.ui b/data/ui/overwrite-dialog.ui
new file mode 100644
index 0000000..0bdb162
--- /dev/null
+++ b/data/ui/overwrite-dialog.ui
@@ -0,0 +1,342 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkVBox" id="overwrite_dialog_box">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label124">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Overwrite the old file with the new one?</property>
+ <property name="justify">center</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="padding">5</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox46">
+ <property name="visible">True</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkVBox" id="vbox57">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame2">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkHBox" id="hbox110">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="old_image_frame">
+ <property name="width_request">256</property>
+ <property name="height_request">256</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label137">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Old File:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table15">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="old_image_size_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="old_image_time_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEventBox" id="old_image_filename_eventbox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="old_image_filename_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox58">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="frame3">
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <child>
+ <object class="GtkHBox" id="hbox111">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkFrame" id="new_image_frame">
+ <property name="width_request">256</property>
+ <property name="height_request">256</property>
+ <property name="visible">True</property>
+ <property name="label_xalign">0</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <child type="label">
+ <object class="GtkLabel" id="label138">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">New File:</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="table16">
+ <property name="visible">True</property>
+ <property name="n_rows">3</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="new_image_size_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="new_image_time_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEventBox" id="new_image_filename_eventbox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkLabel" id="new_image_filename_label">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="wrap">True</property>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options">GTK_FILL</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="padding">5</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHSeparator" id="hseparator1">
+ <property name="visible">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="overwrite_yes_radiobutton">
+ <property name="label" translatable="yes">Over_write the old file</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="overwrite_no_radiobutton">
+ <property name="label" translatable="yes">Do not overwrite _the old file</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">overwrite_yes_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="overwrite_all_radiobutton">
+ <property name="label" translatable="yes">Overwrite _all files</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">overwrite_yes_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkRadioButton" id="overwrite_none_radiobutton">
+ <property name="label" translatable="yes">_Do not overwrite any file</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">overwrite_yes_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox112">
+ <property name="visible">True</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkRadioButton" id="overwrite_rename_radiobutton">
+ <property name="label" translatable="yes">_Save the new file as:</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">overwrite_yes_radiobutton</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="overwrite_rename_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">7</property>
+ </packing>
+ </child>
+ </object>
+</interface>
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 25caf25..96d3bab 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = catalogs comments exiv2 file_manager file_tools file_viewer image_viewer list_tools search
+SUBDIRS = catalogs comments exiv2 file_manager file_tools file_viewer image_viewer list_tools rename_series search
-include $(top_srcdir)/git.mk
diff --git a/extensions/file_manager/actions.c b/extensions/file_manager/actions.c
index 2cfd948..10bce2b 100644
--- a/extensions/file_manager/actions.c
+++ b/extensions/file_manager/actions.c
@@ -333,7 +333,7 @@ gth_browser_activate_action_edit_paste (GtkAction *action,
paste_data = g_new0 (PasteData, 1);
paste_data->browser = g_object_ref (browser);
- paste_data->destination = g_object_ref (gth_browser_get_location (browser));
+ paste_data->destination = g_object_ref (gth_browser_get_location_data (browser));
gtk_clipboard_request_contents (gtk_widget_get_clipboard (GTK_WIDGET (browser), GDK_SELECTION_CLIPBOARD),
GNOME_COPIED_FILES,
@@ -361,13 +361,6 @@ gth_browser_activate_action_edit_duplicate (GtkAction *action,
}
-void
-gth_browser_activate_action_edit_rename (GtkAction *action,
- GthBrowser *browser)
-{
-}
-
-
static void
delete_file_permanently (GtkWindow *window,
GList *file_list)
@@ -513,7 +506,7 @@ gth_browser_activate_action_folder_open_in_file_manager (GtkAction *action,
gtk_get_current_event_time (),
&error))
{
- _gtk_error_dialog_from_gerror_run (GTK_WINDOW (browser), _("Could not open location"), &error);
+ _gtk_error_dialog_from_gerror_run (GTK_WINDOW (browser), _("Could not open the location"), &error);
}
g_free (uri);
diff --git a/extensions/file_manager/actions.h b/extensions/file_manager/actions.h
index efff79e..fefde72 100644
--- a/extensions/file_manager/actions.h
+++ b/extensions/file_manager/actions.h
@@ -33,7 +33,6 @@ DEFINE_ACTION(gth_browser_activate_action_edit_cut_files)
DEFINE_ACTION(gth_browser_activate_action_edit_copy_files)
DEFINE_ACTION(gth_browser_activate_action_edit_paste)
DEFINE_ACTION(gth_browser_activate_action_edit_duplicate)
-DEFINE_ACTION(gth_browser_activate_action_edit_rename)
DEFINE_ACTION(gth_browser_activate_action_edit_trash)
DEFINE_ACTION(gth_browser_activate_action_edit_delete)
DEFINE_ACTION(gth_browser_activate_action_folder_open_in_file_manager)
diff --git a/extensions/file_manager/callbacks.c b/extensions/file_manager/callbacks.c
index 5e7a0bb..fffdccd 100644
--- a/extensions/file_manager/callbacks.c
+++ b/extensions/file_manager/callbacks.c
@@ -37,7 +37,6 @@ static const char *vfs_ui_info =
" <menu name='Edit' action='EditMenu'>"
" <placeholder name='Folder_Actions'>"
" <menuitem action='Edit_Duplicate'/>"
-" <menuitem action='Edit_Rename'/>"
" <separator/>"
" <menuitem action='Edit_Trash'/>"
" <menuitem action='Edit_Delete'/>"
@@ -140,10 +139,6 @@ static GtkActionEntry action_entries[] = {
N_("D_uplicate"), "<control><shift>D",
N_("Duplicate the selected files"),
G_CALLBACK (gth_browser_activate_action_edit_duplicate) },
- { "Edit_Rename", NULL,
- N_("_Rename"), "F2",
- N_("Rename the selected files"),
- G_CALLBACK (gth_browser_activate_action_edit_rename) },
{ "Edit_Trash", "user-trash",
N_("Mo_ve to Trash"), "Delete",
N_("Move the selected files to the Trash"),
@@ -425,7 +420,6 @@ fm__gth_browser_update_sensitivity_cb (GthBrowser *browser)
set_action_sensitive (data, "Edit_Trash", sensitive);
set_action_sensitive (data, "Edit_Delete", sensitive);
set_action_sensitive (data, "Edit_Duplicate", sensitive);
- set_action_sensitive (data, "Edit_Rename", sensitive);
folder = gth_folder_tree_get_selected (GTH_FOLDER_TREE (gth_browser_get_folder_tree (browser)));
set_action_sensitive (data, "Folder_Create", (folder != NULL) && g_file_info_get_attribute_boolean (folder->info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE));
diff --git a/extensions/list_tools/actions.c b/extensions/list_tools/actions.c
index f967f3a..16128bc 100644
--- a/extensions/list_tools/actions.c
+++ b/extensions/list_tools/actions.c
@@ -28,8 +28,8 @@
void
-gth_browser_action_list_tools_edit_scripts (GtkAction *action,
- GthBrowser *browser)
+gth_browser_action_edit_scripts (GtkAction *action,
+ GthBrowser *browser)
{
dlg_personalize_scripts (browser);
}
diff --git a/extensions/list_tools/actions.h b/extensions/list_tools/actions.h
index e082239..aa55847 100644
--- a/extensions/list_tools/actions.h
+++ b/extensions/list_tools/actions.h
@@ -27,6 +27,6 @@
#define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
-DEFINE_ACTION(gth_browser_action_list_tools_edit_scripts)
+DEFINE_ACTION(gth_browser_action_edit_scripts)
#endif /* ACTIONS_H */
diff --git a/extensions/list_tools/callbacks.c b/extensions/list_tools/callbacks.c
index 91286e1..8d3eea4 100644
--- a/extensions/list_tools/callbacks.c
+++ b/extensions/list_tools/callbacks.c
@@ -63,7 +63,7 @@ static GtkActionEntry action_entries[] = {
{ "ListTools_EditScripts", GTK_STOCK_EDIT,
N_("Personalize..."), NULL,
NULL,
- G_CALLBACK (gth_browser_action_list_tools_edit_scripts) }
+ G_CALLBACK (gth_browser_action_edit_scripts) }
};
diff --git a/extensions/list_tools/gth-script-editor-dialog.c b/extensions/list_tools/gth-script-editor-dialog.c
index 0374ca4..ab6eb1c 100644
--- a/extensions/list_tools/gth-script-editor-dialog.c
+++ b/extensions/list_tools/gth-script-editor-dialog.c
@@ -146,7 +146,7 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
gtk_window_set_transient_for (GTK_WINDOW (self), parent);
gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
@@ -157,7 +157,7 @@ gth_script_editor_dialog_construct (GthScriptEditorDialog *self,
content = _gtk_builder_get_widget (self->priv->builder, "script_editor");
gtk_container_set_border_width (GTK_CONTAINER (content), 5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), content, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
g_signal_connect (GET_WIDGET ("command_entry"),
"icon-press",
diff --git a/extensions/list_tools/gth-script.c b/extensions/list_tools/gth-script.c
index d9258e9..ecb0443 100644
--- a/extensions/list_tools/gth-script.c
+++ b/extensions/list_tools/gth-script.c
@@ -423,7 +423,7 @@ gth_script_get_requested_attributes (GthScript *script)
char **b;
char *attributes;
- re = g_regex_new ("%prop\\{([^}]+)\\}", 0, 0, NULL);
+ re = g_regex_new ("%attr\\{([^}]+)\\}", 0, 0, NULL);
a = g_regex_split (re, script->priv->command, 0);
for (i = 0, n = 0; a[i] != NULL; i++)
if ((i > 0) && (i % 2 == 0))
@@ -663,12 +663,16 @@ create_attribute_list (GList *file_list,
GString *s;
GList *scan;
- re = g_regex_new ("%prop\\{([^}]+)\\}", 0, 0, NULL);
+ re = g_regex_new ("%attr\\{([^}]+)\\}", 0, 0, NULL);
a = g_regex_split (re, match, 0);
if (g_strv_length (a) >= 2)
attribute = g_strstrip (a[1]);
- if (attribute == NULL)
+
+ if (attribute == NULL) {
+ g_strfreev (a);
+ g_regex_unref (re);
return NULL;
+ }
s = g_string_new ("");
for (scan = file_list; scan; scan = scan->next) {
@@ -715,8 +719,8 @@ command_line_eval_cb (const GMatchInfo *info,
gpointer data)
{
ReplaceData *replace_data = data;
+ char *r = NULL;
char *match;
- char *r;
match = g_match_info_fetch (info, 0);
if (strcmp (match, "%U") == 0)
@@ -731,7 +735,7 @@ command_line_eval_cb (const GMatchInfo *info,
r = create_file_list (replace_data->file_list, get_ext_func, replace_data->quote_values);
else if (strcmp (match, "%P") == 0)
r = create_file_list (replace_data->file_list, get_parent_func, replace_data->quote_values);
- else if (strncmp (match, "%prop", 5) == 0) {
+ else if (strncmp (match, "%attr", 5) == 0) {
r = create_attribute_list (replace_data->file_list, match, replace_data->quote_values);
if (r == NULL)
*replace_data->error = g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_FAILED, _("Malformed command"));
diff --git a/extensions/rename_series/Makefile.am b/extensions/rename_series/Makefile.am
new file mode 100644
index 0000000..20230fe
--- /dev/null
+++ b/extensions/rename_series/Makefile.am
@@ -0,0 +1,36 @@
+SUBDIRS = data
+
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = librename_series.la
+
+librename_series_la_SOURCES = \
+ actions.c \
+ actions.h \
+ callbacks.c \
+ callbacks.h \
+ dlg-rename-series.c \
+ dlg-rename-series.h \
+ gth-rename-task.c \
+ gth-rename-task.h \
+ main.c
+
+librename_series_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb
+librename_series_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+librename_series_la_LIBADD = $(GTHUMB_LIBS)
+librename_series_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = rename_series.extension.in.in
+extensionini_DATA = $(extensionini_in_files:.extension.in.in=.extension)
+
+%.extension.in: %.extension.in.in $(extension_LTLIBRARIES)
+ sed -e "s|%LIBRARY%|`. ./$(extension_LTLIBRARIES) && echo $$dlname`|" \
+ $< > $@
+
+%.extension: %.extension.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(extensionini_in_files)
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/rename_series/actions.c b/extensions/rename_series/actions.c
new file mode 100644
index 0000000..bc5b8e3
--- /dev/null
+++ b/extensions/rename_series/actions.c
@@ -0,0 +1,43 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <gthumb.h>
+#include "dlg-rename-series.h"
+
+
+void
+gth_browser_activate_action_edit_rename (GtkAction *action,
+ GthBrowser *browser)
+{
+ GList *items;
+ GList *file_list;
+
+ items = gth_file_selection_get_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+ file_list = gth_file_list_get_files (GTH_FILE_LIST (gth_browser_get_file_list (browser)), items);
+ dlg_rename_series (browser, file_list);
+
+ _g_object_list_unref (file_list);
+ _gtk_tree_path_list_free (items);
+}
diff --git a/extensions/rename_series/actions.h b/extensions/rename_series/actions.h
new file mode 100644
index 0000000..7688d82
--- /dev/null
+++ b/extensions/rename_series/actions.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef ACTIONS_H
+#define ACTIONS_H
+
+#include <gtk/gtk.h>
+
+#define DEFINE_ACTION(x) void x (GtkAction *action, gpointer data);
+
+DEFINE_ACTION(gth_browser_activate_action_edit_rename)
+
+#endif /* ACTIONS_H */
diff --git a/extensions/rename_series/callbacks.c b/extensions/rename_series/callbacks.c
new file mode 100644
index 0000000..46cb978
--- /dev/null
+++ b/extensions/rename_series/callbacks.c
@@ -0,0 +1,163 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gthumb.h>
+#include "actions.h"
+
+
+#define BROWSER_DATA_KEY "rename-series-browser-data"
+
+
+static const char *vfs_ui_info =
+"<ui>"
+" <menubar name='MenuBar'>"
+" <menu name='Edit' action='EditMenu'>"
+" <placeholder name='Folder_Actions'>"
+" <menuitem action='Edit_Rename'/>"
+" </placeholder>"
+" </menu>"
+" </menubar>"
+"</ui>";
+
+
+static GtkActionEntry action_entries[] = {
+ { "Edit_Rename", NULL,
+ N_("_Rename"), "F2",
+ N_("Rename the selected files"),
+ G_CALLBACK (gth_browser_activate_action_edit_rename) },
+};
+
+
+typedef struct {
+ GtkActionGroup *action_group;
+ guint vfs_merge_id;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+ g_free (data);
+}
+
+
+static void
+set_action_sensitive (BrowserData *data,
+ const char *action_name,
+ gboolean sensitive)
+{
+ GtkAction *action;
+
+ action = gtk_action_group_get_action (data->action_group, action_name);
+ g_object_set (action, "sensitive", sensitive, NULL);
+}
+
+
+void
+rs__gth_browser_construct_cb (GthBrowser *browser)
+{
+ BrowserData *data;
+
+ g_return_if_fail (GTH_IS_BROWSER (browser));
+
+ data = g_new0 (BrowserData, 1);
+
+ data->action_group = gtk_action_group_new ("Rename Actions");
+ gtk_action_group_set_translation_domain (data->action_group, NULL);
+ gtk_action_group_add_actions (data->action_group,
+ action_entries,
+ G_N_ELEMENTS (action_entries),
+ browser);
+ gtk_ui_manager_insert_action_group (gth_browser_get_ui_manager (browser), data->action_group, 0);
+
+ g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+}
+
+
+static void
+file_manager_update_ui (BrowserData *data,
+ GthBrowser *browser)
+{
+ if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser))) {
+ if (data->vfs_merge_id == 0) {
+ GError *local_error = NULL;
+
+ data->vfs_merge_id = gtk_ui_manager_add_ui_from_string (gth_browser_get_ui_manager (browser), vfs_ui_info, -1, &local_error);
+ if (data->vfs_merge_id == 0) {
+ g_warning ("building ui failed: %s", local_error->message);
+ g_error_free (local_error);
+ }
+ }
+ }
+ else if (data->vfs_merge_id != 0) {
+ gtk_ui_manager_remove_ui (gth_browser_get_ui_manager (browser), data->vfs_merge_id);
+ data->vfs_merge_id = 0;
+ }
+}
+
+
+void
+rs__gth_browser_set_current_page_cb (GthBrowser *browser)
+{
+ BrowserData *data;
+
+ data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+ file_manager_update_ui (data, browser);
+}
+
+
+void
+rs__gth_browser_load_location_after_cb (GthBrowser *browser,
+ GFile *location,
+ const GError *error)
+{
+ BrowserData *data;
+
+ if (location == NULL)
+ return;
+
+ data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+ file_manager_update_ui (data, browser);
+}
+
+
+void
+rs__gth_browser_update_sensitivity_cb (GthBrowser *browser)
+{
+ BrowserData *data;
+ GthFileSource *file_source;
+ int n_selected;
+ gboolean sensitive;
+
+ data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+ g_return_if_fail (data != NULL);
+
+ file_source = gth_browser_get_location_source (browser);
+ n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+
+ sensitive = (n_selected > 0) && (file_source != NULL);
+ set_action_sensitive (data, "Edit_Rename", sensitive);
+}
diff --git a/extensions/rename_series/callbacks.h b/extensions/rename_series/callbacks.h
new file mode 100644
index 0000000..b882b43
--- /dev/null
+++ b/extensions/rename_series/callbacks.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef CALLBACKS_H
+#define CALLBACKS_H
+
+#include <gthumb.h>
+
+void rs__gth_browser_construct_cb (GthBrowser *browser);
+void rs__gth_browser_set_current_page_cb (GthBrowser *browser);
+void rs__gth_browser_load_location_after_cb (GthBrowser *browser,
+ GFile *location,
+ GError *error);
+void rs__gth_browser_update_sensitivity_cb (GthBrowser *browser);
+
+#endif /* CALLBACKS_H */
diff --git a/extensions/rename_series/data/Makefile.am b/extensions/rename_series/data/Makefile.am
new file mode 100644
index 0000000..4d5385d
--- /dev/null
+++ b/extensions/rename_series/data/Makefile.am
@@ -0,0 +1,2 @@
+SUBDIRS = ui
+-include $(top_srcdir)/git.mk
diff --git a/extensions/rename_series/data/ui/Makefile.am b/extensions/rename_series/data/ui/Makefile.am
new file mode 100644
index 0000000..9cc1d5f
--- /dev/null
+++ b/extensions/rename_series/data/ui/Makefile.am
@@ -0,0 +1,5 @@
+uidir = $(datadir)/gthumb/ui
+ui_DATA = rename-series.ui
+EXTRA_DIST = $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/rename_series/data/ui/rename-series.ui b/extensions/rename_series/data/ui/rename-series.ui
new file mode 100644
index 0000000..62a8931
--- /dev/null
+++ b/extensions/rename_series/data/ui/rename-series.ui
@@ -0,0 +1,514 @@
+<?xml version="1.0"?>
+<interface>
+ <requires lib="gtk+" version="2.16"/>
+ <!-- interface-naming-policy project-wide -->
+ <object class="GtkDialog" id="rename_series_dialog">
+ <property name="border_width">5</property>
+ <property name="title" translatable="yes">Rename</property>
+ <property name="type_hint">dialog</property>
+ <property name="has_separator">False</property>
+ <child internal-child="vbox">
+ <object class="GtkVBox" id="dialog-vbox1">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">2</property>
+ <child>
+ <object class="GtkVBox" id="vbox1">
+ <property name="visible">True</property>
+ <property name="border_width">6</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkTable" id="table1">
+ <property name="visible">True</property>
+ <property name="n_rows">5</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label7">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Start _at:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">start_at_spinbutton</property>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label5">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Sort by:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label123">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" comments="Translators: this is the text case (upper or lower case).">Cas_e:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="x_options">GTK_FILL</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="reverse_order_checkbutton">
+ <property name="label" translatable="yes">Re_verse Order</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_underline">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="sort_by_box">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="hbox2">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkSpinButton" id="start_at_spinbutton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="adjustment">start_at_adjustment</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkHBox" id="change_case_box">
+ <property name="visible">True</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ <property name="y_options"></property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox2">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkEntry" id="template_entry">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="invisible_char">●</property>
+ <property name="activates_default">True</property>
+ <property name="secondary_icon_stock">gtk-help</property>
+ <property name="secondary_icon_activatable">True</property>
+ <property name="secondary_icon_sensitive">True</property>
+ <property name="secondary_icon_tooltip_text">Help</property>
+ </object>
+ <packing>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkTable" id="template_help_table">
+ <property name="n_rows">6</property>
+ <property name="n_columns">2</property>
+ <property name="column_spacing">12</property>
+ <property name="row_spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label3">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label">#</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label2">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">%F</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label6">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">%E</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label9">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">New enumerator digit</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">1</property>
+ <property name="bottom_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label10">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The original filename</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">2</property>
+ <property name="bottom_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label11">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The original extension</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">3</property>
+ <property name="bottom_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label14">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Special code</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label15">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">Description</property>
+ <attributes>
+ <attribute name="weight" value="bold"/>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label16">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes" comments="Translate only 'attribute name'">%attr{ attribute name }</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label17">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">A file attribute</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">5</property>
+ <property name="bottom_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label18">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">%N</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="label19">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">The original enumerator</property>
+ <attributes>
+ <attribute name="size" value="8000"/>
+ </attributes>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ <property name="top_attach">4</property>
+ <property name="bottom_attach">5</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="right_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox3">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkLabel" id="label1">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Template:</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="x_options">GTK_FILL</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkVBox" id="vbox51">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkLabel" id="label69">
+ <property name="visible">True</property>
+ <property name="xalign">0</property>
+ <property name="label" translatable="yes">_Preview:</property>
+ <property name="use_markup">True</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="preview_scrolledwindow">
+ <property name="width_request">300</property>
+ <property name="height_request">200</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <placeholder/>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child internal-child="action_area">
+ <object class="GtkHButtonBox" id="dialog-action_area1">
+ <property name="visible">True</property>
+ <property name="layout_style">end</property>
+ <child>
+ <object class="GtkButton" id="cancel_button">
+ <property name="label">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="ok_button">
+ <property name="label" translatable="yes">_Rename</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="receives_default">True</property>
+ <property name="image">image1</property>
+ <property name="use_underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="help_button">
+ <property name="label">gtk-help</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ <property name="secondary">True</property>
+ </packing>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="pack_type">end</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ <action-widgets>
+ <action-widget response="0">cancel_button</action-widget>
+ <action-widget response="0">ok_button</action-widget>
+ <action-widget response="0">help_button</action-widget>
+ </action-widgets>
+ </object>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-ok</property>
+ </object>
+ <object class="GtkSizeGroup" id="sizegroup1">
+ <property name="mode">vertical</property>
+ <widgets>
+ <widget name="label1"/>
+ <widget name="template_entry"/>
+ </widgets>
+ </object>
+ <object class="GtkAdjustment" id="start_at_adjustment">
+ <property name="upper">1000000000</property>
+ <property name="step_increment">1</property>
+ <property name="page_increment">10</property>
+ <property name="page_size">10</property>
+ </object>
+</interface>
diff --git a/extensions/rename_series/dlg-rename-series.c b/extensions/rename_series/dlg-rename-series.c
new file mode 100644
index 0000000..bdc30c3
--- /dev/null
+++ b/extensions/rename_series/dlg-rename-series.c
@@ -0,0 +1,491 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "dlg-rename-series.h"
+#include "gth-rename-task.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+
+
+enum {
+ GTH_CHANGE_CASE_NONE = 0,
+ GTH_CHANGE_CASE_LOWER,
+ GTH_CHANGE_CASE_UPPER,
+};
+
+enum {
+ SORT_DATA_COLUMN,
+ SORT_NAME_COLUMN,
+ SORT_NUM_COLUMNS
+};
+
+enum {
+ PREVIEW_OLD_NAME_COLUMN,
+ PREVIEW_NEW_NAME_COLUMN,
+ PREVIEW_NUM_COLUMNS
+};
+
+
+typedef struct {
+ GthBrowser *browser;
+ GList *file_list;
+ GList *new_file_list;
+ GList *new_names_list;
+ gboolean single_file;
+ GtkBuilder *builder;
+ GtkWidget *dialog;
+ GtkWidget *list_view;
+ GtkWidget *sort_combobox;
+ GtkWidget *change_case_combobox;
+ GtkListStore *list_store;
+ GtkListStore *sort_model;
+ gboolean help_visible;
+} DialogData;
+
+
+static void
+destroy_cb (GtkWidget *widget,
+ DialogData *data)
+{
+ gth_browser_set_dialog (data->browser, "rename_series", NULL);
+
+ g_object_unref (data->builder);
+ _g_object_list_unref (data->file_list);
+ _g_string_list_free (data->new_names_list);
+ g_list_free (data->new_file_list);
+ g_free (data);
+}
+
+
+static void
+ok_clicked_cb (GtkWidget *widget,
+ DialogData *data)
+{
+ GList *old_files;
+ GList *new_files;
+ GList *scan1;
+ GList *scan2;
+ GthTask *task;
+
+ old_files = NULL;
+ new_files = NULL;
+
+ for (scan1 = data->new_file_list, scan2 = data->new_names_list;
+ scan1 && scan2;
+ scan1 = scan1->next, scan2 = scan2->next)
+ {
+ GthFileData *file_data = scan1->data;
+ char *new_name = scan2->data;
+ GFile *parent;
+ GFile *new_file;
+
+ parent = g_file_get_parent (file_data->file);
+ new_file = g_file_get_child (parent, new_name);
+
+ old_files = g_list_prepend (old_files, g_object_ref (file_data->file));
+ new_files = g_list_prepend (new_files, new_file);
+
+ g_object_unref (parent);
+ }
+ old_files = g_list_reverse (old_files);
+ new_files = g_list_reverse (new_files);
+
+ task = gth_rename_task_new (old_files, new_files);
+ gth_browser_exec_task (data->browser, task, FALSE);
+
+ gtk_widget_destroy (data->dialog);
+}
+
+
+typedef struct {
+ const char *template;
+ GthFileData *file_data;
+ int n;
+ GError **error;
+} TemplateData;
+
+
+static char *
+get_original_enum (GthFileData *file_data,
+ char *match)
+{
+ char *basename;
+ GRegex *re;
+ char **a;
+ char *value = NULL;
+
+ basename = g_file_get_basename (file_data->file);
+ re = g_regex_new ("([0-9]+)", 0, 0, NULL);
+ a = g_regex_split (re, basename, 0);
+ if (g_strv_length (a) >= 2)
+ value = g_strdup (g_strstrip (a[1]));
+
+ g_strfreev (a);
+ g_regex_unref (re);
+ g_free (basename);
+
+ return value;
+}
+
+
+static char *
+get_attribute_value (GthFileData *file_data,
+ char *match)
+{
+ GRegex *re;
+ char **a;
+ char *attribute = NULL;
+ char *value = NULL;
+
+ re = g_regex_new ("%attr\\{([^}]+)\\}", 0, 0, NULL);
+ a = g_regex_split (re, match, 0);
+ if (g_strv_length (a) >= 2)
+ attribute = g_strstrip (a[1]);
+
+ if ((attribute != NULL) && (*attribute != '\0')) {
+ value = gth_file_data_get_attribute_as_string (file_data, attribute);
+ if (value != NULL) {
+ char *tmp_value;
+
+ tmp_value = _g_utf8_replace (value, "[\r\n]", " ");
+ g_free (value);
+ value = tmp_value;
+ }
+ }
+
+ g_strfreev (a);
+ g_regex_unref (re);
+
+ return value;
+}
+
+
+static gboolean
+template_eval_cb (const GMatchInfo *info,
+ GString *res,
+ gpointer data)
+{
+ TemplateData *template_data = data;
+ char *r = NULL;
+ char *match;
+
+ match = g_match_info_fetch (info, 0);
+ if (strcmp (match, "%F") == 0) {
+ r = g_file_get_basename (template_data->file_data->file);
+ }
+ else if (strcmp (match, "%E") == 0) {
+ char *uri;
+
+ uri = g_file_get_uri (template_data->file_data->file);
+ r = g_strdup (_g_uri_get_file_extension (uri));
+
+ g_free (uri);
+ }
+ else if (strcmp (match, "%N") == 0) {
+ r = get_original_enum (template_data->file_data, match);
+ }
+ else if (strncmp (match, "%attr", 5) == 0) {
+ r = get_attribute_value (template_data->file_data, match);
+ /*if (r == NULL)
+ *template_data->error = g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_FAILED, _("Malformed template"));*/
+ }
+ else if (strncmp (match, "#", 1) == 0) {
+ char *format;
+
+ format = g_strdup_printf ("%%0%dd", strlen (match));
+ r = g_strdup_printf (format, template_data->n);
+
+ g_free (format);
+ }
+
+ if (r != NULL)
+ g_string_append (res, r);
+
+ g_free (r);
+ g_free (match);
+
+ return FALSE;
+}
+
+
+static void
+dlg_rename_series_update_preview (DialogData *data)
+{
+ GtkTreeIter iter;
+ int change_case;
+ TemplateData *template_data;
+ GRegex *re;
+ GList *scan;
+ GError *error = NULL;
+ GList *scan1, *scan2;
+
+ if (data->new_names_list != NULL) {
+ _g_string_list_free (data->new_names_list);
+ data->new_names_list = NULL;
+ }
+
+ if (data->new_file_list != NULL) {
+ g_list_free (data->new_file_list);
+ data->new_file_list = NULL;
+ }
+
+ data->new_file_list = g_list_copy (data->file_list);
+ if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (data->sort_combobox), &iter)) {
+ GthFileDataSort *sort_type;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (data->sort_model),
+ &iter,
+ SORT_DATA_COLUMN, &sort_type,
+ -1);
+
+ data->new_file_list = g_list_sort (data->new_file_list, (GCompareFunc) sort_type->cmp_func);
+ }
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("reverse_order_checkbutton"))))
+ data->new_file_list = g_list_reverse (data->new_file_list);
+
+ change_case = gtk_combo_box_get_active (GTK_COMBO_BOX (data->change_case_combobox));
+
+ template_data = g_new0 (TemplateData, 1);
+ template_data->error = &error;
+ template_data->n = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (GET_WIDGET ("start_at_spinbutton")));
+ template_data->template = gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("template_entry")));
+ re = g_regex_new ("#+|%F|%E|%N|%attr\\{[^}]+\\}", 0, 0, NULL);
+ for (scan = data->new_file_list; scan; scan = scan->next) {
+ char *new_name;
+ char *new_name2;
+
+ template_data->file_data = scan->data;
+ new_name = g_regex_replace_eval (re, template_data->template, -1, 0, 0, template_eval_cb, template_data, &error);
+ if (error != NULL)
+ break;
+
+ switch (change_case) {
+ case GTH_CHANGE_CASE_LOWER:
+ new_name2 = g_utf8_strdown (new_name, -1);
+ break;
+ case GTH_CHANGE_CASE_UPPER:
+ new_name2 = g_utf8_strup (new_name, -1);
+ break;
+ default:
+ new_name2 = g_strdup (new_name);
+ break;
+ }
+
+ data->new_names_list = g_list_prepend (data->new_names_list, new_name2);
+ template_data->n = template_data->n + 1;
+
+ g_free (new_name);
+ }
+ data->new_names_list = g_list_reverse (data->new_names_list);
+
+ if (error != NULL) {
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->dialog), _("Could not rename the files"), &error);
+ return;
+ }
+
+ /* -- update the list view -- */
+
+ gtk_list_store_clear (data->list_store);
+ for (scan1 = data->new_file_list, scan2 = data->new_names_list;
+ scan1 && scan2;
+ scan1 = scan1->next, scan2 = scan2->next)
+ {
+ GthFileData *file_data1 = scan1->data;
+ GthFileData *new_name = scan2->data;
+ GtkTreeIter iter;
+
+ gtk_list_store_append (data->list_store, &iter);
+ gtk_list_store_set (data->list_store, &iter,
+ PREVIEW_OLD_NAME_COLUMN, g_file_info_get_display_name (file_data1->info),
+ PREVIEW_NEW_NAME_COLUMN, new_name,
+ -1);
+ }
+}
+
+
+static void
+template_entry_icon_press_cb (GtkEntry *entry,
+ GtkEntryIconPosition icon_pos,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ DialogData *data = user_data;
+
+ data->help_visible = ! data->help_visible;
+
+ if (data->help_visible)
+ gtk_widget_show (GET_WIDGET("template_help_table"));
+ else
+ gtk_widget_hide (GET_WIDGET("template_help_table"));
+}
+
+
+static void
+update_preview_cb (GtkWidget *widget,
+ DialogData *data)
+{
+ dlg_rename_series_update_preview (data);
+}
+
+
+void
+dlg_rename_series (GthBrowser *browser,
+ GList *file_list)
+{
+ DialogData *data;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+ int i;
+ GList *scan;
+
+ if (gth_browser_get_dialog (browser, "rename_series") != NULL) {
+ gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "rename_series")));
+ return;
+ }
+
+ data = g_new0 (DialogData, 1);
+ data->browser = browser;
+ data->builder = _gtk_builder_new_from_file ("rename-series.ui", "rename_series");
+ data->file_list = gth_file_data_list_dup (file_list);
+
+ /* Get the widgets. */
+
+ data->dialog = _gtk_builder_get_widget (data->builder, "rename_series_dialog");
+ gth_browser_set_dialog (browser, "rename_series", data->dialog);
+ g_object_set_data (G_OBJECT (data->dialog), "dialog_data", data);
+
+ /* Set widgets data. */
+
+ data->list_store = gtk_list_store_new (PREVIEW_NUM_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_STRING);
+ data->list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (data->list_store));
+ g_object_unref (data->list_store);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("Old Name"),
+ renderer,
+ "text", PREVIEW_OLD_NAME_COLUMN,
+ NULL);
+ gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (data->list_view), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes (_("New Name"),
+ renderer,
+ "text", PREVIEW_NEW_NAME_COLUMN,
+ NULL);
+ gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (data->list_view), column);
+
+ gtk_widget_show (data->list_view);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("preview_scrolledwindow")), data->list_view);
+
+ /* sort by */
+
+ data->sort_model = gtk_list_store_new (SORT_NUM_COLUMNS,
+ G_TYPE_POINTER,
+ G_TYPE_STRING);
+ data->sort_combobox = gtk_combo_box_new_with_model (GTK_TREE_MODEL (data->sort_model));
+ g_object_unref (data->sort_model);
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (data->sort_combobox), renderer, TRUE);
+ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (data->sort_combobox),
+ renderer,
+ "text", SORT_NAME_COLUMN,
+ NULL);
+
+ for (i = 0, scan = gth_main_get_all_sort_types (); scan; scan = scan->next, i++) {
+ GthFileDataSort *sort_type = scan->data;
+ GtkTreeIter iter;
+
+ gtk_list_store_append (data->sort_model, &iter);
+ gtk_list_store_set (data->sort_model, &iter,
+ SORT_DATA_COLUMN, sort_type,
+ SORT_NAME_COLUMN, sort_type->display_name,
+ -1);
+ }
+ gtk_combo_box_set_active (GTK_COMBO_BOX (data->sort_combobox), 0);
+ gtk_widget_show (data->sort_combobox);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("sort_by_box")), data->sort_combobox);
+
+ /* change case */
+
+ data->change_case_combobox = _gtk_combo_box_new_with_texts (_("Keep original case"),
+ _("Convert to lower-case"),
+ _("Convert to upper-case"),
+ NULL);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (data->change_case_combobox), 0);
+ gtk_widget_show (data->change_case_combobox);
+ gtk_container_add (GTK_CONTAINER (GET_WIDGET ("change_case_box")), data->change_case_combobox);
+
+ dlg_rename_series_update_preview (data);
+
+ /* Set the signals handlers. */
+
+ g_signal_connect (G_OBJECT (data->dialog),
+ "destroy",
+ G_CALLBACK (destroy_cb),
+ data);
+ g_signal_connect (GET_WIDGET ("ok_button"),
+ "clicked",
+ G_CALLBACK (ok_clicked_cb),
+ data);
+ g_signal_connect_swapped (GET_WIDGET ("cancel_button"),
+ "clicked",
+ G_CALLBACK (gtk_widget_destroy),
+ G_OBJECT (data->dialog));
+ g_signal_connect (GET_WIDGET ("template_entry"),
+ "icon-press",
+ G_CALLBACK (template_entry_icon_press_cb),
+ data);
+ g_signal_connect (GET_WIDGET ("template_entry"),
+ "changed",
+ G_CALLBACK (update_preview_cb),
+ data);
+ g_signal_connect (GET_WIDGET ("start_at_spinbutton"),
+ "value_changed",
+ G_CALLBACK (update_preview_cb),
+ data);
+ g_signal_connect (data->sort_combobox,
+ "changed",
+ G_CALLBACK (update_preview_cb),
+ data);
+ g_signal_connect (data->change_case_combobox,
+ "changed",
+ G_CALLBACK (update_preview_cb),
+ data);
+ g_signal_connect (GET_WIDGET ("reverse_order_checkbutton"),
+ "toggled",
+ G_CALLBACK (update_preview_cb),
+ data);
+
+ /* Run dialog. */
+
+ gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (browser));
+ gtk_window_set_modal (GTK_WINDOW (data->dialog), FALSE);
+ gtk_widget_show (data->dialog);
+}
diff --git a/extensions/rename_series/dlg-rename-series.h b/extensions/rename_series/dlg-rename-series.h
new file mode 100644
index 0000000..ce085d2
--- /dev/null
+++ b/extensions/rename_series/dlg-rename-series.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DLG_RENAME_SERIES_H
+#define DLG_RENAME_SERIES_H
+
+#include <gthumb.h>
+
+void dlg_rename_series (GthBrowser *browser,
+ GList *file_list);
+
+#endif /* DLG_RENAME_SERIES_H */
diff --git a/extensions/rename_series/gth-rename-task.c b/extensions/rename_series/gth-rename-task.c
new file mode 100644
index 0000000..57c4266
--- /dev/null
+++ b/extensions/rename_series/gth-rename-task.c
@@ -0,0 +1,308 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include "gth-rename-task.h"
+
+
+struct _GthRenameTaskPrivate {
+ GList *old_files;
+ GList *new_files;
+ GList *current_old;
+ GList *current_new;
+ int n_files;
+ int n_current;
+ GFile *source;
+ GFile *destination;
+ GCancellable *cancellable;
+ GthOverwriteResponse default_response;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_rename_task_finalize (GObject *object)
+{
+ GthRenameTask *self;
+
+ self = GTH_RENAME_TASK (object);
+
+ g_object_unref (self->priv->cancellable);
+ _g_object_unref (self->priv->source);
+ _g_object_unref (self->priv->destination);
+ _g_object_list_unref (self->priv->old_files);
+ _g_object_list_unref (self->priv->new_files);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void _gth_rename_task_exec (GthRenameTask *self);
+
+
+static void
+_gth_rename_task_exec_next_file (GthRenameTask *self)
+{
+ self->priv->current_old = self->priv->current_old->next;
+ self->priv->current_new = self->priv->current_new->next;
+ self->priv->n_current++;
+
+ if (self->priv->current_old == NULL)
+ gth_task_completed (GTH_TASK (self), NULL);
+ else
+ _gth_rename_task_exec (self);
+}
+
+
+static void _gth_rename_task_try_rename (GthRenameTask *self,
+ GFile *source,
+ GFile *destination,
+ GFileCopyFlags copy_flags);
+
+
+static void
+overwrite_dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ gpointer user_data)
+{
+ GthRenameTask *self = user_data;
+
+ if (response_id != GTK_RESPONSE_OK)
+ self->priv->default_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
+ else
+ self->priv->default_response = gth_overwrite_dialog_get_response (GTH_OVERWRITE_DIALOG (dialog));
+
+ gtk_widget_hide (GTK_WIDGET (dialog));
+
+ switch (self->priv->default_response) {
+ case GTH_OVERWRITE_RESPONSE_NO:
+ case GTH_OVERWRITE_RESPONSE_ALWAYS_NO:
+ case GTH_OVERWRITE_RESPONSE_UNSPECIFIED:
+ _gth_rename_task_exec_next_file (self);
+ break;
+
+ case GTH_OVERWRITE_RESPONSE_YES:
+ case GTH_OVERWRITE_RESPONSE_ALWAYS_YES:
+ _gth_rename_task_try_rename (self,
+ self->priv->source,
+ self->priv->destination,
+ G_FILE_COPY_OVERWRITE);
+ break;
+
+ case GTH_OVERWRITE_RESPONSE_RENAME:
+ {
+ GFile *parent;
+ GFile *new_destination;
+
+ parent = g_file_get_parent (self->priv->destination);
+ new_destination = g_file_get_child_for_display_name (parent, gth_overwrite_dialog_get_filename (GTH_OVERWRITE_DIALOG (dialog)), NULL);
+ _gth_rename_task_try_rename (self, self->priv->source, new_destination, 0);
+
+ g_object_unref (new_destination);
+ g_object_unref (parent);
+ }
+ break;
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+
+static void
+_gth_rename_task_try_rename (GthRenameTask *self,
+ GFile *source,
+ GFile *destination,
+ GFileCopyFlags copy_flags)
+{
+ char *source_name;
+ char *destination_name;
+ char *details;
+ GError *error = NULL;
+
+ if (g_cancellable_set_error_if_cancelled (self->priv->cancellable, &error)) {
+ gth_task_completed (GTH_TASK (self), error);
+ return;
+ }
+
+ g_object_ref (source);
+ _g_object_unref (self->priv->source);
+ self->priv->source = source;
+
+ g_object_ref (destination);
+ _g_object_unref (self->priv->destination);
+ self->priv->destination = destination;
+
+ source_name = g_file_get_parse_name (source);
+ destination_name = g_file_get_parse_name (destination);
+ details = g_strdup_printf ("Renaming '%s' as '%s'", source_name, destination_name);
+ gth_task_progress (GTH_TASK (self),
+ _("Renaming files"),
+ details,
+ FALSE,
+ (double) self->priv->n_current / (self->priv->n_files + 1));
+
+ g_free (destination_name);
+ g_free (source_name);
+
+ if (self->priv->default_response == GTH_OVERWRITE_RESPONSE_ALWAYS_YES)
+ copy_flags = G_FILE_COPY_OVERWRITE;
+
+ if (! _g_move_file (source,
+ destination,
+ G_FILE_COPY_ALL_METADATA | copy_flags,
+ self->priv->cancellable,
+ NULL,
+ NULL,
+ &error))
+ {
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
+ if (self->priv->default_response != GTH_OVERWRITE_RESPONSE_ALWAYS_NO) {
+ GtkWidget *dialog;
+
+ dialog = gth_overwrite_dialog_new (source,
+ destination,
+ self->priv->default_response,
+ self->priv->n_files == 1);
+ g_signal_connect (dialog,
+ "response",
+ G_CALLBACK (overwrite_dialog_response_cb),
+ self);
+ gtk_widget_show (dialog);
+
+ return;
+ }
+ }
+ else {
+ gth_task_completed (GTH_TASK (self), error);
+ return;
+ }
+ }
+
+ _gth_rename_task_exec_next_file (self);
+}
+
+
+static void
+_gth_rename_task_exec (GthRenameTask *self)
+{
+ GFile *source;
+ GFile *destination;
+
+ if (self->priv->current_old == NULL) {
+ gth_task_completed (GTH_TASK (self), NULL);
+ return;
+ }
+
+ source = (GFile *) self->priv->current_old->data;
+ destination = (GFile *) self->priv->current_new->data;
+
+ _gth_rename_task_try_rename (self, source, destination, 0);
+}
+
+
+static void
+gth_rename_task_exec (GthTask *task)
+{
+ _gth_rename_task_exec (GTH_RENAME_TASK (task));
+}
+
+
+static void
+gth_rename_task_cancel (GthTask *task)
+{
+ g_cancellable_cancel (GTH_RENAME_TASK (task)->priv->cancellable);
+}
+
+
+static void
+gth_rename_task_class_init (GthRenameTaskClass *klass)
+{
+ GObjectClass *object_class;
+ GthTaskClass *task_class;
+
+ parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthRenameTaskPrivate));
+
+ object_class = G_OBJECT_CLASS (klass);
+ object_class->finalize = gth_rename_task_finalize;
+
+ task_class = GTH_TASK_CLASS (klass);
+ task_class->exec = gth_rename_task_exec;
+ task_class->cancel = gth_rename_task_cancel;
+}
+
+
+static void
+gth_rename_task_init (GthRenameTask *self)
+{
+ self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_RENAME_TASK, GthRenameTaskPrivate);
+ self->priv->cancellable = g_cancellable_new ();
+ self->priv->default_response = GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
+}
+
+
+GType
+gth_rename_task_get_type (void)
+{
+ static GType type = 0;
+
+ if (! type) {
+ GTypeInfo type_info = {
+ sizeof (GthRenameTaskClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gth_rename_task_class_init,
+ NULL,
+ NULL,
+ sizeof (GthRenameTask),
+ 0,
+ (GInstanceInitFunc) gth_rename_task_init
+ };
+
+ type = g_type_register_static (GTH_TYPE_TASK,
+ "GthRenameTask",
+ &type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+GthTask *
+gth_rename_task_new (GList *old_files,
+ GList *new_files)
+{
+ GthRenameTask *self;
+
+ self = GTH_RENAME_TASK (g_object_new (GTH_TYPE_RENAME_TASK, NULL));
+ self->priv->old_files = _g_object_list_ref (old_files);
+ self->priv->new_files = _g_object_list_ref (new_files);
+ self->priv->current_old = self->priv->old_files;
+ self->priv->current_new = self->priv->new_files;
+ self->priv->n_files = g_list_length (self->priv->old_files);
+ self->priv->n_current = 1;
+
+ return (GthTask *) self;
+}
diff --git a/extensions/rename_series/gth-rename-task.h b/extensions/rename_series/gth-rename-task.h
new file mode 100644
index 0000000..840e2a1
--- /dev/null
+++ b/extensions/rename_series/gth-rename-task.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_RENAME_TASK_H
+#define GTH_RENAME_TASK_H
+
+#include <glib.h>
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_RENAME_TASK (gth_rename_task_get_type ())
+#define GTH_RENAME_TASK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_RENAME_TASK, GthRenameTask))
+#define GTH_RENAME_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_RENAME_TASK, GthRenameTaskClass))
+#define GTH_IS_RENAME_TASK(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_RENAME_TASK))
+#define GTH_IS_RENAME_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_RENAME_TASK))
+#define GTH_RENAME_TASK_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_RENAME_TASK, GthRenameTaskClass))
+
+typedef struct _GthRenameTask GthRenameTask;
+typedef struct _GthRenameTaskClass GthRenameTaskClass;
+typedef struct _GthRenameTaskPrivate GthRenameTaskPrivate;
+
+struct _GthRenameTask {
+ GthTask __parent;
+ GthRenameTaskPrivate *priv;
+};
+
+struct _GthRenameTaskClass {
+ GthTaskClass __parent;
+};
+
+GType gth_rename_task_get_type (void);
+GthTask * gth_rename_task_new (GList *old_files, /* GFile */
+ GList *new_files /* GFile */);
+
+G_END_DECLS
+
+#endif /* GTH_RENAME_TASK_H */
diff --git a/extensions/rename_series/main.c b/extensions/rename_series/main.c
new file mode 100644
index 0000000..bd4d00a
--- /dev/null
+++ b/extensions/rename_series/main.c
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "callbacks.h"
+
+
+G_MODULE_EXPORT void
+gthumb_extension_activate (void)
+{
+ gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (rs__gth_browser_construct_cb), NULL);
+ gth_hook_add_callback ("gth-browser-set-current-page", 10, G_CALLBACK (rs__gth_browser_set_current_page_cb), NULL);
+ gth_hook_add_callback ("gth-browser-load-location-after", 10, G_CALLBACK (rs__gth_browser_load_location_after_cb), NULL);
+ gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (rs__gth_browser_update_sensitivity_cb), NULL);
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_deactivate (void)
+{
+}
+
+
+G_MODULE_EXPORT gboolean
+gthumb_extension_is_configurable (void)
+{
+ return FALSE;
+}
+
+
+G_MODULE_EXPORT void
+gthumb_extension_configure (GtkWindow *parent)
+{
+}
diff --git a/extensions/rename_series/rename_series.extension.in.in b/extensions/rename_series/rename_series.extension.in.in
new file mode 100644
index 0000000..9481ec1
--- /dev/null
+++ b/extensions/rename_series/rename_series.extension.in.in
@@ -0,0 +1,10 @@
+[Extension]
+_Name=Rename files
+_Description=Rename series of files.
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
+
+[Loader]
+Type=module
+File=%LIBRARY%
diff --git a/extensions/search/gth-search-editor-dialog.c b/extensions/search/gth-search-editor-dialog.c
index a668ca4..0cfbc0f 100644
--- a/extensions/search/gth-search-editor-dialog.c
+++ b/extensions/search/gth-search-editor-dialog.c
@@ -131,14 +131,14 @@ gth_search_editor_dialog_construct (GthSearchEditorDialog *self,
gtk_window_set_transient_for (GTK_WINDOW (self), parent);
gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
self->priv->builder = _gtk_builder_new_from_file ("search-editor.ui", "search");
content = _gtk_builder_get_widget (self->priv->builder, "search_editor");
gtk_container_set_border_width (GTK_CONTAINER (content), 5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), content, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
self->priv->match_type_combobox = gtk_combo_box_new_text ();
_gtk_combo_box_append_texts (GTK_COMBO_BOX (self->priv->match_type_combobox),
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index f415f7f..3f3deab 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -71,6 +71,7 @@ PUBLIC_HEADER_FILES = \
gth-monitor.h \
gth-multipage.h \
gth-nav-window.h \
+ gth-overwrite-dialog.h \
gth-pixbuf-task.h \
gth-preferences.h \
gth-progress-dialog.h \
@@ -180,6 +181,7 @@ gthumb_SOURCES = \
gth-monitor.c \
gth-multipage.c \
gth-nav-window.c \
+ gth-overwrite-dialog.c \
gth-pixbuf-task.c \
gth-preferences.c \
gth-progress-dialog.c \
diff --git a/gthumb/dlg-extensions.c b/gthumb/dlg-extensions.c
index b65fd00..0d7de83 100644
--- a/gthumb/dlg-extensions.c
+++ b/gthumb/dlg-extensions.c
@@ -230,6 +230,22 @@ add_columns (GtkTreeView *treeview,
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
+ /* the checkbox column */
+
+ column = gtk_tree_view_column_new ();
+ gtk_tree_view_column_set_title (column, _("Use"));
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (renderer,
+ "toggled",
+ G_CALLBACK (cell_renderer_toggle_toggled_cb),
+ data);
+
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer, extension_active_data_func_cb, data, NULL);
+
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+
/* the name column. */
column = gtk_tree_view_column_new ();
@@ -247,22 +263,6 @@ add_columns (GtkTreeView *treeview,
gtk_tree_view_column_set_expand (column, TRUE);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-
- /* the checkbox column */
-
- column = gtk_tree_view_column_new ();
- gtk_tree_view_column_set_title (column, _("Use"));
-
- renderer = gtk_cell_renderer_toggle_new ();
- g_signal_connect (renderer,
- "toggled",
- G_CALLBACK (cell_renderer_toggle_toggled_cb),
- data);
-
- gtk_tree_view_column_pack_start (column, renderer, TRUE);
- gtk_tree_view_column_set_cell_data_func (column, renderer, extension_active_data_func_cb, data, NULL);
-
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
}
@@ -384,6 +384,7 @@ dlg_extensions (GthBrowser *browser)
data->list_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (data->list_store));
g_object_unref (data->list_store);
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (data->list_view), TRUE);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (data->list_view), TRUE);
add_columns (GTK_TREE_VIEW (data->list_view), data);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (data->list_store), 0, extension_compare_func, NULL, NULL);
diff --git a/gthumb/gio-utils.c b/gthumb/gio-utils.c
index 6629906..832cdbb 100644
--- a/gthumb/gio-utils.c
+++ b/gthumb/gio-utils.c
@@ -1084,7 +1084,6 @@ g_copy_files_async (GList *sources,
GList *source_sidecars = NULL;
GList *destination_sidecars = NULL;
-
gth_hook_invoke ("add-sidecars", sources, &source_sidecars);
gth_hook_invoke ("add-sidecars", destinations, &destination_sidecars);
@@ -1501,6 +1500,66 @@ g_directory_copy_destination_info_ready_cb (GObject *source_object,
}
+gboolean
+_g_move_file (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error)
+{
+ GList *sources;
+ GList *destinations;
+ GList *source_sidecars = NULL;
+ GList *destination_sidecars = NULL;
+ GList *scan1;
+ GList *scan2;
+
+ if (! g_file_move (source,
+ destination,
+ flags,
+ cancellable,
+ progress_callback,
+ progress_callback_data,
+ error))
+ {
+ return FALSE;
+ }
+
+ if (flags && G_FILE_COPY_ALL_METADATA == 0)
+ return TRUE;
+
+ /* move the metadata sidecars if requested */
+
+ sources = g_list_prepend (NULL, source);
+ gth_hook_invoke ("add-sidecars", sources, &source_sidecars);
+ source_sidecars = g_list_reverse (source_sidecars);
+
+ destinations = g_list_prepend (NULL, destination);
+ gth_hook_invoke ("add-sidecars", destinations, &destination_sidecars);
+ destination_sidecars = g_list_reverse (destination_sidecars);
+
+ for (scan1 = source_sidecars, scan2 = destination_sidecars;
+ scan1 && scan2;
+ scan1 = scan1->next, scan2 = scan2->next)
+ {
+ source = scan1->data;
+ destination = scan2->data;
+
+ g_file_move (source, destination, 0, cancellable, NULL, NULL, NULL);
+ }
+
+ _g_object_list_unref (destination_sidecars);
+ g_list_free (destinations);
+ _g_object_list_unref (source_sidecars);
+ g_list_free (sources);
+
+
+ return TRUE;
+}
+
+
void
g_directory_copy_async (GFile *source,
GFile *destination,
diff --git a/gthumb/gio-utils.h b/gthumb/gio-utils.h
index 0bcf4e1..c72788c 100644
--- a/gthumb/gio-utils.h
+++ b/gthumb/gio-utils.h
@@ -130,6 +130,13 @@ void g_directory_copy_async (GFile *source,
gboolean _g_delete_files (GList *file_list,
gboolean include_metadata,
GError **error);
+gboolean _g_move_file (GFile *source,
+ GFile *destination,
+ GFileCopyFlags flags,
+ GCancellable *cancellable,
+ GFileProgressCallback progress_callback,
+ gpointer progress_callback_data,
+ GError **error);
gboolean g_load_file_in_buffer (GFile *file,
void **buffer,
gsize *size,
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index afd03a5..eaa40ad 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -488,7 +488,7 @@ gth_browser_update_sensitivity (GthBrowser *browser)
_gth_browser_set_action_sensitive (browser, "View_Stop", browser->priv->fullscreen || (browser->priv->activity_ref > 0));
_gth_browser_set_action_sensitive (browser, "View_Prev", current_file_pos > 0);
_gth_browser_set_action_sensitive (browser, "View_Next", (current_file_pos != -1) && (current_file_pos < n_files - 1));
- _gth_browser_set_action_sensitive (browser, "Edit_Metadata", n_selected > 0);
+ _gth_browser_set_action_sensitive (browser, "Edit_Metadata", n_selected == 1);
gth_sidebar_update_sensitivity (GTH_SIDEBAR (browser->priv->viewer_sidebar));
if (browser->priv->viewer_page != NULL)
@@ -1655,8 +1655,10 @@ _gth_browser_close (GthWindow *window)
{
GthBrowser *browser = (GthBrowser *) window;
- if (browser->priv->background_tasks != NULL)
+ if (browser->priv->background_tasks != NULL) {
+ gtk_window_present (GTK_WINDOW (browser->priv->progress_dialog));
return;
+ }
if (gth_browser_get_file_modified (browser))
_gth_browser_ask_whether_to_save (browser,
@@ -3071,6 +3073,13 @@ gth_browser_get_location (GthBrowser *browser)
GthFileData *
+gth_browser_get_location_data (GthBrowser *browser)
+{
+ return browser->priv->location;
+}
+
+
+GthFileData *
gth_browser_get_current_file (GthBrowser *browser)
{
return browser->priv->current_file;
diff --git a/gthumb/gth-browser.h b/gthumb/gth-browser.h
index 9c412d4..4aa8e82 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -68,6 +68,7 @@ struct _GthBrowserClass
GType gth_browser_get_type (void);
GtkWidget * gth_browser_new (const char *uri);
GFile * gth_browser_get_location (GthBrowser *browser);
+GthFileData * gth_browser_get_location_data (GthBrowser *browser);
GthFileData * gth_browser_get_current_file (GthBrowser *browser);
gboolean gth_browser_get_file_modified (GthBrowser *browser);
void gth_browser_go_to (GthBrowser *browser,
diff --git a/gthumb/gth-edit-metadata-dialog.c b/gthumb/gth-edit-metadata-dialog.c
index 189e52f..b741639 100644
--- a/gthumb/gth-edit-metadata-dialog.c
+++ b/gthumb/gth-edit-metadata-dialog.c
@@ -37,8 +37,8 @@ struct _GthEditMetadataDialogPrivate {
};
-static void
-gth_edit_metadata_dialog_class_init (GthEditMetadataDialogClass *klass)
+static void
+gth_edit_metadata_dialog_class_init (GthEditMetadataDialogClass *klass)
{
gth_edit_metadata_dialog_parent_class = g_type_class_peek_parent (klass);
g_type_class_add_private (klass, sizeof (GthEditMetadataDialogPrivate));
@@ -52,30 +52,30 @@ gth_edit_metadata_dialog_init (GthEditMetadataDialog *edit_metadata_dialog)
}
-GType
-gth_edit_metadata_dialog_get_type (void)
+GType
+gth_edit_metadata_dialog_get_type (void)
{
static GType type = 0;
-
+
if (type == 0) {
- static const GTypeInfo g_define_type_info = {
- sizeof (GthEditMetadataDialogClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) gth_edit_metadata_dialog_class_init,
- (GClassFinalizeFunc) NULL,
- NULL,
- sizeof (GthEditMetadataDialog),
- 0,
- (GInstanceInitFunc) gth_edit_metadata_dialog_init,
- NULL
+ static const GTypeInfo g_define_type_info = {
+ sizeof (GthEditMetadataDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gth_edit_metadata_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GthEditMetadataDialog),
+ 0,
+ (GInstanceInitFunc) gth_edit_metadata_dialog_init,
+ NULL
};
- type = g_type_register_static (GTK_TYPE_DIALOG,
- "GthEditMetadataDialog",
- &g_define_type_info,
+ type = g_type_register_static (GTK_TYPE_DIALOG,
+ "GthEditMetadataDialog",
+ &g_define_type_info,
0);
}
-
+
return type;
}
@@ -85,10 +85,10 @@ gth_edit_metadata_dialog_construct (GthEditMetadataDialog *self)
{
GArray *pages;
int i;
-
+
gtk_window_set_resizable (GTK_WINDOW (self), TRUE);
gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
@@ -97,25 +97,25 @@ gth_edit_metadata_dialog_construct (GthEditMetadataDialog *self)
self->priv->notebook = gtk_notebook_new ();
gtk_widget_show (self->priv->notebook);
gtk_container_set_border_width (GTK_CONTAINER (self->priv->notebook), 5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), self->priv->notebook, TRUE, TRUE, 0);
-
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), self->priv->notebook, TRUE, TRUE, 0);
+
pages = gth_main_get_type_set ("edit-metadata-dialog-page");
if (pages == NULL)
return;
-
+
for (i = 0; i < pages->len; i++) {
GType page_type;
GtkWidget *page;
-
+
page_type = g_array_index (pages, GType, i);
page = g_object_new (page_type, NULL);
if (! GTH_IS_EDIT_METADATA_PAGE (page)) {
g_object_unref (page);
continue;
}
-
+
gtk_widget_show (page);
- gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
+ gtk_notebook_append_page (GTK_NOTEBOOK (self->priv->notebook),
page,
gtk_label_new (gth_edit_metadata_page_get_name (GTH_EDIT_METADATA_PAGE (page))));
}
@@ -123,7 +123,7 @@ gth_edit_metadata_dialog_construct (GthEditMetadataDialog *self)
GtkWidget *
-gth_edit_metadata_dialog_new (void)
+gth_edit_metadata_dialog_new (void)
{
GthEditMetadataDialog *self;
@@ -141,17 +141,17 @@ gth_edit_metadata_dialog_set_file (GthEditMetadataDialog *dialog,
char *title;
GList *pages;
GList *scan;
-
+
if (file == NULL)
return;
-
+
title = g_strdup_printf (_("%s Properties"), g_file_info_get_display_name (file->info));
gtk_window_set_title (GTK_WINDOW (dialog), title);
-
+
pages = gtk_container_get_children (GTK_CONTAINER (dialog->priv->notebook));
- for (scan = pages; scan; scan = scan->next)
+ for (scan = pages; scan; scan = scan->next)
gth_edit_metadata_page_set_file (GTH_EDIT_METADATA_PAGE (scan->data), file);
-
+
g_list_free (pages);
g_free (title);
}
@@ -163,11 +163,11 @@ gth_edit_metadata_dialog_update_info (GthEditMetadataDialog *dialog,
{
GList *pages;
GList *scan;
-
+
pages = gtk_container_get_children (GTK_CONTAINER (dialog->priv->notebook));
- for (scan = pages; scan; scan = scan->next)
+ for (scan = pages; scan; scan = scan->next)
gth_edit_metadata_page_update_info (GTH_EDIT_METADATA_PAGE (scan->data), info);
-
+
g_list_free (pages);
}
@@ -175,21 +175,21 @@ gth_edit_metadata_dialog_update_info (GthEditMetadataDialog *dialog,
/* -- gth_edit_metadata_dialog_page -- */
-GType
+GType
gth_edit_metadata_page_get_type (void) {
static GType gth_edit_metadata_page_type_id = 0;
if (gth_edit_metadata_page_type_id == 0) {
- static const GTypeInfo g_define_type_info = {
- sizeof (GthEditMetadataPageIface),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) NULL,
- (GClassFinalizeFunc) NULL,
- NULL,
- 0,
- 0,
- (GInstanceInitFunc) NULL,
- NULL
+ static const GTypeInfo g_define_type_info = {
+ sizeof (GthEditMetadataPageIface),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) NULL,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ 0,
+ 0,
+ (GInstanceInitFunc) NULL,
+ NULL
};
gth_edit_metadata_page_type_id = g_type_register_static (G_TYPE_INTERFACE, "GthEditMetadataPageIface", &g_define_type_info, 0);
}
@@ -197,9 +197,9 @@ gth_edit_metadata_page_get_type (void) {
}
-void
+void
gth_edit_metadata_page_set_file (GthEditMetadataPage *self,
- GthFileData *file_data)
+ GthFileData *file_data)
{
GTH_EDIT_METADATA_PAGE_GET_INTERFACE (self)->set_file (self, file_data);
}
diff --git a/gthumb/gth-filter-editor-dialog.c b/gthumb/gth-filter-editor-dialog.c
index 55dd194..17298c8 100644
--- a/gthumb/gth-filter-editor-dialog.c
+++ b/gthumb/gth-filter-editor-dialog.c
@@ -170,14 +170,14 @@ gth_filter_editor_dialog_construct (GthFilterEditorDialog *self,
GList *scan;
GtkListStore *selection_model;
GtkCellRenderer *renderer;
-
+
if (title != NULL)
gtk_window_set_title (GTK_WINDOW (self), title);
if (parent != NULL)
gtk_window_set_transient_for (GTK_WINDOW (self), parent);
gtk_window_set_resizable (GTK_WINDOW (self), FALSE);
gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
@@ -187,7 +187,7 @@ gth_filter_editor_dialog_construct (GthFilterEditorDialog *self,
content = _gtk_builder_get_widget (self->priv->builder, "filter_editor");
gtk_container_set_border_width (GTK_CONTAINER (content), 5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), content, TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
/**/
@@ -220,7 +220,7 @@ gth_filter_editor_dialog_construct (GthFilterEditorDialog *self,
selection_model = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
self->priv->selection_combobox = gtk_combo_box_new_with_model (GTK_TREE_MODEL (selection_model));
g_object_unref (selection_model);
-
+
renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self->priv->selection_combobox),
renderer,
@@ -229,11 +229,11 @@ gth_filter_editor_dialog_construct (GthFilterEditorDialog *self,
renderer,
"text", SELECTION_COLUMN_NAME,
NULL);
-
+
for (scan = gth_main_get_all_sort_types (); scan; scan = scan->next) {
GthFileDataSort *sort_type = scan->data;
GtkTreeIter iter;
-
+
gtk_list_store_append (selection_model, &iter);
gtk_list_store_set (selection_model, &iter,
SELECTION_COLUMN_DATA, sort_type,
@@ -357,25 +357,25 @@ _gth_filter_editor_dialog_set_new_filter (GthFilterEditorDialog *self)
gboolean
-get_iter_for_sort_type (GthFilterEditorDialog *self,
- const char *sort_type_name,
+get_iter_for_sort_type (GthFilterEditorDialog *self,
+ const char *sort_type_name,
GtkTreeIter *iter)
{
GtkTreeModel *model;
-
+
model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->priv->selection_combobox));
-
+
if (! gtk_tree_model_get_iter_first (model, iter))
return FALSE;
do {
GthFileDataSort *sort_type;
-
+
gtk_tree_model_get (model, iter, SELECTION_COLUMN_DATA, &sort_type, -1);
if (g_strcmp0 (sort_type->name, sort_type_name) == 0)
return TRUE;
- }
+ }
while (gtk_tree_model_iter_next (model, iter));
-
+
return FALSE;
}
@@ -408,13 +408,13 @@ gth_filter_editor_dialog_set_filter (GthFilterEditorDialog *self,
self->priv->filter_visible = gth_test_is_visible (GTH_TEST (filter));
gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), gth_test_get_display_name (GTH_TEST (filter)));
-
+
chain = gth_filter_get_test (filter);
match_type = chain != NULL ? gth_test_chain_get_match_type (chain) : GTH_MATCH_TYPE_NONE;
-
+
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("match_checkbutton")), match_type != GTH_MATCH_TYPE_NONE);
gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->match_type_combobox), match_type == GTH_MATCH_TYPE_ANY ? 1 : 0);
-
+
_gtk_container_remove_children (GTK_CONTAINER (GET_WIDGET ("tests_box")), NULL, NULL);
if (match_type != GTH_MATCH_TYPE_NONE) {
GList *tests;
@@ -438,7 +438,7 @@ gth_filter_editor_dialog_set_filter (GthFilterEditorDialog *self,
if (limit_type != GTH_LIMIT_TYPE_NONE) {
char *value;
GtkTreeIter iter;
-
+
gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->limit_object_combobox), limit_type - 1);
if (limit_type == GTH_LIMIT_TYPE_SIZE) {
int sizes[] = { 1024, 1024 * 1024, 1024 * 1024 * 1024 };
@@ -513,7 +513,7 @@ gth_filter_editor_dialog_get_filter (GthFilterEditorDialog *self,
g_object_unref (test);
}
g_list_free (test_selectors);
-
+
gth_filter_set_test (filter, GTH_TEST_CHAIN (chain));
}
else
@@ -526,7 +526,7 @@ gth_filter_editor_dialog_get_filter (GthFilterEditorDialog *self,
GtkTreeIter iter;
GthFileDataSort *sort_type;
GtkSortType sort_direction;
-
+
size = atol (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("limit_size_entry"))));
idx = gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->limit_object_combobox));
if (idx == 0)
@@ -550,9 +550,9 @@ gth_filter_editor_dialog_get_filter (GthFilterEditorDialog *self,
&iter,
SELECTION_COLUMN_DATA, &sort_type,
-1);
-
+
sort_direction = gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->selection_order_combobox));
-
+
gth_filter_set_limit (filter, limit_type, size, sort_type->name, sort_direction);
}
diff --git a/gthumb/gth-overwrite-dialog.c b/gthumb/gth-overwrite-dialog.c
new file mode 100644
index 0000000..89f9990
--- /dev/null
+++ b/gthumb/gth-overwrite-dialog.c
@@ -0,0 +1,288 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include "glib-utils.h"
+#include "gth-image-viewer.h"
+#include "gth-metadata-provider.h"
+#include "gth-overwrite-dialog.h"
+#include "gtk-utils.h"
+
+
+static gpointer gth_overwrite_dialog_parent_class = NULL;
+
+
+struct _GthOverwriteDialogPrivate {
+ GtkBuilder *builder;
+ GFile *source;
+ GFile *destination;
+ GtkWidget *old_image_viewer;
+ GtkWidget *new_image_viewer;
+};
+
+
+static void
+gth_overwrite_dialog_finalize (GObject *object)
+{
+ GthOverwriteDialog *dialog;
+
+ dialog = GTH_OVERWRITE_DIALOG (object);
+
+ g_object_unref (dialog->priv->builder);
+ g_object_unref (dialog->priv->source);
+ g_object_unref (dialog->priv->destination);
+
+ G_OBJECT_CLASS (gth_overwrite_dialog_parent_class)->finalize (object);
+}
+
+
+static void
+gth_overwrite_dialog_class_init (GthOverwriteDialogClass *klass)
+{
+ gth_overwrite_dialog_parent_class = g_type_class_peek_parent (klass);
+ g_type_class_add_private (klass, sizeof (GthOverwriteDialogPrivate));
+
+ G_OBJECT_CLASS (klass)->finalize = gth_overwrite_dialog_finalize;
+}
+
+
+static void
+gth_overwrite_dialog_init (GthOverwriteDialog *dialog)
+{
+ dialog->priv = G_TYPE_INSTANCE_GET_PRIVATE (dialog, GTH_TYPE_OVERWRITE_DIALOG, GthOverwriteDialogPrivate);
+}
+
+
+GType
+gth_overwrite_dialog_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ static const GTypeInfo g_define_type_info = {
+ sizeof (GthOverwriteDialogClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gth_overwrite_dialog_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GthOverwriteDialog),
+ 0,
+ (GInstanceInitFunc) gth_overwrite_dialog_init,
+ NULL
+ };
+ type = g_type_register_static (GTK_TYPE_DIALOG,
+ "GthOverwriteDialog",
+ &g_define_type_info,
+ 0);
+ }
+
+ return type;
+}
+
+
+static void
+info_ready_cb (GList *files,
+ GError *error,
+ gpointer user_data)
+{
+ GthOverwriteDialog *self = user_data;
+ GthFileData *source;
+ GthFileData *destination;
+ char *text;
+ GTimeVal *timeval;
+ GIcon *icon;
+ GdkPixbuf *pixbuf;
+
+ if (error != NULL) {
+ _gtk_error_dialog_from_gerror_show (GTK_WINDOW (self), _("Cannot read file information"), &error);
+ return;
+ }
+
+ /* source */
+
+ source = files->data;
+
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "old_image_filename_label")), g_file_info_get_display_name (source->info));
+
+ text = g_format_size_for_display (g_file_info_get_size (source->info));
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "old_image_size_label")), text);
+ g_free (text);
+
+ timeval = gth_file_data_get_modification_time (source);
+ text = _g_time_val_to_exif_date (timeval);
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "old_image_time_label")), text);
+ g_free (text);
+
+ icon = (GIcon*) g_file_info_get_attribute_object (source->info, "preview::icon");
+ pixbuf = _g_icon_get_pixbuf (icon, 256, gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (self))));
+ if (pixbuf != NULL) {
+ gth_image_viewer_set_pixbuf (GTH_IMAGE_VIEWER (self->priv->old_image_viewer), pixbuf);
+ g_object_unref (pixbuf);
+ }
+
+ /* destination */
+
+ destination = files->next->data;
+
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_filename_label")), g_file_info_get_display_name (destination->info));
+
+ text = g_format_size_for_display (g_file_info_get_size (destination->info));
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_size_label")), text);
+ g_free (text);
+
+ timeval = gth_file_data_get_modification_time (destination);
+ text = _g_time_val_to_exif_date (timeval);
+ gtk_label_set_text (GTK_LABEL (_gtk_builder_get_widget (self->priv->builder, "new_image_time_label")), text);
+ g_free (text);
+
+ /**/
+}
+
+
+static void
+overwrite_rename_radiobutton_toggled_cb (GtkToggleButton *button,
+ gpointer user_data)
+{
+ GthOverwriteDialog *self = user_data;
+
+ gtk_widget_set_sensitive (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_entry"),
+ gtk_toggle_button_get_active (button));
+}
+
+
+static void
+gth_overwrite_dialog_construct (GthOverwriteDialog *self,
+ GthOverwriteResponse default_response,
+ gboolean single_file)
+{
+ GtkWidget *box;
+ GtkWidget *overwrite_radiobutton;
+ GList *files;
+
+ gtk_window_set_title (GTK_WINDOW (self), "");
+ gtk_window_set_resizable (GTK_WINDOW (self), TRUE);
+ gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (self), 5);
+
+ gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_OK, GTK_RESPONSE_OK);
+
+ self->priv->builder = _gtk_builder_new_from_file ("overwrite-dialog.ui", NULL);
+ box = _gtk_builder_get_widget (self->priv->builder, "overwrite_dialog_box");
+ gtk_widget_show (box);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), box, TRUE, TRUE, 0);
+
+ switch (default_response) {
+ case GTH_OVERWRITE_RESPONSE_YES:
+ overwrite_radiobutton = _gtk_builder_get_widget (self->priv->builder, "overwrite_yes_radiobutton");
+ break;
+ case GTH_OVERWRITE_RESPONSE_NO:
+ case GTH_OVERWRITE_RESPONSE_UNSPECIFIED:
+ overwrite_radiobutton = _gtk_builder_get_widget (self->priv->builder, "overwrite_no_radiobutton");
+ break;
+ case GTH_OVERWRITE_RESPONSE_ALWAYS_YES:
+ overwrite_radiobutton = _gtk_builder_get_widget (self->priv->builder, "overwrite_all_radiobutton");
+ break;
+ case GTH_OVERWRITE_RESPONSE_ALWAYS_NO:
+ overwrite_radiobutton = _gtk_builder_get_widget (self->priv->builder, "overwrite_none_radiobutton");
+ break;
+ case GTH_OVERWRITE_RESPONSE_RENAME:
+ overwrite_radiobutton = _gtk_builder_get_widget (self->priv->builder, "overwrite_rename_radiobutton");
+ break;
+ }
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (overwrite_radiobutton), TRUE);
+
+ if (single_file) {
+ gtk_widget_hide (_gtk_builder_get_widget (self->priv->builder, "overwrite_all_radiobutton"));
+ gtk_widget_hide (_gtk_builder_get_widget (self->priv->builder, "overwrite_none_radiobutton"));
+ }
+
+ gtk_widget_set_sensitive (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_entry"), default_response == GTH_OVERWRITE_RESPONSE_RENAME);
+ if (default_response == GTH_OVERWRITE_RESPONSE_RENAME)
+ gtk_widget_grab_focus (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_entry"));
+
+ self->priv->old_image_viewer = gth_image_viewer_new ();
+ gth_image_viewer_set_fit_mode (GTH_IMAGE_VIEWER (self->priv->old_image_viewer), GTH_FIT_SIZE_IF_LARGER);
+ gtk_widget_show (self->priv->old_image_viewer);
+ gtk_container_add (GTK_CONTAINER (_gtk_builder_get_widget (self->priv->builder, "old_image_frame")), self->priv->old_image_viewer);
+
+ self->priv->new_image_viewer = gth_image_viewer_new ();
+ gth_image_viewer_set_fit_mode (GTH_IMAGE_VIEWER (self->priv->new_image_viewer), GTH_FIT_SIZE_IF_LARGER);
+ gtk_widget_show (self->priv->new_image_viewer);
+ gtk_container_add (GTK_CONTAINER (_gtk_builder_get_widget (self->priv->builder, "new_image_frame")), self->priv->new_image_viewer);
+
+ g_signal_connect (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_radiobutton"),
+ "toggled",
+ G_CALLBACK (overwrite_rename_radiobutton_toggled_cb),
+ self);
+
+ files = NULL;
+ files = g_list_append (files, self->priv->source);
+ files = g_list_append (files, self->priv->destination);
+ _g_query_all_metadata_async (files, "standard::*,time::modified,time::modified-usec,preview::icon", NULL, info_ready_cb, self);
+
+ g_list_free (files);
+}
+
+
+GtkWidget *
+gth_overwrite_dialog_new (GFile *source,
+ GFile *destination,
+ GthOverwriteResponse default_respose,
+ gboolean single_file)
+{
+ GthOverwriteDialog *self;
+
+ self = g_object_new (GTH_TYPE_OVERWRITE_DIALOG, NULL);
+ self->priv->source = g_object_ref (source);
+ self->priv->destination = g_object_ref (destination);
+ gth_overwrite_dialog_construct (self, default_respose, single_file);
+
+ return (GtkWidget *) self;
+}
+
+
+GthOverwriteResponse
+gth_overwrite_dialog_get_response (GthOverwriteDialog *self)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "overwrite_yes_radiobutton"))))
+ return GTH_OVERWRITE_RESPONSE_YES;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "overwrite_no_radiobutton"))))
+ return GTH_OVERWRITE_RESPONSE_NO;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "overwrite_all_radiobutton"))))
+ return GTH_OVERWRITE_RESPONSE_ALWAYS_YES;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "overwrite_none_radiobutton"))))
+ return GTH_OVERWRITE_RESPONSE_ALWAYS_NO;
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_radiobutton"))))
+ return GTH_OVERWRITE_RESPONSE_RENAME;
+ return GTH_OVERWRITE_RESPONSE_UNSPECIFIED;
+}
+
+
+const char *
+gth_overwrite_dialog_get_filename (GthOverwriteDialog *self)
+{
+ return gtk_entry_get_text (GTK_ENTRY (_gtk_builder_get_widget (self->priv->builder, "overwrite_rename_entry")));
+}
diff --git a/gthumb/gth-overwrite-dialog.h b/gthumb/gth-overwrite-dialog.h
new file mode 100644
index 0000000..e198225
--- /dev/null
+++ b/gthumb/gth-overwrite-dialog.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ * GThumb
+ *
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_OVERWRITE_DIALOG_H
+#define GTH_OVERWRITE_DIALOG_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GTH_OVERWRITE_RESPONSE_UNSPECIFIED,
+ GTH_OVERWRITE_RESPONSE_YES,
+ GTH_OVERWRITE_RESPONSE_NO,
+ GTH_OVERWRITE_RESPONSE_ALWAYS_YES,
+ GTH_OVERWRITE_RESPONSE_ALWAYS_NO,
+ GTH_OVERWRITE_RESPONSE_RENAME
+} GthOverwriteResponse;
+
+#define GTH_TYPE_OVERWRITE_DIALOG (gth_overwrite_dialog_get_type ())
+#define GTH_OVERWRITE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_OVERWRITE_DIALOG, GthOverwriteDialog))
+#define GTH_OVERWRITE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_OVERWRITE_DIALOG, GthOverwriteDialogClass))
+#define GTH_IS_OVERWRITE_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_OVERWRITE_DIALOG))
+#define GTH_IS_OVERWRITE_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_OVERWRITE_DIALOG))
+#define GTH_OVERWRITE_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_OVERWRITE_DIALOG, GthOverwriteDialogClass))
+
+typedef struct _GthOverwriteDialog GthOverwriteDialog;
+typedef struct _GthOverwriteDialogClass GthOverwriteDialogClass;
+typedef struct _GthOverwriteDialogPrivate GthOverwriteDialogPrivate;
+
+struct _GthOverwriteDialog {
+ GtkDialog parent_instance;
+ GthOverwriteDialogPrivate *priv;
+};
+
+struct _GthOverwriteDialogClass {
+ GtkDialogClass parent_class;
+};
+
+GType gth_overwrite_dialog_get_type (void);
+GtkWidget * gth_overwrite_dialog_new (GFile *source,
+ GFile *destination,
+ GthOverwriteResponse default_respose,
+ gboolean single_file);
+GthOverwriteResponse gth_overwrite_dialog_get_response (GthOverwriteDialog *dialog);
+const char * gth_overwrite_dialog_get_filename (GthOverwriteDialog *dialog);
+
+G_END_DECLS
+
+#endif /* GTH_OVERWRITE_DIALOG_H */
diff --git a/gthumb/gth-progress-dialog.c b/gthumb/gth-progress-dialog.c
index 30f6491..685f714 100644
--- a/gthumb/gth-progress-dialog.c
+++ b/gthumb/gth-progress-dialog.c
@@ -262,7 +262,7 @@ gth_progress_dialog_init (GthProgressDialog *self)
gtk_window_set_title (GTK_WINDOW (self), "");
gtk_window_set_resizable (GTK_WINDOW (self), TRUE);
gtk_dialog_set_has_separator (GTK_DIALOG (self), FALSE);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (self)->vbox), 5);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
gtk_container_set_border_width (GTK_CONTAINER (self), 5);
gtk_dialog_add_button (GTK_DIALOG (self), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
@@ -270,7 +270,7 @@ gth_progress_dialog_init (GthProgressDialog *self)
self->priv->task_box = gtk_vbox_new (FALSE, 6);
gtk_widget_show (self->priv->task_box);
gtk_container_set_border_width (GTK_CONTAINER (self->priv->task_box), 5);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (self)->vbox), self->priv->task_box, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), self->priv->task_box, FALSE, FALSE, 0);
g_signal_connect (self, "response", G_CALLBACK (progress_dialog_response_cb), self);
g_signal_connect (self, "delete-event", G_CALLBACK (gtk_widget_hide_on_delete), self);
diff --git a/gthumb/gtk-utils.c b/gthumb/gtk-utils.c
index e1566e2..f1d1d1c 100644
--- a/gthumb/gtk-utils.c
+++ b/gthumb/gtk-utils.c
@@ -102,8 +102,8 @@ _gtk_message_dialog_new (GtkWindow *parent,
gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (d), 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (d)->vbox), 6);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d)->vbox), 8);
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), 6);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), 8);
/* Add label and image */
@@ -137,7 +137,7 @@ _gtk_message_dialog_new (GtkWindow *parent,
gtk_box_pack_start (GTK_BOX (hbox), label,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
hbox,
FALSE, FALSE, 0);
@@ -194,8 +194,8 @@ _gtk_request_dialog_run (GtkWindow *parent,
gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (d), 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (d)->vbox), 6);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d)->vbox), 12);
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), 6);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), 12);
/* Add label and image */
@@ -232,7 +232,7 @@ _gtk_request_dialog_run (GtkWindow *parent,
gtk_box_pack_start (GTK_BOX (hbox), vbox,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
hbox,
FALSE, FALSE, 0);
@@ -294,8 +294,8 @@ _gtk_yesno_dialog_new (GtkWindow *parent,
gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (d), 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (d)->vbox), 6);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d)->vbox), 8);
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), 6);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), 8);
/* Add label and image */
@@ -315,7 +315,7 @@ _gtk_yesno_dialog_new (GtkWindow *parent,
gtk_box_pack_start (GTK_BOX (hbox), label,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
hbox,
FALSE, FALSE, 0);
@@ -374,8 +374,8 @@ _gtk_yesno_dialog_with_checkbutton_new (GtkWindow *parent,
gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (d), 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (d)->vbox), 6);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d)->vbox), 8);
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), 6);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), 8);
/* Add label and image */
@@ -395,14 +395,14 @@ _gtk_yesno_dialog_with_checkbutton_new (GtkWindow *parent,
gtk_box_pack_start (GTK_BOX (hbox), label,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
hbox,
FALSE, FALSE, 0);
/* Add checkbutton */
check_button = gtk_check_button_new_with_mnemonic (check_button_label);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
check_button,
FALSE, FALSE, 0);
gtk_widget_show (check_button);
@@ -467,8 +467,8 @@ _gtk_message_dialog_with_checkbutton_new (GtkWindow *parent,
gtk_dialog_set_has_separator (GTK_DIALOG (d), FALSE);
gtk_container_set_border_width (GTK_CONTAINER (d), 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (d)->vbox), 6);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (d)->vbox), 8);
+ gtk_container_set_border_width (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (d))), 6);
+ gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))), 8);
/* Add label and image */
@@ -502,7 +502,7 @@ _gtk_message_dialog_with_checkbutton_new (GtkWindow *parent,
gtk_box_pack_start (GTK_BOX (hbox), label,
TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
hbox,
FALSE, FALSE, 0);
@@ -511,7 +511,7 @@ _gtk_message_dialog_with_checkbutton_new (GtkWindow *parent,
/* Add checkbutton */
check_button = gtk_check_button_new_with_mnemonic (check_button_label);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (d)->vbox),
+ gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (d))),
check_button,
FALSE, FALSE, 0);
gtk_widget_show (check_button);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]