[gthumb] Added a GthListView to use a GtkTreeView to view the file list



commit 9b0bf42d20af924937fe186478cce59d8f55b34f
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Feb 13 19:01:37 2011 +0100

    Added a GthListView to use a GtkTreeView to view the file list

 extensions/catalogs/gth-organize-task.c            |    2 +-
 extensions/facebook/dlg-export-to-facebook.c       |    2 +-
 extensions/find_duplicates/gth-find-duplicates.c   |    8 +-
 extensions/flicker/dlg-export-to-flickr.c          |    2 +-
 extensions/flicker/dlg-import-from-flickr.c        |    8 +-
 extensions/photo_importer/dlg-photo-importer.c     |    6 +-
 extensions/photobucket/dlg-export-to-photobucket.c |    2 +-
 extensions/picasaweb/dlg-export-to-picasaweb.c     |    2 +-
 extensions/picasaweb/dlg-import-from-picasaweb.c   |    4 +-
 gthumb/Makefile.am                                 |    2 +
 gthumb/gth-browser.c                               |   28 +-
 gthumb/gth-cell-renderer-thumbnail.c               |    6 +-
 gthumb/gth-file-list.c                             |   86 ++--
 gthumb/gth-file-list.h                             |    4 +-
 gthumb/gth-file-selection.c                        |   81 ++-
 gthumb/gth-file-selection.h                        |   33 +-
 gthumb/gth-file-view.c                             |  108 +++-
 gthumb/gth-file-view.h                             |  183 ++++---
 gthumb/gth-icon-view.c                             |   57 ++
 gthumb/gth-icon-view.h                             |    2 +-
 gthumb/gth-list-view.c                             |  653 ++++++++++++++++++++
 gthumb/gth-list-view.h                             |   59 ++
 22 files changed, 1124 insertions(+), 214 deletions(-)
---
diff --git a/extensions/catalogs/gth-organize-task.c b/extensions/catalogs/gth-organize-task.c
index dbfb07d..3795628 100644
--- a/extensions/catalogs/gth-organize-task.c
+++ b/extensions/catalogs/gth-organize-task.c
@@ -801,7 +801,7 @@ gth_organize_task_init (GthOrganizeTask *self)
 						      gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GET_WIDGET ("organization_treeview"))));
 	g_object_unref (icon);
 
-	self->priv->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, FALSE);
+	self->priv->file_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, FALSE);
 	gth_file_list_set_caption (GTH_FILE_LIST (self->priv->file_list), "standard::display-name");
 	gtk_widget_show (self->priv->file_list);
 	gtk_box_pack_start (GTK_BOX (GET_WIDGET ("preview_box")), self->priv->file_list, TRUE, TRUE, 0);
diff --git a/extensions/facebook/dlg-export-to-facebook.c b/extensions/facebook/dlg-export-to-facebook.c
index f286d38..7807e93 100644
--- a/extensions/facebook/dlg-export-to-facebook.c
+++ b/extensions/facebook/dlg-export-to-facebook.c
@@ -549,7 +549,7 @@ dlg_export_to_facebook (GthBrowser *browser,
 
 	/* Set the widget data */
 
-	data->list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
+	data->list_view = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (data->list_view), 112);
 	gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (data->list_view))), 0);
 	gth_file_list_enable_thumbs (GTH_FILE_LIST (data->list_view), TRUE);
diff --git a/extensions/find_duplicates/gth-find-duplicates.c b/extensions/find_duplicates/gth-find-duplicates.c
index 4f120eb..e4caeb0 100644
--- a/extensions/find_duplicates/gth-find-duplicates.c
+++ b/extensions/find_duplicates/gth-find-duplicates.c
@@ -455,7 +455,7 @@ update_file_list_sensitivity (GthFindDuplicates *self)
 
 
 static void
-duplicates_list_view_selection_changed_cb (GtkIconView *iconview,
+duplicates_list_view_selection_changed_cb (GthFileView *fileview,
 					   gpointer     user_data)
 {
 	GthFindDuplicates *self = user_data;
@@ -679,7 +679,7 @@ gth_find_duplicates_exec (GthBrowser *browser,
 	}
 
 	self->priv->builder = _gtk_builder_new_from_file ("find-duplicates-dialog.ui", "find_duplicates");
-	self->priv->duplicates_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, FALSE);
+	self->priv->duplicates_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, FALSE);
 	gth_file_list_set_caption (GTH_FILE_LIST (self->priv->duplicates_list), "find-duplicates::n-duplicates,gth::file::display-size");
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (self->priv->duplicates_list), 112);
 	gtk_widget_set_size_request (self->priv->duplicates_list, -1, 200);
@@ -698,8 +698,8 @@ gth_find_duplicates_exec (GthBrowser *browser,
 				  "clicked",
 				  G_CALLBACK (g_cancellable_cancel),
 				  self->priv->cancellable);
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (self->priv->duplicates_list))),
-			  "selection_changed",
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (self->priv->duplicates_list)),
+			  "file-selection-changed",
 			  G_CALLBACK (duplicates_list_view_selection_changed_cb),
 			  self);
 	g_signal_connect (GET_WIDGET ("file_cellrenderertoggle"),
diff --git a/extensions/flicker/dlg-export-to-flickr.c b/extensions/flicker/dlg-export-to-flickr.c
index 9d93d41..3cff2f5 100644
--- a/extensions/flicker/dlg-export-to-flickr.c
+++ b/extensions/flicker/dlg-export-to-flickr.c
@@ -535,7 +535,7 @@ dlg_export_to_flickr (FlickrServer *server,
 
 	/* Set the widget data */
 
-	data->list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
+	data->list_view = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (data->list_view), 112);
 	gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (data->list_view))), 0);
 	gth_file_list_enable_thumbs (GTH_FILE_LIST (data->list_view), TRUE);
diff --git a/extensions/flicker/dlg-import-from-flickr.c b/extensions/flicker/dlg-import-from-flickr.c
index 2ff353c..2b527ed 100644
--- a/extensions/flicker/dlg-import-from-flickr.c
+++ b/extensions/flicker/dlg-import-from-flickr.c
@@ -508,7 +508,7 @@ flickr_photo_position_func (GthFileData *a,
 
 
 static void
-file_list_selection_changed_cb (GtkIconView *iconview,
+file_list_selection_changed_cb (GthFileView *file_view,
 				gpointer     user_data)
 {
 	update_selection_status ((DialogData *) user_data);
@@ -558,7 +558,7 @@ dlg_import_from_flickr (FlickrServer *server,
 
 	/* Set the widget data */
 
-	data->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, FALSE);
+	data->file_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, FALSE);
 	thumb_loader = gth_file_list_get_thumb_loader (GTH_FILE_LIST (data->file_list));
 	gth_thumb_loader_set_use_cache (thumb_loader, FALSE);
 	gth_thumb_loader_set_loader_func (thumb_loader, flickr_thumbnail_loader);
@@ -618,8 +618,8 @@ dlg_import_from_flickr (FlickrServer *server,
 			  "changed",
 			  G_CALLBACK (photoset_combobox_changed_cb),
 			  data);
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (data->file_list))),
-			  "selection_changed",
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (data->file_list)),
+			  "file-selection-changed",
 			  G_CALLBACK (file_list_selection_changed_cb),
 			  data);
 
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 0338daa..5735d83 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -531,7 +531,7 @@ dlg_photo_importer (GthBrowser *browser,
 					"text", SOURCE_LIST_COLUMN_NAME,
 					NULL);
 
-	data->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, FALSE);
+	data->file_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, FALSE);
 	sort_type = gth_main_get_sort_type ("file::mtime");
 	gth_file_list_set_sort_func (GTH_FILE_LIST (data->file_list), sort_type->cmp_func, FALSE);
 	gth_file_list_enable_thumbs (GTH_FILE_LIST (data->file_list), TRUE);
@@ -625,8 +625,8 @@ dlg_photo_importer (GthBrowser *browser,
 			  "visibility_changed",
 			  G_CALLBACK (file_store_changed_cb),
 			  data);
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (data->file_list))),
-			  "selection_changed",
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (data->file_list)),
+			  "file-selection-changed",
 			  G_CALLBACK (file_view_selection_changed_cb),
 			  data);
 	data->entry_points_changed_id = g_signal_connect (gth_main_get_default_monitor (),
diff --git a/extensions/photobucket/dlg-export-to-photobucket.c b/extensions/photobucket/dlg-export-to-photobucket.c
index e90b154..76c58b7 100644
--- a/extensions/photobucket/dlg-export-to-photobucket.c
+++ b/extensions/photobucket/dlg-export-to-photobucket.c
@@ -622,7 +622,7 @@ dlg_export_to_photobucket (GthBrowser *browser,
 
 	/* Set the widget data */
 
-	list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
+	list_view = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (list_view), 112);
 	gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (list_view))), 0);
 	gth_file_list_enable_thumbs (GTH_FILE_LIST (list_view), TRUE);
