# HG changeset patch # User zas_ # Date 1210200510 0 # Node ID 93c6dc4c537b8bf0138b96a300b35864ab1c11c7 # Parent 9c28465c95d12cde224e00180c7d9c787f0ec123 Add a way to invert the current selection. An item labeled "Invert selection" was added to the Select submenu in the main menu. diff -r 9c28465c95d1 -r 93c6dc4c537b src/layout.c --- 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; diff -r 9c28465c95d1 -r 93c6dc4c537b src/layout.h --- 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); diff -r 9c28465c95d1 -r 93c6dc4c537b src/layout_util.c --- 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"), "P", NULL, CB(layout_menu_info_cb) }, { "SelectAll", NULL, N_("Select _all"), "A", NULL, CB(layout_menu_select_all_cb) }, { "SelectNone", NULL, N_("Select _none"), "A",NULL, CB(layout_menu_unselect_all_cb) }, + { "SelectInvert", NULL, N_("_Invert Selection"), "I", NULL, CB(layout_menu_invert_selection_cb) }, + { "Preferences",GTK_STOCK_PREFERENCES,N_("P_references..."), "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 @@ " " " " " " +" " " " " " " " diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file.c --- 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) diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file.h --- 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); diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file_icon.c --- 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; diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file_icon.h --- 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); diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file_list.c --- 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; diff -r 9c28465c95d1 -r 93c6dc4c537b src/view_file_list.h --- 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);