[gthumb/ext: 1/15] started work on catalog properties



commit d0e3284d63d3c880d30a866df0a98e34d9d70a23
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Mon Dec 7 17:22:56 2009 +0100

    started work on catalog properties

 extensions/catalogs/Makefile.am                   |    2 +
 extensions/catalogs/actions.c                     |    9 +
 extensions/catalogs/actions.h                     |    1 +
 extensions/catalogs/callbacks.c                   |   29 ++
 extensions/catalogs/data/ui/Makefile.am           |    2 +-
 extensions/catalogs/data/ui/catalog-properties.ui |  184 ++++++++++++
 extensions/catalogs/dlg-catalog-properties.c      |  214 ++++++++++++++
 extensions/catalogs/dlg-catalog-properties.h      |   31 ++
 extensions/catalogs/gth-catalog.c                 |   50 +++-
 extensions/catalogs/gth-catalog.h                 |    3 +
 extensions/catalogs/gth-file-source-catalogs.c    |    5 +
 extensions/catalogs/main.c                        |   19 ++
 extensions/search/Makefile.am                     |    2 +
 extensions/search/actions.c                       |   10 +-
 extensions/search/callbacks.c                     |   79 +++++-
 extensions/search/callbacks.h                     |   15 +-
 extensions/search/data/ui/search-editor.ui        |   26 +--
 extensions/search/gth-search-editor-dialog.c      |  192 +------------
 extensions/search/gth-search-editor.c             |  317 +++++++++++++++++++++
 extensions/search/gth-search-editor.h             |   56 ++++
 extensions/search/gth-search-task.c               |   30 +-
 extensions/search/main.c                          |    3 +-
 gthumb/gedit-message-area.c                       |   53 ++--
 gthumb/glib-utils.c                               |   11 +
 gthumb/glib-utils.h                               |    2 +
 gthumb/gth-browser.c                              |   42 ++--
 gthumb/gth-browser.h                              |    4 +-
 gthumb/gth-embedded-dialog.c                      |   24 ++-
 gthumb/gth-embedded-dialog.h                      |    2 +
 gthumb/gth-file-source-vfs.c                      |    6 +
 gthumb/gth-time-selector.c                        |   60 +++-
 gthumb/gth-time-selector.h                        |    2 +
 32 files changed, 1170 insertions(+), 315 deletions(-)
---
diff --git a/extensions/catalogs/Makefile.am b/extensions/catalogs/Makefile.am
index 56c4fab..46219ad 100644
--- a/extensions/catalogs/Makefile.am
+++ b/extensions/catalogs/Makefile.am
@@ -10,6 +10,8 @@ libcatalogs_la_SOURCES = 		\
 	callbacks.h			\
 	dlg-add-to-catalog.c		\
 	dlg-add-to-catalog.h		\
+	dlg-catalog-properties.c	\
+	dlg-catalog-properties.h	\
 	gth-catalog.c			\
 	gth-catalog.h			\
 	gth-file-source-catalogs.c 	\
diff --git a/extensions/catalogs/actions.c b/extensions/catalogs/actions.c
index a10472f..0360db0 100644
--- a/extensions/catalogs/actions.c
+++ b/extensions/catalogs/actions.c
@@ -25,6 +25,7 @@
 #include <gthumb.h>
 #include <gth-catalog.h>
 #include "dlg-add-to-catalog.h"
+#include "dlg-catalog-properties.h"
 
 
 void
