changeset 601:93c6dc4c537b

Add a way to invert the current selection. An item labeled "Invert selection" was added to the Select submenu in the main menu.
author zas_
date Wed, 07 May 2008 22:48:30 +0000
parents 9c28465c95d1
children 02831fd2771b
files src/layout.c src/layout.h src/layout_util.c src/view_file.c src/view_file.h src/view_file_icon.c src/view_file_icon.h src/view_file_list.c src/view_file_list.h
diffstat 9 files changed, 115 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/layout.c	Tue May 06 23:58:08 2008 +0000
+++ b/src/layout.c	Wed May 07 22:48:30 2008 +0000
@@ -875,6 +875,13 @@
 	if (lw->vf) vf_select_none(lw->vf);
 }
 
+void layout_select_invert(LayoutWindow *lw)
+{
+	if (!layout_valid(&lw)) return;
+
+	if (lw->vf) vf_select_invert(lw->vf);
+}
+
 void layout_mark_to_selection(LayoutWindow *lw, gint mark, MarkToSelectionMode mode)
 {
 	if (!layout_valid(&lw)) return;
--- a/src/layout.h	Tue May 06 23:58:08 2008 +0000
+++ b/src/layout.h	Wed May 07 22:48:30 2008 +0000
@@ -50,6 +50,7 @@
 gint layout_selection_count(LayoutWindow *lw, gint64 *bytes);
 void layout_select_all(LayoutWindow *lw);
 void layout_select_none(LayoutWindow *lw);
+void layout_select_invert(LayoutWindow *lw);
 
 void layout_mark_to_selection(LayoutWindow *lw, gint mark, MarkToSelectionMode mode);
 void layout_selection_to_mark(LayoutWindow *lw, gint mark, SelectionToMarkMode mode);
--- a/src/layout_util.c	Tue May 06 23:58:08 2008 +0000
+++ b/src/layout_util.c	Wed May 07 22:48:30 2008 +0000
@@ -717,6 +717,13 @@
 	layout_select_none(lw);
 }
 
+static void layout_menu_invert_selection_cb(GtkAction *action, gpointer data)
+{
+	LayoutWindow *lw = data;
+
+	layout_select_invert(lw);
+}
+
 static void layout_menu_marks_cb(GtkToggleAction *action, gpointer data)
 {
 	LayoutWindow *lw = data;
@@ -1095,6 +1102,8 @@
   { "Properties",GTK_STOCK_PROPERTIES,	N_("_Properties"),	"<control>P",	NULL,	CB(layout_menu_info_cb) },
   { "SelectAll",	NULL,		N_("Select _all"),	"<control>A",	NULL,	CB(layout_menu_select_all_cb) },
   { "SelectNone",	NULL,		N_("Select _none"), "<control><shift>A",NULL,	CB(layout_menu_unselect_all_cb) },
+  { "SelectInvert",	NULL,		N_("_Invert Selection"), "<control><shift>I",	NULL,	CB(layout_menu_invert_selection_cb) },
+
   { "Preferences",GTK_STOCK_PREFERENCES,N_("P_references..."),	"<control>O",	NULL,	CB(layout_menu_config_cb) },
   { "Maintenance",	NULL,		N_("_Thumbnail maintenance..."),NULL,	NULL,	CB(layout_menu_remove_thumb_cb) },
   { "Wallpaper",	NULL,		N_("Set as _wallpaper"),NULL,		NULL,	CB(layout_menu_wallpaper_cb) },
@@ -1200,6 +1209,7 @@
 "    <menu action='SelectMenu'>"
 "      <menuitem action='SelectAll'/>"
 "      <menuitem action='SelectNone'/>"
+"      <menuitem action='SelectInvert'/>"
 "      <separator/>"
 "      <menuitem action='ShowMarks'/>"
 "      <separator/>"
--- a/src/view_file.c	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file.c	Wed May 07 22:48:30 2008 +0000
@@ -222,6 +222,15 @@
 	}
 }
 
+void vf_select_invert(ViewFile *vf)
+{
+	switch(vf->type)
+	{
+	case FILEVIEW_LIST: vflist_select_invert(vf); break;
+	case FILEVIEW_ICON: vficon_select_invert(vf); break;
+	}
+}
+
 void vf_select_by_fd(ViewFile *vf, FileData *fd)
 {
 	switch(vf->type)
--- a/src/view_file.h	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file.h	Wed May 07 22:48:30 2008 +0000
@@ -42,6 +42,7 @@
 
 void vf_select_all(ViewFile *vf);
 void vf_select_none(ViewFile *vf);
+void vf_select_invert(ViewFile *vf);
 void vf_select_by_fd(ViewFile *vf, FileData *fd);
 
 void vf_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode);