diff --git a/extensions/picasaweb/dlg-export-to-picasaweb.c b/extensions/picasaweb/dlg-export-to-picasaweb.c
index 0c6f610..d1960c9 100644
--- a/extensions/picasaweb/dlg-export-to-picasaweb.c
+++ b/extensions/picasaweb/dlg-export-to-picasaweb.c
@@ -1008,7 +1008,7 @@ dlg_export_to_picasaweb (GthBrowser *browser,
 
 	/* Set the widget data */
 
-	data->list_view = gth_file_list_new (GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
+	data->list_view = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NO_SELECTION, FALSE);
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (data->list_view), 112);
 	gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (data->list_view))), 0);
 	gth_file_list_enable_thumbs (GTH_FILE_LIST (data->list_view), TRUE);
diff --git a/extensions/picasaweb/dlg-import-from-picasaweb.c b/extensions/picasaweb/dlg-import-from-picasaweb.c
index 89cfe66..feccd04 100644
--- a/extensions/picasaweb/dlg-import-from-picasaweb.c
+++ b/extensions/picasaweb/dlg-import-from-picasaweb.c
@@ -995,7 +995,7 @@ dlg_import_from_picasaweb (GthBrowser *browser)
 
 	/* Set the widget data */
 
-	data->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, FALSE);
+	data->file_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, FALSE);
 	thumb_loader = gth_file_list_get_thumb_loader (GTH_FILE_LIST (data->file_list));
 	gth_thumb_loader_set_use_cache (thumb_loader, FALSE);
 	gth_thumb_loader_set_loader_func (thumb_loader, picasa_web_thumbnail_loader);
@@ -1050,7 +1050,7 @@ dlg_import_from_picasaweb (GthBrowser *browser)
 			  G_CALLBACK (album_combobox_changed_cb),
 			  data);
 	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (data->file_list))),
-			  "selection_changed",
+			  "file-selection-changed",
 			  G_CALLBACK (file_list_selection_changed_cb),
 			  data);
 
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index c118877..3f00e47 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -73,6 +73,7 @@ PUBLIC_HEADER_FILES = 					\
 	gth-image-viewer.h				\
 	gth-image-viewer-tool.h				\
 	gth-info-bar.h					\
+	gth-list-view.h					\
 	gth-location-chooser.h				\
 	gth-main.h					\
 	gth-menu-button.h				\
@@ -189,6 +190,7 @@ gthumb_SOURCES = 					\
 	gth-image-viewer.c				\
 	gth-image-viewer-tool.c				\
 	gth-info-bar.c					\
+	gth-list-view.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 0afd31c..cd3ba6c 100644
--- a/gthumb/gth-browser.c
+++ b/gthumb/gth-browser.c
@@ -41,8 +41,10 @@
 #include "gth-filterbar.h"
 #include "gth-folder-tree.h"
 #include "gth-icon-cache.h"
+#include "gth-icon-view.h"
 #include "gth-info-bar.h"
 #include "gth-image-preloader.h"
+#include "gth-list-view.h"
 #include "gth-location-chooser.h"
 #include "gth-main.h"
 #include "gth-marshal.h"
@@ -3354,7 +3356,7 @@ gth_thumbnail_view_selection_changed_cb (GtkIconView *iconview,
 
 
 static void
-gth_file_view_item_activated_cb (GtkIconView *iconview,
+gth_file_view_file_activated_cb (GthFileView *file_view,
 				 GtkTreePath *path,
 				 gpointer     user_data)
 {
@@ -4000,7 +4002,7 @@ _gth_browser_construct (GthBrowser *browser)
 	gtk_widget_set_size_request (browser->priv->viewer_sidebar_alignment, DEF_VIEWER_SIDEBAR_WIDTH, -1);
 	gtk_paned_pack2 (GTK_PANED (browser->priv->viewer_sidebar_pane), browser->priv->viewer_sidebar_alignment, FALSE, FALSE);
 
-	browser->priv->thumbnail_list = gth_file_list_new ((viewer_thumbnails_orientation == GTK_ORIENTATION_HORIZONTAL) ? GTH_FILE_LIST_TYPE_H_SIDEBAR : GTH_FILE_LIST_TYPE_V_SIDEBAR, TRUE);
+	browser->priv->thumbnail_list = gth_file_list_new (gth_icon_view_new (), (viewer_thumbnails_orientation == GTK_ORIENTATION_HORIZONTAL) ? GTH_FILE_LIST_TYPE_H_SIDEBAR : GTH_FILE_LIST_TYPE_V_SIDEBAR, TRUE);
 	gth_file_list_set_caption (GTH_FILE_LIST (browser->priv->thumbnail_list), "none");
 	gth_file_view_set_spacing (GTH_FILE_VIEW (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->thumbnail_list))), 0);
 	gth_file_list_set_thumb_size (GTH_FILE_LIST (browser->priv->thumbnail_list), 95);
@@ -4010,8 +4012,8 @@ _gth_browser_construct (GthBrowser *browser)
 		gtk_paned_pack1 (GTK_PANED (browser->priv->viewer_thumbnails_pane), browser->priv->thumbnail_list, FALSE, FALSE);
 	_gth_browser_set_thumbnail_list_visibility (browser, eel_gconf_get_boolean (PREF_UI_THUMBNAIL_LIST_VISIBLE, TRUE));
 
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->thumbnail_list))),
-			  "selection_changed",
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->thumbnail_list)),
+			  "file-selection-changed",
 			  G_CALLBACK (gth_thumbnail_view_selection_changed_cb),
 			  browser);
 
@@ -4200,7 +4202,7 @@ _gth_browser_construct (GthBrowser *browser)
 
 	/* the file list */
 
-	browser->priv->file_list = gth_file_list_new (GTH_FILE_LIST_TYPE_NORMAL, TRUE);
+	browser->priv->file_list = gth_file_list_new (gth_icon_view_new (), GTH_FILE_LIST_TYPE_NORMAL, TRUE);
 	gth_browser_set_sort_order (browser,
 				    gth_main_get_sort_type (eel_gconf_get_string (PREF_SORT_TYPE, "file::mtime")),
 				    eel_gconf_get_boolean (PREF_SORT_INVERSE, FALSE));
@@ -4214,23 +4216,23 @@ _gth_browser_construct (GthBrowser *browser)
 	gtk_widget_show (browser->priv->file_list);
 	gtk_box_pack_start (GTK_BOX (vbox), browser->priv->file_list, TRUE, TRUE, 0);
 
-	g_signal_connect (G_OBJECT (browser->priv->file_list),
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->file_list)),
 			  "button-press-event",
 			  G_CALLBACK (gth_file_list_button_press_cb),
 			  browser);
-	g_signal_connect (G_OBJECT (browser->priv->file_list),
+	g_signal_connect (browser->priv->file_list,
 			  "popup-menu",
 			  G_CALLBACK (gth_file_list_popup_menu_cb),
 			  browser);
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->file_list))),
-			  "selection-changed",
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->file_list)),
+			  "file-selection-changed",
 			  G_CALLBACK (gth_file_view_selection_changed_cb),
 			  browser);
-	g_signal_connect (G_OBJECT (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->file_list))),
-			  "item-activated",
-			  G_CALLBACK (gth_file_view_item_activated_cb),
+	g_signal_connect (gth_file_list_get_view (GTH_FILE_LIST (browser->priv->file_list)),
+			  "file-activated",
+			  G_CALLBACK (gth_file_view_file_activated_cb),
 			  browser);
-	g_signal_connect (G_OBJECT (browser->priv->file_list),
+	g_signal_connect (browser->priv->file_list,
 			  "key-press-event",
 			  G_CALLBACK (gth_file_list_key_press_cb),
 			  browser);
diff --git a/gthumb/gth-cell-renderer-thumbnail.c b/gthumb/gth-cell-renderer-thumbnail.c
index bc8ffb7..5b95f68 100644
--- a/gthumb/gth-cell-renderer-thumbnail.c
+++ b/gthumb/gth-cell-renderer-thumbnail.c
@@ -266,7 +266,7 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
 	thumb_rect.height -= ypad * 2;
 
 	if (! gdk_rectangle_intersect (cell_area, &thumb_rect, &draw_rect)
-	|| ! gdk_rectangle_intersect (expose_area, &thumb_rect, &draw_rect))
+	    || ! gdk_rectangle_intersect (expose_area, &thumb_rect, &draw_rect))
 	{
 		return;
 	}