@@ -355,6 +356,14 @@ gth_browser_activate_action_catalog_rename (GtkAction  *action,
 
 
 void
+gth_browser_activate_action_catalog_properties (GtkAction  *action,
+						GthBrowser *browser)
+{
+	dlg_catalog_properties (browser, gth_browser_get_location_data (browser));  /* FIXME */
+}
+
+
+void
 gth_browser_activate_action_go_to_container (GtkAction  *action,
 					     GthBrowser *browser)
 {
diff --git a/extensions/catalogs/actions.h b/extensions/catalogs/actions.h
index 046aef2..4f4d2bd 100644
--- a/extensions/catalogs/actions.h
+++ b/extensions/catalogs/actions.h
@@ -33,6 +33,7 @@ DEFINE_ACTION(gth_browser_activate_action_catalog_new)
 DEFINE_ACTION(gth_browser_activate_action_catalog_new_library)
 DEFINE_ACTION(gth_browser_activate_action_catalog_remove)
 DEFINE_ACTION(gth_browser_activate_action_catalog_rename)
+DEFINE_ACTION(gth_browser_activate_action_catalog_properties)
 DEFINE_ACTION(gth_browser_activate_action_go_to_container)
 
 void gth_browser_add_to_catalog (GthBrowser *browser,
diff --git a/extensions/catalogs/callbacks.c b/extensions/catalogs/callbacks.c
index 43c6aad..26e27b5 100644
--- a/extensions/catalogs/callbacks.c
+++ b/extensions/catalogs/callbacks.c
@@ -29,7 +29,10 @@
 #include "gth-file-source-catalogs.h"
 #include "actions.h"
 
+
 #define BROWSER_DATA_KEY "catalogs-browser-data"
+#define _RESPONSE_PROPERTIES 1
+#define _RESPONSE_ORGANIZE 2
 
 
 static const char *fixed_ui_info =
@@ -141,6 +144,7 @@ typedef struct {
 	guint           vfs_merge_id;
 	gboolean        catalog_menu_loaded;
 	guint           monitor_events;
+	GtkWidget      *properties_button;
 } BrowserData;
 
 
@@ -558,6 +562,14 @@ catalogs__gth_browser_folder_tree_popup_before_cb (GthBrowser    *browser,
 }
 
 
+static void
+properties_button_clicked_cb (GtkButton  *button,
+			      GthBrowser *browser)
+{
+	gth_browser_activate_action_catalog_properties (NULL, browser);
+}
+
+
 void
 catalogs__gth_browser_load_location_after_cb (GthBrowser   *browser,
 					      GthFileData  *location_data,
@@ -580,8 +592,25 @@ catalogs__gth_browser_load_location_after_cb (GthBrowser   *browser,
 				g_error_free (error);
 			}
 		}
+
+		if (data->properties_button == NULL) {
+			data->properties_button = gtk_button_new_from_stock (GTK_STOCK_PROPERTIES);
+			g_object_add_weak_pointer (G_OBJECT (data->properties_button), (gpointer *)&data->properties_button);
+			gtk_button_set_relief (GTK_BUTTON (data->properties_button), GTK_RELIEF_NONE);
+			GTK_WIDGET_SET_FLAGS (data->properties_button, GTK_CAN_DEFAULT);
+			gtk_widget_show (data->properties_button);
+			gedit_message_area_add_action_widget (GEDIT_MESSAGE_AREA (gth_browser_get_list_extra_widget (browser)),
+							      data->properties_button,
+							      _RESPONSE_PROPERTIES);
+			g_signal_connect (data->properties_button,
+					  "clicked",
+					  G_CALLBACK (properties_button_clicked_cb),
+					  browser);
+		}
 	}
 	else {
+		if (GTH_IS_FILE_SOURCE_VFS (gth_browser_get_location_source (browser)))
+			gedit_message_area_add_button (GEDIT_MESSAGE_AREA (gth_browser_get_list_extra_widget (browser)), _("Organize..."), _RESPONSE_ORGANIZE);
 		if (data->vfs_merge_id != 0) {
 			gtk_ui_manager_remove_ui (gth_browser_get_ui_manager (browser), data->vfs_merge_id);
 			data->vfs_merge_id = 0;
diff --git a/extensions/catalogs/data/ui/Makefile.am b/extensions/catalogs/data/ui/Makefile.am
index b5e7f21..4b3c318 100644
--- a/extensions/catalogs/data/ui/Makefile.am
+++ b/extensions/catalogs/data/ui/Makefile.am
@@ -1,5 +1,5 @@
 uidir = $(datadir)/gthumb-2.0/ui
-ui_DATA = add-to-catalog.ui
+ui_DATA = add-to-catalog.ui catalog-properties.ui
 EXTRA_DIST = $(ui_DATA)
 
 -include $(top_srcdir)/git.mk
diff --git a/extensions/catalogs/data/ui/catalog-properties.ui b/extensions/catalogs/data/ui/catalog-properties.ui
new file mode 100644
index 0000000..405ba56
--- /dev/null
+++ b/extensions/catalogs/data/ui/catalog-properties.ui
@@ -0,0 +1,184 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="properties_dialog">
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">Properties</property>
+    <property name="resizable">False</property>
+    <property name="type_hint">normal</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">8</property>
+        <child>
+          <object class="GtkVBox" id="main_vbox">
+            <property name="visible">True</property>
+            <property name="border_width">5</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Catalog</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkTable" id="table1">
+                        <property name="visible">True</property>
+                        <property name="n_rows">2</property>
+                        <property name="n_columns">2</property>
+                        <property name="column_spacing">6</property>
+                        <property name="row_spacing">6</property>
+                        <child>
+                          <object class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Name:</property>
+                            <property name="use_underline">True</property>
+                            <property name="mnemonic_widget">name_entry</property>
+                          </object>
+                          <packing>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label3">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">_Date:</property>
+                            <property name="use_underline">True</property>
+                          </object>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkEntry" id="name_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="date_container_box">
+                            <property name="visible">True</property>
+                            <child>
+                              <placeholder/>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="cancel_button">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="save_button">
+                <property name="label">gtk-save</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="help_button">
+                <property name="label">gtk-help</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_stock">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+                <property name="secondary">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">cancel_button</action-widget>
+      <action-widget response="0">save_button</action-widget>
+      <action-widget response="0">help_button</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/extensions/catalogs/dlg-catalog-properties.c b/extensions/catalogs/dlg-catalog-properties.c
new file mode 100644
index 0000000..7237e25
--- /dev/null
+++ b/extensions/catalogs/dlg-catalog-properties.c
@@ -0,0 +1,214 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <gtk/gtk.h>
+#include "dlg-catalog-properties.h"
+#include "gth-catalog.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (data->builder, (name))
+
+
+typedef struct {
+	GthBrowser  *browser;
+	GtkBuilder  *builder;
+	GtkWidget   *dialog;
+	GtkWidget   *time_selector;
+	GthCatalog  *catalog;
+	GthFileData *file_data;
+	GFile       *original_file;
+} DialogData;
+
+
+static void
+destroy_cb (GtkWidget  *widget,
+	    DialogData *data)
+{
+	g_object_ref (data->file_data);
+	_g_object_unref (data->catalog);
+	g_object_unref (data->builder);
+	g_free (data);
+}
+
+
+static void
+catalog_saved_cb (void     *buffer,
+		  gsize     count,
+		  GError   *error,
+		  gpointer  user_data)
+{
+	DialogData *data = user_data;
+
+	if (error == NULL) {
+		if (! g_file_equal (data->original_file, data->file_data->file)) {
+			GFile *gio_file;
+
+			gio_file = gth_catalog_file_to_gio_file (data->original_file);
+			g_file_delete (gio_file, NULL, NULL);
+			g_object_unref (gio_file);
+
+			gth_monitor_file_renamed (gth_main_get_default_monitor (),
+						  data->original_file,
+						  data->file_data->file);
+		}
+	}
+	else
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW (data->browser), _("Could not save the catalog"), &error);
+
+	g_free (buffer);
+	gtk_widget_destroy (data->dialog);
+}
+
+
+static void
+save_button_clicked_cb (GtkButton  *button,
+			DialogData *data)
+{
+	GFile       *parent;
+	char        *uri;
+	char        *display_name;
+	GFile       *new_file;
+	GthDateTime *date_time;
+	GFile       *gio_file;
+	char        *buffer;
+	gsize        buffer_size;
+
+	parent = g_file_get_parent (data->original_file);
+	uri = g_file_get_uri (data->original_file);
+	display_name = g_strconcat (gtk_entry_get_text (GTK_ENTRY (GET_WIDGET ("name_entry"))), _g_uri_get_file_extension (uri), NULL);
+	new_file = g_file_get_child_for_display_name (parent, display_name, NULL);
+	if ((new_file != NULL) && ! g_file_equal (new_file, data->original_file))
+		gth_file_data_set_file (data->file_data, new_file);
+
+	g_free (display_name);
+	g_free (uri);
+	_g_object_unref (new_file);
+	g_object_unref (parent);
+
+	date_time = gth_datetime_new ();
+	gth_time_selector_get_value (GTH_TIME_SELECTOR (data->time_selector), date_time);
+	gth_catalog_set_date (data->catalog, date_time);
+	gth_datetime_free (date_time);
+
+	/* invoke the hook to save derived catalogs such as searches */
+
+	if (gth_hook_invoke_get ("dlg-catalog-properties-save", data->builder, data->file_data, data->catalog) != NULL) {
+		gtk_widget_destroy (data->dialog);
+		return;
+	}
+
+	/* ...else save as a standard catalog */
+
+	gio_file = gth_catalog_file_to_gio_file (data->file_data->file);
+	buffer = gth_catalog_to_data (data->catalog, &buffer_size);
+	g_write_file_async (gio_file,
+			    buffer,
+			    buffer_size,
+			    G_PRIORITY_DEFAULT,
+			    NULL,
+			    catalog_saved_cb,
+			    data);
+
+	g_object_unref (gio_file);
+}
+
+
+static void
+help_button_clicked_cb (GtkWidget  *widget,
+			DialogData *data)
+{
+	show_help_dialog (GTK_WINDOW (data->dialog), "catalog-properties");
+}
+
+
+static void
+catalog_ready_cb (GObject  *object,
+		  GError   *error,
+		  gpointer  user_data)
+{
+	DialogData *data = user_data;
+
+	if (error != NULL) {
+		_gtk_error_dialog_from_gerror_show (GTK_WINDOW(data->browser), _("Could not load the catalog"), &error);
+		gtk_widget_destroy (data->dialog);
+		return;
+	}
+
+	data->catalog = g_object_ref (object);
+	gtk_entry_set_text (GTK_ENTRY (GET_WIDGET ("name_entry")), gth_catalog_get_display_name (data->file_data->file));
+	gth_time_selector_set_value (GTH_TIME_SELECTOR (data->time_selector), gth_catalog_get_date (data->catalog));
+
+	gth_hook_invoke ("dlg-catalog-properties", data->builder, data->file_data, data->catalog);
+
+	gtk_widget_show (data->dialog);
+}
+
+
+void
+dlg_catalog_properties (GthBrowser  *browser,
+			GthFileData *file_data)
+{
+	DialogData *data;
+
+	g_return_if_fail (file_data != NULL);
+
+	data = g_new0 (DialogData, 1);
+	data->browser = browser;
+	data->file_data = g_object_ref (file_data);
+	data->original_file = g_file_dup (data->file_data->file);
+	data->builder = _gtk_builder_new_from_file ("catalog-properties.ui", "catalogs");
+	data->dialog = GET_WIDGET ("properties_dialog");
+
+	/* Set widgets data. */
+
+	data->time_selector = gth_time_selector_new ();
+	gth_time_selector_show_time (GTH_TIME_SELECTOR (data->time_selector), FALSE);
+	gtk_widget_show (data->time_selector);
+	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("date_container_box")), data->time_selector, TRUE, TRUE, 0);
+
+	/* Set the signals handlers. */
+
+	g_signal_connect (G_OBJECT (data->dialog),
+			  "destroy",
+			  G_CALLBACK (destroy_cb),
+			  data);
+	g_signal_connect (G_OBJECT (GET_WIDGET ("save_button")),
+			  "clicked",
+			  G_CALLBACK (save_button_clicked_cb),
+			  data);
+	g_signal_connect_swapped (G_OBJECT (GET_WIDGET ("cancel_button")),
+				  "clicked",
+				  G_CALLBACK (gtk_widget_destroy),
+				  data->dialog);
+	g_signal_connect (G_OBJECT (GET_WIDGET ("help_button")),
+			  "clicked",
+			  G_CALLBACK (help_button_clicked_cb),
+			  data);
+
+	/* run dialog. */
+
+	gtk_window_set_transient_for (GTK_WINDOW (data->dialog), GTK_WINDOW (browser));
+	gtk_window_set_modal (GTK_WINDOW (data->dialog), TRUE);
+
+	gth_catalog_load_from_file (file_data->file, NULL, catalog_ready_cb, data);
+}
diff --git a/extensions/catalogs/dlg-catalog-properties.h b/extensions/catalogs/dlg-catalog-properties.h
new file mode 100644
index 0000000..558d224
--- /dev/null
+++ b/extensions/catalogs/dlg-catalog-properties.h
@@ -0,0 +1,31 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DLG_CATALOG_PROPERTIES_H
+#define DLG_CATALOG_PROPERTIES_H
+
+#include <gthumb.h>
+
+void dlg_catalog_properties (GthBrowser  *browser,
+			     GthFileData *file_data);
+
+#endif /* DLG_CATALOG_PROPERTIES_H */
diff --git a/extensions/catalogs/gth-catalog.c b/extensions/catalogs/gth-catalog.c
index 9610ecf..e1fa0fc 100644
--- a/extensions/catalogs/gth-catalog.c
+++ b/extensions/catalogs/gth-catalog.c
@@ -35,6 +35,7 @@ struct _GthCatalogPrivate {
 	GthCatalogType  type;
 	GFile          *file;
 	GList          *file_list;
+	GthDateTime    *date_time;
 	gboolean        active;
 	char           *order;
 	gboolean        order_inverse;
@@ -54,6 +55,7 @@ gth_catalog_finalize (GObject *object)
 		if (catalog->priv->file != NULL)
 			g_object_unref (catalog->priv->file);
 		_g_object_list_unref (catalog->priv->file_list);
+		gth_datetime_free (catalog->priv->date_time);
 		g_free (catalog->priv->order);
 		g_free (catalog->priv);
 		catalog->priv = NULL;
@@ -95,6 +97,8 @@ read_catalog_data_from_xml (GthCatalog  *catalog,
 				gth_catalog_set_order (catalog,
 						       dom_element_get_attribute (child, "type"),
 						       g_strcmp0 (dom_element_get_attribute (child, "inverse"), "1") == 0);
+			if (g_strcmp0 (child->tag_name, "date") == 0)
+				gth_datetime_from_exif_date (catalog->priv->date_time, dom_element_get_attribute (child, "value"));
 		}
 		catalog->priv->file_list = g_list_reverse (catalog->priv->file_list);
 	}
@@ -184,16 +188,27 @@ base_to_data (GthCatalog *catalog,
 					    "version", CATALOG_FORMAT,
 					    NULL);
 	dom_element_append_child (DOM_ELEMENT (doc), root);
+
+	if (catalog->priv->order != NULL)
+		dom_element_append_child (root, dom_document_create_element (doc, "order",
+									     "type", catalog->priv->order,
+									     "inverse", (catalog->priv->order_inverse ? "1" : "0"),
+									     NULL));
+
+	if (gth_datetime_valid (catalog->priv->date_time)) {
+		char *s;
+
+		s = gth_datetime_to_exif_date (catalog->priv->date_time);
+		dom_element_append_child (root, dom_document_create_element (doc, "date",
+									     "value", s,
+									     NULL));
+		g_free (s);
+	}
+
 	if (catalog->priv->file_list != NULL) {
 		DomElement *node;
 		GList      *scan;
 
-		if (catalog->priv->order != NULL)
-			dom_element_append_child (root, dom_document_create_element (doc, "order",
-										     "type", catalog->priv->order,
-										     "inverse", (catalog->priv->order_inverse ? "1" : "0"),
-										     NULL));
-
 		node = dom_document_create_element (doc, "files", NULL);
 		dom_element_append_child (root, node);
 
@@ -234,6 +249,7 @@ static void
 gth_catalog_init (GthCatalog *catalog)
 {
 	catalog->priv = g_new0 (GthCatalogPrivate, 1);
+	catalog->priv->date_time = gth_datetime_new ();
 }
 
 
@@ -396,6 +412,28 @@ gth_catalog_remove_file (GthCatalog *catalog,
 }
 
 
+void
+gth_catalog_set_date (GthCatalog  *catalog,
+		      GthDateTime *date_time)
+{
+	if (gth_datetime_valid (date_time))
+		g_date_set_dmy (catalog->priv->date_time->date,
+				g_date_get_day (date_time->date),
+				g_date_get_month (date_time->date),
+				g_date_get_year (date_time->date));
+	else
+		g_date_clear (catalog->priv->date_time->date, 1);
+	gth_time_set_hms (catalog->priv->date_time->time, 0, 0, 0, 0);
+}
+
+
+GthDateTime *
+gth_catalog_get_date (GthCatalog *catalog)
+{
+	return catalog->priv->date_time;
+}
+
+
 /* -- gth_catalog_list_async --  */
 
 
diff --git a/extensions/catalogs/gth-catalog.h b/extensions/catalogs/gth-catalog.h
index b8520a9..2f263aa 100644
--- a/extensions/catalogs/gth-catalog.h
+++ b/extensions/catalogs/gth-catalog.h
@@ -94,6 +94,9 @@ gboolean      gth_catalog_insert_file    (GthCatalog           *catalog,
 					  GFile                *file);
 int           gth_catalog_remove_file    (GthCatalog           *catalog,
 					  GFile                *file);
+void          gth_catalog_set_date       (GthCatalog           *catalog,
+					  GthDateTime          *date_time);
+GthDateTime * gth_catalog_get_date       (GthCatalog           *catalog);
 void          gth_catalog_list_async     (GthCatalog           *catalog,
 					  const char           *attributes,
 					  GCancellable         *cancellable,
diff --git a/extensions/catalogs/gth-file-source-catalogs.c b/extensions/catalogs/gth-file-source-catalogs.c
index f8a4d47..7c8ed22 100644
--- a/extensions/catalogs/gth-file-source-catalogs.c
+++ b/extensions/catalogs/gth-file-source-catalogs.c
@@ -79,6 +79,7 @@ update_file_info (GthFileSource *file_source,
 
 	if (g_str_has_suffix (uri, ".gqv") || g_str_has_suffix (uri, ".catalog")) {
 		g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
+		g_file_info_set_content_type (info, "gthumb/catalog");
 		g_file_info_set_icon (info, g_themed_icon_new ("image-catalog"));
 		g_file_info_set_sort_order (info, 1);
 		g_file_info_set_attribute_boolean (info, "gthumb::no-child", TRUE);
@@ -89,6 +90,7 @@ update_file_info (GthFileSource *file_source,
 	}
 	else if (g_str_has_suffix (uri, ".search")) {
 		g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
+		g_file_info_set_content_type (info, "gthumb/search");
 		g_file_info_set_icon (info, g_themed_icon_new ("image-search"));
 		g_file_info_set_sort_order (info, 1);
 		g_file_info_set_attribute_boolean (info, "gthumb::no-child", TRUE);
@@ -99,6 +101,7 @@ update_file_info (GthFileSource *file_source,
 	}
 	else {
 		g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
+		g_file_info_set_content_type (info, "gthumb/library");
 		g_file_info_set_icon (info, g_themed_icon_new ("image-library"));
 		g_file_info_set_sort_order (info, 0);
 		g_file_info_set_attribute_boolean (info, "gthumb::no-child", FALSE);
@@ -382,6 +385,8 @@ read_metadata_info_ready_cb (GList    *files,
 	result = files->data;
 	g_file_info_copy_into (result->info, read_metadata->file_data->info);
 
+	update_file_info (read_metadata->file_source, read_metadata->file_data->file, read_metadata->file_data->info);
+
 	if (_g_file_attributes_matches (read_metadata->attributes, "sort::*")) {
 		GFile *gio_file;
 
diff --git a/extensions/catalogs/main.c b/extensions/catalogs/main.c
index ffc080e..870b060 100644
--- a/extensions/catalogs/main.c
+++ b/extensions/catalogs/main.c
@@ -40,6 +40,25 @@ gthumb_extension_activate (void)
 	 **/
 	gth_hook_register ("gth-catalog-load-from-data", 1);
 
+	/**
+	 * Called to add sections to the catalog properties dialog.
+	 *
+	 * @builder   (GtkBuilder *): the builder relative to the window
+	 * @file_data (GthFileData *): the catalog file
+	 * @catalog (GthCatalog *): the catalog data
+	 **/
+	gth_hook_register ("dlg-catalog-properties", 3);
+
+	/**
+	 * Called to save the properties dialog changes.
+	 *
+	 * @builder   (GtkBuilder *): the builder relative to the window
+	 * @file_data (GthFileData *): the catalog file
+	 * @catalog (GthCatalog *): the catalog data
+	 * @return (gboolean): TRUE if the catalog has been saved, FALSE otherwise.
+	 **/
+	gth_hook_register ("dlg-catalog-properties-save", 3);
+
 	gth_hook_add_callback ("gth-catalog-load-from-data", 10, G_CALLBACK (catalogs__gth_catalog_load_from_data_cb), NULL);
 
 	gth_main_register_file_source (GTH_TYPE_FILE_SOURCE_CATALOGS);
diff --git a/extensions/search/Makefile.am b/extensions/search/Makefile.am
index 4f91f69..3c7d688 100644
--- a/extensions/search/Makefile.am
+++ b/extensions/search/Makefile.am
@@ -10,6 +10,8 @@ libsearch_la_SOURCES = 			\
 	callbacks.h			\
 	gth-search.c			\
 	gth-search.h			\
+	gth-search-editor.c		\
+	gth-search-editor.h		\
 	gth-search-editor-dialog.c	\
 	gth-search-editor-dialog.h	\
 	gth-search-task.c		\
diff --git a/extensions/search/actions.c b/extensions/search/actions.c
index b57a883..fb84241 100644
--- a/extensions/search/actions.c
+++ b/extensions/search/actions.c
@@ -34,11 +34,11 @@ search_editor_dialog__response_cb (GtkDialog *dialog,
 			           int        response,
 			           gpointer   user_data)
 {
-	GthBrowser   *browser = user_data;
-	GthSearch    *search;
-	GError       *error = NULL;
-	GFile        *search_catalog;
-	GthTask      *task;
+	GthBrowser *browser = user_data;
+	GthSearch  *search;
+	GError     *error = NULL;
+	GFile      *search_catalog;
+	GthTask    *task;
 
 	if (response != GTK_RESPONSE_OK) {
 		gtk_widget_destroy (GTK_WIDGET (dialog));
diff --git a/extensions/search/callbacks.c b/extensions/search/callbacks.c
index a1d340d..9a0da02 100644
--- a/extensions/search/callbacks.c
+++ b/extensions/search/callbacks.c
@@ -28,9 +28,11 @@
 #include <extensions/catalogs/gth-catalog.h>
 #include "actions.h"
 #include "gth-search.h"
+#include "gth-search-editor.h"
 
 
 #define BROWSER_DATA_KEY "search-browser-data"
+#define _RESPONSE_REFRESH 2
 
 
 static const char *find_ui_info =
@@ -96,6 +98,7 @@ typedef struct {
 	guint           find_merge_id;
 	GtkActionGroup *search_actions;
 	guint           search_merge_id;
+	GtkWidget      *refresh_button;
 } BrowserData;
 
 
@@ -135,21 +138,27 @@ search__gth_browser_construct_cb (GthBrowser *browser)
 }
 
 
+static void
+refresh_button_clicked_cb (GtkButton  *button,
+			   GthBrowser *browser)
+{
+	gth_browser_activate_action_edit_search_update (NULL, browser);
+}
+
+
 void
 search__gth_browser_load_location_after_cb (GthBrowser   *browser,
 					    GthFileData  *location_data,
 					    const GError *error)
 {
 	BrowserData *data;
-	char        *uri;
 
 	if ((location_data == NULL) || (error != NULL))
 		return;
 
 	data = g_object_get_data (G_OBJECT (browser), BROWSER_DATA_KEY);
-	uri = g_file_get_uri (location_data->file);
 
-	if (g_str_has_suffix (uri, ".search") && (error == NULL)) {
+	if (_g_content_type_is_a (g_file_info_get_content_type (location_data->info), "gthumb/search")) {
 		if (data->find_merge_id != 0) {
 			gtk_ui_manager_remove_ui (gth_browser_get_ui_manager (browser), data->find_merge_id);
 			data->find_merge_id = 0;
@@ -165,6 +174,21 @@ search__gth_browser_load_location_after_cb (GthBrowser   *browser,
 			/*gtk_tool_item_set_is_important (GTK_TOOL_ITEM (gtk_ui_manager_get_widget (gth_browser_get_ui_manager (browser), "/ToolBar/SourceCommands/Edit_Search_Update")), TRUE);*/
 			gtk_tool_item_set_is_important (GTK_TOOL_ITEM (gtk_ui_manager_get_widget (gth_browser_get_ui_manager (browser), "/ToolBar/SourceCommands/Edit_Search_Edit")), TRUE);
 		}
+
+		if (data->refresh_button == NULL) {
+			data->refresh_button = gtk_button_new_from_stock (GTK_STOCK_REFRESH);
+			g_object_add_weak_pointer (G_OBJECT (data->refresh_button), (gpointer *)&data->refresh_button);
+			gtk_button_set_relief (GTK_BUTTON (data->refresh_button), GTK_RELIEF_NONE);
+			GTK_WIDGET_SET_FLAGS (data->refresh_button, GTK_CAN_DEFAULT);
+			gtk_widget_show (data->refresh_button);
+			gedit_message_area_add_action_widget (GEDIT_MESSAGE_AREA (gth_browser_get_list_extra_widget (browser)),
+							      data->refresh_button,
+							      _RESPONSE_REFRESH);
+			g_signal_connect (data->refresh_button,
+					  "clicked",
+					  G_CALLBACK (refresh_button_clicked_cb),
+					  browser);
+		}
 	}
 	else {
 		if (data->search_merge_id != 0) {
@@ -182,19 +206,52 @@ search__gth_browser_load_location_after_cb (GthBrowser   *browser,
 			gtk_tool_item_set_is_important (GTK_TOOL_ITEM (gtk_ui_manager_get_widget (gth_browser_get_ui_manager (browser), "/ToolBar/SourceCommands/Edit_Find")), TRUE);
 		}
 	}
-
-	g_free (uri);
 }
 
 
 GthCatalog *
 search__gth_catalog_load_from_data_cb (const void *buffer)
 {
-	if ((buffer == NULL)
-	    || (strncmp (buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<search ", 47) != 0))
-	{
-		return NULL;
-	}
-	else
+	if ((buffer != NULL) && (strncmp (buffer, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<search ", 47) == 0))
 		return (GthCatalog *) gth_search_new ();
+	else
+		return NULL;
+}
+
+
+void
+search__dlg_catalog_properties (GtkBuilder  *builder,
+				GthFileData *file_data,
+				GthCatalog  *catalog)
+{
+	GtkWidget     *vbox;
+	GtkWidget     *label;
+	PangoAttrList *attrs;
+	GtkWidget     *alignment;
+	GtkWidget     *search_editor;
+
+	if (! _g_content_type_is_a (g_file_info_get_content_type (file_data->info), "gthumb/search"))
+		return;
+
+	vbox = gtk_vbox_new (FALSE, 6);
+	gtk_widget_show (vbox);
+	gtk_box_pack_start (GTK_BOX (_gtk_builder_get_widget (builder, "main_vbox")), vbox, FALSE, FALSE, 0);
+
+	label = gtk_label_new (_("Search"));
+	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+	attrs = pango_attr_list_new ();
+	pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
+	gtk_label_set_attributes (GTK_LABEL (label), attrs);
+	pango_attr_list_unref (attrs);
+	gtk_widget_show (label);
+	gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+	alignment = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
+	gtk_widget_show (alignment);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 0, 0, 12, 0);
+	gtk_box_pack_start (GTK_BOX (vbox), alignment, FALSE, FALSE, 0);
+
+	search_editor = gth_search_editor_new (GTH_SEARCH (catalog));
+	gtk_widget_show (search_editor);
+	gtk_container_add (GTK_CONTAINER (alignment), search_editor);
 }
diff --git a/extensions/search/callbacks.h b/extensions/search/callbacks.h
index 76588ee..7de3d8e 100644
--- a/extensions/search/callbacks.h
+++ b/extensions/search/callbacks.h
@@ -26,11 +26,14 @@
 #include <gthumb.h>
 #include <extensions/catalogs/gth-catalog.h>
 
-void search__gth_browser_construct_cb            (GthBrowser *browser);
-void search__gth_browser_update_sensitivity_cb   (GthBrowser *browser);
-void search__gth_browser_load_location_after_cb  (GthBrowser *browser,
-						  GFile      *location,
-						  GError     *error);
-GthCatalog * search__gth_catalog_load_from_data_cb   (const void *buffer);
+void search__gth_browser_construct_cb              (GthBrowser  *browser);
+void search__gth_browser_update_sensitivity_cb     (GthBrowser  *browser);
+void search__gth_browser_load_location_after_cb    (GthBrowser  *browser,
+						    GFile       *location,
+						    GError      *error);
+GthCatalog * search__gth_catalog_load_from_data_cb (const void  *buffer);
+void search__dlg_catalog_properties                (GthBrowser  *browser,
+						    GtkBuilder  *builder,
+						    GthFileData *file_data);
 
 #endif /* CALLBACKS_H */
diff --git a/extensions/search/data/ui/search-editor.ui b/extensions/search/data/ui/search-editor.ui
index 762395d..fec1c7b 100644
--- a/extensions/search/data/ui/search-editor.ui
+++ b/extensions/search/data/ui/search-editor.ui
@@ -8,12 +8,9 @@
     <property name="orientation">vertical</property>
     <property name="spacing">12</property>
     <child>
-      <object class="GtkTable" id="table1">
+      <object class="GtkHBox" id="hbox2">
         <property name="visible">True</property>
-        <property name="n_rows">2</property>
-        <property name="n_columns">2</property>
-        <property name="column_spacing">6</property>
-        <property name="row_spacing">6</property>
+        <property name="spacing">6</property>
         <child>
           <object class="GtkLabel" id="label2">
             <property name="visible">True</property>
@@ -22,20 +19,20 @@
             <property name="use_underline">True</property>
           </object>
           <packing>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
+            <property name="expand">False</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
           <object class="GtkFileChooserButton" id="start_at_filechooserbutton">
+            <property name="width_request">200</property>
             <property name="visible">True</property>
             <property name="action">select-folder</property>
+            <property name="create_folders">False</property>
             <property name="title" translatable="yes"></property>
           </object>
           <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -48,15 +45,10 @@
             <property name="draw_indicator">True</property>
           </object>
           <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
+            <property name="expand">False</property>
+            <property name="position">2</property>
           </packing>
         </child>
-        <child>
-          <placeholder/>
-        </child>
       </object>
       <packing>
         <property name="expand">False</property>
diff --git a/extensions/search/gth-search-editor-dialog.c b/extensions/search/gth-search-editor-dialog.c
index 0cfbc0f..0d75c29 100644
--- a/extensions/search/gth-search-editor-dialog.c
+++ b/extensions/search/gth-search-editor-dialog.c
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <gtk/gtk.h>
 #include <gthumb.h>
+#include "gth-search-editor.h"
 #include "gth-search-editor-dialog.h"
 
 
@@ -35,7 +36,7 @@ static gpointer parent_class = NULL;
 
 struct _GthSearchEditorDialogPrivate {
 	GtkBuilder *builder;
-	GtkWidget  *match_type_combobox;
+	GtkWidget  *search_editor;
 };
 
 
@@ -47,7 +48,6 @@ gth_search_editor_dialog_finalize (GObject *object)
 	dialog = GTH_SEARCH_EDITOR_DIALOG (object);
 
 	if (dialog->priv != NULL) {
-		g_object_unref (dialog->priv->builder);
 		g_free (dialog->priv);
 		dialog->priv = NULL;
 	}
@@ -103,28 +103,11 @@ gth_search_editor_dialog_get_type (void)
 
 
 static void
-update_sensitivity (GthSearchEditorDialog *self)
-{
-	GList *test_selectors;
-	int    more_selectors;
-	GList *scan;
-
-	test_selectors = gtk_container_get_children (GTK_CONTAINER (GET_WIDGET ("tests_box")));
-	more_selectors = (test_selectors != NULL) && (test_selectors->next != NULL);
-	for (scan = test_selectors; scan; scan = scan->next)
-		gth_test_selector_can_remove (GTH_TEST_SELECTOR (scan->data), more_selectors);
-	g_list_free (test_selectors);
-}
-
-
-static void
 gth_search_editor_dialog_construct (GthSearchEditorDialog *self,
 				    const char            *title,
 				    GthSearch             *search,
 			            GtkWindow             *parent)
 {
-	GtkWidget       *content;
-
 	if (title != NULL)
     		gtk_window_set_title (GTK_WINDOW (self), title);
   	if (parent != NULL)
@@ -134,26 +117,10 @@ gth_search_editor_dialog_construct (GthSearchEditorDialog *self,
 	gtk_box_set_spacing (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), 5);
 	gtk_container_set_border_width (GTK_CONTAINER (self), 5);
 
-    	self->priv->builder = _gtk_builder_new_from_file ("search-editor.ui", "search");
-
-    	content = _gtk_builder_get_widget (self->priv->builder, "search_editor");
-    	gtk_container_set_border_width (GTK_CONTAINER (content), 5);
-  	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), content, TRUE, TRUE, 0);
-
-	self->priv->match_type_combobox = gtk_combo_box_new_text ();
-  	_gtk_combo_box_append_texts (GTK_COMBO_BOX (self->priv->match_type_combobox),
-  				     _("all the following rules"),
-  				     _("any of the following rules"),
-  				     NULL);
-	gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->match_type_combobox), 0);
-  	gtk_widget_show (self->priv->match_type_combobox);
-  	gtk_container_add (GTK_CONTAINER (GET_WIDGET ("match_type_combobox_box")),
-  			   self->priv->match_type_combobox);
-
-	gtk_label_set_use_underline (GTK_LABEL (GET_WIDGET ("match_label")), TRUE);
-	gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("match_label")), self->priv->match_type_combobox);
-
-  	gth_search_editor_dialog_set_search (self, search);
+    	self->priv->search_editor = gth_search_editor_new (search);
+    	gtk_container_set_border_width (GTK_CONTAINER (self->priv->search_editor), 5);
+    	gtk_widget_show (self->priv->search_editor);
+  	gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self))), self->priv->search_editor, TRUE, TRUE, 0);
 }
 
 
@@ -171,117 +138,11 @@ gth_search_editor_dialog_new (const char *title,
 }
 
 
-static GtkWidget *
-_gth_search_editor_dialog_add_test (GthSearchEditorDialog *self,
-				    int                    pos);
-
-
-static void
-test_selector_add_test_cb (GthTestSelector       *selector,
-			   GthSearchEditorDialog *self)
-{
-	int pos;
-
-	pos = _gtk_container_get_pos (GTK_CONTAINER (GET_WIDGET ("tests_box")), (GtkWidget*) selector);
-	_gth_search_editor_dialog_add_test (self, pos == -1 ? -1 : pos + 1);
-	update_sensitivity (self);
-}
-
-
-static void
-test_selector_remove_test_cb (GthTestSelector       *selector,
-			      GthSearchEditorDialog *self)
-{
-	gtk_container_remove (GTK_CONTAINER (GET_WIDGET ("tests_box")), (GtkWidget*) selector);
-	update_sensitivity (self);
-}
-
-
-static GtkWidget *
-_gth_search_editor_dialog_add_test (GthSearchEditorDialog *self,
-				    int                    pos)
-{
-	GtkWidget *test_selector;
-
-	test_selector = gth_test_selector_new ();
-	gtk_widget_show (test_selector);
-
-	g_signal_connect (G_OBJECT (test_selector),
-			  "add_test",
-			  G_CALLBACK (test_selector_add_test_cb),
-			  self);
-	g_signal_connect (G_OBJECT (test_selector),
-			  "remove_test",
-			  G_CALLBACK (test_selector_remove_test_cb),
-			  self);
-
-	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tests_box")), test_selector, FALSE, FALSE, 0);
-
-	if (pos >= 0)
-		gtk_box_reorder_child (GTK_BOX (GET_WIDGET ("tests_box")),
-				       test_selector,
-				       pos);
-
-	return test_selector;
-}
-
-
-static void
-_gth_search_editor_dialog_set_new_search (GthSearchEditorDialog *self)
-{
-	gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")), get_home_uri ());
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton")), TRUE);
-	_gtk_container_remove_children (GTK_CONTAINER (GET_WIDGET ("tests_box")), NULL, NULL);
-}
-
-
 void
 gth_search_editor_dialog_set_search (GthSearchEditorDialog *self,
 				     GthSearch             *search)
 {
-	GthTestChain *test;
-	GthMatchType  match_type;
-
-	_gth_search_editor_dialog_set_new_search (self);
-
-	if (search == NULL) {
-		_gth_search_editor_dialog_add_test (self, -1);
-		update_sensitivity (self);
-		return;
-	}
-
-	if (gth_search_get_folder (search) != NULL) {
-		char *uri;
-
-		uri = g_file_get_uri (gth_search_get_folder (search));
-		if (uri != NULL) {
-			gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")), uri);
-			g_free (uri);
-		}
-	}
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton")), gth_search_is_recursive (search));
-
-	test = gth_search_get_test (search);
-	match_type = (test != NULL) ? gth_test_chain_get_match_type (test) : GTH_MATCH_TYPE_NONE;
-	_gtk_container_remove_children (GTK_CONTAINER (GET_WIDGET ("tests_box")), NULL, NULL);
-	if (match_type != GTH_MATCH_TYPE_NONE) {
-		GList *tests;
-		GList *scan;
-
-		tests = gth_test_chain_get_tests (test);
-		for (scan = tests; scan; scan = scan->next) {
-			GthTest   *test = scan->data;
-			GtkWidget *test_selector;
-
-			test_selector = _gth_search_editor_dialog_add_test (self, -1);
-			gth_test_selector_set_test (GTH_TEST_SELECTOR (test_selector), test);
-		}
-		_g_object_list_unref (tests);
-	}
-	else
-		_gth_search_editor_dialog_add_test (self, -1);
-
-	update_sensitivity (self);
+	gth_search_editor_set_search (GTH_SEARCH_EDITOR (self->priv->search_editor), search);
 }
 
 
@@ -289,42 +150,5 @@ GthSearch *
 gth_search_editor_dialog_get_search (GthSearchEditorDialog  *self,
 				     GError                **error)
 {
-	GthSearch *search;
-	char      *uri;
-	GthTest   *test;
-	GList     *test_selectors;
-	GList     *scan;
-
-	search = gth_search_new ();
-
-	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")));
-	if (uri != NULL) {
-		GFile *folder;
-
-		folder = g_file_new_for_uri (uri);
-		gth_search_set_folder (search, folder);
-		g_object_unref (folder);
-	}
-
-	gth_search_set_recursive (search, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton"))));
-
-	test = gth_test_chain_new (gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->match_type_combobox)) + 1, NULL);
-	test_selectors = gtk_container_get_children (GTK_CONTAINER (GET_WIDGET ("tests_box")));
-	for (scan = test_selectors; scan; scan = scan->next) {
-		GthTestSelector *test_selector = GTH_TEST_SELECTOR (scan->data);
-		GthTest         *sub_test;
-
-		sub_test = gth_test_selector_get_test (test_selector, error);
-		if (sub_test == NULL) {
-			g_object_unref (search);
-			return NULL;
-		}
-
-		gth_test_chain_add_test (GTH_TEST_CHAIN (test), sub_test);
-		g_object_unref (sub_test);
-	}
-	g_list_free (test_selectors);
-	gth_search_set_test (search, GTH_TEST_CHAIN (test));
-
-	return search;
+	return gth_search_editor_get_search (GTH_SEARCH_EDITOR (self->priv->search_editor), error);
 }
diff --git a/extensions/search/gth-search-editor.c b/extensions/search/gth-search-editor.c
new file mode 100644
index 0000000..4af217e
--- /dev/null
+++ b/extensions/search/gth-search-editor.c
@@ -0,0 +1,317 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <gtk/gtk.h>
+#include <gthumb.h>
+#include "gth-search-editor.h"
+
+
+#define GET_WIDGET(name) _gtk_builder_get_widget (self->priv->builder, (name))
+
+
+static gpointer parent_class = NULL;
+
+
+struct _GthSearchEditorPrivate {
+	GtkBuilder *builder;
+	GtkWidget  *match_type_combobox;
+};
+
+
+static void
+gth_search_editor_finalize (GObject *object)
+{
+	GthSearchEditor *dialog;
+
+	dialog = GTH_SEARCH_EDITOR (object);
+
+	if (dialog->priv != NULL) {
+		g_object_unref (dialog->priv->builder);
+		g_free (dialog->priv);
+		dialog->priv = NULL;
+	}
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gth_search_editor_class_init (GthSearchEditorClass *class)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	object_class = (GObjectClass*) class;
+
+	object_class->finalize = gth_search_editor_finalize;
+}
+
+
+static void
+gth_search_editor_init (GthSearchEditor *dialog)
+{
+	dialog->priv = g_new0 (GthSearchEditorPrivate, 1);
+}
+
+
+GType
+gth_search_editor_get_type (void)
+{
+        static GType type = 0;
+
+        if (! type) {
+                GTypeInfo type_info = {
+			sizeof (GthSearchEditorClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_search_editor_class_init,
+			NULL,
+			NULL,
+			sizeof (GthSearchEditor),
+			0,
+			(GInstanceInitFunc) gth_search_editor_init
+		};
+
+		type = g_type_register_static (GTK_TYPE_VBOX,
+					       "GthSearchEditor",
+					       &type_info,
+					       0);
+	}
+
+        return type;
+}
+
+
+static void
+update_sensitivity (GthSearchEditor *self)
+{
+	GList *test_selectors;
+	int    more_selectors;
+	GList *scan;
+
+	test_selectors = gtk_container_get_children (GTK_CONTAINER (GET_WIDGET ("tests_box")));
+	more_selectors = (test_selectors != NULL) && (test_selectors->next != NULL);
+	for (scan = test_selectors; scan; scan = scan->next)
+		gth_test_selector_can_remove (GTH_TEST_SELECTOR (scan->data), more_selectors);
+	g_list_free (test_selectors);
+}
+
+
+static void
+gth_search_editor_construct (GthSearchEditor *self,
+			     GthSearch       *search)
+{
+	GtkWidget *content;
+
+    	self->priv->builder = _gtk_builder_new_from_file ("search-editor.ui", "search");
+
+    	content = _gtk_builder_get_widget (self->priv->builder, "search_editor");
+    	gtk_container_set_border_width (GTK_CONTAINER (content), 0);
+  	gtk_box_pack_start (GTK_BOX (self), content, TRUE, TRUE, 0);
+
+	self->priv->match_type_combobox = gtk_combo_box_new_text ();
+  	_gtk_combo_box_append_texts (GTK_COMBO_BOX (self->priv->match_type_combobox),
+  				     _("all the following rules"),
+  				     _("any of the following rules"),
+  				     NULL);
+	gtk_combo_box_set_active (GTK_COMBO_BOX (self->priv->match_type_combobox), 0);
+  	gtk_widget_show (self->priv->match_type_combobox);
+  	gtk_container_add (GTK_CONTAINER (GET_WIDGET ("match_type_combobox_box")),
+  			   self->priv->match_type_combobox);
+
+	gtk_label_set_use_underline (GTK_LABEL (GET_WIDGET ("match_label")), TRUE);
+	gtk_label_set_mnemonic_widget (GTK_LABEL (GET_WIDGET ("match_label")), self->priv->match_type_combobox);
+
+  	gth_search_editor_set_search (self, search);
+}
+
+
+GtkWidget *
+gth_search_editor_new (GthSearch  *search)
+{
+	GthSearchEditor *self;
+
+	self = g_object_new (GTH_TYPE_SEARCH_EDITOR, NULL);
+	gth_search_editor_construct (self, search);
+
+	return (GtkWidget *) self;
+}
+
+
+static GtkWidget *
+_gth_search_editor_add_test (GthSearchEditor *self,
+			     int              pos);
+
+
+static void
+test_selector_add_test_cb (GthTestSelector *selector,
+			   GthSearchEditor *self)
+{
+	int pos;
+
+	pos = _gtk_container_get_pos (GTK_CONTAINER (GET_WIDGET ("tests_box")), (GtkWidget*) selector);
+	_gth_search_editor_add_test (self, pos == -1 ? -1 : pos + 1);
+	update_sensitivity (self);
+}
+
+
+static void
+test_selector_remove_test_cb (GthTestSelector *selector,
+			      GthSearchEditor *self)
+{
+	gtk_container_remove (GTK_CONTAINER (GET_WIDGET ("tests_box")), (GtkWidget*) selector);
+	update_sensitivity (self);
+}
+
+
+static GtkWidget *
+_gth_search_editor_add_test (GthSearchEditor *self,
+			     int              pos)
+{
+	GtkWidget *test_selector;
+
+	test_selector = gth_test_selector_new ();
+	gtk_widget_show (test_selector);
+
+	g_signal_connect (G_OBJECT (test_selector),
+			  "add_test",
+			  G_CALLBACK (test_selector_add_test_cb),
+			  self);
+	g_signal_connect (G_OBJECT (test_selector),
+			  "remove_test",
+			  G_CALLBACK (test_selector_remove_test_cb),
+			  self);
+
+	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("tests_box")), test_selector, FALSE, FALSE, 0);
+
+	if (pos >= 0)
+		gtk_box_reorder_child (GTK_BOX (GET_WIDGET ("tests_box")),
+				       test_selector,
+				       pos);
+
+	return test_selector;
+}
+
+
+static void
+_gth_search_editor_set_new_search (GthSearchEditor *self)
+{
+	gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")), get_home_uri ());
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton")), TRUE);
+	_gtk_container_remove_children (GTK_CONTAINER (GET_WIDGET ("tests_box")), NULL, NULL);
+}
+
+
+void
+gth_search_editor_set_search (GthSearchEditor *self,
+			      GthSearch       *search)
+{
+	GthTestChain *test;
+	GthMatchType  match_type;
+
+	_gth_search_editor_set_new_search (self);
+
+	if (search == NULL) {
+		_gth_search_editor_add_test (self, -1);
+		update_sensitivity (self);
+		return;
+	}
+
+	if (gth_search_get_folder (search) != NULL) {
+		char *uri;
+
+		uri = g_file_get_uri (gth_search_get_folder (search));
+		if (uri != NULL) {
+			gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")), uri);
+			g_free (uri);
+		}
+	}
+	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton")), gth_search_is_recursive (search));
+
+	test = gth_search_get_test (search);
+	match_type = (test != NULL) ? gth_test_chain_get_match_type (test) : GTH_MATCH_TYPE_NONE;
+	_gtk_container_remove_children (GTK_CONTAINER (GET_WIDGET ("tests_box")), NULL, NULL);
+	if (match_type != GTH_MATCH_TYPE_NONE) {
+		GList *tests;
+		GList *scan;
+
+		tests = gth_test_chain_get_tests (test);
+		for (scan = tests; scan; scan = scan->next) {
+			GthTest   *test = scan->data;
+			GtkWidget *test_selector;
+
+			test_selector = _gth_search_editor_add_test (self, -1);
+			gth_test_selector_set_test (GTH_TEST_SELECTOR (test_selector), test);
+		}
+		_g_object_list_unref (tests);
+	}
+	else
+		_gth_search_editor_add_test (self, -1);
+
+	update_sensitivity (self);
+}
+
+
+GthSearch *
+gth_search_editor_get_search (GthSearchEditor  *self,
+			      GError          **error)
+{
+	GthSearch *search;
+	char      *uri;
+	GthTest   *test;
+	GList     *test_selectors;
+	GList     *scan;
+
+	search = gth_search_new ();
+
+	uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (GET_WIDGET ("start_at_filechooserbutton")));
+	if (uri != NULL) {
+		GFile *folder;
+
+		folder = g_file_new_for_uri (uri);
+		gth_search_set_folder (search, folder);
+		g_object_unref (folder);
+	}
+
+	gth_search_set_recursive (search, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (GET_WIDGET ("include_subfolders_checkbutton"))));
+
+	test = gth_test_chain_new (gtk_combo_box_get_active (GTK_COMBO_BOX (self->priv->match_type_combobox)) + 1, NULL);
+	test_selectors = gtk_container_get_children (GTK_CONTAINER (GET_WIDGET ("tests_box")));
+	for (scan = test_selectors; scan; scan = scan->next) {
+		GthTestSelector *test_selector = GTH_TEST_SELECTOR (scan->data);
+		GthTest         *sub_test;
+
+		sub_test = gth_test_selector_get_test (test_selector, error);
+		if (sub_test == NULL) {
+			g_object_unref (search);
+			return NULL;
+		}
+
+		gth_test_chain_add_test (GTH_TEST_CHAIN (test), sub_test);
+		g_object_unref (sub_test);
+	}
+	g_list_free (test_selectors);
+	gth_search_set_test (search, GTH_TEST_CHAIN (test));
+
+	return search;
+}
diff --git a/extensions/search/gth-search-editor.h b/extensions/search/gth-search-editor.h
new file mode 100644
index 0000000..cf445ec
--- /dev/null
+++ b/extensions/search/gth-search-editor.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_SEARCH_EDITOR_H
+#define GTH_SEARCH_EDITOR_H
+
+#include <gtk/gtk.h>
+#include "gth-search.h"
+
+#define GTH_TYPE_SEARCH_EDITOR            (gth_search_editor_get_type ())
+#define GTH_SEARCH_EDITOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_SEARCH_EDITOR, GthSearchEditor))
+#define GTH_SEARCH_EDITOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_SEARCH_EDITOR, GthSearchEditorClass))
+#define GTH_IS_SEARCH_EDITOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_SEARCH_EDITOR))
+#define GTH_IS_SEARCH_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_SEARCH_EDITOR))
+#define GTH_SEARCH_EDITOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_SEARCH_EDITOR, GthSearchEditorClass))
+
+typedef struct _GthSearchEditor        GthSearchEditor;
+typedef struct _GthSearchEditorClass   GthSearchEditorClass;
+typedef struct _GthSearchEditorPrivate GthSearchEditorPrivate;
+
+struct _GthSearchEditor {
+	GtkVBox parent_instance;
+	GthSearchEditorPrivate *priv;
+};
+
+struct _GthSearchEditorClass {
+	GtkVBoxClass parent_class;
+};
+
+GType       gth_search_editor_get_type   (void);
+GtkWidget * gth_search_editor_new        (GthSearch        *search);
+void        gth_search_editor_set_search (GthSearchEditor  *self,
+				 	  GthSearch        *search);
+GthSearch * gth_search_editor_get_search (GthSearchEditor  *self,
+					  GError          **error);
+
+#endif /* GTH_SEARCH_EDITOR_H */
diff --git a/extensions/search/gth-search-task.c b/extensions/search/gth-search-task.c
index 107ed90..db508a9 100644
--- a/extensions/search/gth-search-task.c
+++ b/extensions/search/gth-search-task.c
@@ -96,7 +96,7 @@ embedded_dialog_response_cb (GeditMessageArea *message_area,
 
 	switch (response_id) {
 	case GTK_RESPONSE_CLOSE:
-		gth_browser_set_list_extra_widget (data->browser, NULL);
+		/* gth_browser_set_list_extra_widget (data->browser, NULL); FIXME */
 		break;
 
 	case GTK_RESPONSE_CANCEL:
@@ -124,18 +124,21 @@ save_search_result_copy_done_cb (void     *buffer,
 
 	gth_embedded_dialog_set_primary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), _("Search completed"));
 
-	result = gth_catalog_get_file_list (GTH_CATALOG (task->priv->search));
+	/*result = gth_catalog_get_file_list (GTH_CATALOG (task->priv->search));
 	n = g_list_length (result);
 	text = g_strdup_printf (ngettext("%d file found.", "%d files found.", n), n);
 	gth_embedded_dialog_set_secondary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), text);
 
-	g_free (text);
+	g_free (text);*/
 
-	gedit_message_area_clear_action_area (GEDIT_MESSAGE_AREA (task->priv->dialog));
+	gth_browser_load_location_after (task->priv->browser, NULL);
+
+	/* FIXME
 	gedit_message_area_add_stock_button_with_text (GEDIT_MESSAGE_AREA (task->priv->dialog),
 						       NULL,
 						       GTK_STOCK_CLOSE,
 						       GTK_RESPONSE_CLOSE);
+	*/
 
 	task->priv->io_operation = FALSE;
 	gth_task_completed (GTH_TASK (task), task->priv->error);
@@ -222,9 +225,10 @@ start_dir_func (GFile      *directory,
 	char          *uri;
 	char          *text;
 
-	uri = g_file_get_uri (directory);
+	uri = g_file_get_parse_name (directory);
 	text = g_strdup_printf ("Searching in %s", uri);
-	gth_embedded_dialog_set_secondary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), text);
+	/*gth_embedded_dialog_set_secondary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), text); FIXME */
+	gth_embedded_dialog_set_primary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), text);
 
 	g_free (text);
 	g_free (uri);
@@ -239,7 +243,6 @@ browser_location_ready_cb (GthBrowser    *browser,
 			   gboolean       error,
 			   GthSearchTask *task)
 {
-	GtkWidget          *alignment;
 	EmbeddedDialogData *dialog_data;
 
 	g_signal_handler_disconnect (task->priv->browser, task->priv->location_ready_id);
@@ -249,17 +252,14 @@ browser_location_ready_cb (GthBrowser    *browser,
 		return;
 	}
 
-	alignment = gtk_alignment_new (0, 0, 1.0, 1.0);
-	gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), 3, 3, 0, 0);
-	gtk_widget_show (alignment);
-
-	task->priv->dialog = gth_embedded_dialog_new (GTK_STOCK_FIND, _("Searching..."), NULL);
+	task->priv->dialog = gth_browser_get_list_extra_widget (browser);
+	gth_embedded_dialog_set_icon (GTH_EMBEDDED_DIALOG (task->priv->dialog), GTK_STOCK_FIND);
+	gth_embedded_dialog_set_primary_text (GTH_EMBEDDED_DIALOG (task->priv->dialog), _("Searching..."));
+	gedit_message_area_clear_action_area (GEDIT_MESSAGE_AREA (task->priv->dialog));
 	gedit_message_area_add_stock_button_with_text (GEDIT_MESSAGE_AREA (task->priv->dialog),
 						       NULL,
 						       GTK_STOCK_CANCEL,
 						       GTK_RESPONSE_CANCEL);
-	gtk_widget_show (task->priv->dialog);
-	gtk_container_add (GTK_CONTAINER (alignment), task->priv->dialog);
 
 	dialog_data = g_new0 (EmbeddedDialogData, 1);
 	dialog_data->browser = task->priv->browser;
@@ -273,8 +273,6 @@ browser_location_ready_cb (GthBrowser    *browser,
 			  G_CALLBACK (embedded_dialog_response_cb),
 			  dialog_data);
 
-	gth_browser_set_list_extra_widget (task->priv->browser, alignment);
-
 	/**/
 
 	if (gth_search_get_test (task->priv->search) != NULL)
diff --git a/extensions/search/main.c b/extensions/search/main.c
index f315b48..eaf684d 100644
--- a/extensions/search/main.c
+++ b/extensions/search/main.c
@@ -32,7 +32,8 @@ gthumb_extension_activate (void)
 {
 	gth_hook_add_callback ("gth-catalog-load-from-data", 10, G_CALLBACK (search__gth_catalog_load_from_data_cb), NULL);
 	gth_hook_add_callback ("gth-browser-construct", 10, G_CALLBACK (search__gth_browser_construct_cb), NULL);
-	gth_hook_add_callback ("gth-browser-load-location-after", 10, G_CALLBACK (search__gth_browser_load_location_after_cb), NULL);
+	gth_hook_add_callback ("gth-browser-load-location-after", 20, G_CALLBACK (search__gth_browser_load_location_after_cb), NULL);
+	gth_hook_add_callback ("dlg-catalog-properties", 10, G_CALLBACK (search__dlg_catalog_properties), NULL);
 }
 
 
diff --git a/gthumb/gedit-message-area.c b/gthumb/gedit-message-area.c
index 2b60663..f30458d 100644
--- a/gthumb/gedit-message-area.c
+++ b/gthumb/gedit-message-area.c
@@ -237,20 +237,29 @@ style_set (GtkWidget        *widget,
 static void
 gedit_message_area_init (GeditMessageArea *message_area)
 {
+	GtkWidget *vbox;
+
 	message_area->priv = GEDIT_MESSAGE_AREA_GET_PRIVATE (message_area);
 
-	message_area->priv->main_hbox = gtk_hbox_new (FALSE, 16); /* FIXME: use style properties */
+	message_area->priv->main_hbox = gtk_hbox_new (FALSE, 3); /* FIXME: use style properties */
 	gtk_widget_show (message_area->priv->main_hbox);
-	gtk_container_set_border_width (GTK_CONTAINER (message_area->priv->main_hbox),
-					8); /* FIXME: use style properties */
+	gtk_container_set_border_width (GTK_CONTAINER (message_area->priv->main_hbox), 3); /* FIXME: use style properties */
 
-	message_area->priv->action_area = gtk_vbox_new (TRUE, 10); /* FIXME: use style properties */
-	gtk_widget_show (message_area->priv->action_area);
+	vbox = gtk_vbox_new (FALSE, 0);
+	gtk_widget_show (vbox);
 	gtk_box_pack_end (GTK_BOX (message_area->priv->main_hbox),
-			    message_area->priv->action_area,
-			    FALSE,
-			    TRUE,
-			    0);
+			  vbox,
+			  FALSE,
+			  FALSE,
+			  0);
+
+	message_area->priv->action_area = gtk_hbox_new (FALSE, 3); /* FIXME: use style properties */
+	gtk_widget_show (message_area->priv->action_area);
+	gtk_box_pack_end (GTK_BOX (vbox),
+			  message_area->priv->action_area,
+			  TRUE,
+			  FALSE,
+			  0);
 
 	gtk_box_pack_start (GTK_BOX (message_area),
 			    message_area->priv->main_hbox,
@@ -258,21 +267,24 @@ gedit_message_area_init (GeditMessageArea *message_area)
 			    TRUE,
 			    0);
 
+	/*
 	gtk_widget_set_app_paintable (GTK_WIDGET (message_area), TRUE);
 
 	g_signal_connect (message_area,
 			  "expose-event",
 			  G_CALLBACK (paint_message_area),
 			  NULL);
+	 */
 
 	/* Note that we connect to style-set on one of the internal
 	 * widgets, not on the message area itself, since gtk does
 	 * not deliver any further style-set signals for a widget on
 	 * which the style has been forced with gtk_widget_set_style() */
-	g_signal_connect (message_area->priv->main_hbox,
+
+	/*g_signal_connect (message_area->priv->main_hbox,
 			  "style-set",
 			  G_CALLBACK (style_set),
-			  message_area);
+			  message_area);*/
 }
 
 static gint
@@ -334,18 +346,11 @@ gedit_message_area_add_action_widget (GeditMessageArea *message_area,
 	else
 		g_warning ("Only 'activatable' widgets can be packed into the action area of a GeditMessageArea");
 
-	if (response_id != GTK_RESPONSE_HELP)
-		gtk_box_pack_start (GTK_BOX (message_area->priv->action_area),
-				    child,
-				    FALSE,
-				    FALSE,
-				    0);
-	else
-		gtk_box_pack_end (GTK_BOX (message_area->priv->action_area),
-				    child,
-				    FALSE,
-				    FALSE,
-				    0);
+	gtk_box_pack_end (GTK_BOX (message_area->priv->action_area),
+			  child,
+			  FALSE,
+			  FALSE,
+			  0);
 }
 
 /**
@@ -394,7 +399,7 @@ gedit_message_area_add_button (GeditMessageArea *message_area,
 	g_return_val_if_fail (button_text != NULL, NULL);
 
 	button = gtk_button_new_from_stock (button_text);
-
+	gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
 	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
 
 	gtk_widget_show (button);
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index be711cb..6cec036 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -2322,6 +2322,17 @@ _g_file_info_swap_attributes (GFileInfo  *info,
 
 
 gboolean
+_g_content_type_is_a (const char *type,
+		      const char *supertype)
+{
+	if (type == NULL)
+		return FALSE;
+	else
+		return g_content_type_is_a (type, supertype);
+}
+
+
+gboolean
 _g_mime_type_is_image (const char *mime_type)
 {
 	g_return_val_if_fail (mime_type != NULL, FALSE);
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index ac4a09c..65a5f70 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -254,6 +254,8 @@ gboolean        _g_file_attributes_matches       (const char *attributes,
 void            _g_file_info_swap_attributes     (GFileInfo  *info,
 						  const char *attr1,
 						  const char *attr2);
+gboolean        _g_content_type_is_a             (const char *type,
+						  const char *supertype);
 gboolean        _g_mime_type_is_image            (const char *mime_type);
 gboolean        _g_mime_type_is_video            (const char *mime_type);
 gboolean        _g_mime_type_is_audio            (const char *mime_type);
diff --git a/gthumb/gth-browser.c b/gthumb/gth-browser.c
index 257f04e..7a29977 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -32,6 +32,7 @@
 #include "gth-browser-actions-entries.h"
 #include "gth-browser-ui.h"
 #include "gth-duplicable.h"
+#include "gth-embedded-dialog.h"
 #include "gth-enum-types.h"
 #include "gth-error.h"
 #include "gth-file-list.h"
@@ -526,6 +527,18 @@ gth_browser_update_sensitivity (GthBrowser *browser)
 }
 
 
+void
+gth_browser_load_location_after (GthBrowser *browser,
+				 GError     *error)
+{
+	gedit_message_area_clear_action_area (GEDIT_MESSAGE_AREA (browser->priv->list_extra_widget));
+	gth_embedded_dialog_set_gicon (GTH_EMBEDDED_DIALOG (browser->priv->list_extra_widget), g_file_info_get_icon (browser->priv->location->info));
+	gth_embedded_dialog_set_primary_text (GTH_EMBEDDED_DIALOG (browser->priv->list_extra_widget), g_file_info_get_display_name (browser->priv->location->info));
+
+	gth_hook_invoke ("gth-browser-load-location-after", browser, browser->priv->location, error);
+}
+
+
 static void
 _gth_browser_set_location (GthBrowser  *browser,
 			   GthFileData *location)
@@ -978,7 +991,7 @@ load_data_done (LoadData *load_data,
 	    || (load_data->action == GTH_ACTION_GO_UP)
 	    || (load_data->action == GTH_ACTION_VIEW))
 	{
-		gth_hook_invoke ("gth-browser-load-location-after", browser, browser->priv->location, error);
+		gth_browser_load_location_after (browser, error);
 	}
 
 	if (error == NULL)
@@ -1605,7 +1618,7 @@ _gth_browser_load (GthBrowser *browser,
 	}
 
 	gth_browser_update_sensitivity (browser);
-	gth_browser_set_list_extra_widget (browser, NULL);
+	/* gth_browser_set_list_extra_widget (browser, NULL); FIXME */
 	load_data_load_next_folder (load_data);
 
 	g_object_unref (entry_point);
@@ -3244,7 +3257,7 @@ _gth_browser_construct (GthBrowser *browser)
 
 	/* the box that contains the location and the folder list.  */
 
-	vbox = gtk_vbox_new (FALSE, 6);
+	vbox = gtk_vbox_new (FALSE, 4);
 	gtk_widget_show (vbox);
 	gtk_paned_pack1 (GTK_PANED (browser->priv->browser_sidebar), vbox, TRUE, TRUE);
 
@@ -3314,10 +3327,15 @@ _gth_browser_construct (GthBrowser *browser)
 
 	/* the list extra widget container */
 
-	browser->priv->list_extra_widget_container = gtk_vbox_new (FALSE, 0);
+	browser->priv->list_extra_widget_container = gtk_alignment_new (0, 0, 1.0, 1.0);
+	gtk_alignment_set_padding (GTK_ALIGNMENT (browser->priv->list_extra_widget_container), 0, 0, 0, 0);
 	gtk_widget_show (browser->priv->list_extra_widget_container);
 	gtk_box_pack_start (GTK_BOX (vbox), browser->priv->list_extra_widget_container, FALSE, FALSE, 0);
 
+	browser->priv->list_extra_widget = gth_embedded_dialog_new (NULL, NULL, NULL);
+	gtk_widget_show (browser->priv->list_extra_widget);
+	gtk_container_add (GTK_CONTAINER (browser->priv->list_extra_widget_container), browser->priv->list_extra_widget);
+
 	/* the file list */
 
 	browser->priv->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL);
@@ -3895,22 +3913,6 @@ gth_browser_exec_task (GthBrowser *browser,
 }
 
 
-void
-gth_browser_set_list_extra_widget (GthBrowser *browser,
-				   GtkWidget  *widget)
-{
-	if (browser->priv->list_extra_widget != NULL) {
-		gtk_container_remove (GTK_CONTAINER (browser->priv->list_extra_widget_container), browser->priv->list_extra_widget);
-		browser->priv->list_extra_widget = NULL;
-	}
-
-	if (widget != NULL) {
-		browser->priv->list_extra_widget = widget;
-		gtk_container_add (GTK_CONTAINER (browser->priv->list_extra_widget_container), browser->priv->list_extra_widget);
-	}
-}
-
-
 GtkWidget *
 gth_browser_get_list_extra_widget (GthBrowser *browser)
 {
diff --git a/gthumb/gth-browser.h b/gthumb/gth-browser.h
index 83d5bcf..7a139b8 100644
--- a/gthumb/gth-browser.h
+++ b/gthumb/gth-browser.h
@@ -119,8 +119,6 @@ void             gth_browser_reload                 (GthBrowser       *browser);
 void             gth_browser_exec_task              (GthBrowser       *browser,
 						     GthTask          *task,
 						     gboolean          foreground);
-void             gth_browser_set_list_extra_widget  (GthBrowser       *browser,
-						     GtkWidget        *widget);
 GtkWidget *      gth_browser_get_list_extra_widget  (GthBrowser       *browser);
 void             gth_browser_set_current_page       (GthBrowser       *browser,
 						     GthBrowserPage    page);
@@ -154,6 +152,8 @@ void             gth_browser_load_file              (GthBrowser       *browser,
 						     gboolean          view);
 void             gth_browser_update_title           (GthBrowser       *browser);
 void             gth_browser_update_sensitivity     (GthBrowser       *browser);
+void             gth_browser_load_location_after    (GthBrowser       *browser,
+						     GError           *error);
 void             gth_browser_show_viewer_properties (GthBrowser       *browser,
 						     gboolean          show);
 void             gth_browser_show_viewer_tools      (GthBrowser       *browser,
diff --git a/gthumb/gth-embedded-dialog.c b/gthumb/gth-embedded-dialog.c
index 1a71622..3074bbb 100644
--- a/gthumb/gth-embedded-dialog.c
+++ b/gthumb/gth-embedded-dialog.c
@@ -42,9 +42,8 @@ gth_embedded_dialog_finalize (GObject *object)
 
 	dialog = GTH_EMBEDDED_DIALOG (object);
 
-	if (dialog->priv != NULL) {
+	if (dialog->priv != NULL)
 		dialog->priv = NULL;
-	}
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -110,7 +109,7 @@ gth_embedded_dialog_construct (GthEmbeddedDialog *self)
 
 	self->priv->icon_image = image = gtk_image_new ();
 	gtk_box_pack_start (GTK_BOX (hbox_content), image, FALSE, FALSE, 0);
-	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0);
+	gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
 
 	vbox = gtk_vbox_new (FALSE, 6);
 	gtk_widget_show (vbox);
@@ -123,7 +122,6 @@ gth_embedded_dialog_construct (GthEmbeddedDialog *self)
 	gtk_misc_set_alignment (GTK_MISC (primary_label), 0, 0.5);
 	GTK_WIDGET_SET_FLAGS (primary_label, GTK_CAN_FOCUS);
 	gtk_label_set_selectable (GTK_LABEL (primary_label), TRUE);
-
 	
 	self->priv->secondary_text_label = secondary_label = gtk_label_new (NULL);
 	gtk_box_pack_start (GTK_BOX (vbox), secondary_label, TRUE, TRUE, 0);
@@ -146,7 +144,7 @@ gth_embedded_dialog_new (const char *icon_stock_id,
 	GthEmbeddedDialog *self;
 
 	self = g_object_new (GTH_TYPE_EMBEDDED_DIALOG, NULL);
-	gth_embedded_dialog_construct (self);	
+	gth_embedded_dialog_construct (self);
 	gth_embedded_dialog_set_icon (self, icon_stock_id);
 	gth_embedded_dialog_set_primary_text (self, primary_text);
 	gth_embedded_dialog_set_secondary_text (self, secondary_text);
@@ -164,7 +162,21 @@ gth_embedded_dialog_set_icon (GthEmbeddedDialog *dialog,
 		return;
 	}
 
-	gtk_image_set_from_stock (GTK_IMAGE (dialog->priv->icon_image), icon_stock_id, GTK_ICON_SIZE_DIALOG);
+	gtk_image_set_from_stock (GTK_IMAGE (dialog->priv->icon_image), icon_stock_id, GTK_ICON_SIZE_BUTTON);
+	gtk_widget_show (dialog->priv->icon_image);
+}
+
+
+void
+gth_embedded_dialog_set_gicon (GthEmbeddedDialog *dialog,
+			       GIcon             *icon)
+{
+	if (icon == NULL) {
+		gtk_widget_hide (dialog->priv->icon_image);
+		return;
+	}
+
+	gtk_image_set_from_gicon (GTK_IMAGE (dialog->priv->icon_image), icon, GTK_ICON_SIZE_BUTTON);
 	gtk_widget_show (dialog->priv->icon_image);
 }
 
diff --git a/gthumb/gth-embedded-dialog.h b/gthumb/gth-embedded-dialog.h
index 05f1230..e9016fb 100644
--- a/gthumb/gth-embedded-dialog.h
+++ b/gthumb/gth-embedded-dialog.h
@@ -56,6 +56,8 @@ GtkWidget *   gth_embedded_dialog_new                (const char        *icon_st
 						      const char        *secondary_text);
 void          gth_embedded_dialog_set_icon           (GthEmbeddedDialog *dialog,
 						      const char        *icon_stock_id);
+void          gth_embedded_dialog_set_gicon          (GthEmbeddedDialog *dialog,
+						      GIcon             *icon);
 void          gth_embedded_dialog_set_primary_text   (GthEmbeddedDialog *dialog,
 						      const char        *primary_text);
 void          gth_embedded_dialog_set_secondary_text (GthEmbeddedDialog *dialog,
diff --git a/gthumb/gth-file-source-vfs.c b/gthumb/gth-file-source-vfs.c
index 66da77d..50916d8 100644
--- a/gthumb/gth-file-source-vfs.c
+++ b/gthumb/gth-file-source-vfs.c
@@ -62,6 +62,12 @@ gth_file_source_vfs_get_entry_points (GthFileSource *file_source)
 
 	list = NULL;
 
+	file = g_file_new_for_path (g_get_user_special_dir (G_USER_DIRECTORY_PICTURES));
+	info = gth_file_source_get_file_info (file_source, file, GFILE_BASIC_ATTRIBUTES ",access::*");
+	list = g_list_append (list, gth_file_data_new (file, info));
+	g_object_unref (info);
+	g_object_unref (file);
+
 	file = g_file_new_for_uri (get_home_uri ());
 	info = gth_file_source_get_file_info (file_source, file, GFILE_BASIC_ATTRIBUTES ",access::*");
 	g_file_info_set_display_name (info, _("Home Folder"));
diff --git a/gthumb/gth-time-selector.c b/gthumb/gth-time-selector.c
index 0b385aa..a6a625e 100644
--- a/gthumb/gth-time-selector.c
+++ b/gthumb/gth-time-selector.c
@@ -44,6 +44,8 @@ struct _GthTimeSelectorPrivate
 	GtkWidget   *calendar_popup;
 	GtkWidget   *time_combo_box;
 	GtkWidget   *popup_box;
+	GtkWidget   *now_button;
+	gboolean     use_time;
 };
 
 
@@ -179,7 +181,13 @@ update_date_from_view (GthTimeSelector *self)
 	struct tm tm;
 
 	strptime (gtk_entry_get_text (GTK_ENTRY (self->priv->date_entry)), "%x", &tm);
-	strptime (gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box)))), "%X", &tm);
+	if (self->priv->use_time)
+		strptime (gtk_entry_get_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box)))), "%X", &tm);
+	else {
+		tm.tm_hour = 0;
+		tm.tm_min = 0;
+		tm.tm_sec = 0;
+	}
 	gth_datetime_from_struct_tm (self->priv->date_time, &tm);
 }
 
