[gthumb/ext: 4/79] reorganized the sidebar / toolbox / file_tool hierarchy



commit 699390668369c6bf9a889dfd5d51c12cf25a3402
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Fri Jun 12 21:59:45 2009 +0200

    reorganized the sidebar / toolbox / file_tool hierarchy
    
    the file_tool is now a base class instead of an interface,
    the toolbox is a notebook with the tool options.

 configure.ac                                       |    6 +-
 extensions/Makefile.am                             |    2 +-
 extensions/file_tools/Makefile.am                  |   40 +++
 .../{image_tools => file_tools}/data/Makefile.am   |    0
 .../data/ui/Makefile.am                            |    0
 .../data/ui/crop-options.ui                        |    0
 .../file_tools.extension.in.in}                    |    0
 .../gth-file-tool-crop.c}                          |  204 ++++++++--------
 extensions/file_tools/gth-file-tool-crop.h         |   54 ++++
 .../gth-file-tool-desaturate.c}                    |   72 ++----
 extensions/file_tools/gth-file-tool-desaturate.h   |   52 ++++
 .../gth-file-tool-redo.c}                          |   64 ++----
 extensions/file_tools/gth-file-tool-redo.h         |   52 ++++
 extensions/file_tools/gth-file-tool-save.c         |   84 +++++++
 extensions/file_tools/gth-file-tool-save.h         |   52 ++++
 .../gth-file-tool-undo.c}                          |   64 ++----
 extensions/file_tools/gth-file-tool-undo.h         |   52 ++++
 extensions/{image_tools => file_tools}/main.c      |   23 +-
 extensions/image_tools/Makefile.am                 |   40 ---
 extensions/image_tools/gth-image-tool-crop.h       |   54 ----
 extensions/image_tools/gth-image-tool-desaturate.h |   52 ----
 extensions/image_tools/gth-image-tool-redo.h       |   52 ----
 extensions/image_tools/gth-image-tool-save.c       |  117 ---------
 extensions/image_tools/gth-image-tool-save.h       |   52 ----
 extensions/image_tools/gth-image-tool-undo.h       |   52 ----
 gthumb/Makefile.am                                 |    6 +-
 gthumb/gth-browser.c                               |    8 +-
 gthumb/gth-file-tool.c                             |  254 ++++++++++++++++++++
 gthumb/gth-file-tool.h                             |   79 ++++++
 gthumb/gth-image-dragger.c                         |   36 ++--
 gthumb/gth-image-dragger.h                         |    6 +-
 gthumb/gth-image-selector.c                        |   36 ++--
 gthumb/gth-image-selector.h                        |   50 ++--
 gthumb/gth-image-tool.c                            |  118 ---------
 gthumb/gth-image-tool.h                            |   75 ------
 gthumb/gth-image-viewer-tool.c                     |  118 +++++++++
 gthumb/gth-image-viewer-tool.h                     |   75 ++++++
 gthumb/gth-image-viewer.c                          |  114 +++++-----
 gthumb/gth-image-viewer.h                          |    4 +-
 gthumb/gth-main.c                                  |    2 +-
 gthumb/gth-sidebar.c                               |   95 +++-----
 gthumb/gth-sidebar.h                               |   15 +-
 gthumb/gth-toolbox.c                               |  144 +++++++++---
 gthumb/gth-toolbox.h                               |   22 +--
 44 files changed, 1372 insertions(+), 1125 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index ab4abc8..00ffe6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -226,10 +226,10 @@ extensions/comments/data/Makefile
 extensions/comments/data/ui/Makefile
 extensions/exiv2/Makefile
 extensions/file_manager/Makefile
+extensions/file_tools/Makefile
+extensions/file_tools/data/Makefile
+extensions/file_tools/data/ui/Makefile
 extensions/file_viewer/Makefile
-extensions/image_tools/Makefile
-extensions/image_tools/data/Makefile
-extensions/image_tools/data/ui/Makefile
 extensions/image_viewer/Makefile
 extensions/image_viewer/data/Makefile
 extensions/image_viewer/data/ui/Makefile
diff --git a/extensions/Makefile.am b/extensions/Makefile.am
index 7615900..2bff7c9 100644
--- a/extensions/Makefile.am
+++ b/extensions/Makefile.am
@@ -1,3 +1,3 @@
-SUBDIRS = catalogs comments exiv2 file_manager file_viewer image_tools image_viewer search
+SUBDIRS = catalogs comments exiv2 file_manager file_tools file_viewer image_viewer search
 
 -include $(top_srcdir)/git.mk