@@ -317,8 +317,8 @@ gth_cell_renderer_thumbnail_render (GtkCellRenderer      *cell,
 		if (self->priv->fixed_size && _g_mime_type_is_image (gth_file_data_get_mime_type (self->priv->file))) {
 			frame_rect.width = self->priv->size; /*image_rect.width*/
 			frame_rect.height = self->priv->size; /*image_rect.height*/
-			frame_rect.x = cell_area->x + xpad + THUMBNAIL_BORDER - 1;
-			frame_rect.y = cell_area->y + ypad + THUMBNAIL_BORDER - 1;
+			frame_rect.x = thumb_rect.x + (thumb_rect.width - frame_rect.width) * .5; /*cell_area->x + xpad + THUMBNAIL_BORDER - 1;*/
+			frame_rect.y = thumb_rect.y + (thumb_rect.height - frame_rect.height) * .5; /*cell_area->y + ypad + THUMBNAIL_BORDER - 1;*/
 
 			border = 6;
 		}
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index e04b8b8..9a11585 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -29,9 +29,9 @@
 #include "gth-dumb-notebook.h"
 #include "gth-empty-list.h"
 #include "gth-file-list.h"
+#include "gth-file-selection.h"
 #include "gth-file-store.h"
 #include "gth-icon-cache.h"
-#include "gth-icon-view.h"
 #include "gth-preferences.h"
 #include "gth-thumb-loader.h"
 #include "gtk-utils.h"
@@ -43,7 +43,6 @@
 #define N_VIEWAHEAD 50
 #define N_CREATEAHEAD 50000
 #define EMPTY (N_("(Empty)"))
-#define THUMBNAIL_BORDER (8 * 2)
 #define CHECK_JOBS_INTERVAL 50
 
 
@@ -100,16 +99,11 @@ typedef struct {
 
 
 enum {
-	FILE_POPUP,
-	LAST_SIGNAL
-};
-
-
-enum {
 	GTH_FILE_LIST_PANE_VIEW,
 	GTH_FILE_LIST_PANE_MESSAGE
 };
 
+
 struct _GthFileListPrivateData
 {
 	GthFileListType  type;
@@ -602,12 +596,14 @@ file_store_rows_reordered_cb (GtkTreeModel *tree_model,
 
 static void
 gth_file_list_construct (GthFileList     *file_list,
+			 GtkWidget       *file_view,
 			 GthFileListType  list_type,
 			 gboolean         enable_drag_drop)
 {
 	GtkWidget       *viewport;
 	GtkCellRenderer *renderer;
 	GthFileStore    *model;
+	GtkCellLayout   *cell_layout;
 
 	file_list->priv->thumb_loader = gth_thumb_loader_new (file_list->priv->thumb_size);
 	file_list->priv->icon_cache = gth_icon_cache_new (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (file_list))), file_list->priv->thumb_size / 2);
@@ -643,8 +639,9 @@ gth_file_list_construct (GthFileList     *file_list,
 			  G_CALLBACK (vadj_changed_cb),
 			  file_list);
 
+	file_list->priv->view = file_view;
 	model = gth_file_store_new ();
-	file_list->priv->view = gth_icon_view_new_with_model (GTK_TREE_MODEL (model));
+	gth_file_view_set_model (GTH_FILE_VIEW (file_list->priv->view), GTK_TREE_MODEL (model));
 	g_object_unref (model);
 
 	g_signal_connect (model,
@@ -683,39 +680,39 @@ gth_file_list_construct (GthFileList     *file_list,
 	/* checkbox */
 
 	file_list->priv->checkbox_renderer = renderer = gtk_cell_renderer_toggle_new ();
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (file_list->priv->view), renderer, FALSE);
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (file_list->priv->view),
-					renderer,
-					"active", GTH_FILE_STORE_CHECKED_COLUMN,
-					NULL);
 	g_signal_connect (file_list->priv->checkbox_renderer,
 			  "toggled",
 			  G_CALLBACK (checkbox_toggled_cb),
 			  file_list);
 
+	cell_layout = gth_file_view_add_renderer (GTH_FILE_VIEW (file_list->priv->view),
+						  GTH_FILE_VIEW_RENDERER_CHECKBOX,
+						  file_list->priv->checkbox_renderer);
+	gtk_cell_layout_set_attributes (cell_layout,
+					renderer,
+					"active", GTH_FILE_STORE_CHECKED_COLUMN,
+					NULL);
+
 	/* thumbnail */
 
 	file_list->priv->thumbnail_renderer = renderer = gth_cell_renderer_thumbnail_new ();
-	g_object_set (renderer,
-		      "size", file_list->priv->thumb_size,
-		      "yalign", 1.0,
-		      NULL);
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (file_list->priv->view), renderer, FALSE);
 
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (file_list->priv->view),
+	cell_layout = gth_file_view_add_renderer (GTH_FILE_VIEW (file_list->priv->view),
+						  GTH_FILE_VIEW_RENDERER_THUMBNAIL,
+						  file_list->priv->thumbnail_renderer);
+	gtk_cell_layout_set_attributes (cell_layout,
 					renderer,
 					"thumbnail", GTH_FILE_STORE_THUMBNAIL_COLUMN,
 					"is_icon", GTH_FILE_STORE_IS_ICON_COLUMN,
 					"file", GTH_FILE_STORE_FILE_DATA_COLUMN,
 					NULL);
-
 	if (file_list->priv->type == GTH_FILE_LIST_TYPE_BROWSER)
-		gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (file_list->priv->view),
+		gtk_cell_layout_add_attribute (cell_layout,
 					       renderer,
 					       "selected",
 					       GTH_FILE_STORE_CHECKED_COLUMN);
 	else if (file_list->priv->type == GTH_FILE_LIST_TYPE_SELECTOR)
-		gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (file_list->priv->view),
+		gtk_cell_layout_add_attribute (cell_layout,
 					       renderer,
 					       "checked",
 					       GTH_FILE_STORE_CHECKED_COLUMN);
@@ -723,22 +720,22 @@ gth_file_list_construct (GthFileList     *file_list,
 	/* text */
 
 	file_list->priv->text_renderer = renderer = gtk_cell_renderer_text_new ();
-	g_object_set (G_OBJECT (renderer),
-		      "yalign", 0.0,
-		      /*"ellipsize", PANGO_ELLIPSIZE_NONE,*/
-		      "alignment", PANGO_ALIGN_CENTER,
-		      "width", file_list->priv->thumb_size + THUMBNAIL_BORDER,
-		      "wrap-mode", PANGO_WRAP_WORD_CHAR,
-		      "wrap-width", file_list->priv->thumb_size + THUMBNAIL_BORDER,
-		      NULL);
 
-	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (file_list->priv->view), renderer, FALSE);
-	gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (file_list->priv->view),
+	cell_layout = gth_file_view_add_renderer (GTH_FILE_VIEW (file_list->priv->view),
+						  GTH_FILE_VIEW_RENDERER_TEXT,
+						  file_list->priv->text_renderer);
+	gtk_cell_layout_set_attributes (cell_layout,
 					renderer,
 					"text", GTH_FILE_STORE_METADATA_COLUMN,
 					"visible", GTH_FILE_STORE_METADATA_VISIBLE_COLUMN,
 					NULL);
 
+	gth_file_view_update_attributes (GTH_FILE_VIEW (file_list->priv->view),
+					 file_list->priv->checkbox_renderer,
+					 file_list->priv->thumbnail_renderer,
+					 file_list->priv->text_renderer,
+					 file_list->priv->thumb_size);
+
 	_gth_file_list_set_type (file_list, list_type);
 
 	/* pack the widgets together */
@@ -791,13 +788,14 @@ gth_file_list_get_type (void)
 
 
 GtkWidget*
-gth_file_list_new (GthFileListType list_type,
-		   gboolean        enable_drag_drop)
+gth_file_list_new (GtkWidget       *file_view,
+		   GthFileListType  list_type,
+		   gboolean         enable_drag_drop)
 {
 	GtkWidget *widget;
 
 	widget = GTK_WIDGET (g_object_new (GTH_TYPE_FILE_LIST, NULL));
-	gth_file_list_construct (GTH_FILE_LIST (widget), list_type, enable_drag_drop);
+	gth_file_list_construct (GTH_FILE_LIST (widget), file_view, list_type, enable_drag_drop);
 
 	return widget;
 }
@@ -964,7 +962,9 @@ _gth_file_list_get_metadata (GthFileList *file_list,
 		if (value != NULL) {
 			if (metadata->len > 0)
 				g_string_append (metadata, "\n");
-			if (g_utf8_strlen (value, -1) > MAX_TEXT_LENGTH) {
+			if (gth_file_view_truncate_metadata (GTH_FILE_VIEW (file_list->priv->view))
+			    && g_utf8_strlen (value, -1) > MAX_TEXT_LENGTH)
+			{
 				char *tmp;
 
 				tmp = g_strdup (value);
@@ -1383,13 +1383,11 @@ gth_file_list_set_thumb_size (GthFileList *file_list,
 	gth_icon_cache_free (file_list->priv->icon_cache);
 	file_list->priv->icon_cache = gth_icon_cache_new (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (file_list))), size / 2);
 
-	g_object_set (file_list->priv->thumbnail_renderer,
-		      "size", file_list->priv->thumb_size,
-		      NULL);
-	g_object_set (file_list->priv->text_renderer,
-		      "width", file_list->priv->thumb_size + THUMBNAIL_BORDER,
-		      "wrap-width", file_list->priv->thumb_size + THUMBNAIL_BORDER,
-		      NULL);
+	gth_file_view_update_attributes (GTH_FILE_VIEW (file_list->priv->view),
+					 file_list->priv->checkbox_renderer,
+					 file_list->priv->thumbnail_renderer,
+					 file_list->priv->text_renderer,
+					 file_list->priv->thumb_size);
 
 	_gth_file_list_update_orientation (file_list);
 }
diff --git a/gthumb/gth-file-list.h b/gthumb/gth-file-list.h
index 72be7ca..7a62b9b 100644
--- a/gthumb/gth-file-list.h
+++ b/gthumb/gth-file-list.h
@@ -24,6 +24,7 @@
 
 #include <gtk/gtk.h>
 #include "gth-file-data.h"
+#include "gth-file-view.h"
 #include "gth-file-source.h"
 #include "gth-file-store.h"
 #include "gth-test.h"
@@ -61,7 +62,8 @@ struct _GthFileListClass {
 };
 
 GType             gth_file_list_get_type          (void);
-GtkWidget *       gth_file_list_new               (GthFileListType       list_type,
+GtkWidget *       gth_file_list_new               (GtkWidget            *file_view,
+						   GthFileListType       list_type,
 						   gboolean              enable_drag_drop);
 void              gth_file_list_set_type          (GthFileList          *file_list,
 						   GthFileListType       list_type);
diff --git a/gthumb/gth-file-selection.c b/gthumb/gth-file-selection.c
index d6aeb97..8b5aecd 100644
--- a/gthumb/gth-file-selection.c
+++ b/gthumb/gth-file-selection.c
@@ -22,6 +22,61 @@
 #include "gth-file-selection.h"
 
 
+enum {
+	FILE_SELECTION_CHANGED,
+	LAST_SIGNAL
+};
+
+
+static guint gth_file_selection_signals[LAST_SIGNAL] = { 0 };
+
+
+static void
+gth_file_selection_base_init (gpointer g_class)
+{
+	static gboolean initialized = FALSE;
+
+	if (! initialized) {
+		gth_file_selection_signals[FILE_SELECTION_CHANGED] =
+			g_signal_new ("file-selection-changed",
+				      GTH_TYPE_FILE_SELECTION,
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (GthFileSelectionIface, file_selection_changed),
+				      NULL, NULL,
+				      g_cclosure_marshal_VOID__VOID,
+				      G_TYPE_NONE, 0);
+		initialized = TRUE;
+	}
+}
+
+
+GType
+gth_file_selection_get_type (void)
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthFileSelectionIface),
+			(GBaseInitFunc) gth_file_selection_base_init,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) NULL,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			0,
+			0,
+			(GInstanceInitFunc) NULL,
+			NULL
+		};
+		type = g_type_register_static (G_TYPE_INTERFACE,
+					       "GthFileSelection",
+					       &g_define_type_info,
+					       0);
+	}
+
+	return type;
+}
+
 
 void
 gth_file_selection_set_selection_mode (GthFileSelection *self,
@@ -102,28 +157,8 @@ gth_file_selection_get_n_selected (GthFileSelection *self)
 }
 
 
