[gthumb/ext] added the "resize images" tool



commit 4316810dcbccfc1d6d293438f936b611d52bb483
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Oct 4 18:37:18 2009 +0200

    added the "resize images" tool

 configure.ac                                       |    3 +
 extensions/Makefile.am                             |    1 +
 extensions/resize_images/Makefile.am               |   34 ++
 extensions/resize_images/actions.c                 |   43 +++
 extensions/resize_images/actions.h                 |   32 ++
 extensions/resize_images/callbacks.c               |  107 +++++++
 extensions/resize_images/callbacks.h               |   31 ++
 extensions/resize_images/data/Makefile.am          |   18 +
 .../data/gthumb_resize_images.schemas.in           |   65 ++++
 extensions/resize_images/data/ui/Makefile.am       |    5 +
 extensions/resize_images/data/ui/resize-images.ui  |  328 ++++++++++++++++++++
 extensions/resize_images/dlg-resize-images.c       |  222 +++++++++++++
 extensions/resize_images/dlg-resize-images.h       |   33 ++
 extensions/resize_images/main.c                    |   54 ++++
 extensions/resize_images/preferences.h             |   37 +++
 .../resize_images/resize_images.extension.in.in    |   10 +
 gthumb/Makefile.am                                 |    2 +
 gthumb/gth-main.c                                  |    1 +
 gthumb/gth-pixbuf-list-task.c                      |  318 +++++++++++++++++++
 gthumb/gth-pixbuf-list-task.h                      |   59 ++++
 gthumb/typedefs.h                                  |   14 +
 21 files changed, 1417 insertions(+), 0 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 784dc58..b6a0fe4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -283,6 +283,9 @@ extensions/red_eye_removal/data/ui/Makefile
 extensions/rename_series/Makefile
 extensions/rename_series/data/Makefile
 extensions/rename_series/data/ui/Makefile
+extensions/resize_images/Makefile
+extensions/resize_images/data/Makefile
+extensions/resize_images/data/ui/Makefile
 extensions/search/Makefile
 extensions/search/data/Makefile
 extensions/search/data/ui/Makefile
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 4383bf1..aa92000 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -11,6 +11,7 @@ SUBDIRS = 		\
 	photo_importer	\
 	red_eye_removal	\
 	rename_series 	\
+	resize_images	\
 	search		\
 	slideshow
 