diff --git a/extensions/file_tools/Makefile.am b/extensions/file_tools/Makefile.am
new file mode 100644
index 0000000..82ca783
--- /dev/null
+++ b/extensions/file_tools/Makefile.am
@@ -0,0 +1,40 @@
+SUBDIRS = data
+
+extensiondir = $(libdir)/gthumb-2.0/extensions
+extension_LTLIBRARIES = libfile_tools.la
+
+libfile_tools_la_SOURCES = 		\
+	gth-file-tool-crop.c		\
+	gth-file-tool-crop.h		\
+	gth-file-tool-desaturate.c	\
+	gth-file-tool-desaturate.h	\
+	gth-file-tool-redo.c		\
+	gth-file-tool-redo.h		\
+	gth-file-tool-save.c		\
+	gth-file-tool-save.h		\
+	gth-file-tool-undo.c		\
+	gth-file-tool-undo.h		\
+	main.c
+
+libfile_tools_la_CFLAGS = $(GTHUMB_CFLAGS) $(DISABLE_DEPRECATED) $(WARNINGS) -I$(top_srcdir) -I$(top_builddir)/gthumb 
+libfile_tools_la_LDFLAGS = $(EXTENSION_LIBTOOL_FLAGS)
+libfile_tools_la_LIBADD = $(GTHUMB_LIBS)
+libfile_tools_la_DEPENDENCIES = $(top_builddir)/gthumb/gthumb$(EXEEXT)
+
+extensioninidir = $(extensiondir)
+extensionini_in_files = file_tools.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) 
+
+CLEANFILES = $(extensionini_DATA)
+
+DISTCLEANFILES = $(extensionini_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/extensions/image_tools/data/Makefile.am b/extensions/file_tools/data/Makefile.am
similarity index 100%
rename from extensions/image_tools/data/Makefile.am
rename to extensions/file_tools/data/Makefile.am
diff --git a/extensions/image_tools/data/ui/Makefile.am b/extensions/file_tools/data/ui/Makefile.am
similarity index 100%
rename from extensions/image_tools/data/ui/Makefile.am
rename to extensions/file_tools/data/ui/Makefile.am
diff --git a/extensions/image_tools/data/ui/crop-options.ui b/extensions/file_tools/data/ui/crop-options.ui
similarity index 100%
rename from extensions/image_tools/data/ui/crop-options.ui
rename to extensions/file_tools/data/ui/crop-options.ui
diff --git a/extensions/image_tools/image_tools.extension.in.in b/extensions/file_tools/file_tools.extension.in.in
similarity index 100%
rename from extensions/image_tools/image_tools.extension.in.in
rename to extensions/file_tools/file_tools.extension.in.in
diff --git a/extensions/image_tools/gth-image-tool-crop.c b/extensions/file_tools/gth-file-tool-crop.c
similarity index 77%
rename from extensions/image_tools/gth-image-tool-crop.c
rename to extensions/file_tools/gth-file-tool-crop.c
index 0338854..5291de7 100644
--- a/extensions/image_tools/gth-image-tool-crop.c
+++ b/extensions/file_tools/gth-file-tool-crop.c
@@ -23,7 +23,7 @@
 #include <config.h>
 #include <gthumb.h>
 #include <extensions/image_viewer/gth-image-viewer-page.h>
-#include "gth-image-tool-crop.h"
+#include "gth-file-tool-crop.h"
 
 
 #define GET_WIDGET(x) (_gtk_builder_get_widget (self->priv->builder, (x)))
@@ -45,7 +45,7 @@ typedef enum {
 static gpointer parent_class = NULL;
 
 
-struct _GthImageToolCropPrivate {
+struct _GthFileToolCropPrivate {
 	GdkPixbuf        *src_pixbuf;
 	GtkBuilder       *builder;
 	int               pixbuf_width;
@@ -62,50 +62,31 @@ struct _GthImageToolCropPrivate {
 
 
 static void
-gth_image_tool_crop_real_update_sensitivity (GthFileTool *base,
-					     GtkWidget   *window)
+gth_file_tool_crop_update_sensitivity (GthFileTool *base)
 {
-	GthImageToolCrop *self;
-
-	self = (GthImageToolCrop*) base;
-}
-
+	GtkWidget *window;
+	GtkWidget *viewer_page;
 
-static void
-gth_file_tool_interface_init (GthFileToolIface *iface)
-{
-	iface->update_sensitivity = gth_image_tool_crop_real_update_sensitivity;
+	window = gth_file_tool_get_window (base);
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
+		gtk_widget_set_sensitive (GTK_WIDGET (base), FALSE);
+	else
+		gtk_widget_set_sensitive (GTK_WIDGET (base), TRUE);
 }
 
 
 static void
-cancel_button_clicked_cb (GtkButton        *button,
-			  GthImageToolCrop *self)
+cancel_button_clicked_cb (GtkButton       *button,
+			  GthFileToolCrop *self)
 {
-	GtkWidget *window;
-	GtkWidget *sidebar;
-	GtkWidget *viewer_page;
-	GtkWidget *viewer;
-
-	window = gtk_widget_get_toplevel (GTK_WIDGET (self));
-	sidebar = gth_browser_get_viewer_sidebar (GTH_BROWSER (window));
-	gth_sidebar_set_options (GTH_SIDEBAR (sidebar), NULL, NULL, NULL);
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar), GTH_SIDEBAR_PAGE_TOOLS);
-
-	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
-	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
-	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), NULL);
-
-	_g_object_unref (self->priv->src_pixbuf);
-	_g_object_unref (self->priv->builder);
-	self->priv->src_pixbuf = NULL;
-	self->priv->builder = NULL;
+	gth_file_tool_hide_options (GTH_FILE_TOOL (self));
 }
 
 
 static void
-crop_button_clicked_cb (GtkButton        *button,
-			GthImageToolCrop *self)
+crop_button_clicked_cb (GtkButton       *button,
+			GthFileToolCrop *self)
 {
 	GdkRectangle  selection;
 	GdkPixbuf    *new_pixbuf;
@@ -123,10 +104,10 @@ crop_button_clicked_cb (GtkButton        *button,
 		GtkWidget *window;
 		GtkWidget *viewer_page;
 
-		window = gtk_widget_get_toplevel (GTK_WIDGET (self));
+		window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
 		viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 		gth_image_viewer_page_set_pixbuf (GTH_IMAGE_VIEWER_PAGE (viewer_page), new_pixbuf);
-		cancel_button_clicked_cb (NULL, self);
+		gth_file_tool_hide_options (GTH_FILE_TOOL (self));
 
 		g_object_unref (new_pixbuf);
 	}
@@ -135,7 +116,7 @@ crop_button_clicked_cb (GtkButton        *button,
 
 static void
 selection_x_value_changed_cb (GtkSpinButton    *spin,
-			      GthImageToolCrop *self)
+			      GthFileToolCrop *self)
 {
 	gth_image_selector_set_selection_x (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
 }
@@ -143,7 +124,7 @@ selection_x_value_changed_cb (GtkSpinButton    *spin,
 
 static void
 selection_y_value_changed_cb (GtkSpinButton    *spin,
-			      GthImageToolCrop *self)
+			      GthFileToolCrop *self)
 {
 	gth_image_selector_set_selection_y (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
 }
@@ -151,7 +132,7 @@ selection_y_value_changed_cb (GtkSpinButton    *spin,
 
 static void
 selection_width_value_changed_cb (GtkSpinButton    *spin,
-				  GthImageToolCrop *self)
+				  GthFileToolCrop *self)
 {
 	gth_image_selector_set_selection_width (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
 }
@@ -159,14 +140,14 @@ selection_width_value_changed_cb (GtkSpinButton    *spin,
 
 static void
 selection_height_value_changed_cb (GtkSpinButton    *spin,
-				   GthImageToolCrop *self)
+				   GthFileToolCrop *self)
 {
 	gth_image_selector_set_selection_height (self->priv->selector, gtk_spin_button_get_value_as_int (spin));
 }
 
 
 static void
-set_spin_range_value (GthImageToolCrop *self,
+set_spin_range_value (GthFileToolCrop *self,
 		      GtkWidget        *spin,
 		      int               min,
 		      int               max,
@@ -181,7 +162,7 @@ set_spin_range_value (GthImageToolCrop *self,
 
 static void
 selector_selection_changed_cb (GthImageSelector *selector,
-			       GthImageToolCrop *self)
+			       GthFileToolCrop *self)
 {
 	GdkRectangle selection;
 	int          min, max;
@@ -209,7 +190,7 @@ selector_selection_changed_cb (GthImageSelector *selector,
 
 
 static void
-set_spin_value (GthImageToolCrop *self,
+set_spin_value (GthFileToolCrop *self,
 		GtkWidget        *spin,
 		int               x)
 {
@@ -221,7 +202,7 @@ set_spin_value (GthImageToolCrop *self,
 
 static void
 ratio_combobox_changed_cb (GtkComboBox      *combobox,
-			   GthImageToolCrop *self)
+			   GthFileToolCrop *self)
 {
 	GtkWidget *ratio_w_spinbutton;
 	GtkWidget *ratio_h_spinbutton;
@@ -286,7 +267,7 @@ ratio_combobox_changed_cb (GtkComboBox      *combobox,
 
 static void
 update_ratio (GtkSpinButton    *spin,
-	      GthImageToolCrop *self,
+	      GthFileToolCrop *self,
 	      gboolean          swap_x_and_y_to_start)
 {
 	gboolean use_ratio;
@@ -310,7 +291,7 @@ update_ratio (GtkSpinButton    *spin,
 
 static void
 ratio_value_changed_cb (GtkSpinButton    *spin,
-			GthImageToolCrop *self)
+			GthFileToolCrop *self)
 {
 	update_ratio (spin, self, FALSE);
 }
@@ -318,35 +299,35 @@ ratio_value_changed_cb (GtkSpinButton    *spin,
 
 static void
 invert_ratio_changed_cb (GtkSpinButton    *spin,
-			 GthImageToolCrop *self)
+			 GthFileToolCrop *self)
 {
 	update_ratio (spin, self, TRUE);
 }
 
 
-static void
-button_clicked_cb (GtkButton *button,
-		   gpointer   data)
+static GtkWidget *
+gth_file_tool_crop_get_options (GthFileTool *base)
 {
-	GthImageToolCrop *self;
-	GtkWidget        *window;
-	GtkWidget        *viewer_page;
-	GtkWidget        *viewer;
-	GtkWidget        *options;
-	GtkWidget        *sidebar;
-	char             *text;
+	GthFileToolCrop *self;
+	GtkWidget       *window;
+	GtkWidget       *viewer_page;
+	GtkWidget       *viewer;
+	GtkWidget       *options;
+	char            *text;
 
-	self = (GthImageToolCrop *) button;
+	self = (GthFileToolCrop *) base;
 
-	window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
-		return;
+		return NULL;
+
+	_g_object_unref (self->priv->src_pixbuf);
 
 	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
 	self->priv->src_pixbuf = gth_image_viewer_get_current_pixbuf (GTH_IMAGE_VIEWER (viewer));
 	if (self->priv->src_pixbuf == NULL)
-		return;
+		return NULL;
 
 	g_object_ref (self->priv->src_pixbuf);
 
@@ -354,8 +335,10 @@ button_clicked_cb (GtkButton *button,
 	self->priv->pixbuf_height = gdk_pixbuf_get_height (self->priv->src_pixbuf);
 	_gtk_widget_get_screen_size (window, &self->priv->screen_width, &self->priv->screen_height);
 
-	self->priv->builder = _gtk_builder_new_from_file ("crop-options.ui", "image_tools");
+	self->priv->builder = _gtk_builder_new_from_file ("crop-options.ui", "file_tools");
+
 	options = _gtk_builder_get_widget (self->priv->builder, "options");
+	gtk_widget_show (options);
 	self->priv->crop_x_spinbutton = _gtk_builder_get_widget (self->priv->builder, "crop_x_spinbutton");
 	self->priv->crop_y_spinbutton = _gtk_builder_get_widget (self->priv->builder, "crop_y_spinbutton");
 	self->priv->crop_width_spinbutton = _gtk_builder_get_widget (self->priv->builder, "crop_width_spinbutton");
@@ -378,10 +361,6 @@ button_clicked_cb (GtkButton *button,
 	gtk_widget_show (self->priv->ratio_combobox);
 	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("ratio_combobox_box")), self->priv->ratio_combobox, FALSE, FALSE, 0);
 
-	gtk_widget_show (options);
-	sidebar = gth_browser_get_viewer_sidebar (GTH_BROWSER (window));
-	gth_sidebar_set_options (GTH_SIDEBAR (sidebar), "gtk-edit", _("Crop"), options);
-
 	g_signal_connect (GET_WIDGET ("crop_button"),
 			  "clicked",
 			  G_CALLBACK (crop_button_clicked_cb),
@@ -434,49 +413,61 @@ button_clicked_cb (GtkButton *button,
 			  self);*/
 
 	gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->ratio_combobox), 0);
-	gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar), GTH_SIDEBAR_PAGE_OPTIONS);
-	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageTool *) self->priv->selector);
+	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), (GthImageViewerTool *) self->priv->selector);
+
+	return options;
 }
 
 
 static void
-gth_image_tool_crop_instance_init (GthImageToolCrop *self)
+gth_file_tool_crop_destroy_options (GthFileTool *base)
 {
-	GtkWidget *hbox;
-	GtkWidget *icon;
-	GtkWidget *label;
+	GthFileToolCrop *self;
+	GtkWidget       *window;
+	GtkWidget       *viewer_page;
+	GtkWidget       *viewer;
 
-	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_IMAGE_TOOL_CROP, GthImageToolCropPrivate);
-	self->priv->builder = NULL;
+	self = (GthFileToolCrop *) base;
 
-	gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
+	window = gth_file_tool_get_window (GTH_FILE_TOOL (self));
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	viewer = gth_image_viewer_page_get_image_viewer (GTH_IMAGE_VIEWER_PAGE (viewer_page));
+	gth_image_viewer_set_tool (GTH_IMAGE_VIEWER (viewer), NULL);
 
-	hbox = gtk_hbox_new (FALSE, 6);
+	_g_object_unref (self->priv->src_pixbuf);
+	_g_object_unref (self->priv->builder);
+	_g_object_unref (self->priv->selector);
 
-	icon = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
-	gtk_widget_show (icon);
-	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+	self->priv->src_pixbuf = NULL;
+	self->priv->builder = NULL;
+	self->priv->selector = NULL;
+}
 
-	label = gtk_label_new (_("Crop"));
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
-	gtk_widget_show (hbox);
-	gtk_container_add (GTK_CONTAINER (self), hbox);
+static void
+gth_file_tool_crop_activate (GthFileTool *base)
+{
+	gth_file_tool_show_options (base);
+}
+
 
-	g_signal_connect (self, "clicked", G_CALLBACK (button_clicked_cb), self);
+static void
+gth_file_tool_crop_instance_init (GthFileToolCrop *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL_CROP, GthFileToolCropPrivate);
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_EDIT, _("Crop"), _("Crop"));
 }
 
 
 static void
-gth_image_tool_crop_finalize (GObject *object)
+gth_file_tool_crop_finalize (GObject *object)
 {
-	GthImageToolCrop *self;
+	GthFileToolCrop *self;
 
 	g_return_if_fail (object != NULL);
-	g_return_if_fail (GTH_IS_IMAGE_TOOL_CROP (object));
+	g_return_if_fail (GTH_IS_FILE_TOOL_CROP (object));
 
-	self = (GthImageToolCrop *) object;
+	self = (GthFileToolCrop *) object;
 
 	_g_object_unref (self->priv->src_pixbuf);
 	_g_object_unref (self->priv->selector);
@@ -488,41 +479,42 @@ gth_image_tool_crop_finalize (GObject *object)
 
 
 static void
-gth_image_tool_crop_class_init (GthImageToolCropClass *class)
+gth_file_tool_crop_class_init (GthFileToolCropClass *class)
 {
-	GObjectClass *gobject_class;
+	GObjectClass     *gobject_class;
+	GthFileToolClass *file_tool_class;
 
 	parent_class = g_type_class_peek_parent (class);
-	g_type_class_add_private (class, sizeof (GthImageToolCropPrivate));
+	g_type_class_add_private (class, sizeof (GthFileToolCropPrivate));
 
 	gobject_class = (GObjectClass*) class;
-	gobject_class->finalize = gth_image_tool_crop_finalize;
+	gobject_class->finalize = gth_file_tool_crop_finalize;
+
+	file_tool_class = (GthFileToolClass *) class;
+	file_tool_class->update_sensitivity = gth_file_tool_crop_update_sensitivity;
+	file_tool_class->activate = gth_file_tool_crop_activate;
+	file_tool_class->get_options = gth_file_tool_crop_get_options;
+	file_tool_class->destroy_options = gth_file_tool_crop_destroy_options;
 }
 
 
 GType
-gth_image_tool_crop_get_type (void) {
+gth_file_tool_crop_get_type (void) {
 	static GType type_id = 0;
 	if (type_id == 0) {
 		static const GTypeInfo g_define_type_info = {
-			sizeof (GthImageToolCropClass),
+			sizeof (GthFileToolCropClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) gth_image_tool_crop_class_init,
+			(GClassInitFunc) gth_file_tool_crop_class_init,
 			(GClassFinalizeFunc) NULL,
 			NULL,
-			sizeof (GthImageToolCrop),
+			sizeof (GthFileToolCrop),
 			0,
-			(GInstanceInitFunc) gth_image_tool_crop_instance_init,
-			NULL
-		};
-		static const GInterfaceInfo gth_file_tool_info = {
-			(GInterfaceInitFunc) gth_file_tool_interface_init,
-			(GInterfaceFinalizeFunc) NULL,
+			(GInstanceInitFunc) gth_file_tool_crop_instance_init,
 			NULL
 		};
-		type_id = g_type_register_static (GTK_TYPE_BUTTON, "GthImageToolCrop", &g_define_type_info, 0);
-		g_type_add_interface_static (type_id, GTH_TYPE_FILE_TOOL, &gth_file_tool_info);
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolCrop", &g_define_type_info, 0);
 	}
 	return type_id;
 }
diff --git a/extensions/file_tools/gth-file-tool-crop.h b/extensions/file_tools/gth-file-tool-crop.h
new file mode 100644
index 0000000..d003ff7
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-crop.h
@@ -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.
+ */
+
+#ifndef GTH_FILE_TOOL_CROP_H
+#define GTH_FILE_TOOL_CROP_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_CROP (gth_file_tool_crop_get_type ())
+#define GTH_FILE_TOOL_CROP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_CROP, GthFileToolCrop))
+#define GTH_FILE_TOOL_CROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_CROP, GthFileToolCropClass))
+#define GTH_IS_FILE_TOOL_CROP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_CROP))
+#define GTH_IS_FILE_TOOL_CROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_CROP))
+#define GTH_FILE_TOOL_CROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_CROP, GthFileToolCropClass))
+
+typedef struct _GthFileToolCrop GthFileToolCrop;
+typedef struct _GthFileToolCropClass GthFileToolCropClass;
+typedef struct _GthFileToolCropPrivate GthFileToolCropPrivate;
+
+struct _GthFileToolCrop {
+	GthFileTool parent_instance;
+	GthFileToolCropPrivate *priv;
+};
+
+struct _GthFileToolCropClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_crop_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_CROP_H */
diff --git a/extensions/image_tools/gth-image-tool-desaturate.c b/extensions/file_tools/gth-file-tool-desaturate.c
similarity index 62%
rename from extensions/image_tools/gth-image-tool-desaturate.c
rename to extensions/file_tools/gth-file-tool-desaturate.c
index 179e739..520c24b 100644
--- a/extensions/image_tools/gth-image-tool-desaturate.c
+++ b/extensions/file_tools/gth-file-tool-desaturate.c
@@ -23,23 +23,21 @@
 #include <config.h>
 #include <gthumb.h>
 #include <extensions/image_viewer/gth-image-viewer-page.h>
-#include "gth-image-tool-desaturate.h"
+#include "gth-file-tool-desaturate.h"
 
 
 static void
-gth_image_tool_desaturate_real_update_sensitivity (GthFileTool *base,
-						   GtkWidget   *window)
+gth_file_tool_desaturate_update_sensitivity (GthFileTool *base)
 {
-	GthImageToolDesaturate *self;
-
-	self = (GthImageToolDesaturate*) base;
-}
-
+	GtkWidget *window;
+	GtkWidget *viewer_page;
 
-static void
-gth_file_tool_interface_init (GthFileToolIface *iface)
-{
-	iface->update_sensitivity = gth_image_tool_desaturate_real_update_sensitivity;
+	window = gth_file_tool_get_window (base);
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
+		gtk_widget_set_sensitive (GTK_WIDGET (base), FALSE);
+	else
+		gtk_widget_set_sensitive (GTK_WIDGET (base), TRUE);
 }
 
 
@@ -73,8 +71,7 @@ desaturate_release (GthPixbufTask *pixop)
 
 
 static void
-button_clicked_cb (GtkButton *button,
-		   gpointer   data)
+gth_file_tool_desaturate_activate (GthFileTool *base)
 {
 	GtkWidget *window;
 	GtkWidget *viewer_page;
@@ -83,7 +80,7 @@ button_clicked_cb (GtkButton *button,
 	GdkPixbuf *dest_pixbuf;
 	GthTask   *task;
 
-	window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
 		return;
@@ -108,54 +105,37 @@ button_clicked_cb (GtkButton *button,
 
 
 static void
-gth_image_tool_desaturate_instance_init (GthImageToolDesaturate *self)
+gth_file_tool_desaturate_instance_init (GthFileToolDesaturate *self)
 {
-	GtkWidget *hbox;
-	GtkWidget *icon;
-	GtkWidget *label;
-
-	gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
-
-	hbox = gtk_hbox_new (FALSE, 6);
-
-	icon = gtk_image_new_from_stock (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
-	gtk_widget_show (icon);
-	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-
-	label = gtk_label_new (_("Desaturate"));
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_EDIT, _("Desaturate"), _("Desaturate"));
+}
 
-	gtk_widget_show (hbox);
-	gtk_container_add (GTK_CONTAINER (self), hbox);
 
-	g_signal_connect (self, "clicked", G_CALLBACK (button_clicked_cb), self);
+static void
+gth_file_tool_desaturate_class_init (GthFileToolClass *klass)
+{
+	klass->update_sensitivity = gth_file_tool_desaturate_update_sensitivity;
+	klass->activate = gth_file_tool_desaturate_activate;
 }
 
 
 GType
-gth_image_tool_desaturate_get_type (void) {
+gth_file_tool_desaturate_get_type (void) {
 	static GType type_id = 0;
 	if (type_id == 0) {
 		static const GTypeInfo g_define_type_info = {
-			sizeof (GthImageToolDesaturateClass),
+			sizeof (GthFileToolDesaturateClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
+			(GClassInitFunc) gth_file_tool_desaturate_class_init,
 			(GClassFinalizeFunc) NULL,
 			NULL,
-			sizeof (GthImageToolDesaturate),
+			sizeof (GthFileToolDesaturate),
 			0,
-			(GInstanceInitFunc) gth_image_tool_desaturate_instance_init,
-			NULL
-		};
-		static const GInterfaceInfo gth_file_tool_info = {
-			(GInterfaceInitFunc) gth_file_tool_interface_init,
-			(GInterfaceFinalizeFunc) NULL,
+			(GInstanceInitFunc) gth_file_tool_desaturate_instance_init,
 			NULL
 		};
-		type_id = g_type_register_static (GTK_TYPE_BUTTON, "GthImageToolDesaturate", &g_define_type_info, 0);
-		g_type_add_interface_static (type_id, GTH_TYPE_FILE_TOOL, &gth_file_tool_info);
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolDesaturate", &g_define_type_info, 0);
 	}
 	return type_id;
 }
diff --git a/extensions/file_tools/gth-file-tool-desaturate.h b/extensions/file_tools/gth-file-tool-desaturate.h
new file mode 100644
index 0000000..e909a05
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-desaturate.h
@@ -0,0 +1,52 @@
+/* -*- 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_FILE_TOOL_DESATURATE_H
+#define GTH_FILE_TOOL_DESATURATE_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_DESATURATE (gth_file_tool_desaturate_get_type ())
+#define GTH_FILE_TOOL_DESATURATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_DESATURATE, GthFileToolDesaturate))
+#define GTH_FILE_TOOL_DESATURATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_DESATURATE, GthFileToolDesaturateClass))
+#define GTH_IS_FILE_TOOL_DESATURATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_DESATURATE))
+#define GTH_IS_FILE_TOOL_DESATURATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_DESATURATE))
+#define GTH_FILE_TOOL_DESATURATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_DESATURATE, GthFileToolDesaturateClass))
+
+typedef struct _GthFileToolDesaturate GthFileToolDesaturate;
+typedef struct _GthFileToolDesaturateClass GthFileToolDesaturateClass;
+
+struct _GthFileToolDesaturate {
+	GthFileTool parent_instance;
+};
+
+struct _GthFileToolDesaturateClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_desaturate_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_DESATURATE_H */
diff --git a/extensions/image_tools/gth-image-tool-redo.c b/extensions/file_tools/gth-file-tool-redo.c
similarity index 54%
rename from extensions/image_tools/gth-image-tool-redo.c
rename to extensions/file_tools/gth-file-tool-redo.c
index c09451e..64f1297 100644
--- a/extensions/image_tools/gth-image-tool-redo.c
+++ b/extensions/file_tools/gth-file-tool-redo.c
@@ -23,15 +23,16 @@
 #include <config.h>
 #include <gthumb.h>
 #include <extensions/image_viewer/gth-image-viewer-page.h>
-#include "gth-image-tool-redo.h"
+#include "gth-file-tool-redo.h"
 
 
 static void
-gth_file_tool_redo_real_update_sensitivity (GthFileTool *base,
-					    GtkWidget   *window)
+gth_file_tool_redo_update_sensitivity (GthFileTool *base)
 {
+	GtkWidget *window;
 	GtkWidget *viewer_page;
 
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
 		gtk_widget_set_sensitive (GTK_WIDGET (base), FALSE);
@@ -42,20 +43,12 @@ gth_file_tool_redo_real_update_sensitivity (GthFileTool *base,
 
 
 static void
-gth_file_tool_interface_init (GthFileToolIface *iface)
-{
-	iface->update_sensitivity = gth_file_tool_redo_real_update_sensitivity;
-}
-
-
-static void
-button_clicked_cb (GtkButton *button,
-		   gpointer   data)
+gth_file_tool_redo_activate (GthFileTool *base)
 {
 	GtkWidget *window;
 	GtkWidget *viewer_page;
 
-	window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
 		return;
@@ -65,54 +58,37 @@ button_clicked_cb (GtkButton *button,
 
 
 static void
-gth_image_tool_redo_instance_init (GthImageToolRedo *self)
+gth_file_tool_redo_instance_init (GthFileToolRedo *self)
 {
-	GtkWidget *hbox;
-	GtkWidget *icon;
-	GtkWidget *label;
-
-	gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
-
-	hbox = gtk_hbox_new (FALSE, 6);
-
-	icon = gtk_image_new_from_stock (GTK_STOCK_REDO, GTK_ICON_SIZE_MENU);
-	gtk_widget_show (icon);
-	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-
-	label = gtk_label_new (_("Redo"));
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_REDO, _("Redo"), _("Redo"));
+}
 
-	gtk_widget_show (hbox);
-	gtk_container_add (GTK_CONTAINER (self), hbox);
 
-	g_signal_connect (self, "clicked", G_CALLBACK (button_clicked_cb), self);
+static void
+gth_file_tool_redo_class_init (GthFileToolClass *klass)
+{
+	klass->update_sensitivity = gth_file_tool_redo_update_sensitivity;
+	klass->activate = gth_file_tool_redo_activate;
 }
 
 
 GType
-gth_image_tool_redo_get_type (void) {
+gth_file_tool_redo_get_type (void) {
 	static GType type_id = 0;
 	if (type_id == 0) {
 		static const GTypeInfo g_define_type_info = {
-			sizeof (GthImageToolRedoClass),
+			sizeof (GthFileToolRedoClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
+			(GClassInitFunc) gth_file_tool_redo_class_init,
 			(GClassFinalizeFunc) NULL,
 			NULL,
-			sizeof (GthImageToolRedo),
+			sizeof (GthFileToolRedo),
 			0,
-			(GInstanceInitFunc) gth_image_tool_redo_instance_init,
-			NULL
-		};
-		static const GInterfaceInfo gth_file_tool_info = {
-			(GInterfaceInitFunc) gth_file_tool_interface_init,
-			(GInterfaceFinalizeFunc) NULL,
+			(GInstanceInitFunc) gth_file_tool_redo_instance_init,
 			NULL
 		};
-		type_id = g_type_register_static (GTK_TYPE_BUTTON, "GthImageToolRedo", &g_define_type_info, 0);
-		g_type_add_interface_static (type_id, GTH_TYPE_FILE_TOOL, &gth_file_tool_info);
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolRedo", &g_define_type_info, 0);
 	}
 	return type_id;
 }
diff --git a/extensions/file_tools/gth-file-tool-redo.h b/extensions/file_tools/gth-file-tool-redo.h
new file mode 100644
index 0000000..a2775a6
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-redo.h
@@ -0,0 +1,52 @@
+/* -*- 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_FILE_TOOL_REDO_H
+#define GTH_FILE_TOOL_REDO_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_REDO (gth_file_tool_redo_get_type ())
+#define GTH_FILE_TOOL_REDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_REDO, GthFileToolRedo))
+#define GTH_FILE_TOOL_REDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_REDO, GthFileToolRedoClass))
+#define GTH_IS_FILE_TOOL_REDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_REDO))
+#define GTH_IS_FILE_TOOL_REDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_REDO))
+#define GTH_FILE_TOOL_REDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_REDO, GthFileToolRedoClass))
+
+typedef struct _GthFileToolRedo GthFileToolRedo;
+typedef struct _GthFileToolRedoClass GthFileToolRedoClass;
+
+struct _GthFileToolRedo {
+	GthFileTool parent_instance;
+};
+
+struct _GthFileToolRedoClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_redo_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_REDO_H */
diff --git a/extensions/file_tools/gth-file-tool-save.c b/extensions/file_tools/gth-file-tool-save.c
new file mode 100644
index 0000000..aa66d4e
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-save.c
@@ -0,0 +1,84 @@
+/* -*- 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 <gthumb.h>
+#include "gth-file-tool-save.h"
+
+
+static void
+gth_file_tool_save_update_sensitivity (GthFileTool *base)
+{
+	GtkWidget *window;
+
+	window = gth_file_tool_get_window (base);
+	gtk_widget_set_sensitive (GTK_WIDGET (base), gth_browser_get_file_modified (GTH_BROWSER (window)));
+}
+
+
+static void
+gth_file_tool_save_activate (GthFileTool *tool)
+{
+	GtkWidget *window;
+	GtkWidget *viewer_page;
+
+	window = gth_file_tool_get_window (tool);
+	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
+	gth_viewer_page_save (GTH_VIEWER_PAGE (viewer_page), NULL, NULL, NULL);
+}
+
+
+static void
+gth_file_tool_save_instance_init (GthFileToolSave *self)
+{
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_SAVE, _("Save"), _("Save"));
+}
+
+
+static void
+gth_file_tool_save_class_init (GthFileToolClass *klass)
+{
+	klass->update_sensitivity = gth_file_tool_save_update_sensitivity;
+	klass->activate = gth_file_tool_save_activate;
+}
+
+
+GType
+gth_file_tool_save_get_type (void) {
+	static GType type_id = 0;
+	if (type_id == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthFileToolSaveClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gth_file_tool_save_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GthFileToolSave),
+			0,
+			(GInstanceInitFunc) gth_file_tool_save_instance_init,
+			NULL
+		};
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolSave", &g_define_type_info, 0);
+	}
+	return type_id;
+}
diff --git a/extensions/file_tools/gth-file-tool-save.h b/extensions/file_tools/gth-file-tool-save.h
new file mode 100644
index 0000000..fa39bbd
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-save.h
@@ -0,0 +1,52 @@
+/* -*- 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_FILE_TOOL_SAVE_H
+#define GTH_FILE_TOOL_SAVE_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_SAVE (gth_file_tool_save_get_type ())
+#define GTH_FILE_TOOL_SAVE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_SAVE, GthFileToolSave))
+#define GTH_FILE_TOOL_SAVE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_SAVE, GthFileToolSaveClass))
+#define GTH_IS_FILE_TOOL_SAVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_SAVE))
+#define GTH_IS_FILE_TOOL_SAVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_SAVE))
+#define GTH_FILE_TOOL_SAVE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_SAVE, GthFileToolSaveClass))
+
+typedef struct _GthFileToolSave GthFileToolSave;
+typedef struct _GthFileToolSaveClass GthFileToolSaveClass;
+
+struct _GthFileToolSave {
+	GthFileTool parent_instance;
+};
+
+struct _GthFileToolSaveClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_save_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_SAVE_H */
diff --git a/extensions/image_tools/gth-image-tool-undo.c b/extensions/file_tools/gth-file-tool-undo.c
similarity index 54%
rename from extensions/image_tools/gth-image-tool-undo.c
rename to extensions/file_tools/gth-file-tool-undo.c
index 2653187..a2f0532 100644
--- a/extensions/image_tools/gth-image-tool-undo.c
+++ b/extensions/file_tools/gth-file-tool-undo.c
@@ -23,15 +23,16 @@
 #include <config.h>
 #include <gthumb.h>
 #include <extensions/image_viewer/gth-image-viewer-page.h>
-#include "gth-image-tool-undo.h"
+#include "gth-file-tool-undo.h"
 
 
 static void
-gth_file_tool_undo_real_update_sensitivity (GthFileTool *base,
-					    GtkWidget   *window)
+gth_file_tool_undo_update_sensitivity (GthFileTool *base)
 {
+	GtkWidget *window;
 	GtkWidget *viewer_page;
 
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
 		gtk_widget_set_sensitive (GTK_WIDGET (base), FALSE);
@@ -41,20 +42,12 @@ gth_file_tool_undo_real_update_sensitivity (GthFileTool *base,
 
 
 static void
-gth_file_tool_interface_init (GthFileToolIface *iface)
-{
-	iface->update_sensitivity = gth_file_tool_undo_real_update_sensitivity;
-}
-
-
-static void
-button_clicked_cb (GtkButton *button,
-		   gpointer   data)
+gth_file_tool_undo_activate (GthFileTool *base)
 {
 	GtkWidget *window;
 	GtkWidget *viewer_page;
 
-	window = gtk_widget_get_toplevel (GTK_WIDGET (button));
+	window = gth_file_tool_get_window (base);
 	viewer_page = gth_browser_get_viewer_page (GTH_BROWSER (window));
 	if (! GTH_IS_IMAGE_VIEWER_PAGE (viewer_page))
 		return;
@@ -64,54 +57,37 @@ button_clicked_cb (GtkButton *button,
 
 
 static void
-gth_image_tool_undo_instance_init (GthImageToolUndo *self)
+gth_file_tool_undo_instance_init (GthFileToolUndo *self)
 {
-	GtkWidget *hbox;
-	GtkWidget *icon;
-	GtkWidget *label;
-
-	gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
-
-	hbox = gtk_hbox_new (FALSE, 6);
-
-	icon = gtk_image_new_from_stock (GTK_STOCK_UNDO, GTK_ICON_SIZE_MENU);
-	gtk_widget_show (icon);
-	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
-
-	label = gtk_label_new (_("Undo"));
-	gtk_widget_show (label);
-	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+	gth_file_tool_construct (GTH_FILE_TOOL (self), GTK_STOCK_UNDO, _("Undo"), _("Undo"));
+}
 
-	gtk_widget_show (hbox);
-	gtk_container_add (GTK_CONTAINER (self), hbox);
 
-	g_signal_connect (self, "clicked", G_CALLBACK (button_clicked_cb), self);
+static void
+gth_file_tool_undo_class_init (GthFileToolClass *klass)
+{
+	klass->update_sensitivity = gth_file_tool_undo_update_sensitivity;
+	klass->activate = gth_file_tool_undo_activate;
 }
 
 
 GType
-gth_image_tool_undo_get_type (void) {
+gth_file_tool_undo_get_type (void) {
 	static GType type_id = 0;
 	if (type_id == 0) {
 		static const GTypeInfo g_define_type_info = {
-			sizeof (GthImageToolUndoClass),
+			sizeof (GthFileToolUndoClass),
 			(GBaseInitFunc) NULL,
 			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
+			(GClassInitFunc) gth_file_tool_undo_class_init,
 			(GClassFinalizeFunc) NULL,
 			NULL,
-			sizeof (GthImageToolUndo),
+			sizeof (GthFileToolUndo),
 			0,
-			(GInstanceInitFunc) gth_image_tool_undo_instance_init,
-			NULL
-		};
-		static const GInterfaceInfo gth_file_tool_info = {
-			(GInterfaceInitFunc) gth_file_tool_interface_init,
-			(GInterfaceFinalizeFunc) NULL,
+			(GInstanceInitFunc) gth_file_tool_undo_instance_init,
 			NULL
 		};
-		type_id = g_type_register_static (GTK_TYPE_BUTTON, "GthImageToolUndo", &g_define_type_info, 0);
-		g_type_add_interface_static (type_id, GTH_TYPE_FILE_TOOL, &gth_file_tool_info);
+		type_id = g_type_register_static (GTH_TYPE_FILE_TOOL, "GthFileToolUndo", &g_define_type_info, 0);
 	}
 	return type_id;
 }
diff --git a/extensions/file_tools/gth-file-tool-undo.h b/extensions/file_tools/gth-file-tool-undo.h
new file mode 100644
index 0000000..abf6ee9
--- /dev/null
+++ b/extensions/file_tools/gth-file-tool-undo.h
@@ -0,0 +1,52 @@
+/* -*- 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_FILE_TOOL_UNDO_H
+#define GTH_FILE_TOOL_UNDO_H
+
+#include <gthumb.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL_UNDO (gth_file_tool_undo_get_type ())
+#define GTH_FILE_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL_UNDO, GthFileToolUndo))
+#define GTH_FILE_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL_UNDO, GthFileToolUndoClass))
+#define GTH_IS_FILE_TOOL_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL_UNDO))
+#define GTH_IS_FILE_TOOL_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL_UNDO))
+#define GTH_FILE_TOOL_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL_UNDO, GthFileToolUndoClass))
+
+typedef struct _GthFileToolUndo GthFileToolUndo;
+typedef struct _GthFileToolUndoClass GthFileToolUndoClass;
+
+struct _GthFileToolUndo {
+	GthFileTool parent_instance;
+};
+
+struct _GthFileToolUndoClass {
+	GthFileToolClass parent_class;
+};
+
+GType  gth_file_tool_undo_get_type  (void);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_UNDO_H */
diff --git a/extensions/image_tools/main.c b/extensions/file_tools/main.c
similarity index 65%
rename from extensions/image_tools/main.c
rename to extensions/file_tools/main.c
index 920aa08..54978f8 100644
--- a/extensions/image_tools/main.c
+++ b/extensions/file_tools/main.c
@@ -24,24 +24,21 @@
 #include <config.h>
 #include <gtk/gtk.h>
 #include <gthumb.h>
-#include "gth-image-tool-crop.h"
-#include "gth-image-tool-desaturate.h"
-#include "gth-image-tool-redo.h"
-#include "gth-image-tool-save.h"
-#include "gth-image-tool-undo.h"
+#include "gth-file-tool-crop.h"
+#include "gth-file-tool-desaturate.h"
+#include "gth-file-tool-redo.h"
+#include "gth-file-tool-save.h"
+#include "gth-file-tool-undo.h"
 
 
 G_MODULE_EXPORT void
 gthumb_extension_activate (void)
 {
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_SAVE);
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_UNDO);
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_REDO);
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_CROP);
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_DESATURATE);
-
-	/*gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_SAVE);
-	gth_main_register_type ("file-tools", GTH_TYPE_IMAGE_TOOL_SAVE_AS);*/
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_UNDO);
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_REDO);
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_SAVE);
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_CROP);
+	gth_main_register_type ("file-tools", GTH_TYPE_FILE_TOOL_DESATURATE);
 }
 
 
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index 0e65ad5..6ce0e53 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -47,6 +47,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-file-source.h				\
 	gth-file-source-vfs.h				\
 	gth-file-store.h				\
+	gth-file-tool.h					\
 	gth-file-view.h					\
 	gth-filter.h					\
 	gth-filterbar.h					\
@@ -61,8 +62,8 @@ PUBLIC_HEADER_FILES = 					\
 	gth-image-loader.h				\
 	gth-image-preloader.h				\
 	gth-image-selector.h				\
-	gth-image-tool.h				\
 	gth-image-viewer.h				\
+	gth-image-viewer-tool.h				\
 	gth-location-chooser.h				\
 	gth-main.h					\
 	gth-marshal.h					\
@@ -145,6 +146,7 @@ gthumb_SOURCES = 					\
 	gth-file-source.c				\
 	gth-file-source-vfs.c				\
 	gth-file-store.c				\
+	gth-file-tool.c					\
 	gth-file-view.c					\
 	gth-filter.c					\
 	gth-filterbar.c					\
@@ -159,8 +161,8 @@ gthumb_SOURCES = 					\
 	gth-image-loader.c				\
 	gth-image-preloader.c				\
 	gth-image-selector.c				\
-	gth-image-tool.c				\
 	gth-image-viewer.c				\
+	gth-image-viewer-tool.c				\
 	gth-location-chooser.c				\
 	gth-main.c					\
 	gth-main-default-hooks.c			\
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 04afeb7..dcf45ba 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -2576,7 +2576,7 @@ _gth_browser_construct (GthBrowser *browser)
 	gtk_widget_show (browser->priv->viewer_container);
 	gtk_paned_pack1 (GTK_PANED (browser->priv->viewer_pane), browser->priv->viewer_container, TRUE, TRUE);
 
-	browser->priv->viewer_sidebar = gth_sidebar_new ();
+	browser->priv->viewer_sidebar = gth_sidebar_new ("file-tools");
 	gtk_paned_pack2 (GTK_PANED (browser->priv->viewer_pane), browser->priv->viewer_sidebar, FALSE, TRUE);
 
 	/* -- browser page -- */
@@ -2701,7 +2701,7 @@ _gth_browser_construct (GthBrowser *browser)
 
 	/* the file property box */
 
-	browser->priv->file_properties = gth_sidebar_new ();
+	browser->priv->file_properties = gth_sidebar_new ("file-list-tools");
 	gtk_widget_hide (browser->priv->file_properties);
 	gtk_paned_pack2 (GTK_PANED (browser->priv->browser_sidebar), browser->priv->file_properties, FALSE, TRUE);
 
@@ -3555,7 +3555,7 @@ gth_browser_show_viewer_properties (GthBrowser *browser,
 	if (show) {
 		_gth_browser_set_action_active (browser, "Viewer_Tools", FALSE);
 		gtk_widget_show (browser->priv->viewer_sidebar);
-		gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->priv->viewer_sidebar), GTH_SIDEBAR_PAGE_PROPERTIES);
+		gth_sidebar_show_properties (GTH_SIDEBAR (browser->priv->viewer_sidebar));
 	}
 	else
 		gtk_widget_hide (browser->priv->viewer_sidebar);
@@ -3569,7 +3569,7 @@ gth_browser_show_viewer_tools (GthBrowser *browser,
 	if (show) {
 		_gth_browser_set_action_active (browser, "Viewer_Properties", FALSE);
 		gtk_widget_show (browser->priv->viewer_sidebar);
-		gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->priv->viewer_sidebar), GTH_SIDEBAR_PAGE_TOOLS);
+		gth_sidebar_show_tools (GTH_SIDEBAR (browser->priv->viewer_sidebar));
 	}
 	else
 		gtk_widget_hide (browser->priv->viewer_sidebar);
diff --git a/gthumb/gth-file-tool.c b/gthumb/gth-file-tool.c
new file mode 100644
index 0000000..d966e79
--- /dev/null
+++ b/gthumb/gth-file-tool.c
@@ -0,0 +1,254 @@
+/* -*- 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-file-tool.h"
+
+
+enum {
+        SHOW_OPTIONS,
+        HIDE_OPTIONS,
+        LAST_SIGNAL
+};
+
+
+static gpointer parent_class = NULL;
+static guint gth_file_tool_signals[LAST_SIGNAL] = { 0 };
+
+
+struct _GthFileToolPrivate {
+	GtkWidget  *window;
+	const char *icon_name;
+	const char *button_text;
+	const char *options_title;
+};
+
+
+static void
+gth_file_tool_base_update_sensitivity (GthFileTool *self)
+{
+	/* void */
+}
+
+
+static void
+gth_file_tool_base_activate (GthFileTool *self)
+{
+	/* void*/
+}
+
+
+static GtkWidget *
+gth_file_tool_base_get_options (GthFileTool *self)
+{
+	return NULL;
+}
+
+
+static void
+gth_file_tool_base_destroy_options (GthFileTool *self)
+{
+	/* void */
+}
+
+
+static void
+gth_file_tool_finalize (GObject *object)
+{
+	GthFileTool *self;
+
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (GTH_IS_FILE_TOOL (object));
+
+	self = (GthFileTool *) object;
+
+	/* Chain up */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_file_tool_class_init (GthFileToolClass *klass)
+{
+	GObjectClass *gobject_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthFileToolPrivate));
+
+	gobject_class = (GObjectClass*) klass;
+	gobject_class->finalize = gth_file_tool_finalize;
+
+	klass->update_sensitivity = gth_file_tool_base_update_sensitivity;
+	klass->activate = gth_file_tool_base_activate;
+	klass->get_options = gth_file_tool_base_get_options;
+	klass->destroy_options = gth_file_tool_base_destroy_options;
+
+	gth_file_tool_signals[SHOW_OPTIONS] =
+	                g_signal_new ("show-options",
+	                              G_TYPE_FROM_CLASS (klass),
+	                              G_SIGNAL_RUN_LAST,
+	                              G_STRUCT_OFFSET (GthFileToolClass, show_options),
+	                              NULL, NULL,
+	                              g_cclosure_marshal_VOID__VOID,
+	                              G_TYPE_NONE,
+	                              0);
+	gth_file_tool_signals[HIDE_OPTIONS] =
+			g_signal_new ("hide-options",
+		                      G_TYPE_FROM_CLASS (klass),
+		                      G_SIGNAL_RUN_LAST,
+		                      G_STRUCT_OFFSET (GthFileToolClass, hide_options),
+		                      NULL, NULL,
+		                      g_cclosure_marshal_VOID__VOID,
+		                      G_TYPE_NONE,
+		                      0);
+}
+
+
+static void
+gth_file_tool_instance_init (GthFileTool *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_FILE_TOOL, GthFileToolPrivate);
+	self->priv->icon_name = NULL;
+	self->priv->button_text = NULL;
+	self->priv->options_title = NULL;
+
+	gtk_button_set_relief (GTK_BUTTON (self), GTK_RELIEF_NONE);
+}
+
+
+GType
+gth_file_tool_get_type (void) {
+	static GType type_id = 0;
+	if (type_id == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthFileToolClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gth_file_tool_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GthFileTool),
+			0,
+			(GInstanceInitFunc) gth_file_tool_instance_init,
+			NULL
+		};
+		type_id = g_type_register_static (GTK_TYPE_BUTTON, "GthFileTool", &g_define_type_info, 0);
+	}
+	return type_id;
+}
+
+
+void
+gth_file_tool_construct (GthFileTool *self,
+			 const char  *icon_name,
+			 const char  *button_text,
+			 const char  *options_title)
+{
+	GtkWidget *hbox;
+	GtkWidget *icon;
+	GtkWidget *label;
+
+	self->priv->icon_name = icon_name;
+	self->priv->button_text = button_text;
+	self->priv->options_title = options_title;
+
+	hbox = gtk_hbox_new (FALSE, 6);
+
+	icon = gtk_image_new_from_stock (icon_name, GTK_ICON_SIZE_MENU);
+	gtk_widget_show (icon);
+	gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
+
+	label = gtk_label_new (button_text);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+
+	gtk_widget_show (hbox);
+	gtk_container_add (GTK_CONTAINER (self), hbox);
+}
+
+
+GtkWidget *
+gth_file_tool_get_window (GthFileTool *self)
+{
+	if (self->priv->window == NULL) {
+		self->priv->window = gtk_widget_get_toplevel (GTK_WIDGET (self));
+		if (! GTK_WIDGET_TOPLEVEL (self->priv->window))
+			self->priv->window = NULL;
+	}
+	return self->priv->window;
+}
+
+
+const char *
+gth_file_tool_get_icon_name (GthFileTool *self)
+{
+	return self->priv->icon_name;
+}
+
+
+void
+gth_file_tool_activate (GthFileTool *self)
+{
+	GTH_FILE_TOOL_GET_CLASS (self)->activate (self);
+}
+
+
+void
+gth_file_tool_update_sensitivity (GthFileTool *self)
+{
+	GTH_FILE_TOOL_GET_CLASS (self)->update_sensitivity (self);
+}
+
+
+void
+gth_file_tool_show_options (GthFileTool *self)
+{
+	g_signal_emit (self, gth_file_tool_signals[SHOW_OPTIONS], 0, NULL);
+}
+
+
+void
+gth_file_tool_hide_options (GthFileTool *self)
+{
+	g_signal_emit (self, gth_file_tool_signals[HIDE_OPTIONS], 0, NULL);
+}
+
+
+GtkWidget *
+gth_file_tool_get_options (GthFileTool *self)
+{
+	return GTH_FILE_TOOL_GET_CLASS (self)->get_options (self);
+}
+
+
+const char *
+gth_file_tool_get_options_title (GthFileTool *self)
+{
+	return self->priv->options_title;
+}
+
+
+void
+gth_file_tool_destroy_options (GthFileTool *self)
+{
+	GTH_FILE_TOOL_GET_CLASS (self)->destroy_options (self);
+}
diff --git a/gthumb/gth-file-tool.h b/gthumb/gth-file-tool.h
new file mode 100644
index 0000000..79ba3a1
--- /dev/null
+++ b/gthumb/gth-file-tool.h
@@ -0,0 +1,79 @@
+/* -*- 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_FILE_TOOL_H
+#define GTH_FILE_TOOL_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_FILE_TOOL (gth_file_tool_get_type ())
+#define GTH_FILE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL, GthFileTool))
+#define GTH_FILE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_FILE_TOOL, GthFileToolClass))
+#define GTH_IS_FILE_TOOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL))
+#define GTH_IS_FILE_TOOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_FILE_TOOL))
+#define GTH_FILE_TOOL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_FILE_TOOL, GthFileToolClass))
+
+typedef struct _GthFileTool GthFileTool;
+typedef struct _GthFileToolClass GthFileToolClass;
+typedef struct _GthFileToolPrivate GthFileToolPrivate;
+
+struct _GthFileTool {
+	GtkButton parent_instance;
+	GthFileToolPrivate *priv;
+};
+
+struct _GthFileToolClass {
+	GtkButtonClass parent_class;
+
+	/*< virtual functions >*/
+
+	void         (*update_sensitivity) (GthFileTool *self);
+	void         (*activate)           (GthFileTool *self);
+	GtkWidget *  (*get_options)        (GthFileTool *self);
+	void         (*destroy_options)    (GthFileTool *self);
+
+	/*< signals >*/
+
+	void         (*show_options)       (GthFileTool *self);
+	void         (*hide_options)       (GthFileTool *self);
+};
+
+GType         gth_file_tool_get_type            (void);
+void          gth_file_tool_construct           (GthFileTool *self,
+					         const char  *icon_name,
+					         const char  *button_text,
+					         const char  *options_title);
+GtkWidget *   gth_file_tool_get_window          (GthFileTool *self);
+const char *  gth_file_tool_get_icon_name       (GthFileTool *self);
+void          gth_file_tool_activate            (GthFileTool *self);
+void          gth_file_tool_update_sensitivity  (GthFileTool *self);
+GtkWidget *   gth_file_tool_get_options         (GthFileTool *self);
+const char *  gth_file_tool_get_options_title   (GthFileTool *self);
+void          gth_file_tool_destroy_options     (GthFileTool *self);
+void          gth_file_tool_show_options        (GthFileTool *self);
+void          gth_file_tool_hide_options        (GthFileTool *self);
+
+G_END_DECLS
+
+#endif /* GTH_FILE_TOOL_H */
diff --git a/gthumb/gth-image-dragger.c b/gthumb/gth-image-dragger.c
index c5c2836..d987de2 100644
--- a/gthumb/gth-image-dragger.c
+++ b/gthumb/gth-image-dragger.c
@@ -68,22 +68,22 @@ gth_image_dragger_instance_init (GthImageDragger *dragger)
 
 
 static void
-gth_image_dragger_realize (GthImageTool *base)
+gth_image_dragger_realize (GthImageViewerTool *base)
 {
 	/* void */
 }
 
 
 static void
-gth_image_dragger_unrealize (GthImageTool *base)
+gth_image_dragger_unrealize (GthImageViewerTool *base)
 {
 	/* void */
 }
 
 
 static void
-gth_image_dragger_size_allocate (GthImageTool  *self,
-				 GtkAllocation *allocation)
+gth_image_dragger_size_allocate (GthImageViewerTool  *self,
+				 GtkAllocation       *allocation)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -104,8 +104,8 @@ gth_image_dragger_size_allocate (GthImageTool  *self,
 
 
 static void
-gth_image_dragger_expose (GthImageTool *self,
-			  GdkRectangle *event_area)
+gth_image_dragger_expose (GthImageViewerTool *self,
+			  GdkRectangle       *event_area)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -140,8 +140,8 @@ gth_image_dragger_expose (GthImageTool *self,
 
 
 static gboolean
-gth_image_dragger_button_press (GthImageTool   *self,
-				GdkEventButton *event)
+gth_image_dragger_button_press (GthImageViewerTool *self,
+				GdkEventButton     *event)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -183,8 +183,8 @@ gth_image_dragger_button_press (GthImageTool   *self,
 
 
 static gboolean
-gth_image_dragger_button_release (GthImageTool   *self,
-				  GdkEventButton *event)
+gth_image_dragger_button_release (GthImageViewerTool *self,
+				  GdkEventButton     *event)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -203,8 +203,8 @@ gth_image_dragger_button_release (GthImageTool   *self,
 
 
 static gboolean
-gth_image_dragger_motion_notify (GthImageTool   *self,
-				 GdkEventMotion *event)
+gth_image_dragger_motion_notify (GthImageViewerTool *self,
+				 GdkEventMotion     *event)
 {
 	GthImageDragger *dragger;
 	GthImageViewer  *viewer;
@@ -229,21 +229,21 @@ gth_image_dragger_motion_notify (GthImageTool   *self,
 
 
 static void
-gth_image_dragger_image_changed (GthImageTool *self)
+gth_image_dragger_image_changed (GthImageViewerTool *self)
 {
 	/* void */
 }
 
 
 static void
-gth_image_dragger_zoom_changed (GthImageTool *self)
+gth_image_dragger_zoom_changed (GthImageViewerTool *self)
 {
 	/* void */
 }
 
 
 static void
-gth_image_dragger_gth_image_tool_interface_init (GthImageToolIface *iface)
+gth_image_dragger_gth_image_tool_interface_init (GthImageViewerToolIface *iface)
 {
 	iface->realize = gth_image_dragger_realize;
 	iface->unrealize = gth_image_dragger_unrealize;
@@ -284,14 +284,14 @@ gth_image_dragger_get_type (void)
 					       "GthImageDragger",
 					       &type_info,
 					       0);
-		g_type_add_interface_static (type, GTH_TYPE_IMAGE_TOOL, &gth_image_tool_info);
+		g_type_add_interface_static (type, GTH_TYPE_IMAGE_VIEWER_TOOL, &gth_image_tool_info);
 	}
 
 	return type;
 }
 
 
-GthImageTool *
+GthImageViewerTool *
 gth_image_dragger_new (GthImageViewer *viewer)
 {
 	GthImageDragger *dragger;
@@ -299,5 +299,5 @@ gth_image_dragger_new (GthImageViewer *viewer)
 	dragger = g_object_new (GTH_TYPE_IMAGE_DRAGGER, NULL);
 	dragger->priv->viewer = viewer;
 
-	return GTH_IMAGE_TOOL (dragger);
+	return GTH_IMAGE_VIEWER_TOOL (dragger);
 }
diff --git a/gthumb/gth-image-dragger.h b/gthumb/gth-image-dragger.h
index 65e14e0..cb87fa0 100644
--- a/gthumb/gth-image-dragger.h
+++ b/gthumb/gth-image-dragger.h
@@ -25,8 +25,8 @@
 
 #include <glib.h>
 #include <glib-object.h>
-#include "gth-image-tool.h"
 #include "gth-image-viewer.h"
+#include "gth-image-viewer-tool.h"
 
 G_BEGIN_DECLS
 
@@ -52,8 +52,8 @@ struct _GthImageDraggerClass
 	GObjectClass __parent_class;
 };
 
-GType           gth_image_dragger_get_type (void);
-GthImageTool *  gth_image_dragger_new      (GthImageViewer *viewer);
+GType                 gth_image_dragger_get_type (void);
+GthImageViewerTool *  gth_image_dragger_new      (GthImageViewer *viewer);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-image-selector.c b/gthumb/gth-image-selector.c
index f694955..aefe823 100644
--- a/gthumb/gth-image-selector.c
+++ b/gthumb/gth-image-selector.c
@@ -502,7 +502,7 @@ init_selection (GthImageSelector *self)
 
 
 static void
-gth_image_selector_realize (GthImageTool *base)
+gth_image_selector_realize (GthImageViewerTool *base)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 	GtkWidget        *widget;
@@ -540,7 +540,7 @@ gth_image_selector_realize (GthImageTool *base)
 
 
 static void
-gth_image_selector_unrealize (GthImageTool *base)
+gth_image_selector_unrealize (GthImageViewerTool *base)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -559,8 +559,8 @@ gth_image_selector_unrealize (GthImageTool *base)
 
 
 static void
-gth_image_selector_size_allocate (GthImageTool  *base,
-				  GtkAllocation *allocation)
+gth_image_selector_size_allocate (GthImageViewerTool *base,
+				  GtkAllocation      *allocation)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -646,8 +646,8 @@ paint_image (GthImageSelector *self,
 
 
 static void
-gth_image_selector_expose (GthImageTool *base,
-			   GdkRectangle *event_area)
+gth_image_selector_expose (GthImageViewerTool *base,
+			   GdkRectangle       *event_area)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -731,8 +731,8 @@ update_cursor (GthImageSelector *self,
 
 
 static gboolean
-gth_image_selector_button_release (GthImageTool   *base,
-				   GdkEventButton *event)
+gth_image_selector_button_release (GthImageViewerTool *base,
+				   GdkEventButton     *event)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -850,8 +850,8 @@ check_and_set_new_selection (GthImageSelector *self,
 
 
 static gboolean
-gth_image_selector_button_press (GthImageTool   *base,
-				 GdkEventButton *event)
+gth_image_selector_button_press (GthImageViewerTool *base,
+				 GdkEventButton     *event)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 	gboolean          retval = FALSE;
@@ -1116,8 +1116,8 @@ autoscroll_cb (gpointer data)
 
 
 static gboolean
-gth_image_selector_motion_notify (GthImageTool   *base,
-				  GdkEventMotion *event)
+gth_image_selector_motion_notify (GthImageViewerTool *base,
+				  GdkEventMotion     *event)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 	GtkWidget        *widget;
@@ -1215,7 +1215,7 @@ gth_image_selector_motion_notify (GthImageTool   *base,
 
 
 static void
-gth_image_selector_image_changed (GthImageTool *base)
+gth_image_selector_image_changed (GthImageViewerTool *base)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 
@@ -1249,7 +1249,7 @@ gth_image_selector_image_changed (GthImageTool *base)
 
 
 static void
-gth_image_selector_zoom_changed (GthImageTool *base)
+gth_image_selector_zoom_changed (GthImageViewerTool *base)
 {
 	GthImageSelector *self = GTH_IMAGE_SELECTOR (base);
 	GdkRectangle      selection;
@@ -1339,7 +1339,7 @@ gth_image_selector_class_init (GthImageSelectorClass *class)
 
 
 static void
-gth_image_selector_gth_image_tool_interface_init (GthImageToolIface *iface)
+gth_image_selector_gth_image_tool_interface_init (GthImageViewerToolIface *iface)
 {
 	iface->realize = gth_image_selector_realize;
 	iface->unrealize = gth_image_selector_unrealize;
@@ -1380,14 +1380,14 @@ gth_image_selector_get_type (void)
 					       "GthImageSelector",
 					       &type_info,
 					       0);
-		g_type_add_interface_static (type, GTH_TYPE_IMAGE_TOOL, &gth_image_tool_info);
+		g_type_add_interface_static (type, GTH_TYPE_IMAGE_VIEWER_TOOL, &gth_image_tool_info);
 	}
 
 	return type;
 }
 
 
-GthImageTool *
+GthImageViewerTool *
 gth_image_selector_new (GthImageViewer  *viewer,
 			GthSelectorType  type)
 {
@@ -1396,7 +1396,7 @@ gth_image_selector_new (GthImageViewer  *viewer,
 	selector = g_object_new (GTH_TYPE_IMAGE_SELECTOR, NULL);
 	selector->priv->viewer = viewer;
 
-	return GTH_IMAGE_TOOL (selector);
+	return GTH_IMAGE_VIEWER_TOOL (selector);
 }
 
 
diff --git a/gthumb/gth-image-selector.h b/gthumb/gth-image-selector.h
index 2f60445..0a548d5 100644
--- a/gthumb/gth-image-selector.h
+++ b/gthumb/gth-image-selector.h
@@ -25,8 +25,8 @@
 
 #include <glib.h>
 #include <glib-object.h>
-#include "gth-image-tool.h"
 #include "gth-image-viewer.h"
+#include "gth-image-viewer-tool.h"
 
 G_BEGIN_DECLS
 
@@ -68,30 +68,30 @@ struct _GthImageSelectorClass
 	void (* mask_visibility_changed) (GthImageSelector *selector);
 };
 
-GType           gth_image_selector_get_type             (void);
-GthImageTool *  gth_image_selector_new                  (GthImageViewer   *viewer,
-							 GthSelectorType   type);
-void            gth_image_selector_set_selection_x      (GthImageSelector *selector,
-							 int               x);
-void            gth_image_selector_set_selection_y      (GthImageSelector *selector,
-							 int               y);
-void            gth_image_selector_set_selection_width  (GthImageSelector *selector,
-							 int               width);
-void            gth_image_selector_set_selection_height (GthImageSelector *selector,
-							 int               height);
-void            gth_image_selector_set_selection        (GthImageSelector *selector,
-							 GdkRectangle      selection);
-void            gth_image_selector_get_selection        (GthImageSelector *selector,
-							 GdkRectangle     *selection);
-void            gth_image_selector_set_ratio            (GthImageSelector *selector,
-							 gboolean          use_ratio,
-							 double            ratio,
-							 gboolean          swap_x_and_y_to_start);
-double          gth_image_selector_get_ratio            (GthImageSelector *selector);
-gboolean        gth_image_selector_get_use_ratio        (GthImageSelector *selector);
-void            gth_image_selector_set_mask_visible     (GthImageSelector *selector,
-							 gboolean          visible);
-gboolean        gth_image_selector_get_mask_visible     (GthImageSelector *selector);
+GType                 gth_image_selector_get_type             (void);
+GthImageViewerTool *  gth_image_selector_new                  (GthImageViewer   *viewer,
+							       GthSelectorType   type);
+void                  gth_image_selector_set_selection_x      (GthImageSelector *selector,
+							       int               x);
+void                  gth_image_selector_set_selection_y      (GthImageSelector *selector,
+							       int               y);
+void                  gth_image_selector_set_selection_width  (GthImageSelector *selector,
+							       int               width);
+void                  gth_image_selector_set_selection_height (GthImageSelector *selector,
+							       int               height);
+void                  gth_image_selector_set_selection        (GthImageSelector *selector,
+							       GdkRectangle      selection);
+void                  gth_image_selector_get_selection        (GthImageSelector *selector,
+							       GdkRectangle     *selection);
+void                  gth_image_selector_set_ratio            (GthImageSelector *selector,
+							       gboolean          use_ratio,
+							       double            ratio,
+							       gboolean          swap_x_and_y_to_start);
+double                gth_image_selector_get_ratio            (GthImageSelector *selector);
+gboolean              gth_image_selector_get_use_ratio        (GthImageSelector *selector);
+void                  gth_image_selector_set_mask_visible     (GthImageSelector *selector,
+							       gboolean          visible);
+gboolean              gth_image_selector_get_mask_visible     (GthImageSelector *selector);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-image-viewer-tool.c b/gthumb/gth-image-viewer-tool.c
new file mode 100644
index 0000000..c56d35a
--- /dev/null
+++ b/gthumb/gth-image-viewer-tool.c
@@ -0,0 +1,118 @@
+/* -*- 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-image-viewer-tool.h"
+
+
+GType
+gth_image_viewer_tool_get_type (void)
+{
+	static GType type_id = 0;
+	if (type_id == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthImageViewerToolIface),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) NULL,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			0,
+			0,
+			(GInstanceInitFunc) NULL,
+			NULL
+		};
+		type_id = g_type_register_static (G_TYPE_INTERFACE,
+						  "GthImageViewerTool",
+						  &g_define_type_info,
+						  0);
+	}
+	return type_id;
+}
+
+
+void
+gth_image_viewer_tool_realize (GthImageViewerTool *self)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->realize (self);
+}
+
+
+void
+gth_image_viewer_tool_unrealize (GthImageViewerTool *self)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->unrealize (self);
+}
+
+
+void
+gth_image_viewer_tool_size_allocate (GthImageViewerTool *self,
+			      GtkAllocation      *allocation)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->size_allocate (self, allocation);
+}
+
+
+void
+gth_image_viewer_tool_expose (GthImageViewerTool *self,
+		       GdkRectangle       *paint_area)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->expose (self, paint_area);
+}
+
+
+gboolean
+gth_image_viewer_tool_button_press (GthImageViewerTool *self,
+			     GdkEventButton     *event)
+{
+	return GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->button_press (self, event);
+}
+
+
+gboolean
+gth_image_viewer_tool_button_release (GthImageViewerTool *self,
+			       GdkEventButton     *event)
+{
+	return GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->button_release (self, event);
+}
+
+
+gboolean
+gth_image_viewer_tool_motion_notify (GthImageViewerTool *self,
+			      GdkEventMotion     *event)
+{
+	return GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->motion_notify (self, event);
+}
+
+
+void
+gth_image_viewer_tool_image_changed (GthImageViewerTool *self)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->image_changed (self);
+}
+
+
+void
+gth_image_viewer_tool_zoom_changed (GthImageViewerTool *self)
+{
+	GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE (self)->zoom_changed (self);
+}
diff --git a/gthumb/gth-image-viewer-tool.h b/gthumb/gth-image-viewer-tool.h
new file mode 100644
index 0000000..be2f28b
--- /dev/null
+++ b/gthumb/gth-image-viewer-tool.h
@@ -0,0 +1,75 @@
+/* -*- 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_IMAGE_VIEWER_TOOL_H
+#define GTH_IMAGE_VIEWER_TOOL_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_IMAGE_VIEWER_TOOL               (gth_image_viewer_tool_get_type ())
+#define GTH_IMAGE_VIEWER_TOOL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_IMAGE_VIEWER_TOOL, GthImageViewerTool))
+#define GTH_IS_IMAGE_VIEWER_TOOL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_IMAGE_VIEWER_TOOL))
+#define GTH_IMAGE_VIEWER_TOOL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTH_TYPE_IMAGE_VIEWER_TOOL, GthImageViewerToolIface))
+
+typedef struct _GthImageViewerTool GthImageViewerTool;
+typedef struct _GthImageViewerToolIface GthImageViewerToolIface;
+
+struct _GthImageViewerToolIface {
+	GTypeInterface parent_iface;
+
+	void      (*realize)        (GthImageViewerTool   *self);
+	void      (*unrealize)      (GthImageViewerTool   *self);
+	void      (*size_allocate)  (GthImageViewerTool   *self,
+				     GtkAllocation  *allocation);
+	void      (*expose)         (GthImageViewerTool   *self,
+				     GdkRectangle   *paint_area);
+	gboolean  (*button_press)   (GthImageViewerTool   *self,
+				     GdkEventButton *event);
+	gboolean  (*button_release) (GthImageViewerTool   *self,
+				     GdkEventButton *event);
+	gboolean  (*motion_notify)  (GthImageViewerTool   *self,
+				     GdkEventMotion *event);
+	void      (*image_changed)  (GthImageViewerTool   *self);
+	void      (*zoom_changed)   (GthImageViewerTool   *self);
+};
+
+GType      gth_image_viewer_tool_get_type         (void);
+void       gth_image_viewer_tool_realize          (GthImageViewerTool *self);
+void       gth_image_viewer_tool_unrealize        (GthImageViewerTool *self);
+void       gth_image_viewer_tool_size_allocate    (GthImageViewerTool *self,
+						   GtkAllocation      *allocation);
+void       gth_image_viewer_tool_expose           (GthImageViewerTool *self,
+						   GdkRectangle       *paint_area);
+gboolean   gth_image_viewer_tool_button_press     (GthImageViewerTool *self,
+						   GdkEventButton     *event);
+gboolean   gth_image_viewer_tool_button_release   (GthImageViewerTool *self,
+						   GdkEventButton     *event);
+gboolean   gth_image_viewer_tool_motion_notify    (GthImageViewerTool *self,
+						   GdkEventMotion     *event);
+void       gth_image_viewer_tool_image_changed    (GthImageViewerTool *self);
+void       gth_image_viewer_tool_zoom_changed     (GthImageViewerTool *self);
+
+G_END_DECLS
+
+#endif /* GTH_IMAGE_VIEWER_TOOL_H */
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index c5ede2d..6ccfc13 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -65,65 +65,65 @@ enum {
 
 
 struct _GthImageViewerPrivate {
-	gboolean         is_animation;
-	gboolean         play_animation;
-	gboolean         rendering;
-	gboolean         cursor_visible;
+	gboolean                is_animation;
+	gboolean                play_animation;
+	gboolean                rendering;
+	gboolean                cursor_visible;
 
-	gboolean         frame_visible;
-	int              frame_border;
-	int              frame_border2;
+	gboolean                frame_visible;
+	int                     frame_border;
+	int                     frame_border2;
 
-	GthTranspType    transp_type;
-	GthCheckType     check_type;
-	int              check_size;
-	guint32          check_color1;
-	guint32          check_color2;
+	GthTranspType           transp_type;
+	GthCheckType            check_type;
+	int                     check_size;
+	guint32                 check_color1;
+	guint32                 check_color2;
 
-	guint            anim_id;
-	GdkPixbuf       *frame_pixbuf;
-	int              frame_delay;
+	guint                   anim_id;
+	GdkPixbuf              *frame_pixbuf;
+	int                     frame_delay;
 
 	GthImageLoader         *loader;
 	GdkPixbufAnimation     *anim;
 	GdkPixbufAnimationIter *iter;
-	GTimeVal                time;        /* Timer used to get the right
-					      * frame. */
+	GTimeVal                time;               /* Timer used to get the right
+					             * frame. */
 
-	GthImageTool    *tool;
+	GthImageViewerTool     *tool;
 
-	GdkCursor       *cursor;
-	GdkCursor       *cursor_void;
+	GdkCursor              *cursor;
+	GdkCursor              *cursor_void;
 
-	double           zoom_level;
-	guint            zoom_quality : 1;   /* A ZoomQualityType value. */
-	guint            zoom_change : 3;    /* A ZoomChangeType value. */
+	double                  zoom_level;
+	guint                   zoom_quality : 1;   /* A ZoomQualityType value. */
+	guint                   zoom_change : 3;    /* A ZoomChangeType value. */
 
-	GthFit           fit;
-	gboolean         doing_zoom_fit;     /* Whether we are performing
-					      * a zoom to fit the window. */
-	gboolean         is_void;            /* If TRUE do not show anything.
-					      *	Itis resetted to FALSE we an
-					      * image is loaded. */
+	GthFit                  fit;
+	gboolean                doing_zoom_fit;     /* Whether we are performing
+					             * a zoom to fit the window. */
+	gboolean                is_void;            /* If TRUE do not show anything.
+					             * It is reset to FALSE we an
+					             * image is loaded. */
 
-	gboolean         double_click;
-	gboolean         just_focused;
+	gboolean                double_click;
+	gboolean                just_focused;
 
-	GdkPixbuf       *paint_pixbuf;
-	int              paint_max_width;
-	int              paint_max_height;
-	int              paint_bps;
-	GdkColorspace    paint_color_space;
+	GdkPixbuf              *paint_pixbuf;
+	int                     paint_max_width;
+	int                     paint_max_height;
+	int                     paint_bps;
+	GdkColorspace           paint_color_space;
 
-	gboolean         black_bg;
+	gboolean                black_bg;
 
-	gboolean         skip_zoom_change;
-	gboolean         skip_size_change;
+	gboolean                skip_zoom_change;
+	gboolean                skip_size_change;
 
-	gboolean         next_scroll_repaint; /* used in fullscreen mode to
-					       * delete the comment before
-					       * scrolling. */
-	gboolean         reset_scrollbars;
+	gboolean                next_scroll_repaint; /* used in fullscreen mode to
+					              * delete the comment before
+					              * scrolling. */
+	gboolean                reset_scrollbars;
 };
 
 
@@ -301,7 +301,7 @@ set_zoom (GthImageViewer *viewer,
 	viewer->priv->zoom_level = zoom_level;
 
 	_gth_image_viewer_update_image_area (viewer);
-	gth_image_tool_zoom_changed (viewer->priv->tool);
+	gth_image_viewer_tool_zoom_changed (viewer->priv->tool);
 
 	if (! viewer->priv->doing_zoom_fit) {
 		gtk_widget_queue_resize (GTK_WIDGET (viewer));
@@ -382,7 +382,7 @@ gth_image_viewer_realize (GtkWidget *widget)
 		viewer->priv->check_color2 = base_color;
 	}
 
-	gth_image_tool_realize (viewer->priv->tool);
+	gth_image_viewer_tool_realize (viewer->priv->tool);
 }
 
 
@@ -404,7 +404,7 @@ gth_image_viewer_unrealize (GtkWidget *widget)
 		viewer->priv->cursor_void = NULL;
 	}
 
-	gth_image_tool_unrealize (viewer->priv->tool);
+	gth_image_viewer_tool_unrealize (viewer->priv->tool);
 
 	GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
 }
@@ -577,7 +577,7 @@ gth_image_viewer_size_allocate (GtkWidget       *widget,
 					allocation->x, allocation->y,
 					allocation->width, allocation->height);
 
-	gth_image_tool_size_allocate (viewer->priv->tool, allocation);
+	gth_image_viewer_tool_size_allocate (viewer->priv->tool, allocation);
 
 	if (! viewer->priv->skip_size_change)
 		g_signal_emit (G_OBJECT (viewer),
@@ -831,7 +831,7 @@ gth_image_viewer_expose (GtkWidget      *widget,
 			       x2, y2);
 	}
 
-	gth_image_tool_expose (viewer->priv->tool, &event->area);
+	gth_image_viewer_tool_expose (viewer->priv->tool, &event->area);
 
 	viewer->priv->rendering = FALSE;
 
@@ -885,7 +885,7 @@ gth_image_viewer_button_press (GtkWidget      *widget,
 	else
 		viewer->priv->double_click = FALSE;
 
-	retval = gth_image_tool_button_press (viewer->priv->tool, event);
+	retval = gth_image_viewer_tool_button_press (viewer->priv->tool, event);
 
 	if (viewer->pressed) {
 		viewer->event_x_start = viewer->event_x_prev = event->x;
@@ -914,7 +914,7 @@ gth_image_viewer_button_release (GtkWidget      *widget,
 			       0);
 	}
 
-	gth_image_tool_button_release (viewer->priv->tool, event);
+	gth_image_viewer_tool_button_release (viewer->priv->tool, event);
 
 	viewer->priv->just_focused = FALSE;
 	viewer->pressed = FALSE;
@@ -1098,7 +1098,7 @@ gth_image_viewer_motion_notify (GtkWidget      *widget,
 		viewer->drag_y = event->y + viewer->y_offset;
 	}
 
-	gth_image_tool_motion_notify (viewer->priv->tool, event);
+	gth_image_viewer_tool_motion_notify (viewer->priv->tool, event);
 
 	if (viewer->pressed) {
 		viewer->event_x_prev = event->x;
@@ -1683,7 +1683,7 @@ image_loader_ready_cb (GthImageLoader *il,
 	if (viewer->priv->is_animation)
 		init_animation (viewer);
 
-	gth_image_tool_image_changed (viewer->priv->tool);
+	gth_image_viewer_tool_image_changed (viewer->priv->tool);
 
 	switch (viewer->priv->zoom_change) {
 	case GTH_ZOOM_CHANGE_ACTUAL_SIZE:
@@ -2018,7 +2018,7 @@ gth_image_viewer_set_void (GthImageViewer *viewer)
 		viewer->y_offset = 0;
 	}
 
-	gth_image_tool_image_changed (viewer->priv->tool);
+	gth_image_viewer_tool_image_changed (viewer->priv->tool);
 
 	gtk_widget_queue_resize (GTK_WIDGET (viewer));
 	gtk_widget_queue_draw (GTK_WIDGET (viewer));
@@ -2417,8 +2417,8 @@ gth_image_viewer_get_adjustments (GthImageViewer  *self,
 
 
 void
-gth_image_viewer_set_tool (GthImageViewer *viewer,
-			   GthImageTool   *tool)
+gth_image_viewer_set_tool (GthImageViewer     *viewer,
+			   GthImageViewerTool *tool)
 {
 	_g_object_unref (viewer->priv->tool);
 	if (tool == NULL)
@@ -2426,8 +2426,8 @@ gth_image_viewer_set_tool (GthImageViewer *viewer,
 	else
 		viewer->priv->tool = g_object_ref (tool);
 	if (GTK_WIDGET_REALIZED (viewer))
-		gth_image_tool_realize (viewer->priv->tool);
-	gth_image_tool_image_changed (viewer->priv->tool);
+		gth_image_viewer_tool_realize (viewer->priv->tool);
+	gth_image_viewer_tool_image_changed (viewer->priv->tool);
 	gtk_widget_queue_resize (GTK_WIDGET (viewer));
 	gtk_widget_queue_draw (GTK_WIDGET (viewer));
 }
diff --git a/gthumb/gth-image-viewer.h b/gthumb/gth-image-viewer.h
index be56e09..54b5d20 100644
--- a/gthumb/gth-image-viewer.h
+++ b/gthumb/gth-image-viewer.h
@@ -27,7 +27,7 @@
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <gdk-pixbuf/gdk-pixbuf-loader.h>
 #include "gth-image-loader.h"
-#include "gth-image-tool.h"
+#include "gth-image-viewer-tool.h"
 #include "gth-file-data.h"
 
 G_BEGIN_DECLS
@@ -230,7 +230,7 @@ void           gth_image_viewer_get_adjustments          (GthImageViewer     *se
 							  GtkAdjustment     **hadj,
 							  GtkAdjustment     **vadj);
 void           gth_image_viewer_set_tool                 (GthImageViewer     *viewer,
-							  GthImageTool       *tool);
+							  GthImageViewerTool *tool);
 
 /* Scrolling. */
 
diff --git a/gthumb/gth-main.c b/gthumb/gth-main.c
index 326f590..8e6c2c6 100644
--- a/gthumb/gth-main.c
+++ b/gthumb/gth-main.c
@@ -954,7 +954,7 @@ gth_main_get_default_extension_manager (void)
 void
 gth_main_activate_extensions (void)
 {
-	const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_viewer", "image_tools", "image_viewer", "search", NULL };
+	const char *default_extensions[] = { "catalogs", "comments", "exiv2", "file_manager", "file_tools", "file_viewer", "image_viewer", "search", NULL };
 	int         i;
 
 	if (Main->priv->extension_manager == NULL)
diff --git a/gthumb/gth-sidebar.c b/gthumb/gth-sidebar.c
index c5e109c..99746ff 100644
--- a/gthumb/gth-sidebar.c
+++ b/gthumb/gth-sidebar.c
@@ -32,15 +32,18 @@
 #define GTH_SIDEBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTH_TYPE_SIDEBAR, GthSidebarPrivate))
 
 
+enum {
+	GTH_SIDEBAR_PAGE_PROPERTIES,
+	GTH_SIDEBAR_PAGE_TOOLS
+};
+
+
 static gpointer parent_class = NULL;
 
 
 struct _GthSidebarPrivate {
 	GtkWidget *properties;
-	GtkWidget *tools;
-	GtkWidget *options;
-	GtkWidget *options_icon;
-	GtkWidget *options_title;
+	GtkWidget *toolbox;
 };
 
 
@@ -55,51 +58,10 @@ gth_sidebar_class_init (GthSidebarClass *klass)
 static void
 gth_sidebar_init (GthSidebar *sidebar)
 {
-	GtkWidget *options_box;
-	GtkWidget *options_header;
-	GtkWidget *header_align;
-
 	sidebar->priv = GTH_SIDEBAR_GET_PRIVATE (sidebar);
 
 	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (sidebar), FALSE);
 	gtk_notebook_set_show_border (GTK_NOTEBOOK (sidebar), FALSE);
-
-	sidebar->priv->properties = gth_multipage_new ();
-	gtk_widget_show (sidebar->priv->properties);
-	gtk_notebook_append_page (GTK_NOTEBOOK (sidebar), sidebar->priv->properties, NULL);
-
-	sidebar->priv->tools = gth_toolbox_new ("file-tools");
-	gtk_widget_show (sidebar->priv->tools);
-	gtk_notebook_append_page (GTK_NOTEBOOK (sidebar), sidebar->priv->tools, NULL);
-
-	options_box = gtk_vbox_new (FALSE, 0);
-	gtk_widget_show (options_box);
-	gtk_notebook_append_page (GTK_NOTEBOOK (sidebar), options_box, NULL);
-
-	header_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (header_align), 5, 5, 0, 0);
-
-	options_header = gtk_hbox_new (FALSE, 6);
-	gtk_widget_show (options_header);
-	gtk_container_add (GTK_CONTAINER (header_align), options_header);
-
-	sidebar->priv->options_icon = gtk_image_new ();
-	gtk_widget_show (sidebar->priv->options_icon);
-	gtk_box_pack_start (GTK_BOX (options_header), sidebar->priv->options_icon, FALSE, FALSE, 0);
-
-	sidebar->priv->options_title = gtk_label_new ("");
-	gtk_label_set_use_markup (GTK_LABEL (sidebar->priv->options_title), TRUE);
-	gtk_widget_show (sidebar->priv->options_title);
-	gtk_box_pack_start (GTK_BOX (options_header), sidebar->priv->options_title, FALSE, FALSE, 0);
-
-	gtk_widget_show (header_align);
-	gtk_box_pack_start (GTK_BOX (options_box), header_align, FALSE, FALSE, 0);
-
-	sidebar->priv->options = gtk_scrolled_window_new (NULL, NULL);
-	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sidebar->priv->options), GTK_SHADOW_NONE);
-	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sidebar->priv->options), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-	gtk_widget_show (sidebar->priv->options);
-	gtk_box_pack_start (GTK_BOX (options_box), sidebar->priv->options, TRUE, TRUE, 0);
 }
 
 
@@ -150,12 +112,27 @@ _gth_sidebar_add_property_views (GthSidebar *sidebar)
 }
 
 
+static void
+_gth_sidebar_construct (GthSidebar *sidebar,
+		        const char *name)
+{
+	sidebar->priv->properties = gth_multipage_new ();
+	gtk_widget_show (sidebar->priv->properties);
+	gtk_notebook_append_page (GTK_NOTEBOOK (sidebar), sidebar->priv->properties, NULL);
+
+	sidebar->priv->toolbox = gth_toolbox_new (name);
+	gtk_widget_show (sidebar->priv->toolbox);
+	gtk_notebook_append_page (GTK_NOTEBOOK (sidebar), sidebar->priv->toolbox, NULL);
+}
+
+
 GtkWidget *
-gth_sidebar_new (void)
+gth_sidebar_new (const char *name)
 {
 	GthSidebar *sidebar;
 
 	sidebar = g_object_new (GTH_TYPE_SIDEBAR, NULL);
+	_gth_sidebar_construct (sidebar, name);
 	_gth_sidebar_add_property_views (sidebar);
 
 	return (GtkWidget *) sidebar;
@@ -169,6 +146,8 @@ gth_sidebar_set_file (GthSidebar  *sidebar,
 	GList *children;
 	GList *scan;
 
+	gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
+
 	children = gth_multipage_get_children (GTH_MULTIPAGE (sidebar->priv->properties));
 	for (scan = children; scan; scan = scan->next) {
 		GtkWidget *child = scan->data;
@@ -184,29 +163,25 @@ gth_sidebar_set_file (GthSidebar  *sidebar,
 
 
 void
-gth_sidebar_set_options (GthSidebar *sidebar,
-			 const char *icon,
-			 const char *title,
-			 GtkWidget  *options)
+gth_sidebar_show_properties (GthSidebar *sidebar)
 {
-	_gtk_container_remove_children (GTK_CONTAINER (sidebar->priv->options), NULL, NULL);
-	if (options != NULL) {
-		char *markup;
+	if (gtk_notebook_get_current_page (GTK_NOTEBOOK (sidebar)) == GTH_SIDEBAR_PAGE_TOOLS)
+		gth_toolbox_deactivate_tool (GTH_TOOLBOX (sidebar->priv->toolbox));
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar), GTH_SIDEBAR_PAGE_PROPERTIES);
+}
 
-		markup = g_markup_printf_escaped ("<span size='large' weight='bold'>%s</span>", title);
-		gtk_label_set_markup (GTK_LABEL (sidebar->priv->options_title), markup);
-		gtk_image_set_from_stock (GTK_IMAGE (sidebar->priv->options_icon), icon, GTK_ICON_SIZE_LARGE_TOOLBAR);
-		gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (sidebar->priv->options), options);
 
-		g_free (markup);
-	}
+void
+gth_sidebar_show_tools (GthSidebar *sidebar)
+{
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (sidebar), GTH_SIDEBAR_PAGE_TOOLS);
 }
 
 
 void
 gth_sidebar_update_sensitivity (GthSidebar *sidebar)
 {
-	gth_toolbox_update_sensitivity (GTH_TOOLBOX (sidebar->priv->tools));
+	gth_toolbox_update_sensitivity (GTH_TOOLBOX (sidebar->priv->toolbox));
 }
 
 
diff --git a/gthumb/gth-sidebar.h b/gthumb/gth-sidebar.h
index 70d99e1..3b8d840 100644
--- a/gthumb/gth-sidebar.h
+++ b/gthumb/gth-sidebar.h
@@ -44,12 +44,6 @@ typedef struct _GthSidebar        GthSidebar;
 typedef struct _GthSidebarClass   GthSidebarClass;
 typedef struct _GthSidebarPrivate GthSidebarPrivate;
 
-typedef enum {
-	GTH_SIDEBAR_PAGE_PROPERTIES,
-	GTH_SIDEBAR_PAGE_TOOLS,
-	GTH_SIDEBAR_PAGE_OPTIONS
-} GthSidebarPage;
-
 struct _GthSidebar
 {
 	GtkNotebook __parent;
@@ -71,14 +65,13 @@ struct _GthPropertyViewIface {
 };
 
 GType          gth_sidebar_get_type            (void);
-GtkWidget *    gth_sidebar_new                 (void);
+GtkWidget *    gth_sidebar_new                 (const char      *name);
 void           gth_sidebar_set_file            (GthSidebar      *sidebar,
 						GthFileData     *file_data);
-void           gth_sidebar_set_options         (GthSidebar      *sidebar,
-						const char      *icon,
-						const char      *title,
-						GtkWidget       *options);
+void           gth_sidebar_show_properties     (GthSidebar      *sidebar);
+void           gth_sidebar_show_tools          (GthSidebar      *sidebar);
 void           gth_sidebar_update_sensitivity  (GthSidebar      *sidebar);
+
 GType          gth_property_view_get_type      (void);
 void           gth_property_view_set_file      (GthPropertyView *self,
 						GthFileData     *file_data);
diff --git a/gthumb/gth-toolbox.c b/gthumb/gth-toolbox.c
index 3ce0fef..3fcb961 100644
--- a/gthumb/gth-toolbox.c
+++ b/gthumb/gth-toolbox.c
@@ -23,12 +23,20 @@
 #include <config.h>
 #include <gtk/gtk.h>
 #include "gth-main.h"
+#include "gth-file-tool.h"
 #include "gth-toolbox.h"
+#include "gtk-utils.h"
 
 
 #define GTH_TOOLBOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTH_TYPE_TOOLBOX, GthToolboxPrivate))
 
 
+enum {
+	GTH_TOOLBOX_LIST_PAGE = 0,
+	GTH_TOOLBOX_OPTIONS_PAGE
+};
+
+
 enum  {
 	GTH_TOOLBOX_DUMMY_PROPERTY,
 	GTH_TOOLBOX_NAME
@@ -41,6 +49,10 @@ static gpointer parent_class = NULL;
 struct _GthToolboxPrivate {
 	char      *name;
 	GtkWidget *box;
+	GtkWidget *options;
+	GtkWidget *options_icon;
+	GtkWidget *options_title;
+	GtkWidget *active_tool;
 };
 
 
@@ -116,9 +128,15 @@ static void
 gth_toolbox_init (GthToolbox *toolbox)
 {
 	GtkWidget *scrolled;
+	GtkWidget *options_box;
+	GtkWidget *options_header;
+	GtkWidget *header_align;
 
 	toolbox->priv = GTH_TOOLBOX_GET_PRIVATE (toolbox);
-	gtk_box_set_spacing (GTK_BOX (toolbox), 0);
+	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (toolbox), FALSE);
+	gtk_notebook_set_show_border (GTK_NOTEBOOK (toolbox), FALSE);
+
+	/* tools vbox page */
 
 	scrolled = gtk_scrolled_window_new (NULL, NULL);
 	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), GTK_SHADOW_NONE);
@@ -126,12 +144,43 @@ gth_toolbox_init (GthToolbox *toolbox)
 					GTK_POLICY_AUTOMATIC,
 					GTK_POLICY_AUTOMATIC);
 	gtk_widget_show (scrolled);
-	gtk_box_pack_start (GTK_BOX (toolbox), scrolled, TRUE, TRUE, 0);
+	gtk_notebook_append_page (GTK_NOTEBOOK (toolbox), scrolled, NULL);
 
 	toolbox->priv->box = gtk_vbox_new (FALSE, 0);
 	gtk_box_set_spacing (GTK_BOX (toolbox->priv->box), 0);
 	gtk_widget_show (toolbox->priv->box);
 	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), toolbox->priv->box);
+
+	/* tool options page */
+
+	options_box = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (options_box);
+	gtk_notebook_append_page (GTK_NOTEBOOK (toolbox), options_box, NULL);
+
+	header_align = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (header_align), 5, 5, 0, 0);
+
+	options_header = gtk_hbox_new (FALSE, 6);
+	gtk_widget_show (options_header);
+	gtk_container_add (GTK_CONTAINER (header_align), options_header);
+
+	toolbox->priv->options_icon = gtk_image_new ();
+	gtk_widget_show (toolbox->priv->options_icon);
+	gtk_box_pack_start (GTK_BOX (options_header), toolbox->priv->options_icon, FALSE, FALSE, 0);
+
+	toolbox->priv->options_title = gtk_label_new ("");
+	gtk_label_set_use_markup (GTK_LABEL (toolbox->priv->options_title), TRUE);
+	gtk_widget_show (toolbox->priv->options_title);
+	gtk_box_pack_start (GTK_BOX (options_header), toolbox->priv->options_title, FALSE, FALSE, 0);
+
+	gtk_widget_show (header_align);
+	gtk_box_pack_start (GTK_BOX (options_box), header_align, FALSE, FALSE, 0);
+
+	toolbox->priv->options = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (toolbox->priv->options), GTK_SHADOW_NONE);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (toolbox->priv->options), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_widget_show (toolbox->priv->options);
+	gtk_box_pack_start (GTK_BOX (options_box), toolbox->priv->options, TRUE, TRUE, 0);
 }
 
 
@@ -153,7 +202,7 @@ gth_toolbox_get_type (void)
 			(GInstanceInitFunc) gth_toolbox_init
 		};
 
-		type = g_type_register_static (GTK_TYPE_VBOX,
+		type = g_type_register_static (GTK_TYPE_NOTEBOOK,
 					       "GthToolbox",
 					       &type_info,
 					       0);
@@ -164,6 +213,53 @@ gth_toolbox_get_type (void)
 
 
 static void
+child_clicked_cb (GtkWidget *tool,
+		  gpointer   data)
+{
+	gth_file_tool_activate (GTH_FILE_TOOL (tool));
+}
+
+
+static void
+child_show_options_cb (GtkWidget *tool,
+		       gpointer   data)
+{
+	GthToolbox *toolbox = data;
+	GtkWidget  *options;
+	char       *markup;
+
+	options = gth_file_tool_get_options (GTH_FILE_TOOL (tool));
+	if (options == NULL)
+		return;
+
+	toolbox->priv->active_tool = tool;
+
+	_gtk_container_remove_children (GTK_CONTAINER (toolbox->priv->options), NULL, NULL);
+
+	markup = g_markup_printf_escaped ("<span size='large' weight='bold'>%s</span>", gth_file_tool_get_options_title (GTH_FILE_TOOL (tool)));
+	gtk_label_set_markup (GTK_LABEL (toolbox->priv->options_title), markup);
+	gtk_image_set_from_stock (GTK_IMAGE (toolbox->priv->options_icon), gth_file_tool_get_icon_name (GTH_FILE_TOOL (tool)), GTK_ICON_SIZE_LARGE_TOOLBAR);
+	gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (toolbox->priv->options), options);
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (toolbox), GTH_TOOLBOX_OPTIONS_PAGE);
+
+	g_free (markup);
+}
+
+
+static void
+child_hide_options_cb (GtkWidget *tool,
+		       gpointer   data)
+{
+	GthToolbox *toolbox = data;
+
+	gth_file_tool_destroy_options (GTH_FILE_TOOL (tool));
+	gtk_notebook_set_current_page (GTK_NOTEBOOK (toolbox), GTH_TOOLBOX_LIST_PAGE);
+
+	toolbox->priv->active_tool = NULL;
+}
+
+
+static void
 _gth_toolbox_add_childs (GthToolbox *toolbox)
 {
 	GArray *children;
@@ -179,6 +275,9 @@ _gth_toolbox_add_childs (GthToolbox *toolbox)
 
 		child_type = g_array_index (children, GType, i);
 		child = g_object_new (child_type, NULL);
+		g_signal_connect (child, "clicked", G_CALLBACK (child_clicked_cb), toolbox);
+		g_signal_connect (child, "show-options", G_CALLBACK (child_show_options_cb), toolbox);
+		g_signal_connect (child, "hide-options", G_CALLBACK (child_hide_options_cb), toolbox);
 		gtk_widget_show (child);
 		gtk_box_pack_start (GTK_BOX (toolbox->priv->box), child, FALSE, FALSE, 0);
 	}
