[nautilus-actions] Review selection criteria
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Review selection criteria
- Date: Sat, 16 Jan 2010 21:00:54 +0000 (UTC)
commit 9b839a67e5de85e175df4a864a706f5aa67b77e5
Author: Pierre Wieser <pwieser trychlos org>
Date: Fri Jan 15 16:35:07 2010 +0100
Review selection criteria
Fix menu items sensitivity when provider is not writable or selection is multiple.
ChangeLog | 13 ++
nautilus-actions/nact/nact-iactions-list.c | 152 +++++++++++------
nautilus-actions/nact/nact-main-menubar.c | 263 +++++++++++++++++++---------
nautilus-actions/nact/nact-window.c | 34 ++++-
nautilus-actions/nact/nact-window.h | 1 +
5 files changed, 327 insertions(+), 136 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 52bddd3..e80b24e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2009-01-15 Pierre Wieser <pwieser trychlos org>
+
+ * nautilus-actions/nact/nact-iactions-list.c (filter_selection):
+ Review selection criteria, introducing implicit selection.
+
+ * nautilus-actions/nact/nact-main-menubar.c (on_update_sensitivities):
+ Review menu items sensitivity, especially when provider is not writable.
+ Enable new item even when selection is multiple.
+
+ * nautilus-actions/nact/nact-window.c:
+ * nautilus-actions/nact/nact-window.h (nact_window_is_writable_item):
+ New function.
+
2009-01-05 Pierre Wieser <pwieser trychlos org>
* configure.ac: Bump version number.
diff --git a/nautilus-actions/nact/nact-iactions-list.c b/nautilus-actions/nact/nact-iactions-list.c
index 2ab917e..3a015e6 100644
--- a/nautilus-actions/nact/nact-iactions-list.c
+++ b/nautilus-actions/nact/nact-iactions-list.c
@@ -55,9 +55,7 @@ struct NactIActionsListInterfacePrivate {
/* when iterating through a selection
*/
typedef struct {
- guint nb_profiles;
- guint nb_actions;
- guint nb_menus;
+ gboolean has_menu_or_action;
}
SelectionIter;
@@ -86,7 +84,11 @@ static void free_column_edited_callback( NactIActionsList *instance, NAObjec
static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactIActionsList *instance );
static gboolean filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactIActionsList *instance );
+static gboolean filter_selection_is_homogeneous( GtkTreeSelection *selection, NAObject *object );
static void filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str );
+static gboolean filter_selection_has_menu_or_action( GtkTreeSelection *selection );
+static gboolean filter_selection_is_implicitely_selected( NAObject *object );
+static void filter_selection_set_implicitely_selected_childs( NAObject *object, gboolean select );
static gboolean have_dnd_mode( NactIActionsList *instance, IActionsListInstanceData *ialid );
static gboolean have_filter_selection_mode( NactIActionsList *instance, IActionsListInstanceData *ialid );
static gboolean have_only_actions( NactIActionsList *instance, IActionsListInstanceData *ialid );
@@ -889,66 +891,95 @@ display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *m
* 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 nor 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 ?"
+ * So a selection must first be homogeneous, i.e. it only contains
+ * explicitely selected profiles _or_ menus or actions (and their childs).
+ *
+ * To simplify the selection management while letting the user actually
+ * select almost anything, we are doing following assumptions:
+ * - when the user selects one row, all childs are also automatically
+ * selected ; visible childs are setup so that they are known as
+ * 'indirectly' selected
+ * - when a row is set as 'indirectly' selected, user cannot select
+ * nor unselect it (sort of readonly or mandatory implied selection)
+ * while the parent stays itself selected
*/
static gboolean
filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactIActionsList *instance )
{
- SelectionIter *str;
+ static const gchar *thisfn = "nact_iactions_list_filter_selection";
+ GList *selected_paths;
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;
+ /* if there is not yet any selection, then anything is allowed
+ */
+ selected_paths = gtk_tree_selection_get_selected_rows( selection, NULL );
+ if( !selected_paths || !g_list_length( selected_paths )){
+ /*g_debug( "%s: current selection is empty: allowing this one", thisfn );*/
+ filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
+ return( TRUE );
+ }
- /* selecting a profile is only ok if a profile is already selected
+ /* if the object at the row is already 'implicitely' selected, i.e.
+ * selected because of the selection of one of its parents, then
+ * nothing is allowed
*/
- if( NA_IS_OBJECT_PROFILE( object )){
- select_ok = ( str->nb_actions + str->nb_menus == 0 );
+ if( filter_selection_is_implicitely_selected( object )){
+ g_debug( "%s: implicitely selected item: selection not allowed", thisfn );
+ g_object_unref( object );
+ return( FALSE );
}
- /* selecting an action or a menu is only ok if no profile is selected
+ /* object at the row is not 'implicitely' selected: we may so select
+ * or unselect it while the selection stays homogeneous
+ * (rather we set its childs to the corresponding implied status)
*/
- if( NA_IS_OBJECT_ITEM( object )){
- select_ok = ( str->nb_profiles == 0 );
+ if( path_currently_selected ||
+ filter_selection_is_homogeneous( selection, object )){
+
+ filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
}
+ g_object_unref( object );
+ return( TRUE );
+}
+/*
+ * does the selection stay homogeneous when adding this object ?
+ */
+static gboolean
+filter_selection_is_homogeneous( GtkTreeSelection *selection, NAObject *object )
+{
+ gboolean homogeneous;
+
+ if( filter_selection_has_menu_or_action( selection )){
+ homogeneous = !NA_IS_OBJECT_PROFILE( object );
+ } else {
+ homogeneous = NA_IS_OBJECT_PROFILE( object );
+ }
+
+ return( homogeneous );
+}
+
+static gboolean
+filter_selection_has_menu_or_action( GtkTreeSelection *selection )
+{
+ gboolean has_menu_or_action;
+ SelectionIter *str;
+
+ has_menu_or_action = FALSE;
+ str = g_new0( SelectionIter, 1 );
+ str->has_menu_or_action = has_menu_or_action;
+ gtk_tree_selection_selected_foreach( selection, ( GtkTreeSelectionForeachFunc ) filter_selection_iter, str );
+ has_menu_or_action = str->has_menu_or_action;
g_free( str );
- g_object_unref( object );
- return( select_ok );
+ return( has_menu_or_action );
}
static void
@@ -958,20 +989,39 @@ filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter
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_ITEM( object )){
+ str->has_menu_or_action = TRUE;
+ }
- if( NA_IS_OBJECT_PROFILE( object )){
- str->nb_profiles += 1;
+ g_object_unref( object );
+}
- } else if( NA_IS_OBJECT_ACTION( object )){
- str->nb_actions += 1;
+static gboolean
+filter_selection_is_implicitely_selected( NAObject *object )
+{
+ gboolean selected;
- } else if( NA_IS_OBJECT_MENU( object )){
- str->nb_menus += 1;
- }
+ selected = ( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object), "nact-implicit-selection" ));
- g_object_unref( object );
+ return( selected );
+}
+
+/*
+ * the object is being selected (resp. unselected)
+ * recursively set the 'implicit selection' flag for all its childs
+ */
+static void
+filter_selection_set_implicitely_selected_childs( NAObject *object, gboolean select )
+{
+ GList *childs, *ic;
+
+ if( NA_IS_OBJECT_ITEM( object )){
+ childs = na_object_get_items_list( object );
+ for( ic = childs ; ic ; ic = ic->next ){
+ g_object_set_data( G_OBJECT( ic->data ), "nact-implicit-selection", GUINT_TO_POINTER(( guint ) select ));
+ filter_selection_set_implicitely_selected_childs( NA_OBJECT( ic->data ), select );
+ }
+ }
}
static gboolean
diff --git a/nautilus-actions/nact/nact-main-menubar.c b/nautilus-actions/nact/nact-main-menubar.c
index 2d1be8d..6ba21f9 100644
--- a/nautilus-actions/nact/nact-main-menubar.c
+++ b/nautilus-actions/nact/nact-main-menubar.c
@@ -601,124 +601,219 @@ static void
on_update_sensitivities( NactMainWindow *window, gpointer user_data )
{
static const gchar *thisfn = "nact_main_menubar_on_update_sensitivities";
+ NactApplication *application;
+ NAPivot *pivot;
+ gboolean is_level_zero_writable;
+ gboolean has_writable_providers;
+ gboolean has_modified_items;
+ GList *selected_items, *is;
+ NAObject *first_parent;
+ gboolean is_first_parent_writable;
+ gboolean new_item_enabled;
+ gboolean new_profile_enabled;
+ NAObject *selected_action;
+ NAObject *parent_item;
MenubarIndicatorsStruct *mis;
- NAObject *item;
- NAObject *profile;
- NAObject *selected_row;
- gboolean has_modified;
- gint count_list;
+ gboolean is_clipboard_empty;
gint count_selected;
+ gboolean are_parents_writable;
+ NAObject *selected_item;
gboolean cut_enabled;
gboolean copy_enabled;
gboolean paste_enabled;
gboolean paste_into_enabled;
gboolean duplicate_enabled;
gboolean delete_enabled;
- gboolean clipboard_is_empty;
- gboolean new_item_enabled;
- gboolean readonly_item;
- gboolean writable_provider;
- gboolean writable_item;
- gboolean has_writables;
- NAObjectItem *parent;
- gboolean writable_parent;
+ gint count_list;
- g_debug( "%s: window=%p", thisfn, ( void * ) window );
+ g_debug( "%s: window=%p, user_data=%p", thisfn, ( void * ) window, ( void * ) user_data );
g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
- mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
- has_writables = nact_window_has_writable_providers( NACT_WINDOW( window ));
- /*g_debug( "%s: has_writables=%s", thisfn, has_writables ? "True":"False" );*/
+ application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
+ pivot = nact_application_get_pivot( application );
+ is_level_zero_writable = na_pivot_is_level_zero_writable( pivot );
- g_object_get(
- G_OBJECT( window ),
- TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
- TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
- TAB_UPDATABLE_PROP_SELECTED_ROW, &selected_row,
- NULL );
- g_return_if_fail( !item || NA_IS_OBJECT_ITEM( item ));
- g_return_if_fail( !profile || NA_IS_OBJECT_PROFILE( profile ));
+ has_writable_providers = nact_window_has_writable_providers( NACT_WINDOW( window ));
+ has_modified_items = nact_main_window_has_modified_items( window );
- has_modified = nact_main_window_has_modified_items( window );
- readonly_item = item ? na_object_is_readonly( item ) : FALSE;
- writable_provider = item ? nact_window_is_writable_provider( NACT_WINDOW( window ), NA_OBJECT_ITEM( item )) : FALSE;
- writable_item = writable_provider && !readonly_item;
-
- parent = item ? na_object_get_parent( item ) : NULL;
- writable_parent = parent
- ? nact_window_is_writable_provider( NACT_WINDOW( window ), parent ) && !na_object_is_readonly( parent )
- : FALSE;
-
- /* new menu enabled if selection is a menu or an action
- * new action enabled if selection is a menu or an action
- * adding a new item requires that parent be writable
+ selected_items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
+ first_parent = selected_items && g_list_length( selected_items )
+ ? ( NAObject * ) na_object_get_parent( selected_items->data )
+ : NULL;
+ is_first_parent_writable = first_parent
+ ? nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( first_parent ))
+ : is_level_zero_writable;
+
+ mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
+ is_clipboard_empty = ( mis->clipboard_menus + mis->clipboard_actions + mis->clipboard_profiles == 0 );
+ count_selected = mis->selected_menus + mis->selected_actions + mis->selected_profiles;
+ g_return_if_fail( selected_items == NULL || count_selected == g_list_length( selected_items ));
+
+ /* new menu / new action
+ * new item will be inserted just before beginning of selection
+ * parent of the first selected row must be writable
+ * we must have at least one writable provider
*/
- new_item_enabled = ( selected_row == NULL || NA_IS_OBJECT_ITEM( selected_row ));
- new_item_enabled = new_item_enabled && has_writables;
- new_item_enabled = new_item_enabled && ( parent ? writable_parent : TRUE );
+ new_item_enabled = is_first_parent_writable && has_writable_providers;
enable_item( window, "NewMenuItem", new_item_enabled );
enable_item( window, "NewActionItem", new_item_enabled );
- /* new profile enabled if selection is relative to only one writable action */
+ /* new profile enabled if selection is relative to only one writable action
+ * i.e. contains profile(s) of the same action, or only contains one action
+ * action must be writable
+ */
+ new_profile_enabled = TRUE;
+ selected_action = NULL;
+ for( is = selected_items ; is ; is = is->next ){
+
+ if( NA_IS_OBJECT_MENU( is->data )){
+ new_profile_enabled = FALSE;
+ break;
+
+ } else if( NA_IS_OBJECT_ACTION( is->data )){
+ if( !selected_action ){
+ selected_action = NA_OBJECT( is->data );
+ } else if( selected_action != is->data ){
+ new_profile_enabled = FALSE;
+ break;
+ }
+
+ } else if( NA_IS_OBJECT_PROFILE( is->data )){
+ parent_item = NA_OBJECT( na_object_get_parent( is->data ));
+ if( !selected_action ){
+ selected_action = parent_item;
+ } else if( selected_action != parent_item ){
+ new_profile_enabled = FALSE;
+ break;
+ }
+ }
+ }
enable_item( window, "NewProfileItem",
- item != NULL && !NA_IS_OBJECT_MENU( item ) && writable_item );
+ new_profile_enabled &&
+ selected_action != NULL &&
+ nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( selected_action )));
- /* save enabled if at least one item has been modified */
- enable_item( window, "SaveItem", has_modified || mis->level_zero_order_changed );
+ /* save enabled if at least one item has been modified
+ * or level-zero has been resorted and is writable
+ */
+ enable_item( window, "SaveItem",
+ has_modified_items || ( mis->level_zero_order_changed && is_level_zero_writable ));
/* quit always enabled */
- /* edit menu is only enabled when the treeview has the focus
+ /* cut requires a non-empty selection
+ * and that all parents are writable (as implies a delete operation)
*/
+ cut_enabled = mis->treeview_has_focus || mis->popup_handler;
+ cut_enabled &= count_selected;
+ are_parents_writable = TRUE;
+ for( is = selected_items ; is ; is = is->next ){
+ parent_item = ( NAObject * ) na_object_get_parent( is->data );
+ if( parent_item ){
+ if( !nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( parent_item ))){
+ are_parents_writable = FALSE;
+ break;
+ }
+ } else if( !is_level_zero_writable ){
+ are_parents_writable = FALSE;
+ break;
+ }
+ }
+ cut_enabled &= are_parents_writable;
+ enable_item( window, "CutItem", cut_enabled );
- clipboard_is_empty = ( mis->clipboard_menus + mis->clipboard_actions + mis->clipboard_profiles == 0 );
- count_selected = mis->selected_menus + mis->selected_actions + mis->selected_profiles;
-
- /* cut/copy/duplicate/delete enabled when selection not empty */
- /* cut/delete require a writable item */
- cut_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && writable_item && has_writables;
- copy_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && has_writables;
- duplicate_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && has_writables;
- delete_enabled = ( mis->treeview_has_focus || mis->popup_handler ) && count_selected > 0 && writable_item;
+ /* copy only requires a non-empty selection */
+ copy_enabled = mis->treeview_has_focus || mis->popup_handler;
+ copy_enabled &= count_selected;
+ enable_item( window, "CopyItem", copy_enabled );
/* paste enabled if
- * - simple selection
- * - clipboard contains only profiles, and current selection is a profile
- * - clipboard contains actions or menus, and current selection is a menu or an action */
- paste_enabled = FALSE;
- if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 ){
- if( !clipboard_is_empty ){
- if( mis->clipboard_profiles ){
- paste_enabled = item && NA_IS_OBJECT_ACTION( item ) && writable_item;
- } else {
- paste_enabled = ( item != NULL ) && has_writables && ( parent ? writable_parent : TRUE );
+ * - clipboard is not empty
+ * - current selection is not multiple
+ * - if clipboard contains only profiles,
+ * then current selection must be a profile or an action
+ * and the action must be writable
+ * - if clipboard contains actions or menus,
+ * then current selection (if any) must be a menu or an action
+ * and its parent must be writable
+ */
+ paste_enabled = mis->treeview_has_focus || mis->popup_handler;
+ paste_enabled &= !is_clipboard_empty;
+ paste_enabled &= count_selected <= 1;
+ if( mis->clipboard_profiles ){
+ paste_enabled &= count_selected == 1;
+ if( paste_enabled ){
+ selected_action = NA_OBJECT(
+ NA_IS_OBJECT_PROFILE( selected_items->data )
+ ? na_object_get_parent( selected_items->data )
+ : selected_items->data );
+ paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
+ paste_enabled &= nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( selected_action ));
+ }
+ } else {
+ paste_enabled &= has_writable_providers;
+ if( count_selected ){
+ selected_item = NA_OBJECT( selected_items->data );
+ paste_enabled &= NA_IS_OBJECT_ITEM( selected_item );
+ if( paste_enabled ){
+ parent_item = ( NAObject * ) na_object_get_parent( selected_item );
+ paste_enabled &= parent_item
+ ? nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( parent_item ))
+ : is_level_zero_writable;
}
+ } else {
+ paste_enabled &= is_level_zero_writable;
}
}
+ enable_item( window, "PasteItem", paste_enabled );
/* paste into enabled if
- * - simple selection
- * - clipboard has profiles and current item is an action
- * - or current item is a menu
- * do not paste into if current selection is a profile */
- paste_into_enabled = FALSE;
- if(( mis->treeview_has_focus || mis->popup_handler ) && count_selected <= 1 ){
- if( mis->selected_menus + mis->selected_actions ){
- if( !clipboard_is_empty ){
- if( mis->clipboard_profiles ){
- paste_into_enabled = item && NA_IS_OBJECT_ACTION( item ) && writable_item;
- } else {
- paste_into_enabled = item && NA_IS_OBJECT_MENU( item ) && writable_item && has_writables;
- }
+ * - clipboard is not empty
+ * - current selection is not multiple
+ * - if clipboard contains only profiles,
+ * then current selection must be an action
+ * and the action must be writable
+ * - if clipboard contains actions or menus,
+ * then current selection (if any) must be a menu
+ * and its parent must be writable
+ */
+ paste_into_enabled = mis->treeview_has_focus || mis->popup_handler;
+ paste_into_enabled &= !is_clipboard_empty;
+ paste_into_enabled &= count_selected <= 1;
+ if( mis->clipboard_profiles ){
+ paste_enabled &= count_selected == 1;
+ if( paste_enabled ){
+ selected_action = NA_OBJECT( selected_items->data );
+ paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
+ paste_enabled &= nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( selected_action ));
+ }
+ } else {
+ paste_enabled &= has_writable_providers;
+ if( count_selected ){
+ selected_item = NA_OBJECT( selected_items->data );
+ paste_enabled &= NA_IS_OBJECT_MENU( selected_item );
+ if( paste_enabled ){
+ parent_item = ( NAObject * ) na_object_get_parent( selected_item );
+ paste_enabled &= parent_item
+ ? nact_window_is_writable_item( NACT_WINDOW( window ), NA_OBJECT_ID( parent_item ))
+ : is_level_zero_writable;
}
+ } else {
+ paste_enabled &= is_level_zero_writable;
}
}
-
- enable_item( window, "CutItem", cut_enabled );
- enable_item( window, "CopyItem", copy_enabled );
- enable_item( window, "PasteItem", paste_enabled );
enable_item( window, "PasteIntoItem", paste_into_enabled );
+
+ /* duplicate items will be duplicated besides each one
+ * selection must be non-empty
+ * each parent must be writable
+ * -> so this is the same than cut
+ */
+ duplicate_enabled = cut_enabled;
enable_item( window, "DuplicateItem", duplicate_enabled );
+
+ /* delete is same that cut */
+ delete_enabled = cut_enabled;
enable_item( window, "DeleteItem", delete_enabled );
/* reload items always enabled */
@@ -731,7 +826,7 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
enable_item( window, "CollapseAllItem", count_list > 0 );
/* import item enabled if at least one writable provider */
- enable_item( window, "ImportItem", has_writables );
+ enable_item( window, "ImportItem", has_writable_providers );
/* export item enabled if IActionsList store contains actions */
enable_item( window, "ExportItem", mis->have_exportables );
@@ -740,6 +835,8 @@ on_update_sensitivities( NactMainWindow *window, gpointer user_data )
enable_item( window, "HelpItem", FALSE );
/* about always enabled */
+
+ na_object_free_items_list( selected_items );
}
static void
diff --git a/nautilus-actions/nact/nact-window.c b/nautilus-actions/nact/nact-window.c
index 9d7a28b..dada4d5 100644
--- a/nautilus-actions/nact/nact-window.c
+++ b/nautilus-actions/nact/nact-window.c
@@ -197,6 +197,36 @@ nact_window_get_pivot( NactWindow *window )
}
/**
+ * nact_window_is_writable_item:
+ * @window: this #NactWindow instance.
+ * @item: the item, which may be a profile, an action or a menu.
+ *
+ * Returns: %TRUE if the item is writable, %FALSE else.
+ */
+gboolean
+nact_window_is_writable_item( NactWindow *window, const NAObjectId *item )
+{
+ gboolean writable;
+ NAObjectItem *parent;
+
+ writable = FALSE;
+
+ g_return_val_if_fail( NACT_IS_WINDOW( window ), writable );
+ g_return_val_if_fail( NA_IS_OBJECT_ID( item ), writable );
+
+ if( !window->private->dispose_has_run ){
+
+ parent = NA_IS_OBJECT_PROFILE( item ) ? na_object_get_parent( item ) : NA_OBJECT_ITEM( item );
+
+ writable =
+ !na_object_is_readonly( parent ) &&
+ nact_window_is_writable_provider( window, parent );
+ }
+
+ return( writable );
+}
+
+/**
* nact_window_is_writable_provider:
* @window: this #NactWindow instance.
* @item: the current item.
@@ -204,8 +234,8 @@ nact_window_get_pivot( NactWindow *window )
* Returns: %TRUE if the item's provider is willing to write, %FALSE else.
*
* If the provider item has not yet any provider, i.e. has never been
- * saved elsewhere, then we return %FALSE, assuming that we eventually
- * find at least one willing-to-write provider.
+ * saved elsewhere, then we test if we have at least one
+ * willing-to-write provider.
*/
gboolean
nact_window_is_writable_provider( NactWindow *window, const NAObjectItem *item )
diff --git a/nautilus-actions/nact/nact-window.h b/nautilus-actions/nact/nact-window.h
index f586d5b..08bd506 100644
--- a/nautilus-actions/nact/nact-window.h
+++ b/nautilus-actions/nact/nact-window.h
@@ -75,6 +75,7 @@ GType nact_window_get_type( void );
NAPivot *nact_window_get_pivot( NactWindow *window );
+gboolean nact_window_is_writable_item( NactWindow *window, const NAObjectId *item );
gboolean nact_window_is_writable_provider( NactWindow *window, const NAObjectItem *item );
gboolean nact_window_has_writable_providers( NactWindow *window );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]