[nautilus-actions] Define a filter selection function in treeview
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Define a filter selection function in treeview
- Date: Sat, 26 Sep 2009 22:47:00 +0000 (UTC)
commit fa3a12cc008096a80fadc0afdfeb92e692456418
Author: Pierre Wieser <pwieser trychlos org>
Date: Thu Sep 17 19:28:15 2009 +0200
Define a filter selection function in treeview
ChangeLog | 9 ++
src/nact/nact-iactions-list.c | 142 +++++++++++++++++++++++++++++++++++-
src/nact/nact-iactions-list.h | 1 +
src/nact/nact-main-menubar.c | 15 ++++
src/nact/nact-main-tab.c | 162 -----------------------------------------
src/nact/nact-main-window.c | 15 ++++
6 files changed, 181 insertions(+), 163 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 03c9dfa..0b53a88 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-17 Pierre Wieser <pwieser trychlos org>
+
+ * src/nact/nact-iactions-list.c (filter_selection,
+ filter_selection_iter): Controls the allowed selection so that
+ we are only able to select profiles, or actions/menus.
+ Define new nact_iactions_list_set_filter_selection_mode() api.
+
+ * src/nact/nact-main-tab.c: Removed (unused) file.
+
2009-09-16 Pierre Wieser <pwieser trychlos org>
* configure.ac:
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index e24a6a6..7e794f8 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -75,11 +75,21 @@ enum {
TOGGLE_EXPAND
};
+/* when iterating through a selection
+ */
+typedef struct {
+ guint nb_profiles;
+ guint nb_actions;
+ guint nb_menus;
+}
+ SelectionIter;
+
/* data set against GObject
*/
#define SHOW_ONLY_ACTIONS_MODE "nact-iactions-list-show-only-actions-mode"
#define IS_FILLING_LIST "nact-iactions-list-is-filling-list"
#define HAVE_DND_MODE "nact-iactions-list-dnd-mode"
+#define FILTER_SELECTION_MODE "nact-iactions-list-filter-selection-mode"
static gint st_signals[ LAST_SIGNAL ] = { 0 };
@@ -91,9 +101,12 @@ static void free_items_callback( NactIActionsList *instance, GSList *ite
static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactIActionsList *instance );
static void extend_selection_to_childs( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreeIter *parent );
+static gboolean filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactIActionsList *instance );
+static void filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str );
static GtkTreeView *get_actions_list_treeview( NactIActionsList *instance );
static gboolean get_item( NactTreeModel *model, GtkTreePath *path, NAObject *object, GSList **items );
static gboolean have_dnd_mode( NactIActionsList *instance );
+static gboolean have_filter_selection_mode( NactIActionsList *instance );
static void insert_item( NactIActionsList *instance, NAObject *item );
static gboolean is_modified_item( NactTreeModel *model, GtkTreePath *path, NAObject *object, GSList **items );
static void iter_on_selection( NactIActionsList *instance, FnIterOnSelection fn_iter, gpointer user_data );
@@ -300,6 +313,8 @@ nact_iactions_list_runtime_init_toplevel( NactIActionsList *instance, GSList *it
GtkTreeView *treeview;
NactTreeModel *model;
gboolean have_dnd;
+ gboolean have_filter_selection;
+ GtkTreeSelection *selection;
g_debug( "%s: instance=%p, items=%p (%d items)",
thisfn, ( void * ) instance, ( void * ) items, g_slist_length( items ));
@@ -309,6 +324,12 @@ nact_iactions_list_runtime_init_toplevel( NactIActionsList *instance, GSList *it
model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
have_dnd = have_dnd_mode( instance );
+ have_filter_selection = have_filter_selection_mode( instance );
+ if( have_filter_selection ){
+ selection = gtk_tree_view_get_selection( treeview );
+ gtk_tree_selection_set_select_function( selection, ( GtkTreeSelectionFunc ) filter_selection, instance, NULL );
+ }
+
nact_tree_model_runtime_init( model, have_dnd );
/* set up selection control */
@@ -540,7 +561,11 @@ nact_iactions_list_get_modified_items( NactIActionsList *instance )
* nact_iactions_list_get_selected_items:
* @window: this #NactIActionsList instance.
*
- * Returns the currently selected actions when in export mode.
+ * Returns the currently selected rows.
+ *
+ * If a selected item is collapsed, we consider that all subitems are
+ * also silently selected. If it is expanded, then only actually
+ * selected rows are returned.
*
* The returned GSList should be nact_iaction_list_free_items_list()-ed.
*/
@@ -859,6 +884,25 @@ nact_iactions_list_set_dnd_mode( NactIActionsList *instance, gboolean have_dnd )
}
/**
+ * nact_iactions_list_set_filter_selection_mode:
+ * @window: this #NactIActionsList instance.
+ * @filter: whether the filter selection function must be installed ?
+ *
+ * If %FALSE, user is able to select any item.
+ * If %TRUE, a filter selection function is installed, and the selection
+ * can only contains :
+ * - either only profiles
+ * - or actions or menus.
+ *
+ * This property defaults to %FALSE.
+ */
+void
+nact_iactions_list_set_filter_selection_mode( NactIActionsList *instance, gboolean filter )
+{
+ g_object_set_data( G_OBJECT( instance ), FILTER_SELECTION_MODE, GINT_TO_POINTER( filter ));
+}
+
+/**
* nact_iactions_list_set_multiple_selection_mode:
* @window: this #NactIActionsList instance.
* @multiple: whether the treeview does support multiple selection ?
@@ -1009,6 +1053,96 @@ extend_selection_to_childs( NactIActionsList *instance, GtkTreeView *treeview, G
}
}
+/*
+ * rationale: it is very difficult to copy anything in the clipboard,
+ * and to hope that this will be easily copyable anywhere after.
+ * We know how to insert profiles, or how to insert actions or menus,
+ * but not how not where to insert e.g. a mix selection.
+ * So the selection allows :
+ * - only profiles, maybe from different actions
+ * - or only actions or menus.
+ *
+ * Note that we do not allow here a selection to be made or not. What
+ * we actually allow is only toggle the selection state. And so, we
+ * only deal with "do we allow to toggle from non-selected ?"
+ */
+static gboolean
+filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactIActionsList *instance )
+{
+ SelectionIter *str;
+ GtkTreeIter iter;
+ NAObject *object;
+ gboolean select_ok;
+
+ if( path_currently_selected ){
+ return( TRUE );
+ }
+
+ /* iter through the selection: does it contain profiles ? actions or
+ * menus ? or both ?
+ */
+ str = g_new0( SelectionIter, 1 );
+ str->nb_profiles = 0;
+ str->nb_actions = 0;
+ str->nb_menus = 0;
+
+ gtk_tree_selection_selected_foreach( selection, ( GtkTreeSelectionForeachFunc ) filter_selection_iter, str );
+
+ /* if there is not yet any selection, then anything is allowed
+ */
+ if( str->nb_profiles + str->nb_actions + str->nb_menus == 0 ){
+ return( TRUE );
+ }
+
+ gtk_tree_model_get_iter( model, &iter, path );
+ gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+
+ g_return_val_if_fail( object, FALSE );
+ g_return_val_if_fail( NA_IS_OBJECT_ID( object ), FALSE );
+
+ select_ok = FALSE;
+
+ /* selecting a profile is only ok if a profile is already selected
+ */
+ if( NA_IS_OBJECT_PROFILE( object )){
+ select_ok = ( str->nb_actions + str->nb_menus == 0 );
+ }
+
+ /* selecting an action or a menu is only ok if no profile is selected
+ */
+ if( NA_IS_OBJECT_ITEM( object )){
+ select_ok = ( str->nb_profiles == 0 );
+ }
+
+ g_free( str );
+ g_object_unref( object );
+
+ return( select_ok );
+}
+
+static void
+filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str )
+{
+ NAObject *object;
+
+ gtk_tree_model_get( model, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+
+ g_return_if_fail( object );
+ g_return_if_fail( NA_IS_OBJECT_ID( object ));
+
+ if( NA_IS_OBJECT_PROFILE( object )){
+ str->nb_profiles += 1;
+
+ } else if( NA_IS_OBJECT_ACTION( object )){
+ str->nb_actions += 1;
+
+ } else if( NA_IS_OBJECT_MENU( object )){
+ str->nb_menus += 1;
+ }
+
+ g_object_unref( object );
+}
+
static GtkTreeView *
get_actions_list_treeview( NactIActionsList *instance )
{
@@ -1040,6 +1174,12 @@ have_dnd_mode( NactIActionsList *instance )
return(( gboolean ) GPOINTER_TO_INT( g_object_get_data( G_OBJECT( instance ), HAVE_DND_MODE )));
}
+static gboolean
+have_filter_selection_mode( NactIActionsList *instance )
+{
+ return(( gboolean ) GPOINTER_TO_INT( g_object_get_data( G_OBJECT( instance ), FILTER_SELECTION_MODE )));
+}
+
/*
* count _all_ modified rows, including profiles
*/
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 1493c65..6277356 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -88,6 +88,7 @@ gboolean nact_iactions_list_is_filling_list( NactIActionsList *instance );
gboolean nact_iactions_list_is_only_actions_mode( NactIActionsList *instance );
void nact_iactions_list_select_row( NactIActionsList *instance, GtkTreePath *path );
void nact_iactions_list_set_dnd_mode( NactIActionsList *instance, gboolean have_dnd );
+void nact_iactions_list_set_filter_selection_mode( NactIActionsList *instance, gboolean filter );
void nact_iactions_list_set_multiple_selection_mode( NactIActionsList *instance, gboolean multiple );
void nact_iactions_list_set_only_actions_mode( NactIActionsList *instance, gboolean only_actions );
void nact_iactions_list_toggle_collapse( NactIActionsList *instance, const NAObject *item );
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 8fa0dca..6ba2d8c 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -441,6 +441,21 @@ on_quit_activated( GtkAction *gtk_action, NactMainWindow *window )
}
}
+/*
+ * cuts the visible selection
+ * - (tree) remove the selection from the treeview
+ * - (main) adds the removed selection to deleted
+ * - (*) set the clipboard
+ * - (tree) select the next row
+ *
+ * The clipboard must be set with a selection suitable for insertion :
+ * - if selection contains only profiles, even from different actions,
+ * then these profiles can only be inserted into an action.
+ * - if the selection contains only actions and menus, then these items
+ * can be inserted at root or inside a menu
+ * - if the selection is a mixed of profiles, and actions or menus,
+ * then nothing can be done with it.
+ */
static void
on_cut_activated( GtkAction *gtk_action, NactMainWindow *window )
{
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index b05eab6..fd85540 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -553,6 +553,20 @@ nact_main_window_action_exists( const NactMainWindow *window, const gchar *uuid
return( FALSE );
}
+/**
+ * nact_main_window_delete_selection:
+ * @window: this #NactMainWindow instance.
+ *
+ * Deletes the currently selected items from the treeview.
+ *
+ * We only delete the selected items from the treeview.
+ * But, if asked for, we return the selection extended to a valid,
+ * contiguous tree, suitable for a later insertion elsewhere.
+ *
+ * Returns: the tree of selected items, or NULL.
+ *
+ * The returned #GSList should be na_object_free_items() by the caller.
+ */
GSList *
nact_main_window_delete_selection( NactMainWindow *window )
{
@@ -722,6 +736,7 @@ on_base_initial_load_toplevel( NactMainWindow *window, gpointer user_data )
}
nact_iactions_list_initial_load_toplevel( NACT_IACTIONS_LIST( window ));
+ nact_iactions_list_set_filter_selection_mode( NACT_IACTIONS_LIST( window ), TRUE );
nact_iactions_list_set_multiple_selection_mode( NACT_IACTIONS_LIST( window ), TRUE );
nact_iactions_list_set_dnd_mode( NACT_IACTIONS_LIST( window ), TRUE );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]