diff --git a/extensions/resize_images/Makefile.am b/extensions/resize_images/Makefile.am
new file mode 100644
index 0000000..dff2abb
--- /dev/null
+++ b/extensions/resize_images/Makefile.am
@@ -0,0 +1,34 @@
+SUBDIRS = data
+
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = libresize_images.la
+
+libresize_images_la_SOURCES = 		\
+	actions.c			\
+	actions.h			\
+	callbacks.c			\
+	callbacks.h			\
+	dlg-resize-images.c		\
+	dlg-resize-images.h		\
+	main.c
+
+libresize_images_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+libresize_images_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libresize_images_la_LIBADD = $(GTHUMB_LIBS)
+libresize_images_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = resize_images.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/resize_images/actions.c b/extensions/resize_images/actions.c
new file mode 100644
index 0000000..a61abf0
--- /dev/null
+++ b/extensions/resize_images/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-resize-images.h"
+
+
+void
+gth_browser_activate_action_tool_resize_images (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_resize_images (browser, file_list);
+
+	_g_object_list_unref (file_list);
+	_gtk_tree_path_list_free (items);
+}
diff --git a/extensions/resize_images/actions.h b/extensions/resize_images/actions.h
new file mode 100644
index 0000000..37c926b
--- /dev/null
+++ b/extensions/resize_images/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_tool_resize_images)
+
+#endif /* ACTIONS_H */
diff --git a/extensions/resize_images/callbacks.c b/extensions/resize_images/callbacks.c
new file mode 100644
index 0000000..100a71d
--- /dev/null
+++ b/extensions/resize_images/callbacks.c
@@ -0,0 +1,107 @@
+/* -*- 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 "resize-images-browser-data"
+
+
+static const char *fixed_ui_info =
+"<ui>"
+"  <popup name='ListToolsPopup'>"
+"    <placeholder name='Tools'>"
+"      <menuitem name='ResizeImages' action='Tool_ResizeImages'/>"
+"    </placeholder>"
+"  </popup>"
+"</ui>";
+
+
+static GtkActionEntry action_entries[] = {
+	{ "Tool_ResizeImages", NULL,
+	  N_("Re_size Images"), NULL,
+	  N_("Resize the selected images"),
+	  G_CALLBACK (gth_browser_activate_action_tool_resize_images) },
+};
+
+
+typedef struct {
+	GtkActionGroup *action_group;
+} BrowserData;
+
+
+static void
+browser_data_free (BrowserData *data)
+{
+	g_free (data);
+}
+
+
+void
+ri__gth_browser_construct_cb (GthBrowser *browser)
+{
+	BrowserData *data;
+	GError      *error = NULL;
+
+	g_return_if_fail (GTH_IS_BROWSER (browser));
+
+	data = g_new0 (BrowserData, 1);
+
+	data->action_group = gtk_action_group_new ("Resize Images 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);
+
+	if (! gtk_ui_manager_add_ui_from_string (gth_browser_get_ui_manager (browser), fixed_ui_info, -1, &error)) {
+		g_message ("building menus failed: %s", error->message);
+		g_clear_error (&error);
+	}
+
+	g_object_set_data_full (G_OBJECT (browser), BROWSER_DATA_KEY, data, (GDestroyNotify) browser_data_free);
+}
+
+
+void
+ri__gth_browser_update_sensitivity_cb (GthBrowser *browser)
+{
+	BrowserData *data;
+	GtkAction   *action;
+	int          n_selected;
+	gboolean     sensitive;
+
+	data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
+	g_return_if_fail (data != NULL);
+
+	n_selected = gth_file_selection_get_n_selected (GTH_FILE_SELECTION (gth_browser_get_file_list_view (browser)));
+	sensitive = n_selected > 0;
+
+	action = gtk_action_group_get_action (data->action_group, "Tool_ResizeImages");
+	g_object_set (action, "sensitive", sensitive, NULL);
+}
diff --git a/extensions/resize_images/callbacks.h b/extensions/resize_images/callbacks.h
new file mode 100644
index 0000000..5280ce2
--- /dev/null
+++ b/extensions/resize_images/callbacks.h
@@ -0,0 +1,31 @@
+/* -*- 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  ri__gth_browser_construct_cb            (GthBrowser *browser);
+void  ri__gth_browser_update_sensitivity_cb   (GthBrowser *browser);
+
+#endif /* CALLBACKS_H */
diff --git a/extensions/resize_images/data/Makefile.am b/extensions/resize_images/data/Makefile.am
new file mode 100644
index 0000000..6f80a99
--- /dev/null
+++ b/extensions/resize_images/data/Makefile.am
@@ -0,0 +1,18 @@
+SUBDIRS = ui
+
+schemadir = @GCONF_SCHEMA_FILE_DIR@
+schema_in_files = gthumb_resize_images.schemas.in
+schema_DATA = $(schema_in_files:.schemas.in=.schemas)
+
+ INTLTOOL_SCHEMAS_RULE@
+
+if GCONF_SCHEMAS_INSTALL
+install-data-local:
+	GCONF_CONFIG_SOURCE=$(GCONF_SCHEMA_CONFIG_SOURCE) $(GCONFTOOL) --makefile-install-rule $(top_builddir)/extensions/resize_images/data/$(schema_DATA)
+endif
+
+EXTRA_DIST = $(schema_in_files)
+
+CLEANFILES = $(schema_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/resize_images/data/gthumb_resize_images.schemas.in b/extensions/resize_images/data/gthumb_resize_images.schemas.in
new file mode 100644
index 0000000..318d733
--- /dev/null
+++ b/extensions/resize_images/data/gthumb_resize_images.schemas.in
@@ -0,0 +1,65 @@
+<gconfschemafile>
+    <schemalist>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/resize_images/width</key>
+	<applyto>/apps/gthumb/ext/resize_images/width</applyto>
+	<owner>gthumb</owner>
+	<type>int</type>
+	<default>640</default>
+	<locale name="C">
+	  <short></short>
+	  <long></long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/resize_images/height</key>
+	<applyto>/apps/gthumb/ext/resize_images/height</applyto>
+	<owner>gthumb</owner>
+	<type>int</type>
+	<default>480</default>
+	<locale name="C">
+	  <short></short>
+	  <long></long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/resize_images/unit</key>
+	<applyto>/apps/gthumb/ext/resize_images/unit</applyto>
+	<owner>gthumb</owner>
+	<type>string</type>
+	<default>%</default>
+	<locale name="C">
+	  <short>Possible values: pixels, percentage</short>
+	  <long></long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/resize_images/keep_aspect_ratio</key>
+	<applyto>/apps/gthumb/ext/resize_images/keep_aspect_ratio</applyto>
+	<owner>gthumb</owner>
+	<type>bool</type>
+	<default>true</default>
+	<locale name="C">
+	  <short></short>
+	  <long></long>
+	</locale>
+      </schema>
+
+      <schema>
+	<key>/schemas/apps/gthumb/ext/resize_images/allow_swap_width_height</key>
+	<applyto>/apps/gthumb/ext/resize_images/allow_swap_width_height</applyto>
+	<owner>gthumb</owner>
+	<type>bool</type>
+	<default>true</default>
+	<locale name="C">
+	  <short></short>
+	  <long></long>
+	</locale>
+      </schema>
+
+    </schemalist>
+</gconfschemafile>
diff --git a/extensions/resize_images/data/ui/Makefile.am b/extensions/resize_images/data/ui/Makefile.am
new file mode 100644
index 0000000..660fbd7
--- /dev/null
+++ b/extensions/resize_images/data/ui/Makefile.am
@@ -0,0 +1,5 @@
+uidir = $(datadir)/gthumb-2.0/ui
+ui_DATA = resize-images.ui
+EXTRA_DIST = $(ui_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/resize_images/data/ui/resize-images.ui b/extensions/resize_images/data/ui/resize-images.ui
new file mode 100644
index 0000000..d94a02e
--- /dev/null
+++ b/extensions/resize_images/data/ui/resize-images.ui
@@ -0,0 +1,328 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy toplevel-contextual -->
+  <object class="GtkAdjustment" id="width_adjustment">
+    <property name="value">2</property>
+    <property name="lower">2</property>
+    <property name="upper">10000</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="height_adjustment">
+    <property name="value">2</property>
+    <property name="lower">2</property>
+    <property name="upper">10000</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkListStore" id="overwrite_model">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">Skip</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Rename</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Ask</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">Overwrite</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkDialog" id="resize_images_dialog">
+    <property name="border_width">6</property>
+    <property name="title" translatable="yes">Resize Images</property>
+    <property name="resizable">False</property>
+    <property name="type_hint">dialog</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox8">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkVBox" id="vbox61">
+            <property name="visible">True</property>
+            <property name="border_width">6</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkVBox" id="vbox63">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="label106">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">&lt;b&gt;New dimensions&lt;/b&gt;</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox72">
+                    <property name="visible">True</property>
+                    <child>
+                      <object class="GtkLabel" id="label105">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">    </property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkVBox" id="vbox62">
+                        <property name="visible">True</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
+                        <child>
+                          <object class="GtkTable" id="table8">
+                            <property name="visible">True</property>
+                            <property name="n_rows">2</property>
+                            <property name="n_columns">3</property>
+                            <property name="column_spacing">12</property>
+                            <property name="row_spacing">6</property>
+                            <child>
+                              <object class="GtkLabel" id="label103">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Width:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">width_spinbutton</property>
+                              </object>
+                              <packing>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label104">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">_Height:</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">height_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="GtkSpinButton" id="width_spinbutton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="adjustment">width_adjustment</property>
+                                <property name="climb_rate">1</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSpinButton" id="height_spinbutton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="adjustment">height_adjustment</property>
+                                <property name="climb_rate">1</property>
+                              </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="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <placeholder/>
+                            </child>
+                            <child>
+                              <object class="GtkComboBox" id="unit_combobox">
+                                <property name="visible">True</property>
+                                <property name="model">unit_model</property>
+                                <property name="active">0</property>
+                                <child>
+                                  <object class="GtkCellRendererText" id="size_renderer"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="left_attach">2</property>
+                                <property name="right_attach">3</property>
+                                <property name="x_options">GTK_FILL</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkCheckButton" id="keep_ratio_checkbutton">
+                            <property name="label" translatable="yes">_Keep aspect ratio</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">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area8">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <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="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+                <property name="secondary">True</property>
+              </packing>
+            </child>
+            <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="can_default">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">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="ok_button">
+                <property name="label">gtk-ok</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>
+              </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="-11">help_button</action-widget>
+      <action-widget response="-6">cancel_button</action-widget>
+      <action-widget response="0">ok_button</action-widget>
+    </action-widgets>
+  </object>
+  <object class="GtkImage" id="ok_image">
+    <property name="visible">True</property>
+    <property name="stock">gtk-ok</property>
+  </object>
+  <object class="GtkListStore" id="unit_model">
+    <columns>
+      <!-- column-name gchararray -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">pixel</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">%</col>
+      </row>
+    </data>
+  </object>
+  <object class="GtkListStore" id="type_model">
+    <columns>
+      <!-- column-name gchararray1 -->
+      <column type="gchararray"/>
+    </columns>
+    <data>
+      <row>
+        <col id="0" translatable="yes">JPEG</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">PNG</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">TIFF</col>
+      </row>
+      <row>
+        <col id="0" translatable="yes">TGA</col>
+      </row>
+    </data>
+  </object>
+</interface>
diff --git a/extensions/resize_images/dlg-resize-images.c b/extensions/resize_images/dlg-resize-images.c
new file mode 100644
index 0000000..e850a18
--- /dev/null
+++ b/extensions/resize_images/dlg-resize-images.c
@@ -0,0 +1,222 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2005-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-resize-images.h"
+#include "preferences.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+#define DEFAULT_FILE_TYPE "jpeg"
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+
+GthUnit units[] = { GTH_UNIT_PIXELS, GTH_UNIT_PERCENTAGE };
+
+
+typedef struct {
+	GthBrowser *browser;
+	GList      *file_list;
+	GtkBuilder *builder;
+	GtkWidget  *dialog;
+} DialogData;
+
+
+typedef struct {
+	int       width;
+	int       height;
+	GthUnit   unit;
+	gboolean  keep_aspect_ratio;
+	gboolean  allow_swap;
+} ResizeData;
+
+
+static void
+destroy_cb (GtkWidget  *widget,
+	    DialogData *data)
+{
+	gth_browser_set_dialog (data->browser, "resize_images", NULL);
+
+	g_object_unref (data->builder);
+	_g_object_list_unref (data->file_list);
+	g_free (data);
+}
+
+
+static void
+resize_step (GthPixbufTask *pixbuf_task)
+{
+	ResizeData *resize_data = pixbuf_task->data;
+	int         w, h;
+	int         new_w, new_h;
+	int         max_w, max_h;
+
+	w = gdk_pixbuf_get_width (pixbuf_task->src);
+	h = gdk_pixbuf_get_height (pixbuf_task->src);
+
+	if (resize_data->allow_swap
+	    && (((h > w) && (resize_data->width > resize_data->height))
+		|| ((h < w) && (resize_data->width < resize_data->height))))
+	{
+		max_w = resize_data->height;
+		max_h = resize_data->width;
+	}
+	else {
+		max_w = resize_data->width;
+		max_h = resize_data->height;
+	}
+
+	if (resize_data->unit == GTH_UNIT_PERCENTAGE) {
+		new_w = w * ((double) max_w / 100.0);
+		new_h = h * ((double) max_h / 100.0);
+	}
+	else if (resize_data->keep_aspect_ratio) {
+		new_w = w;
+		new_h = h;
+		scale_keeping_ratio (&new_w, &new_h, max_w, max_h, TRUE);
+	}
+	else {
+		new_w = max_w;
+		new_h = max_h;
+	}
+
+	if ((new_w > 1) && (new_h > 1)) {
+		if (pixbuf_task->dest != NULL)
+			g_object_unref (pixbuf_task->dest);
+		pixbuf_task->dest = _gdk_pixbuf_scale_simple_safe (pixbuf_task->src, new_w, new_h, GDK_INTERP_BILINEAR);
+	}
+	else
+		pixbuf_task->dest = NULL;
+}
+
+
+static void
+ok_clicked_cb (GtkWidget  *widget,
+	       DialogData *data)
+{
+	ResizeData *resize_data;
+	GthTask    *resize_task;
+	GthTask    *list_task;
+
+	resize_data = g_new0 (ResizeData, 1);
+	resize_data->width = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("width_spinbutton")));
+	resize_data->height = gtk_spin_button_get_value (GTK_SPIN_BUTTON (GET_WIDGET ("height_spinbutton")));
+	resize_data->unit = units[gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")))];
+	resize_data->keep_aspect_ratio = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_ratio_checkbutton")));
+	resize_data->allow_swap = FALSE;
+
+	eel_gconf_set_integer (PREF_RESIZE_IMAGES_SERIES_WIDTH, resize_data->width);
+	eel_gconf_set_integer (PREF_RESIZE_IMAGES_SERIES_HEIGHT, resize_data->height);
+	eel_gconf_set_enum (PREF_RESIZE_IMAGES_UNIT, GTH_TYPE_UNIT, resize_data->unit);
+	eel_gconf_set_boolean (PREF_RESIZE_IMAGES_KEEP_RATIO, resize_data->keep_aspect_ratio);
+
+	resize_task = gth_pixbuf_task_new (_("Resizing images"),
+					   TRUE,
+					   NULL,
+					   resize_step,
+					   NULL,
+					   resize_data,
+					   g_free);
+	list_task = gth_pixbuf_list_task_new (data->browser,
+					      data->file_list,
+					      GTH_PIXBUF_TASK (resize_task));
+	gth_browser_exec_task (data->browser, list_task, FALSE);
+
+	g_object_unref (list_task);
+	g_object_unref (resize_task);
+	gtk_widget_destroy (data->dialog);
+}
+
+
+static void
+update_sensitivity (DialogData *data)
+{
+	gtk_widget_set_sensitive (GET_WIDGET ("keep_ratio_checkbutton"), units[gtk_combo_box_get_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")))] != GTH_UNIT_PERCENTAGE);
+}
+
+
+static void
+unit_combobox_changed_cb (GtkComboBox *combobox,
+			  DialogData  *data)
+{
+	update_sensitivity (data);
+}
+
+
+void
+dlg_resize_images (GthBrowser *browser,
+		   GList      *file_list)
+{
+	DialogData *data;
+
+	if (gth_browser_get_dialog (browser, "resize_images") != NULL) {
+		gtk_window_present (GTK_WINDOW (gth_browser_get_dialog (browser, "resize_images")));
+		return;
+	}
+
+	data = g_new0 (DialogData, 1);
+	data->browser = browser;
+	data->builder = _gtk_builder_new_from_file ("resize-images.ui", "resize_images");
+	data->file_list = gth_file_data_list_dup (file_list);
+
+	/* Get the widgets. */
+
+	data->dialog = _gtk_builder_get_widget (data->builder, "resize_images_dialog");
+	gth_browser_set_dialog (browser, "resize_images", data->dialog);
+	g_object_set_data (G_OBJECT (data->dialog), "dialog_data", data);
+
+	/* Set widgets data. */
+
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("width_spinbutton")), eel_gconf_get_integer (PREF_RESIZE_IMAGES_SERIES_WIDTH, DEFAULT_WIDTH));
+	gtk_spin_button_set_value (GTK_SPIN_BUTTON (GET_WIDGET ("height_spinbutton")), eel_gconf_get_integer (PREF_RESIZE_IMAGES_SERIES_HEIGHT, DEFAULT_HEIGHT));
+	gtk_combo_box_set_active (GTK_COMBO_BOX (GET_WIDGET ("unit_combobox")), eel_gconf_get_enum (PREF_RESIZE_IMAGES_UNIT, GTH_TYPE_UNIT, GTH_UNIT_PIXELS));
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("keep_ratio_checkbutton")), eel_gconf_get_boolean (PREF_RESIZE_IMAGES_KEEP_RATIO, TRUE));
+	update_sensitivity (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 ("unit_combobox"),
+			  "changed",
+			  G_CALLBACK (unit_combobox_changed_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/resize_images/dlg-resize-images.h b/extensions/resize_images/dlg-resize-images.h
new file mode 100644
index 0000000..46f0917
--- /dev/null
+++ b/extensions/resize_images/dlg-resize-images.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2005-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_RESIZE_IMAGES_H
+#define DLG_RESIZE_IMAGES_H
+
+#include <gthumb.h>
+
+
+void   dlg_resize_images  (GthBrowser *browser,
+			   GList      *file_list  /* GthFileData */);
+
+
+#endif /* DLG_RESIZE_IMAGES_H */
diff --git a/extensions/resize_images/main.c b/extensions/resize_images/main.c
new file mode 100644
index 0000000..9258c4f
--- /dev/null
+++ b/extensions/resize_images/main.c
@@ -0,0 +1,54 @@
+/* -*- 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 (ri__gth_browser_construct_cb), NULL);
+	gth_hook_add_callback ("gth-browser-update-sensitivity", 10, G_CALLBACK (ri__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/resize_images/preferences.h b/extensions/resize_images/preferences.h
new file mode 100644
index 0000000..3eccbd0
--- /dev/null
+++ b/extensions/resize_images/preferences.h
@@ -0,0 +1,37 @@
+/* -*- 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 PREFERENCES_H
+#define PREFERENCES_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define  PREF_RESIZE_IMAGES_SERIES_WIDTH   "/apps/gthumb/ext/resize_images/width"
+#define  PREF_RESIZE_IMAGES_SERIES_HEIGHT  "/apps/gthumb/ext/resize_images/height"
+#define  PREF_RESIZE_IMAGES_UNIT           "/apps/gthumb/ext/resize_images/unit"
+#define  PREF_RESIZE_IMAGES_KEEP_RATIO     "/apps/gthumb/ext/resize_images/keep_aspect_ratio"
+
+G_END_DECLS
+
+#endif /* PREFERENCES_H */
diff --git a/extensions/resize_images/resize_images.extension.in.in b/extensions/resize_images/resize_images.extension.in.in
new file mode 100644
index 0000000..6e23681
--- /dev/null
+++ b/extensions/resize_images/resize_images.extension.in.in
@@ -0,0 +1,10 @@
+[Extension]
+_Name=Resize images
+_Description=Resize series of images.
+_Authors=gthumb development team
+Copyright=Copyright © 2009 The Free Software Foundation, Inc.
+Version=1.0
+
+[Loader]
+Type=module
+File=%LIBRARY%
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index aafa1b9..d4d1281 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -75,6 +75,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-nav-window.h				\
 	gth-overwrite-dialog.h				\
 	gth-pixbuf-task.h				\
+	gth-pixbuf-list-task.h				\
 	gth-preferences.h				\
 	gth-progress-dialog.h				\
 	gth-sidebar.h					\
@@ -190,6 +191,7 @@ gthumb_SOURCES = 					\
 	gth-nav-window.c				\
 	gth-overwrite-dialog.c				\
 	gth-pixbuf-task.c				\
+	gth-pixbuf-list-task.c				\
 	gth-preferences.c				\
 	gth-progress-dialog.c				\
 	gth-sidebar.c					\
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index a018d84..1e1a3b8 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -1135,6 +1135,7 @@ gth_main_activate_extensions (void)
 						"photo_importer",
 						"red_eye_removal",
 						"rename_series",
+						"resize_images",
 						"search",
 						"slideshow",
 						NULL };
diff --git a/gthumb/gth-pixbuf-list-task.c b/gthumb/gth-pixbuf-list-task.c
new file mode 100644
index 0000000..d3425c1
--- /dev/null
+++ b/gthumb/gth-pixbuf-list-task.c
@@ -0,0 +1,318 @@
+/* -*- 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-utils.h"
+#include "gth-main.h"
+#include "gth-pixbuf-list-task.h"
+#include "pixbuf-io.h"
+
+
+struct _GthPixbufListTaskPrivate {
+	GthBrowser *browser;
+	GList      *file_list;
+	GthTask    *task;
+	gulong      task_completed;
+	gulong      task_progress;
+	gulong      task_dialog;
+	GList      *current;
+	int         n_current;
+	int         n_files;
+	GdkPixbuf  *original_pixbuf;
+	GdkPixbuf  *new_pixbuf;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_pixbuf_list_task_finalize (GObject *object)
+{
+	GthPixbufListTask *self;
+
+	self = GTH_PIXBUF_LIST_TASK (object);
+
+	_g_object_unref (self->priv->original_pixbuf);
+	_g_object_unref (self->priv->new_pixbuf);
+	g_signal_handler_disconnect (self->priv->task, self->priv->task_completed);
+	g_signal_handler_disconnect (self->priv->task, self->priv->task_progress);
+	g_signal_handler_disconnect (self->priv->task, self->priv->task_dialog);
+	g_object_unref (self->priv->task);
+	_g_object_list_unref (self->priv->file_list);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void process_current_file (GthPixbufListTask *self);
+
+
+static void
+process_next_file (GthPixbufListTask *self)
+{
+	self->priv->current = self->priv->current->next;
+	process_current_file (self);
+}
+
+
+static void
+pixbuf_saved_cb (GthFileData *file_data,
+		 GError      *error,
+		 gpointer     user_data)
+{
+	GthPixbufListTask *self = user_data;
+	GFile             *parent;
+	GList             *file_list;
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	parent = g_file_get_parent (file_data->file);
+	file_list = g_list_append (NULL, file_data->file);
+	gth_monitor_folder_changed (gth_main_get_default_monitor (),
+				    parent,
+				    file_list,
+				    GTH_MONITOR_EVENT_CHANGED);
+
+	g_list_free (file_list);
+	g_object_unref (parent);
+
+	process_next_file (self);
+}
+
+
+static void
+pixbuf_task_dialog_cb (GthTask  *task,
+		       gboolean  opened,
+		       gpointer  user_data)
+{
+	gth_task_dialog (GTH_TASK (user_data), opened);
+}
+
+
+static void
+pixbuf_task_progress_cb (GthTask    *task,
+		         const char *description,
+		         const char *details,
+		         gboolean    pulse,
+		         double      fraction,
+		         gpointer    user_data)
+{
+	/*GthPixbufListTask *self = user_data;*/
+
+	/* FIXME */
+}
+
+
+static void
+pixbuf_task_completed_cb (GthTask  *task,
+			  GError   *error,
+			  gpointer  user_data)
+{
+	GthPixbufListTask *self = user_data;
+	GthFileData       *file_data;
+	char              *pixbuf_type;
+
+	if (g_error_matches (error, GTH_TASK_ERROR, GTH_TASK_ERROR_SKIP_TO_NEXT_FILE)) {
+		process_next_file (self);
+		return;
+	}
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	file_data = self->priv->current->data;
+	pixbuf_type = get_pixbuf_type_from_mime_type (gth_file_data_get_mime_type (file_data));
+	self->priv->new_pixbuf = g_object_ref (GTH_PIXBUF_TASK (task)->dest);
+	_gdk_pixbuf_save_async (self->priv->new_pixbuf,
+				file_data,
+				pixbuf_type,
+				NULL,
+				NULL,
+				pixbuf_saved_cb,
+				self);
+
+	g_free (pixbuf_type);
+}
+
+
+static void
+file_buffer_ready_cb (void     *buffer,
+		      gsize     count,
+		      GError   *error,
+		      gpointer  user_data)
+{
+	GthPixbufListTask *self = user_data;
+	GInputStream      *istream;
+
+	if (error != NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	istream = g_memory_input_stream_new_from_data (buffer, count, NULL);
+	self->priv->original_pixbuf = gdk_pixbuf_new_from_stream (istream, gth_task_get_cancellable (GTH_TASK (self)), &error);
+	g_object_unref (istream);
+
+	if (self->priv->original_pixbuf == NULL) {
+		gth_task_completed (GTH_TASK (self), error);
+		return;
+	}
+
+	gth_pixbuf_task_set_source (GTH_PIXBUF_TASK (self->priv->task), self->priv->original_pixbuf);
+	gth_task_exec (self->priv->task, gth_task_get_cancellable (GTH_TASK (self)));
+}
+
+
+static void
+process_current_file (GthPixbufListTask *self)
+{
+	GthFileData *file_data;
+
+	if (self->priv->current == NULL) {
+		gth_task_completed (GTH_TASK (self), NULL);
+		return;
+	}
+
+	_g_object_unref (self->priv->original_pixbuf);
+	self->priv->original_pixbuf = NULL;
+	_g_object_unref (self->priv->new_pixbuf);
+	self->priv->new_pixbuf = NULL;
+
+	gth_task_progress (GTH_TASK (self),
+			   NULL,
+			   NULL,
+			   FALSE,
+			   ((double) self->priv->n_current + 1) / (self->priv->n_files + 1));
+
+	file_data = self->priv->current->data;
+	g_load_file_async (file_data->file,
+			   G_PRIORITY_DEFAULT,
+			   gth_task_get_cancellable (GTH_TASK (self)),
+			   file_buffer_ready_cb,
+			   self);
+}
+
+
+static void
+gth_pixbuf_list_task_exec (GthTask *task)
+{
+	GthPixbufListTask *self;
+
+	g_return_if_fail (GTH_IS_PIXBUF_LIST_TASK (task));
+
+	self = GTH_PIXBUF_LIST_TASK (task);
+
+	self->priv->current = self->priv->file_list;
+	self->priv->n_current = 0;
+	self->priv->n_files = g_list_length (self->priv->file_list);
+	process_current_file (self);
+}
+
+
+static void
+gth_pixbuf_list_task_class_init (GthPixbufListTaskClass *klass)
+{
+	GObjectClass *object_class;
+	GthTaskClass *task_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthPixbufListTaskPrivate));
+
+	object_class = G_OBJECT_CLASS (klass);
+	object_class->finalize = gth_pixbuf_list_task_finalize;
+
+	task_class = GTH_TASK_CLASS (klass);
+	task_class->exec = gth_pixbuf_list_task_exec;
+}
+
+
+static void
+gth_pixbuf_list_task_init (GthPixbufListTask *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskPrivate);
+	self->priv->original_pixbuf = NULL;
+}
+
+
+GType
+gth_pixbuf_list_task_get_type (void)
+{
+	static GType type = 0;
+
+	if (! type) {
+		GTypeInfo type_info = {
+			sizeof (GthPixbufListTaskClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_pixbuf_list_task_class_init,
+			NULL,
+			NULL,
+			sizeof (GthPixbufListTask),
+			0,
+			(GInstanceInitFunc) gth_pixbuf_list_task_init
+		};
+
+		type = g_type_register_static (GTH_TYPE_TASK,
+					       "GthPixbufListTask",
+					       &type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
+GthTask *
+gth_pixbuf_list_task_new (GthBrowser    *browser,
+			  GList         *file_list,
+			  GthPixbufTask *task)
+{
+	GthPixbufListTask *self;
+
+	g_return_val_if_fail (task != NULL, NULL);
+	g_return_val_if_fail (GTH_IS_PIXBUF_TASK (task), NULL);
+
+	self = GTH_PIXBUF_LIST_TASK (g_object_new (GTH_TYPE_PIXBUF_LIST_TASK, NULL));
+	self->priv->browser = browser;
+	self->priv->file_list = _g_object_list_ref (file_list);
+	self->priv->task = g_object_ref (task);
+	self->priv->task_completed = g_signal_connect (self->priv->task,
+						       "completed",
+						       G_CALLBACK (pixbuf_task_completed_cb),
+						       self);
+	self->priv->task_progress = g_signal_connect (self->priv->task,
+						      "progress",
+						      G_CALLBACK (pixbuf_task_progress_cb),
+						      self);
+	self->priv->task_dialog = g_signal_connect (self->priv->task,
+						    "dialog",
+						    G_CALLBACK (pixbuf_task_dialog_cb),
+						    self);
+
+	return (GthTask *) self;
+}
diff --git a/gthumb/gth-pixbuf-list-task.h b/gthumb/gth-pixbuf-list-task.h
new file mode 100644
index 0000000..7931619
--- /dev/null
+++ b/gthumb/gth-pixbuf-list-task.h
@@ -0,0 +1,59 @@
+/* -*- 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_PIXBUF_LIST_TASK_H
+#define GTH_PIXBUF_LIST_TASK_H
+
+#include <glib.h>
+#include "gth-browser.h"
+#include "gth-pixbuf-task.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_PIXBUF_LIST_TASK            (gth_pixbuf_list_task_get_type ())
+#define GTH_PIXBUF_LIST_TASK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTask))
+#define GTH_PIXBUF_LIST_TASK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskClass))
+#define GTH_IS_PIXBUF_LIST_TASK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_PIXBUF_LIST_TASK))
+#define GTH_IS_PIXBUF_LIST_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_PIXBUF_LIST_TASK))
+#define GTH_PIXBUF_LIST_TASK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_PIXBUF_LIST_TASK, GthPixbufListTaskClass))
+
+typedef struct _GthPixbufListTask        GthPixbufListTask;
+typedef struct _GthPixbufListTaskClass   GthPixbufListTaskClass;
+typedef struct _GthPixbufListTaskPrivate GthPixbufListTaskPrivate;
+
+struct _GthPixbufListTask {
+	GthTask __parent;
+	GthPixbufListTaskPrivate *priv;
+};
+
+struct _GthPixbufListTaskClass {
+	GthTaskClass __parent;
+};
+
+GType      gth_pixbuf_list_task_get_type  (void);
+GthTask *  gth_pixbuf_list_task_new       (GthBrowser    *browser,
+					   GList         *file_list, /* GthFileData list */
+					   GthPixbufTask *task);
+
+G_END_DECLS
+
+#endif /* GTH_PIXBUF_LIST_TASK_H */
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index 02849d1..a8c1a03 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -87,6 +87,20 @@ typedef enum {
 } GthTransform;
 
 
+typedef enum {
+	GTH_UNIT_PIXELS,
+        GTH_UNIT_PERCENTAGE
+} GthUnit;
+
+
+typedef enum {
+	GTH_OVERWRITE_SKIP,
+	GTH_OVERWRITE_RENAME,
+	GTH_OVERWRITE_ASK,
+	GTH_OVERWRITE_OVERWRITE
+} GthOverwriteMode;
+
+
 typedef void (*DataFunc)         (gpointer    user_data);
 typedef void (*ReadyFunc)        (GError     *error,
 			 	  gpointer    user_data);



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