-GType
-gth_file_selection_get_type (void)
+void
+gth_file_selection_changed (GthFileSelection *self)
 {
-	static GType type = 0;
-
-	if (type == 0) {
-		static const GTypeInfo g_define_type_info = {
-			sizeof (GthFileSelectionIface),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
-			(GClassFinalizeFunc) NULL,
-			NULL,
-			0,
-			0,
-			(GInstanceInitFunc) NULL,
-			NULL
-		};
-		type = g_type_register_static (G_TYPE_INTERFACE,
-					       "GthFileSelection",
-					       &g_define_type_info,
-					       0);
-	}
-	return type;
+	g_signal_emit (self, gth_file_selection_signals[FILE_SELECTION_CHANGED], 0);
 }
diff --git a/gthumb/gth-file-selection.h b/gthumb/gth-file-selection.h
index 2089982..4b2f053 100644
--- a/gthumb/gth-file-selection.h
+++ b/gthumb/gth-file-selection.h
@@ -39,22 +39,26 @@ typedef struct _GthFileSelectionIface GthFileSelectionIface;
 struct _GthFileSelectionIface {
 	GTypeInterface parent_iface;
 
+	/*< signals >*/
+
+	void          (*file_selection_changed)  (GthFileSelection *self);
+
 	/*< virtual functions >*/
 
-	void          (*set_selection_mode) (GthFileSelection *self,
-					     GtkSelectionMode  mode);
-	GList *       (*get_selected)       (GthFileSelection *self);
-	void          (*select)             (GthFileSelection *self,
-					     int               pos);
-	void          (*unselect)           (GthFileSelection *self,
-					     int               pos);
-	void          (*select_all)         (GthFileSelection *self);
-	void          (*unselect_all)       (GthFileSelection *self);
-	gboolean      (*is_selected)        (GthFileSelection *self,
-					     int               pos);
-	GtkTreePath * (*get_first_selected) (GthFileSelection *self);
-	GtkTreePath * (*get_last_selected)  (GthFileSelection *self);
-	guint         (*get_n_selected)     (GthFileSelection *self);
+	void          (*set_selection_mode)      (GthFileSelection *self,
+					          GtkSelectionMode  mode);
+	GList *       (*get_selected)            (GthFileSelection *self);
+	void          (*select)                  (GthFileSelection *self,
+					          int               pos);
+	void          (*unselect)                (GthFileSelection *self,
+					          int               pos);
+	void          (*select_all)              (GthFileSelection *self);
+	void          (*unselect_all)            (GthFileSelection *self);
+	gboolean      (*is_selected)             (GthFileSelection *self,
+					          int               pos);
+	GtkTreePath * (*get_first_selected)      (GthFileSelection *self);
+	GtkTreePath * (*get_last_selected)       (GthFileSelection *self);
+	guint         (*get_n_selected)          (GthFileSelection *self);
 };
 
 GType         gth_file_selection_get_type           (void);