--- a/src/view_file_icon.c	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file_icon.c	Wed May 07 22:48:30 2008 +0000
@@ -829,6 +829,31 @@
 	vficon_send_update(vf);
 }
 
+void vficon_select_invert(ViewFile *vf)
+{
+	GList *work;
+
+	work = vf->list;
+	while (work)
+		{
+		IconData *id = work->data;
+		work = work->next;
+
+		if (id->selected & SELECTION_SELECTED)
+			{
+			VFICON_INFO(vf, selection) = g_list_remove(VFICON_INFO(vf, selection), id);
+			vficon_selection_remove(vf, id, SELECTION_SELECTED, NULL);
+			}
+		else
+			{
+			VFICON_INFO(vf, selection) = g_list_append(VFICON_INFO(vf, selection), id);
+			vficon_selection_add(vf, id, SELECTION_SELECTED, NULL);
+			}
+		}
+
+	vficon_send_update(vf);
+}
+
 static void vficon_select(ViewFile *vf, IconData *id)
 {
 	VFICON_INFO(vf, prev_selection) = id;
--- a/src/view_file_icon.h	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file_icon.h	Wed May 07 22:48:30 2008 +0000
@@ -41,6 +41,7 @@
 
 void vficon_select_all(ViewFile *vf);
 void vficon_select_none(ViewFile *vf);
+void vficon_select_invert(ViewFile *vf);
 void vficon_select_by_fd(ViewFile *vf, FileData *fd);
 
 void vficon_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode);
--- a/src/view_file_list.c	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file_list.c	Wed May 07 22:48:30 2008 +0000
@@ -1524,6 +1524,66 @@
 	gtk_tree_selection_unselect_all(selection);
 }
 
+static gboolean tree_model_iter_prev(GtkTreeModel *store, GtkTreeIter *iter)
+{
+	GtkTreePath *tpath;
+	gboolean result;
+
+	tpath = gtk_tree_model_get_path(store, iter);
+	result = gtk_tree_path_prev(tpath);
+	if (result)
+		gtk_tree_model_get_iter(store, iter, tpath);
+
+	gtk_tree_path_free(tpath);
+
+	return result;
+}
+
+static gboolean tree_model_get_iter_last(GtkTreeModel *store, GtkTreeIter *iter)
+{
+	if (!gtk_tree_model_get_iter_first(store, iter))
+		return FALSE;
+
+	while (TRUE)
+		{
+		GtkTreeIter next = *iter;
+		
+		if (gtk_tree_model_iter_next(store, &next))
+			*iter = next;
+		else
+			break;
+		}
+	
+	return TRUE;
+}
+
+void vflist_select_invert(ViewFile *vf)
+{
+	GtkTreeIter iter;
+	GtkTreeSelection *selection;
+	GtkTreeModel *store;
+	gboolean valid;
+
+	store = gtk_tree_view_get_model(GTK_TREE_VIEW(vf->listview));
+	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(vf->listview));
+
+	/* Backward iteration prevents scrolling to the end of the list,
+	 * it scrolls to the first selected row instead. */
+	valid = tree_model_get_iter_last(store, &iter);
+
+	while (valid)
+		{
+		gint selected = gtk_tree_selection_iter_is_selected(selection, &iter);
+
+		if (selected)
+			gtk_tree_selection_unselect_iter(selection, &iter);
+		else
+			gtk_tree_selection_select_iter(selection, &iter);
+				
+		valid = tree_model_iter_prev(store, &iter);
+		}
+}
+
 void vflist_select_by_fd(ViewFile *vf, FileData *fd)
 {
 	GtkTreeIter iter;
--- a/src/view_file_list.h	Tue May 06 23:58:08 2008 +0000
+++ b/src/view_file_list.h	Wed May 07 22:48:30 2008 +0000
@@ -45,6 +45,7 @@
 
 void vflist_select_all(ViewFile *vf);
 void vflist_select_none(ViewFile *vf);
+void vflist_select_invert(ViewFile *vf);
 void vflist_select_by_fd(ViewFile *vf, FileData *fd);
 
 void vflist_mark_to_selection(ViewFile *vf, gint mark, MarkToSelectionMode mode);