@@ -187,19 +195,21 @@ update_date_from_view (GthTimeSelector *self)
 static void
 update_view_from_data (GthTimeSelector *self)
 {
-	if (gth_time_valid (self->priv->date_time->time)) {
-		char      *text;
-		GtkWidget *entry;
-
-		text = gth_datetime_strftime (self->priv->date_time, "%X");
-		entry = gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box));
-		gtk_entry_set_text (GTK_ENTRY (entry), text);
-	}
-	else {
-		GtkWidget *entry;
-
-		entry = gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box));
-		gtk_entry_set_text (GTK_ENTRY (entry), "");
+	if (self->priv->use_time) {
+		if (gth_time_valid (self->priv->date_time->time)) {
+			char      *text;
+			GtkWidget *entry;
+
+			text = gth_datetime_strftime (self->priv->date_time, "%X");
+			entry = gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box));
+			gtk_entry_set_text (GTK_ENTRY (entry), text);
+		}
+		else {
+			GtkWidget *entry;
+
+			entry = gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box));
+			gtk_entry_set_text (GTK_ENTRY (entry), "");
+		}
 	}
 
 	if (g_date_valid (self->priv->date_time->date)) {
@@ -415,7 +425,7 @@ gth_time_selector_construct (GthTimeSelector *self)
 			  G_CALLBACK (today_button_clicked_cb),
 			  self);
 