@@ -72,6 +76,7 @@ gboolean      gth_file_selection_is_selected        (GthFileSelection *self,
 GtkTreePath * gth_file_selection_get_first_selected (GthFileSelection *self);
 GtkTreePath * gth_file_selection_get_last_selected  (GthFileSelection *self);
 guint         gth_file_selection_get_n_selected     (GthFileSelection *self);
+void          gth_file_selection_changed            (GthFileSelection *self);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-file-view.c b/gthumb/gth-file-view.c
index b3d1b5d..241db8d 100644
--- a/gthumb/gth-file-view.c
+++ b/gthumb/gth-file-view.c
@@ -22,6 +22,63 @@
 #include "gth-file-view.h"
 
 
+enum {
+	FILE_ACTIVATED,
+	LAST_SIGNAL
+};
+
+
+static guint gth_file_view_signals[LAST_SIGNAL] = { 0 };
+
+
+static void
+gth_file_view_base_init (gpointer g_class)
+{
+	static gboolean initialized = FALSE;
+
+	if (! initialized) {
+		gth_file_view_signals[FILE_ACTIVATED] =
+			g_signal_new ("file-activated",
+				      GTH_TYPE_FILE_VIEW,
+				      G_SIGNAL_RUN_LAST,
+				      G_STRUCT_OFFSET (GthFileViewIface, file_activated),
+				      NULL, NULL,
+				      g_cclosure_marshal_VOID__BOXED,
+				      G_TYPE_NONE, 1,
+				      GTK_TYPE_TREE_PATH);
+		initialized = TRUE;
+	}
+}
+
+
+GType
+gth_file_view_get_type (void)
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthFileViewIface),
+			(GBaseInitFunc) gth_file_view_base_init,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) NULL,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			0,
+			0,
+			(GInstanceInitFunc) NULL,
+			NULL
+		};
+		type = g_type_register_static (G_TYPE_INTERFACE,
+					       "GthFileView",
+					       &g_define_type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
 void
 gth_file_view_set_model (GthFileView  *self,
 		         GtkTreeModel *model)
@@ -155,29 +212,36 @@ gth_file_view_set_drag_dest_pos (GthFileView    *self,
 }
 
 
-GType
-gth_file_view_get_type (void)
+GtkCellLayout *
+gth_file_view_add_renderer (GthFileView             *self,
+			    GthFileViewRendererType  renderer_type,
+			    GtkCellRenderer         *renderer)
 {
-	static GType type = 0;
+	return GTH_FILE_VIEW_GET_INTERFACE (self)->add_renderer (self, renderer_type, renderer);
+}
 
-	if (type == 0) {
-		static const GTypeInfo g_define_type_info = {
-			sizeof (GthFileViewIface),
-			(GBaseInitFunc) NULL,
-			(GBaseFinalizeFunc) NULL,
-			(GClassInitFunc) NULL,
-			(GClassFinalizeFunc) NULL,
-			NULL,
-			0,
-			0,
-			(GInstanceInitFunc) NULL,
-			NULL
-		};
-		type = g_type_register_static (G_TYPE_INTERFACE,
-					       "GthFileView",
-					       &g_define_type_info,
-					       0);
-	}
 
-	return type;
+void
+gth_file_view_update_attributes (GthFileView     *self,
+				 GtkCellRenderer *checkbox_renderer,
+				 GtkCellRenderer *thumbnail_renderer,
+				 GtkCellRenderer *text_renderer,
+				 int              thumb_size)
+{
+	GTH_FILE_VIEW_GET_INTERFACE (self)->update_attributes (self, checkbox_renderer, thumbnail_renderer, text_renderer, thumb_size);
+}
+
+
+gboolean
+gth_file_view_truncate_metadata (GthFileView *self)
+{
+	return GTH_FILE_VIEW_GET_INTERFACE (self)->truncate_metadata (self);
+}
+
+
+void
+gth_file_view_activate_file (GthFileView *self,
+			     GtkTreePath *path)
+{
+	g_signal_emit (self, gth_file_view_signals[FILE_ACTIVATED], 0, path);
 }
diff --git a/gthumb/gth-file-view.h b/gthumb/gth-file-view.h
index aed3af4..e30070c 100644
--- a/gthumb/gth-file-view.h
+++ b/gthumb/gth-file-view.h
@@ -36,6 +36,8 @@ G_BEGIN_DECLS
 typedef struct _GthFileView GthFileView;
 typedef struct _GthFileViewIface GthFileViewIface;
 
+#define THUMBNAIL_BORDER (8 * 2)
+
 typedef enum  {
 	GTH_VISIBILITY_NONE,
 	GTH_VISIBILITY_FULL,
@@ -44,88 +46,119 @@ typedef enum  {
 	GTH_VISIBILITY_PARTIAL_BOTTOM
 } GthVisibility;
 
+typedef enum {
+	GTH_FILE_VIEW_RENDERER_CHECKBOX,
+	GTH_FILE_VIEW_RENDERER_THUMBNAIL,
+	GTH_FILE_VIEW_RENDERER_TEXT
+} GthFileViewRendererType;
+
 struct _GthFileViewIface {
 	GTypeInterface parent_iface;
 
+	/*< signals >*/
+
+	void            (*file_activated)                (GthFileView              *self,
+					     	     	  GtkTreePath              *path);
+
 	/*< virtual functions >*/
 
-	void           (*set_model)          (GthFileView          *self,
-					      GtkTreeModel         *model);
-	GtkTreeModel * (*get_model)          (GthFileView          *self);
-	void           (*scroll_to)          (GthFileView          *self,
-					      int                   pos,
-					      double                yalign);
-	GthVisibility  (*get_visibility)     (GthFileView          *self,
-					      int                   pos);
-	int            (*get_at_position)    (GthFileView          *self,
-					      int                   x,
-					      int                   y);
-	int            (*get_first_visible)  (GthFileView          *self);
-	int            (*get_last_visible)   (GthFileView          *self);
-	void           (*activated)          (GthFileView          *self,
-					      int                   pos);
-	void           (*set_cursor)         (GthFileView          *self,
-					      int                   pos);
-	int            (*get_cursor)         (GthFileView          *self);
-	void           (*set_spacing)        (GthFileView          *self,
-					      int                   spacing);
-	void           (*enable_drag_source) (GthFileView          *self,
-					      GdkModifierType       start_button_mask,
-					      const GtkTargetEntry *targets,
-					      gint                  n_targets,
-					      GdkDragAction         actions);
-	void           (*unset_drag_source)  (GthFileView          *self);
-	void           (*enable_drag_dest)   (GthFileView          *self,
-					      const GtkTargetEntry *targets,
-					      gint                  n_targets,
-					      GdkDragAction         actions);
-	void           (*unset_drag_dest)    (GthFileView          *self);
-	void           (*set_drag_dest_pos)  (GthFileView          *self,
-					      GdkDragContext       *context,
-			                      int                   x,
-			                      int                   y,
-			                      guint                 time,
-			                      int                  *pos);
+	void            (*set_model)                     (GthFileView              *self,
+							  GtkTreeModel             *model);
+	GtkTreeModel *  (*get_model)                     (GthFileView              *self);
+	void            (*scroll_to)                     (GthFileView              *self,
+							  int                       pos,
+							  double                    yalign);
+	GthVisibility   (*get_visibility)                (GthFileView              *self,
+							  int                       pos);
+	int             (*get_at_position)               (GthFileView              *self,
+							  int                       x,
+							  int                       y);
+	int             (*get_first_visible)             (GthFileView              *self);
+	int             (*get_last_visible)              (GthFileView              *self);
+	void            (*activated)                     (GthFileView              *self,
+							  int                       pos);
+	void            (*set_cursor)                    (GthFileView              *self,
+							  int                       pos);
+	int             (*get_cursor)                    (GthFileView              *self);
+	void            (*set_spacing)                   (GthFileView              *self,
+							  int                       spacing);
+	void            (*enable_drag_source)            (GthFileView              *self,
+							  GdkModifierType           start_button_mask,
+							  const GtkTargetEntry     *targets,
+							  gint                      n_targets,
+							  GdkDragAction             actions);
+	void            (*unset_drag_source)             (GthFileView              *self);
+	void            (*enable_drag_dest)              (GthFileView              *self,
+							  const GtkTargetEntry     *targets,
+							  gint                      n_targets,
+							  GdkDragAction             actions);
+	void            (*unset_drag_dest)               (GthFileView              *self);
+	void            (*set_drag_dest_pos)             (GthFileView              *self,
+							  GdkDragContext           *context,
+							  int                       x,
+							  int                       y,
+							  guint                     time,
+			                      	          int                      *pos);
+	GtkCellLayout * (*add_renderer)                  (GthFileView              *self,
+							  GthFileViewRendererType   renderer_type,
+							  GtkCellRenderer          *renderer);
+	void            (*update_attributes)             (GthFileView              *self,
+							  GtkCellRenderer          *checkbox_renderer,
+							  GtkCellRenderer          *thumbnail_renderer,
+							  GtkCellRenderer          *text_renderer,
+							  int                       thumb_size);
+	gboolean        (*truncate_metadata)             (GthFileView              *self);
 };
 
-GType          gth_file_view_get_type           (void);
-void           gth_file_view_set_model          (GthFileView          *self,
-					 	 GtkTreeModel         *model);
-GtkTreeModel * gth_file_view_get_model          (GthFileView          *self);
-void           gth_file_view_scroll_to          (GthFileView          *self,
-						 int                   pos,
-						 double                yalign);
-GthVisibility  gth_file_view_get_visibility     (GthFileView          *self,
-						 int                   pos);
-int            gth_file_view_get_at_position    (GthFileView          *self,
-						 int                   x,
-						 int                   y);
-int            gth_file_view_get_first_visible  (GthFileView          *self);
-int            gth_file_view_get_last_visible   (GthFileView          *self);
-void           gth_file_view_activated          (GthFileView          *self,
-						 int                   pos);
-void           gth_file_view_set_cursor         (GthFileView          *self,
-						 int                   pos);
-int            gth_file_view_get_cursor         (GthFileView          *self);
-void           gth_file_view_set_spacing        (GthFileView          *self,
-						 int                   spacing);
-void           gth_file_view_enable_drag_source (GthFileView          *self,
-				      		 GdkModifierType       start_button_mask,
-				      		 const GtkTargetEntry *targets,
-				      		 int                   n_targets,
-				      		 GdkDragAction         actions);
-void           gth_file_view_unset_drag_source  (GthFileView          *self);
-void           gth_file_view_enable_drag_dest   (GthFileView          *self,
-				      		 const GtkTargetEntry *targets,
-				      		 int                   n_targets,
-				      		 GdkDragAction         actions);
-void           gth_file_view_unset_drag_dest    (GthFileView          *self);
-void           gth_file_view_set_drag_dest_pos  (GthFileView          *self,
-					         GdkDragContext       *context,
-			                         int                   x,
-			                         int                   y,
-			                         guint                 time,
-				                 int                  *pos);
+GType           gth_file_view_get_type           (void);
+void            gth_file_view_set_model          (GthFileView             *self,
+					 	  GtkTreeModel            *model);
+GtkTreeModel *  gth_file_view_get_model          (GthFileView             *self);
+void            gth_file_view_scroll_to          (GthFileView             *self,
+						  int                      pos,
+						  double                   yalign);
+GthVisibility   gth_file_view_get_visibility     (GthFileView             *self,
+						  int                      pos);
+int             gth_file_view_get_at_position    (GthFileView             *self,
+						  int                      x,
+						  int                      y);
+int             gth_file_view_get_first_visible  (GthFileView             *self);
+int             gth_file_view_get_last_visible   (GthFileView             *self);
+void            gth_file_view_activated          (GthFileView             *self,
+						  int                      pos);
+void            gth_file_view_set_cursor         (GthFileView             *self,
+						  int                      pos);
+int             gth_file_view_get_cursor         (GthFileView             *self);
+void            gth_file_view_set_spacing        (GthFileView             *self,
+						  int                      spacing);
+void            gth_file_view_enable_drag_source (GthFileView             *self,
+				      		  GdkModifierType          start_button_mask,
+				      		  const GtkTargetEntry    *targets,
+				      		  int                      n_targets,
+				      		  GdkDragAction            actions);
+void            gth_file_view_unset_drag_source  (GthFileView             *self);
+void            gth_file_view_enable_drag_dest   (GthFileView             *self,
+				      		  const GtkTargetEntry    *targets,
+				      		  int                      n_targets,
+				      		  GdkDragAction            actions);
+void            gth_file_view_unset_drag_dest    (GthFileView             *self);
+void            gth_file_view_set_drag_dest_pos  (GthFileView             *self,
+		 			          GdkDragContext          *context,
+			                          int                      x,
+			                          int                      y,
+			                          guint                    time,
+				                  int                     *pos);
+GtkCellLayout * gth_file_view_add_renderer       (GthFileView             *self,
+						  GthFileViewRendererType  renderer_type,
+						  GtkCellRenderer         *renderer);
+void            gth_file_view_update_attributes  (GthFileView              *self,
+						  GtkCellRenderer          *checkbox_renderer,
+						  GtkCellRenderer          *thumbnail_renderer,
+						  GtkCellRenderer          *text_renderer,
+						  int                       thumb_size);
+gboolean        gth_file_view_truncate_metadata  (GthFileView              *self);
+void            gth_file_view_activate_file      (GthFileView              *self,
+						  GtkTreePath              *path);
 
 G_END_DECLS
 
diff --git a/gthumb/gth-icon-view.c b/gthumb/gth-icon-view.c
index cd570d3..6736c9d 100644
--- a/gthumb/gth-icon-view.c
+++ b/gthumb/gth-icon-view.c
@@ -306,6 +306,45 @@ gth_icon_view_set_drag_dest_pos (GthFileView    *self,
 }
 
 
+static GtkCellLayout *
+gth_icon_view_add_renderer (GthFileView             *self,
+			    GthFileViewRendererType  renderer_type,
+			    GtkCellRenderer         *renderer)
+{
+	gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (self), renderer, FALSE);
+
+	return GTK_CELL_LAYOUT (self);
+}
+
+
+static void
+gth_icon_view_update_attributes (GthFileView     *self,
+				 GtkCellRenderer *checkbox_renderer,
+				 GtkCellRenderer *thumbnail_renderer,
+				 GtkCellRenderer *text_renderer,
+				 int              thumb_size)
+{
+	g_object_set (thumbnail_renderer,
+		      "size", thumb_size,
+		      "yalign", 1.0,
+		      NULL);
+	g_object_set (text_renderer,
+		      "yalign", 0.0,
+		      "alignment", PANGO_ALIGN_CENTER,
+		      "width", thumb_size + THUMBNAIL_BORDER,
+		      "wrap-mode", PANGO_WRAP_WORD_CHAR,
+		      "wrap-width", thumb_size + THUMBNAIL_BORDER,
+		      NULL);
+}
+
+
+static gboolean
+gth_icon_view_truncate_metadata (GthFileView *base)
+{
+	return TRUE;
+}
+
+
 static void
 gth_icon_view_real_set_selection_mode (GthFileSelection *base,
 				       GtkSelectionMode  mode)
@@ -784,12 +823,23 @@ icon_view_selection_changed_cb (GtkIconView *widget,
 		icon_view->priv->selection_range_start = gtk_tree_path_get_indices (path)[0];
 	}
 
+	gth_file_selection_changed (GTH_FILE_SELECTION (icon_view));
+
 	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
 	g_list_free (list);
 }
 
 
 static void