@@ -200,11 +299,9 @@ gth_toolbox_new (const char *name)
 void
 gth_toolbox_update_sensitivity (GthToolbox *toolbox)
 {
-	GtkWidget *window;
-	GList     *children;
-	GList     *scan;
+	GList *children;
+	GList *scan;
 
-	window = gtk_widget_get_toplevel (GTK_WIDGET (toolbox));
 	children = gtk_container_get_children (GTK_CONTAINER (toolbox->priv->box));
 	for (scan = children; scan; scan = scan->next) {
 		GtkWidget *child = scan->data;
@@ -212,41 +309,16 @@ gth_toolbox_update_sensitivity (GthToolbox *toolbox)
 		if (! GTH_IS_FILE_TOOL (child))
 			continue;
 
-		gth_file_tool_update_sensitivity (GTH_FILE_TOOL (child), window);
+		gth_file_tool_update_sensitivity (GTH_FILE_TOOL (child));
 	}
 
 	g_list_free (children);
 }
 
 
-/* -- gth_file_tool -- */
-
-
-GType
-gth_file_tool_get_type (void) {
-	static GType gth_file_tool_type_id = 0;
-	if (gth_file_tool_type_id == 0) {
-		static const GTypeInfo g_define_type_info = {
-			sizeof (GthFileToolIface),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
-			(GClassFinalizeFunc) NULL,
-			NULL,
-			0,
-			0,
-			(GInstanceInitFunc) NULL,
-			NULL
-		};
-		gth_file_tool_type_id = g_type_register_static (G_TYPE_INTERFACE, "GthFileTool", &g_define_type_info, 0);
-	}
-	return gth_file_tool_type_id;
-}
-
-
 void