-	button = gtk_button_new_with_label (_("Now"));
+	self->priv->now_button = button = gtk_button_new_with_label (_("Now"));
 	gtk_widget_show (button);
 	gtk_box_pack_start (GTK_BOX (button_box), button, TRUE, TRUE, 0);
 	g_signal_connect (button,
@@ -498,11 +508,29 @@ gth_time_selector_new (void)
 
 
 void
+gth_time_selector_show_time (GthTimeSelector *self,
+			     gboolean         show)
+{
+	self->priv->use_time = show;
+	if (show) {
+		gtk_widget_show (self->priv->time_combo_box);
+		gtk_widget_show (self->priv->now_button);
+	}
+	else {
+		gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (self->priv->time_combo_box))), "00:00:00");
+		gtk_widget_hide (self->priv->time_combo_box);
+		gtk_widget_hide (self->priv->now_button);
+	}
+}
+
+
+void
 gth_time_selector_set_value (GthTimeSelector *self,
 			     GthDateTime     *date_time)
 {
 	*self->priv->date_time->date = *date_time->date;
-	*self->priv->date_time->time = *date_time->time;
+	if (self->priv->use_time)
+		*self->priv->date_time->time = *date_time->time;
 	update_view_from_data (self);
 }
 
diff --git a/gthumb/gth-time-selector.h b/gthumb/gth-time-selector.h
index a8bf541..864fe99 100644
--- a/gthumb/gth-time-selector.h
+++ b/gthumb/gth-time-selector.h
@@ -56,6 +56,8 @@ struct _GthTimeSelectorClass
 
 GType         gth_time_selector_get_type       (void) G_GNUC_CONST;
 GtkWidget *   gth_time_selector_new            (void);
+void          gth_time_selector_show_time      (GthTimeSelector *self,
+						gboolean         show);
 void          gth_time_selector_set_value      (GthTimeSelector *self,
 					        GthDateTime     *date_time);
 void          gth_time_selector_set_exif_date  (GthTimeSelector *self,



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