+icon_view_item_activated_cb (GtkIconView *icon_view,
+			     GtkTreePath *path,
+			     gpointer     user_data)
+{
+	gth_file_view_activate_file (GTH_FILE_VIEW (icon_view), path);
+}
+
+
+static void
 gth_icon_view_init (GthIconView *icon_view)
 {
 	icon_view->priv = G_TYPE_INSTANCE_GET_PRIVATE (icon_view, GTH_TYPE_ICON_VIEW, GthIconViewPrivate);
@@ -820,6 +870,10 @@ gth_icon_view_init (GthIconView *icon_view)
 			  "selection-changed",
 			  G_CALLBACK (icon_view_selection_changed_cb),
 			  icon_view);
+	g_signal_connect (icon_view,
+			  "item-activated",
+			  G_CALLBACK (icon_view_item_activated_cb),
+			  icon_view);
 }
 
 
@@ -843,6 +897,9 @@ gth_icon_view_gth_file_view_interface_init (GthFileViewIface *iface)
 	iface->enable_drag_dest = gth_icon_view_enable_drag_dest;
 	iface->unset_drag_dest = gth_icon_view_unset_drag_dest;
 	iface->set_drag_dest_pos = gth_icon_view_set_drag_dest_pos;
+	iface->add_renderer = gth_icon_view_add_renderer;
+	iface->update_attributes = gth_icon_view_update_attributes;
+	iface->truncate_metadata = gth_icon_view_truncate_metadata;
 }
 
 
diff --git a/gthumb/gth-icon-view.h b/gthumb/gth-icon-view.h
index a1fa92c..7b33977 100644
--- a/gthumb/gth-icon-view.h
+++ b/gthumb/gth-icon-view.h
@@ -18,7 +18,7 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
- 
+
 #ifndef GTH_ICON_VIEW_H
 #define GTH_ICON_VIEW_H
 