-gth_file_tool_update_sensitivity (GthFileTool *self,
-				  GtkWidget   *window)
+gth_toolbox_deactivate_tool (GthToolbox *toolbox)
 {
-	GTH_FILE_TOOL_GET_INTERFACE (self)->update_sensitivity (self, window);
+	if (toolbox->priv->active_tool != NULL)
+		gth_file_tool_hide_options (GTH_FILE_TOOL (toolbox->priv->active_tool));
 }
diff --git a/gthumb/gth-toolbox.h b/gthumb/gth-toolbox.h
index 6434cc4..1e56bb0 100644
--- a/gthumb/gth-toolbox.h
+++ b/gthumb/gth-toolbox.h
@@ -34,41 +34,25 @@ G_BEGIN_DECLS
 #define GTH_IS_TOOLBOX_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_TOOLBOX))
 #define GTH_TOOLBOX_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_TOOLBOX, GthToolboxClass))
 
-#define GTH_TYPE_FILE_TOOL               (gth_file_tool_get_type ())
-#define GTH_FILE_TOOL(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_FILE_TOOL, GthFileTool))
-#define GTH_IS_FILE_TOOL(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_FILE_TOOL))
-#define GTH_FILE_TOOL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTH_TYPE_FILE_TOOL, GthFileToolIface))
-
 typedef struct _GthToolbox        GthToolbox;
 typedef struct _GthToolboxClass   GthToolboxClass;
 typedef struct _GthToolboxPrivate GthToolboxPrivate;
 
 struct _GthToolbox
 {
-	GtkVBox __parent;
+	GtkNotebook __parent;
 	GthToolboxPrivate *priv;
 };
 
 struct _GthToolboxClass
 {
-	GtkVBoxClass __parent_class;
-};
-
-typedef struct _GthFileTool GthFileTool;
-typedef struct _GthFileToolIface GthFileToolIface;
-
-struct _GthFileToolIface {
-	GTypeInterface parent_iface;
-	void  (*update_sensitivity) (GthFileTool *self,
-				     GtkWidget   *window);
+	GtkNotebookClass __parent_class;
 };
 
 GType          gth_toolbox_get_type              (void);
 GtkWidget *    gth_toolbox_new                   (const char  *name);
 void           gth_toolbox_update_sensitivity    (GthToolbox  *toolbox);
-GType          gth_file_tool_get_type            (void);
-void           gth_file_tool_update_sensitivity  (GthFileTool *self,
-						  GtkWidget   *window);
+void           gth_toolbox_deactivate_tool       (GthToolbox  *toolbox);
 
 G_END_DECLS
 



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