diff --git a/gthumb/gth-list-view.c b/gthumb/gth-list-view.c
new file mode 100644
index 0000000..4de0e03
--- /dev/null
+++ b/gthumb/gth-list-view.c
@@ -0,0 +1,653 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <gdk/gdkkeysyms.h>
+#include "gth-list-view.h"
+
+
+#define IMAGE_TEXT_SPACING 0
+#define DEFAULT_ICON_SPACING 12
+#define SIZE_REQUEST 50
+
+
+struct _GthListViewPrivate {
+	GtkTreeViewColumn *column;
+};
+
+
+static gpointer               parent_class = NULL;
+static GthFileViewIface      *gth_list_view_gth_file_view_parent_iface = NULL;
+static GthFileSelectionIface *gth_list_view_gth_file_selection_parent_iface = NULL;
+
+
+void
+gth_list_view_real_set_model (GthFileView  *self,
+			      GtkTreeModel *model)
+{
+	gtk_tree_view_set_model (GTK_TREE_VIEW (self), model);
+}
+
+
+GtkTreeModel *
+gth_list_view_real_get_model (GthFileView *self)
+{
+	return gtk_tree_view_get_model (GTK_TREE_VIEW (self));
+}
+
+
+static void
+gth_list_view_real_scroll_to (GthFileView *base,
+			      int          pos,
+			      double       yalign)
+{
+	GtkTreePath *path;
+
+	path = gtk_tree_path_new_from_indices (pos, -1);
+	gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (base),
+				      path,
+				      NULL,
+				      TRUE,
+				      yalign,
+				      0.0);
+
+	gtk_tree_path_free (path);
+}
+
+
+static GthVisibility
+gth_list_view_real_get_visibility (GthFileView *base,
+				   int          pos)
+{
+	GtkTreePath *start_path, *end_path;
+	int          start_pos, end_pos;
+
+	if (! gtk_tree_view_get_visible_range (GTK_TREE_VIEW (base), &start_path, &end_path))
+		return -1;
+
+	start_pos = gtk_tree_path_get_indices (start_path)[0];
+	end_pos = gtk_tree_path_get_indices (end_path)[0];
+
+	gtk_tree_path_free (start_path);
+	gtk_tree_path_free (end_path);
+
+	return ((pos >= start_pos) && (pos <= end_pos)) ? GTH_VISIBILITY_FULL : GTH_VISIBILITY_NONE;
+}
+
+
+static int
+gth_list_view_real_get_at_position (GthFileView *base,
+				    int          x,
+				    int          y)
+{
+	GtkTreePath *path;
+	int          pos;
+
+	if (! gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (base),
+					     x,
+					     y,
+					     &path,
+					     NULL,
+					     NULL,
+					     NULL))
+	{
+		return -1;
+	}
+	pos = gtk_tree_path_get_indices (path)[0];
+
+	gtk_tree_path_free (path);
+
+	return pos;
+}
+
+
+static int
+gth_list_view_real_get_first_visible (GthFileView *base)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+	GtkTreePath *start_path;
+	int          pos;
+
+	if (! gtk_tree_view_get_visible_range (GTK_TREE_VIEW (self), &start_path, NULL))
+		return -1;
+
+	pos = gtk_tree_path_get_indices (start_path)[0];
+	gtk_tree_path_free (start_path);
+
+	return pos;
+}
+
+
+static int
+gth_list_view_real_get_last_visible (GthFileView *base)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+	GtkTreePath *end_path;
+	int          pos;
+
+	if (! gtk_tree_view_get_visible_range (GTK_TREE_VIEW (self), NULL, &end_path))
+		return -1;
+
+	pos = gtk_tree_path_get_indices (end_path)[0];
+	gtk_tree_path_free (end_path);
+
+	return pos;
+}
+
+
+static void
+gth_list_view_real_activated (GthFileView *base,
+			      int          pos)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+	GtkTreePath *path;
+
+	g_return_if_fail (pos >= 0);
+
+	path = gtk_tree_path_new_from_indices (pos, -1);
+	gtk_tree_view_row_activated (GTK_TREE_VIEW (self), path, NULL);
+
+	gtk_tree_path_free (path);
+}
+
+
+static void
+gth_list_view_real_set_cursor (GthFileView *base,
+			       int          pos)
+{
+	GtkTreePath *path;
+
+	g_return_if_fail (pos >= 0);
+
+	path = gtk_tree_path_new_from_indices (pos, -1);
+	gtk_tree_view_set_cursor (GTK_TREE_VIEW (base), path, NULL, FALSE);
+
+	gtk_tree_path_free (path);
+}
+
+
+static int
+gth_list_view_real_get_cursor (GthFileView *base)
+{
+	GtkTreePath *path;
+	int          pos;
+
+	gtk_tree_view_get_cursor (GTK_TREE_VIEW (base), &path, NULL);
+	if (path == NULL)
+		return -1;
+	pos = gtk_tree_path_get_indices (path)[0];
+
+	gtk_tree_path_free (path);
+
+	return pos;
+}
+
+
+void
+gth_list_view_real_set_spacing (GthFileView *self,
+			        int          spacing)
+{
+	/* FIXME
+	gtk_tree_view_set_margin (GTK_TREE_VIEW (self), spacing);
+	gtk_tree_view_set_column_spacing (GTK_TREE_VIEW (self), spacing);
+	gtk_tree_view_set_row_spacing (GTK_TREE_VIEW (self), spacing);
+	*/
+}
+
+
+static void
+gth_list_view_enable_drag_source (GthFileView          *base,
+				  GdkModifierType       start_button_mask,
+				  const GtkTargetEntry *targets,
+				  int                   n_targets,
+				  GdkDragAction         actions)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+
+	gtk_tree_view_enable_model_drag_source (GTK_TREE_VIEW (self),
+						start_button_mask,
+						targets,
+						n_targets,
+						actions);
+}
+
+
+static void
+gth_list_view_unset_drag_source (GthFileView *base)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+
+	gtk_tree_view_unset_rows_drag_source (GTK_TREE_VIEW (self));
+}
+
+
+static void
+gth_list_view_enable_drag_dest (GthFileView          *self,
+				const GtkTargetEntry *targets,
+				int                   n_targets,
+				GdkDragAction         actions)
+{
+	gtk_tree_view_enable_model_drag_dest (GTK_TREE_VIEW (self),
+					      targets,
+					      n_targets,
+					      actions);
+}
+
+
+static void
+gth_list_view_unset_drag_dest (GthFileView *self)
+{
+	gtk_tree_view_unset_rows_drag_dest (GTK_TREE_VIEW (self));
+}
+
+
+static void
+gth_list_view_set_drag_dest_pos (GthFileView    *self,
+				 GdkDragContext *context,
+				 int             x,
+				 int             y,
+				 guint           time,
+				 int            *pos)
+{
+	GtkTreePath             *path = NULL;
+	GtkTreeViewDropPosition  drop_pos;
+
+	if ((x >= 0)
+	    && (y >= 0)
+	    && gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (self),
+			    	    	    	  x,
+			    	    	    	  y,
+			    	    	    	  &path,
+			    	    	    	  &drop_pos))
+	{
+		if (pos != NULL) {
+			int *indices;
+
+			indices = gtk_tree_path_get_indices (path);
+			*pos = indices[0];
+			if (drop_pos == GTK_TREE_VIEW_DROP_INTO_OR_AFTER)
+				drop_pos = GTK_TREE_VIEW_DROP_AFTER;
+			if (drop_pos == GTK_TREE_VIEW_DROP_AFTER)
+				*pos = *pos + 1;
+		}
+		gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self), path, drop_pos);
+	}
+	else {
+		if (pos != NULL)
+			*pos = -1;
+		gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (self), NULL, 0);
+	}
+
+	if (path != NULL)
+		gtk_tree_path_free (path);
+}
+
+
+static GtkCellLayout *
+gth_list_view_add_renderer (GthFileView              *base,
+			    GthFileViewRendererType   renderer_type,
+			    GtkCellRenderer          *renderer)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+
+	switch (renderer_type) {
+	case GTH_FILE_VIEW_RENDERER_CHECKBOX:
+		gtk_tree_view_column_pack_start (self->priv->column, renderer, FALSE);
+		break;
+	case GTH_FILE_VIEW_RENDERER_THUMBNAIL:
+		gtk_tree_view_column_pack_start (self->priv->column, renderer, FALSE);
+		break;
+	case GTH_FILE_VIEW_RENDERER_TEXT:
+		gtk_tree_view_column_pack_start (self->priv->column, renderer, TRUE);
+		break;
+	}
+
+	return GTK_CELL_LAYOUT (self->priv->column);
+}
+
+
+static void
+gth_list_view_update_attributes (GthFileView     *base,
+				 GtkCellRenderer *checkbox_renderer,
+				 GtkCellRenderer *thumbnail_renderer,
+				 GtkCellRenderer *text_renderer,
+				 int              thumb_size)
+{
+	GthListView *self = GTH_LIST_VIEW (base);
+
+	g_object_set (thumbnail_renderer,
+		      "size", thumb_size,
+		      "yalign", 0.5,
+		      NULL);
+	g_object_set (text_renderer,
+		      "ellipsize", PANGO_ELLIPSIZE_END,
+		      "yalign", 0.0,
+		      "alignment", PANGO_ALIGN_LEFT,
+		      NULL);
+
+	gtk_tree_view_column_queue_resize (self->priv->column);
+}
+
+
+static gboolean
+gth_list_view_truncate_metadata (GthFileView *base)
+{
+	return FALSE;
+}
+
+
+static void
+gth_list_view_real_set_selection_mode (GthFileSelection *base,
+				       GtkSelectionMode  mode)
+{
+	gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), mode);
+}
+
+
+static GList *
+gth_list_view_real_get_selected (GthFileSelection *base)
+{
+	return gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), NULL);
+}
+
+
+static void
+gth_list_view_real_select (GthFileSelection *base,
+			   int               pos)
+{
+	GtkTreePath *path;
+
+	path = gtk_tree_path_new_from_indices (pos, -1);
+	gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), path);
+
+	gtk_tree_path_free (path);
+}
+
+
+static void
+gth_list_view_real_unselect (GthFileSelection *base,
+			     int               pos)
+{
+	GtkTreePath *path;
+
+	path = gtk_tree_path_new_from_indices (pos, -1);
+	gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), path);
+
+	gtk_tree_path_free (path);
+}
+
+
+static void
+gth_list_view_real_select_all (GthFileSelection *base)
+{
+	gtk_tree_selection_select_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)));
+}
+
+
+static void
+gth_list_view_real_unselect_all (GthFileSelection *base)
+{
+	gtk_tree_selection_unselect_all (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)));
+}
+
+
+static gboolean
+gth_list_view_real_is_selected (GthFileSelection *base,
+				int               pos)
+{
+	GtkTreePath *path;
+	gboolean     result;
+
+	path = gtk_tree_path_new ();
+	gtk_tree_path_append_index (path, pos);
+	result = gtk_tree_selection_path_is_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), path);
+
+	gtk_tree_path_free (path);
+
+	return result;
+}
+
+
+static GtkTreePath *
+gth_list_view_real_get_first_selected (GthFileSelection *base)
+{
+	GList       *list;
+	GtkTreePath *path;
+
+	list = gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), NULL);
+	if (list != NULL) {
+		list = g_list_sort (list, (GCompareFunc) gtk_tree_path_compare);
+		path = gtk_tree_path_copy ((GtkTreePath *) g_list_first (list)->data);
+	}
+	else
+		path = NULL;
+
+	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (list);
+
+	return path;
+}
+
+
+static GtkTreePath *
+gth_list_view_real_get_last_selected (GthFileSelection *base)
+{
+	GList       *list;
+	GtkTreePath *path;
+
+	list = gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), NULL);
+	if (list != NULL) {
+		list = g_list_sort (list, (GCompareFunc) gtk_tree_path_compare);
+		path = gtk_tree_path_copy ((GtkTreePath *) g_list_last (list)->data);
+	}
+	else
+		path = NULL;
+
+	g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (list);
+
+	return path;
+}
+
+
+static guint
+gth_list_view_real_get_n_selected (GthFileSelection *base)
+{
+	GthListView *self;
+	GList       *selected;
+	guint          n_selected;
+
+	self = GTH_LIST_VIEW (base);
+
+	selected = gtk_tree_selection_get_selected_rows (gtk_tree_view_get_selection (GTK_TREE_VIEW (base)), NULL);
+	n_selected = (guint) g_list_length (selected);
+
+	g_list_foreach (selected, (GFunc) gtk_tree_path_free, NULL);
+	g_list_free (selected);
+
+	return n_selected;
+}
+
+
+GtkWidget *
+gth_list_view_new (void)
+{
+	return g_object_new (GTH_TYPE_LIST_VIEW, NULL);
+}
+
+
+GtkWidget *
+gth_list_view_new_with_model (GtkTreeModel *model)
+{
+	return g_object_new (GTH_TYPE_LIST_VIEW, "model", model, NULL);
+}
+
+
+static void
+gth_list_view_finalize (GObject *object)
+{
+	/*GthListView *self = GTH_LIST_VIEW (object);*/
+
+	/* FIXME */
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gth_list_view_class_init (GthListViewClass *klass)
+{
+	GObjectClass *object_class;
+
+	parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GthListViewPrivate));
+
+	object_class = (GObjectClass*) klass;
+	object_class->finalize = gth_list_view_finalize;
+}
+
+
+static void
+list_view_selection_changed_cb (GtkTreeSelection *treeselection,
+				gpointer          user_data)
+{
+	gth_file_selection_changed (GTH_FILE_SELECTION (user_data));
+}
+
+
+static void
+list_view_row_activated_cb (GtkTreeView       *tree_view,
+			    GtkTreePath       *path,
+			    GtkTreeViewColumn *column,
+			    gpointer           user_data)
+{
+	gth_file_view_activate_file (GTH_FILE_VIEW (tree_view), path);
+}
+
+
+static void
+gth_list_view_init (GthListView *list_view)
+{
+	list_view->priv = G_TYPE_INSTANCE_GET_PRIVATE (list_view, GTH_TYPE_LIST_VIEW, GthListViewPrivate);
+
+	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (list_view), FALSE);
+
+	list_view->priv->column = gtk_tree_view_column_new ();
+	gtk_tree_view_column_set_expand (list_view->priv->column, TRUE);
+	gtk_tree_view_append_column (GTK_TREE_VIEW (list_view), list_view->priv->column);
+
+	gtk_widget_set_size_request (GTK_WIDGET (list_view),
+				     SIZE_REQUEST,
+				     SIZE_REQUEST);
+	gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (list_view)),
+				     GTK_SELECTION_MULTIPLE);
+	g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (list_view)),
+			  "changed",
+			  G_CALLBACK (list_view_selection_changed_cb),
+			  list_view);
+	g_signal_connect (GTK_TREE_VIEW (list_view),
+			  "row-activated",
+			  G_CALLBACK (list_view_row_activated_cb),
+			  list_view);
+}
+
+
+static void
+gth_list_view_gth_file_view_interface_init (GthFileViewIface *iface)
+{
+	gth_list_view_gth_file_view_parent_iface = g_type_interface_peek_parent (iface);
+	iface->set_model = gth_list_view_real_set_model;
+	iface->get_model = gth_list_view_real_get_model;
+	iface->scroll_to = gth_list_view_real_scroll_to;
+	iface->get_visibility = gth_list_view_real_get_visibility;
+	iface->get_at_position = gth_list_view_real_get_at_position;
+	iface->get_first_visible = gth_list_view_real_get_first_visible;
+	iface->get_last_visible = gth_list_view_real_get_last_visible;
+	iface->activated = gth_list_view_real_activated;
+	iface->set_cursor = gth_list_view_real_set_cursor;
+	iface->get_cursor = gth_list_view_real_get_cursor;
+	iface->set_spacing = gth_list_view_real_set_spacing;
+	iface->enable_drag_source = gth_list_view_enable_drag_source;
+	iface->unset_drag_source = gth_list_view_unset_drag_source;
+	iface->enable_drag_dest = gth_list_view_enable_drag_dest;
+	iface->unset_drag_dest = gth_list_view_unset_drag_dest;
+	iface->set_drag_dest_pos = gth_list_view_set_drag_dest_pos;
+	iface->add_renderer = gth_list_view_add_renderer;
+	iface->update_attributes = gth_list_view_update_attributes;
+	iface->truncate_metadata = gth_list_view_truncate_metadata;
+}
+
+
+static void
+gth_list_view_gth_file_selection_interface_init (GthFileSelectionIface *iface)
+{
+	gth_list_view_gth_file_selection_parent_iface = g_type_interface_peek_parent (iface);
+	iface->set_selection_mode = gth_list_view_real_set_selection_mode;
+	iface->get_selected = gth_list_view_real_get_selected;
+	iface->select = gth_list_view_real_select;
+	iface->unselect = gth_list_view_real_unselect;
+	iface->select_all = gth_list_view_real_select_all;
+	iface->unselect_all = gth_list_view_real_unselect_all;
+	iface->is_selected = gth_list_view_real_is_selected;
+	iface->get_first_selected = gth_list_view_real_get_first_selected;
+	iface->get_last_selected = gth_list_view_real_get_last_selected;
+	iface->get_n_selected = gth_list_view_real_get_n_selected;
+}
+
+
+GType
+gth_list_view_get_type (void)
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		static const GTypeInfo g_define_type_info = {
+			sizeof (GthListViewClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) gth_list_view_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,
+			sizeof (GthListView),
+			0,
+			(GInstanceInitFunc) gth_list_view_init,
+			NULL
+		};
+		static const GInterfaceInfo gth_file_view_info = {
+			(GInterfaceInitFunc) gth_list_view_gth_file_view_interface_init,
+			(GInterfaceFinalizeFunc) NULL,
+			NULL
+		};
+		static const GInterfaceInfo gth_file_selection_info = {
+			(GInterfaceInitFunc) gth_list_view_gth_file_selection_interface_init,
+			(GInterfaceFinalizeFunc) NULL,
+			NULL
+		};
+		type = g_type_register_static (GTK_TYPE_TREE_VIEW,
+					       "GthListView",
+					       &g_define_type_info,
+					       0);
+		g_type_add_interface_static (type, GTH_TYPE_FILE_VIEW, &gth_file_view_info);
+		g_type_add_interface_static (type, GTH_TYPE_FILE_SELECTION, &gth_file_selection_info);
+	}
+
+	return type;
+}
diff --git a/gthumb/gth-list-view.h b/gthumb/gth-list-view.h
new file mode 100644
index 0000000..1a823ee
--- /dev/null
+++ b/gthumb/gth-list-view.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2011 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTH_LIST_VIEW_H
+#define GTH_LIST_VIEW_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include "gth-file-view.h"
+#include "gth-file-selection.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_LIST_VIEW            (gth_list_view_get_type ())
+#define GTH_LIST_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_LIST_VIEW, GthListView))
+#define GTH_LIST_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_LIST_VIEW, GthListViewClass))
+#define GTH_IS_LIST_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_LIST_VIEW))
+#define GTH_IS_LIST_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_LIST_VIEW))
+#define GTH_LIST_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTH_TYPE_LIST_VIEW, GthListViewClass))
+
+typedef struct _GthListView GthListView;
+typedef struct _GthListViewClass GthListViewClass;
+typedef struct _GthListViewPrivate GthListViewPrivate;
+
+struct _GthListView {
+	GtkTreeView parent_instance;
+	GthListViewPrivate *priv;
+};
+
+struct _GthListViewClass {
+	GtkTreeViewClass parent_class;
+};
+
+GType        gth_list_view_get_type        (void);
+GtkWidget *  gth_list_view_new             (void);
+GtkWidget *  gth_list_view_new_with_model  (GtkTreeModel *model);
+
+G_END_DECLS
+
+#endif /* GTH_LIST_VIEW_H */



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