[nautilus-actions] Review menu items sensitivity updates
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Review menu items sensitivity updates
- Date: Thu, 3 Feb 2011 00:51:05 +0000 (UTC)
commit 8671735146995dd1663b2d8c6e17475ebb490f31
Author: Pierre Wieser <pwieser trychlos org>
Date: Wed Feb 2 01:10:02 2011 +0100
Review menu items sensitivity updates
+ Writability status is computed once at load time (na_updater_load_items())
+ Menu items sensitivity indicators are computed at selection change
+ The IACTIONS_LIST_SIGNAL_LIST_COUNT_UPDATED is re-send on all_widgets_showed()
so that we are sure that NactMenubar has connected its callbacks.
ChangeLog | 27 ++++++
src/api/na-object-api.h | 3 +
src/api/na-object-item.h | 3 +
src/core/na-object-item.c | 98 ++++++++++++++++++++-
src/core/na-object.c | 6 +-
src/core/na-updater.c | 168 +++++++++++++++++++++++-------------
src/core/na-updater.h | 7 +-
src/nact/nact-application.c | 1 -
src/nact/nact-iactions-list-priv.c | 1 +
src/nact/nact-iactions-list.c | 10 ++
src/nact/nact-main-menubar-edit.c | 40 ++-------
src/nact/nact-main-menubar-file.c | 50 +----------
src/nact/nact-main-window.c | 13 ++-
src/nact/nact-menubar-priv.h | 9 ++-
src/nact/nact-menubar.c | 80 +++++++++++++++--
15 files changed, 346 insertions(+), 170 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 87d388b..b3dd06b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,32 @@
2011-02-01 Pierre Wieser <pwieser trychlos org>
+ Review menu items sensitivity updates
+
+ * src/api/na-object-api.h
+ (na_object_is_finally_writable, na_object_set_writability_status): New macros.
+
+ * src/api/na-object-item.h:
+ * src/core/na-object-item.c
+ (na_object_item_is_finally_writable, na_object_item_set_writability_status):
+ New functions.
+
+ * src/core/na-updater.c:
+ * src/core/na-updater.h (na_updater_load_items): New function.
+
+ * src/nact/nact-application.c (appli_main_window_new):
+ * /src/nact/nact-main-window.c (on_base_initialize_base_window):
+ No more load items when instanciating the main window, but when
+ initializing it.
+
+ * src/nact/nact-iactions-list.c (nact_iactions_list_all_widgets_showed):
+ Send the IACTIONS_LIST_SIGNAL_LIST_COUNT_UPDATED message to update the menubar.
+
+ * src/nact/nact-main-menubar-edit.c (nact_main_menubar_edit_on_update_sensitivities):
+ * src/nact/nact-main-menubar-file.c (nact_main_menubar_file_on_update_sensitivities):
+ * src/nact/nact-menubar-priv.h:
+ * src/nact/nact-menubar.c (on_iactions_list_selection_changed):
+ Rely on indicators pre-computed on selection changes.
+
* src/nact/nact-window.c:
* src/nact/nact-window.h (nact_window_has_writable_providers):
Removed function.
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index db2fef9..1c3e3c3 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -135,6 +135,9 @@ G_BEGIN_DECLS
#define na_object_unref_items( tree ) na_object_item_unref_items( tree )
#define na_object_unref_selected_items( tree ) na_object_item_unref_items_rec( tree )
+#define na_object_is_finally_writable( obj, r ) na_object_item_is_finally_writable( NA_OBJECT_ITEM( obj ), ( r ))
+#define na_object_set_writability_status( obj, w, r ) na_object_item_set_writability_status( NA_OBJECT_ITEM( obj ), ( w ), ( r ))
+
/* NAObjectAction
*/
#define na_object_get_version( obj ) (( gchar * ) na_ifactory_object_get_as_void( NA_IFACTORY_OBJECT( obj ), NAFO_DATA_VERSION ))
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index 82ec29e..495991f 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -110,6 +110,9 @@ void na_object_item_unref_items_rec( GList *items );
void na_object_item_deals_with_version ( NAObjectItem *item );
void na_object_item_rebuild_children_slist( NAObjectItem *item );
+gboolean na_object_item_is_finally_writable ( const NAObjectItem *item, guint *reason );
+void na_object_item_set_writability_status( NAObjectItem *item, gboolean writable, guint reason );
+
G_END_DECLS
#endif /* __NAUTILUS_ACTIONS_API_NA_OBJECT_ITEM_H__ */
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index 12f2319..5b365bd 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -57,9 +57,16 @@ struct _NAObjectItemPrivate {
/* dynamically set when reading the item from the I/O storage
* subsystem; may be reset from FALSE to TRUE if a write operation
* has returned an error.
- * defaults to FALSE for snew, not yet written to a provider, item
+ * defaults to FALSE for new, not yet written to a provider, item
*/
gboolean readonly;
+
+ /* set at load time
+ * takes into account the above 'readonly' status as well as the i/o
+ * provider writability status - does not consider the level-zero case
+ */
+ gboolean writable;
+ guint reason;
};
static NAObjectIdClass *st_parent_class = NULL;
@@ -71,6 +78,7 @@ static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static void object_copy( NAObject*target, const NAObject *source, gboolean recursive );
+static void object_dump( const NAObject *object );
static gchar *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
@@ -130,7 +138,7 @@ class_init( NAObjectItemClass *klass )
object_class->finalize = instance_finalize;
naobject_class = NA_OBJECT_CLASS( klass );
- naobject_class->dump = NULL;
+ naobject_class->dump = object_dump;
naobject_class->copy = object_copy;
naobject_class->are_equal = NULL;
naobject_class->is_valid = NULL;
@@ -202,15 +210,18 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
{
static const gchar *thisfn = "na_object_item_object_copy";
void *provider;
+ NAObjectItem *dest, *src;
g_return_if_fail( NA_IS_OBJECT_ITEM( target ));
g_return_if_fail( NA_IS_OBJECT_ITEM( source ));
- if( !NA_OBJECT_ITEM( target )->private->dispose_has_run &&
- !NA_OBJECT_ITEM( source )->private->dispose_has_run ){
+ dest = NA_OBJECT_ITEM( target );
+ src = NA_OBJECT_ITEM( source );
+
+ if( !dest->private->dispose_has_run && !src->private->dispose_has_run ){
if( recursive ){
- copy_children( NA_OBJECT_ITEM( target ), NA_OBJECT_ITEM( source ));
+ copy_children( dest, src );
}
provider = na_object_get_provider( source );
@@ -226,6 +237,29 @@ object_copy( NAObject *target, const NAObject *source, gboolean recursive )
na_io_provider_duplicate_data( NA_IO_PROVIDER( provider ), NA_OBJECT_ITEM( target ), NA_OBJECT_ITEM( source ), NULL );
}
}
+
+ dest->private->readonly = src->private->readonly;
+ dest->private->writable = src->private->writable;
+ dest->private->reason = src->private->reason;
+ }
+}
+
+static void
+object_dump( const NAObject *object )
+{
+ static const gchar *thisfn = "na_object_item_object_dump";
+ NAObjectItem *item;
+
+ g_return_if_fail( NA_IS_OBJECT_ITEM( object ));
+
+ item = NA_OBJECT_ITEM( object );
+
+ if( !item->private->dispose_has_run ){
+
+ g_debug( "%s: provider_data=%p", thisfn, ( void * ) item->private->provider_data );
+ g_debug( "%s: readonly=%s", thisfn, item->private->readonly ? "True":"False" );
+ g_debug( "%s: writable=%s", thisfn, item->private->writable ? "True":"False" );
+ g_debug( "%s: reason=%u", thisfn, item->private->reason );
}
}
@@ -813,3 +847,57 @@ copy_children( NAObjectItem *target, const NAObjectItem *source )
tgt_children = g_list_reverse( tgt_children );
na_object_set_items( target, tgt_children );
}
+
+/**
+ * na_object_item_is_finally_writable:
+ * @item: this #NAObjectItem -derived object.
+ * @reason: if not %NULL, a pointer to a guint which will hold the reason code.
+ *
+ * Returns: the writability status of the @item.
+ *
+ * Since: 3.1.0
+ */
+gboolean
+na_object_item_is_finally_writable( const NAObjectItem *item, guint *reason )
+{
+ gboolean writable;
+
+ if( reason ){
+ *reason = NA_IIO_PROVIDER_STATUS_UNDETERMINED;
+ }
+ g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
+
+ writable = FALSE;
+
+ if( !item->private->dispose_has_run ){
+
+ writable = item->private->writable;
+ if( reason ){
+ *reason = item->private->reason;
+ }
+ }
+
+ return( writable );
+}
+
+/**
+ * na_object_item_set_writability_status:
+ * @item: this #NAObjectItem -derived object.
+ * @writable: whether the item is finally writable.
+ * @reason: the reason code.
+ *
+ * Set the writability status of the @item.
+ *
+ * Since: 3.1.0
+ */
+void
+na_object_item_set_writability_status( NAObjectItem *item, gboolean writable, guint reason )
+{
+ g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
+
+ if( !item->private->dispose_has_run ){
+
+ item->private->writable = writable;
+ item->private->reason = reason;
+ }
+}
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 1e61045..5c73b11 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -538,7 +538,7 @@ object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data )
void
na_object_object_dump( const NAObject *object )
{
- GList *childs, *ic;
+ GList *children, *ic;
g_return_if_fail( NA_IS_OBJECT( object ));
@@ -548,8 +548,8 @@ na_object_object_dump( const NAObject *object )
if( NA_IS_OBJECT_ITEM( object )){
- childs = na_object_get_items( object );
- for( ic = childs ; ic ; ic = ic->next ){
+ children = na_object_get_items( object );
+ for( ic = children ; ic ; ic = ic->next ){
na_object_dump( ic->data );
}
diff --git a/src/core/na-updater.c b/src/core/na-updater.c
index 5bd0d55..a86d1fc 100644
--- a/src/core/na-updater.c
+++ b/src/core/na-updater.c
@@ -62,6 +62,7 @@ static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static gboolean is_level_zero_writable( const NAUpdater *updater );
+static void set_writability_status( NAObjectItem *item, const NAUpdater *updater );
GType
na_updater_get_type( void )
@@ -199,6 +200,84 @@ na_updater_new( void )
}
/*
+ * na_updater_is_item_writable:
+ * @updater: this #NAUpdater object.
+ * @item: the #NAObjectItem to be written.
+ * @reason: the reason for why @item may not be writable.
+ *
+ * Returns: %TRUE: if @item is actually writable, given the current
+ * status of its provider, %FALSE else.
+ *
+ * For an item be actually writable:
+ * - the item must not be itself in a read-only store, which has been
+ * checked when first reading it
+ * - the provider must be willing (resp. able) to write
+ * - the provider must not has been locked by the admin, nor by the user
+ *
+ * Note that this function does not consider if the item is to be written
+ * at the level zero of the tree, which may be a mandatory preference
+ * (i.e. locked by an admin), and so make this item unwritable.
+ */
+gboolean
+na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item, guint *reason )
+{
+ gboolean writable;
+ NAIOProvider *provider;
+
+ g_return_val_if_fail( NA_IS_UPDATER( updater ), FALSE );
+ g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
+
+ writable = FALSE;
+ if( reason ){
+ *reason = NA_IIO_PROVIDER_STATUS_UNDETERMINED;
+ }
+
+ if( !updater->private->dispose_has_run ){
+
+ writable = TRUE;
+ if( reason ){
+ *reason = NA_IIO_PROVIDER_STATUS_WRITABLE;
+ }
+
+ /* Writability status of the item has been determined at load time
+ * (cf. e.g. io-desktop/nadp-reader.c:read_done_item_is_writable()).
+ * Though I'm plenty conscious that this status is subject to many
+ * changes during the life of the item (e.g. by modifying permissions
+ * on the underlying store), it is just simpler to not reevaluate
+ * this status each time we need it
+ */
+ if( writable ){
+ if( na_object_is_readonly( item )){
+ writable = FALSE;
+ if( reason ){
+ *reason = NA_IIO_PROVIDER_STATUS_ITEM_READONLY;
+ }
+ }
+ }
+
+ if( writable ){
+ provider = na_object_get_provider( item );
+ if( provider ){
+ writable = na_io_provider_is_finally_writable( provider, reason );
+
+ /* the get_writable_provider() api already takes above checks
+ */
+ } else {
+ provider = na_io_provider_find_writable_io_provider( NA_PIVOT( updater ));
+ if( !provider ){
+ writable = FALSE;
+ if( reason ){
+ *reason = NA_IIO_PROVIDER_STATUS_NO_PROVIDER_FOUND;
+ }
+ }
+ }
+ }
+ }
+
+ return( writable );
+}
+
+/*
* na_updater_is_level_zero_writable:
* @updater: the #NAUpdater application object.
*
@@ -338,81 +417,48 @@ na_updater_remove_item( NAUpdater *updater, NAObject *item )
}
/*
- * na_updater_is_item_writable:
- * @updater: this #NAUpdater object.
- * @item: the #NAObjectItem to be written.
- * @reason: the reason for why @item may not be writable.
+ * na_updater_load_items:
+ * @updater: this #NAUpdater instance.
*
- * Returns: %TRUE: if @item is actually writable, given the current
- * status of its provider, %FALSE else.
+ * Loads the items, updating simultaneously their writability status.
*
- * For an item be actually writable:
- * - the item must not be itself in a read-only store, which has been
- * checked when first reading it
- * - the provider must be willing (resp. able) to write
- * - the provider must not has been locked by the admin, nor by the user
+ * Returns: a pointer (not a ref) on the loaded tree.
*
- * Note that this function does not consider if the item is to be written
- * at the level zero of the tree, which may be a mandatory preference
- * (i.e. locked by an admin), and so make this item unwritable.
+ * Since: 3.1.0
*/
-gboolean
-na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item, guint *reason )
+GList *
+na_updater_load_items( NAUpdater *updater )
{
- gboolean writable;
- NAIOProvider *provider;
+ GList *tree;
- g_return_val_if_fail( NA_IS_UPDATER( updater ), FALSE );
- g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), FALSE );
+ g_return_val_if_fail( NA_IS_UPDATER( updater ), NULL );
- writable = FALSE;
- if( reason ){
- *reason = NA_IIO_PROVIDER_STATUS_UNDETERMINED;
- }
+ tree = NULL;
if( !updater->private->dispose_has_run ){
- writable = TRUE;
- if( reason ){
- *reason = NA_IIO_PROVIDER_STATUS_WRITABLE;
- }
+ na_pivot_load_items( NA_PIVOT( updater ));
+ tree = na_pivot_get_items( NA_PIVOT( updater ));
+ g_list_foreach( tree, ( GFunc ) set_writability_status, ( gpointer ) updater );
+ }
- /* Writability status of the item has been determined at load time
- * (cf. e.g. io-desktop/nadp-reader.c:read_done_item_is_writable()).
- * Though I'm plenty conscious that this status is subject to many
- * changes during the life of the item (e.g. by modifying permissions
- * on the underlying store), it is just simpler to not reevaluate
- * this status each time we need it
- */
- if( writable ){
- if( na_object_is_readonly( item )){
- writable = FALSE;
- if( reason ){
- *reason = NA_IIO_PROVIDER_STATUS_ITEM_READONLY;
- }
- }
- }
+ return( tree );
+}
- if( writable ){
- provider = na_object_get_provider( item );
- if( provider ){
- writable = na_io_provider_is_finally_writable( provider, reason );
+static void
+set_writability_status( NAObjectItem *item, const NAUpdater *updater )
+{
+ gboolean writable;
+ guint reason;
+ GList *children;
- /* the get_writable_provider() api already takes above checks
- */
- } else {
- provider = na_io_provider_find_writable_io_provider( NA_PIVOT( updater ));
- if( !provider ){
- writable = FALSE;
- if( reason ){
- *reason = NA_IIO_PROVIDER_STATUS_NO_PROVIDER_FOUND;
- }
- }
- }
- }
- }
+ writable = na_updater_is_item_writable( updater, item, &reason );
+ na_object_set_writability_status( item, writable, reason );
- return( writable );
+ if( NA_IS_OBJECT_MENU( item )){
+ children = na_object_get_items( item );
+ g_list_foreach( children, ( GFunc ) set_writability_status, ( gpointer ) updater );
+ }
}
/*
diff --git a/src/core/na-updater.h b/src/core/na-updater.h
index 534a7c1..0c1bb44 100644
--- a/src/core/na-updater.h
+++ b/src/core/na-updater.h
@@ -74,6 +74,7 @@ NAUpdater *na_updater_new( void );
/* writability status
*/
+gboolean na_updater_is_item_writable ( const NAUpdater *updater, const NAObjectItem *item, guint *reason );
gboolean na_updater_is_level_zero_writable( const NAUpdater *updater );
/* update the tree in memory
@@ -84,9 +85,9 @@ void na_updater_remove_item( NAUpdater *updater, NAObject *item );
/* read from / write to the physical storage subsystem
*/
-gboolean na_updater_is_item_writable( const NAUpdater *updater, const NAObjectItem *item, guint *reason );
-guint na_updater_write_item ( const NAUpdater *updater, NAObjectItem *item, GSList **messages );
-guint na_updater_delete_item ( const NAUpdater *updater, const NAObjectItem *item, GSList **messages );
+GList *na_updater_load_items ( NAUpdater *updater );
+guint na_updater_write_item ( const NAUpdater *updater, NAObjectItem *item, GSList **messages );
+guint na_updater_delete_item( const NAUpdater *updater, const NAObjectItem *item, GSList **messages );
G_END_DECLS
diff --git a/src/nact/nact-application.c b/src/nact/nact-application.c
index d7c4d54..15bf835 100644
--- a/src/nact/nact-application.c
+++ b/src/nact/nact-application.c
@@ -349,7 +349,6 @@ appli_main_window_new( const BaseApplication *application, int *code )
appli->private->updater = na_updater_new();
na_pivot_set_loadable( NA_PIVOT( appli->private->updater ), PIVOT_LOAD_ALL );
- na_pivot_load_items( NA_PIVOT( appli->private->updater ));
main_window = nact_main_window_new( appli );
diff --git a/src/nact/nact-iactions-list-priv.c b/src/nact/nact-iactions-list-priv.c
index eaadabf..dc63960 100644
--- a/src/nact/nact-iactions-list-priv.c
+++ b/src/nact/nact-iactions-list-priv.c
@@ -86,6 +86,7 @@ nact_iactions_list_priv_get_instance_data( NactIActionsList *instance )
void
nact_iactions_list_priv_send_list_count_updated_signal( NactIActionsList *instance, IActionsListInstanceData *ialid )
{
+ g_debug( "nact_iactions_list_priv_send_list_count_updated_signal: emitting signal %s", IACTIONS_LIST_SIGNAL_LIST_COUNT_UPDATED );
g_signal_emit_by_name( instance,
IACTIONS_LIST_SIGNAL_LIST_COUNT_UPDATED,
ialid->menus, ialid->actions, ialid->profiles );
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index f87fdef..4c36153 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -509,12 +509,21 @@ void
nact_iactions_list_all_widgets_showed( NactIActionsList *instance )
{
static const gchar *thisfn = "nact_iactions_list_all_widgets_showed";
+ gboolean profiles_are_displayed;
+ IActionsListInstanceData *ialid;
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
if( st_iactions_list_initialized && !st_iactions_list_finalized ){
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
+ profiles_are_displayed = are_profiles_displayed( instance, ialid );
+
+ if( profiles_are_displayed ){
+ nact_iactions_list_priv_send_list_count_updated_signal( instance, ialid );
+ }
+
nact_iactions_list_bis_select_first_row( instance );
}
}
@@ -669,6 +678,7 @@ nact_iactions_list_fill( NactIActionsList *instance, GList *items )
ialid = nact_iactions_list_priv_get_instance_data( instance );
profiles_are_displayed = are_profiles_displayed( instance, ialid );
+ g_debug( "%s: profiles_are_displayed:%s", thisfn, profiles_are_displayed ? "True":"False" );
ialid->selection_changed_allowed = FALSE;
nact_tree_model_fill( model, items, profiles_are_displayed );
diff --git a/src/nact/nact-main-menubar-edit.c b/src/nact/nact-main-menubar-edit.c
index 76fc766..d8bbe9d 100644
--- a/src/nact/nact-main-menubar-edit.c
+++ b/src/nact/nact-main-menubar-edit.c
@@ -69,34 +69,20 @@ nact_main_menubar_edit_on_update_sensitivities( NactMenubar *bar )
gboolean paste_into_enabled;
gboolean duplicate_enabled;
gboolean delete_enabled;
- GList *is;
NAObject *parent_item;
NAObject *selected_action;
NAObject *selected_item;
- gboolean are_parents_writable;
gboolean is_clipboard_empty;
is_clipboard_empty = ( bar->private->clipboard_menus + bar->private->clipboard_actions + bar->private->clipboard_profiles == 0 );
/* cut requires a non-empty selection
+ * and that the selection is writable
* and that all parents are writable (as implies a delete operation)
*/
cut_enabled = bar->private->treeview_has_focus || bar->private->popup_handler;
cut_enabled &= bar->private->count_selected > 0;
- are_parents_writable = TRUE;
- for( is = bar->private->selected_items ; is ; is = is->next ){
- parent_item = ( NAObject * ) na_object_get_parent( is->data );
- if( parent_item ){
- if( !na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( parent_item ), NULL )){
- are_parents_writable = FALSE;
- break;
- }
- } else if( !bar->private->is_level_zero_writable ){
- are_parents_writable = FALSE;
- break;
- }
- }
- cut_enabled &= are_parents_writable;
+ cut_enabled &= bar->private->are_parents_writable;
nact_menubar_enable_item( bar, "CutItem", cut_enabled );
/* copy only requires a non-empty selection */
@@ -119,25 +105,11 @@ nact_main_menubar_edit_on_update_sensitivities( NactMenubar *bar )
paste_enabled &= bar->private->count_selected <= 1;
if( bar->private->clipboard_profiles ){
paste_enabled &= bar->private->count_selected == 1;
- if( paste_enabled ){
- selected_action = NA_OBJECT(
- NA_IS_OBJECT_PROFILE( bar->private->selected_items->data )
- ? na_object_get_parent( bar->private->selected_items->data )
- : bar->private->selected_items->data );
- paste_enabled &= NA_IS_OBJECT_ACTION( selected_action );
- paste_enabled &= na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( selected_action ), NULL );
- }
+ paste_enabled &= bar->private->is_action_writable;
} else {
paste_enabled &= bar->private->has_writable_providers;
if( bar->private->count_selected ){
- selected_item = NA_OBJECT( bar->private->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
- ? na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( parent_item ), NULL )
- : bar->private->is_level_zero_writable;
- }
+ paste_enabled &= bar->private->is_parent_writable;
} else {
paste_enabled &= bar->private->is_level_zero_writable;
}
@@ -162,7 +134,7 @@ nact_main_menubar_edit_on_update_sensitivities( NactMenubar *bar )
if( paste_into_enabled ){
selected_action = NA_OBJECT( bar->private->selected_items->data );
paste_into_enabled &= NA_IS_OBJECT_ACTION( selected_action );
- paste_into_enabled &= na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( selected_action ), NULL );
+ paste_into_enabled &= na_object_is_finally_writable( selected_action, NULL );
}
} else {
paste_into_enabled &= bar->private->has_writable_providers;
@@ -172,7 +144,7 @@ nact_main_menubar_edit_on_update_sensitivities( NactMenubar *bar )
if( paste_into_enabled ){
parent_item = ( NAObject * ) na_object_get_parent( selected_item );
paste_into_enabled &= parent_item
- ? na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( parent_item ), NULL )
+ ? na_object_is_finally_writable( parent_item, NULL )
: bar->private->is_level_zero_writable;
}
} else {
diff --git a/src/nact/nact-main-menubar-file.c b/src/nact/nact-main-menubar-file.c
index c2e37bb..0d0c850 100644
--- a/src/nact/nact-main-menubar-file.c
+++ b/src/nact/nact-main-menubar-file.c
@@ -75,25 +75,7 @@ nact_main_menubar_file_on_update_sensitivities( NactMenubar *bar )
{
static const gchar *thisfn = "nact_main_menubar_file_on_update_sensitivities";
gboolean new_item_enabled;
- gboolean new_profile_enabled;
- NAObject *first_parent;
- NAObject *selected_action;
- NAObject *parent_item;
- gboolean is_first_parent_writable;
gboolean has_modified_items;
- GList *is;
- NactApplication *application;
- NAUpdater *updater;
-
- application = NACT_APPLICATION( base_window_get_application( bar->private->window ));
- updater = nact_application_get_updater( application );
-
- first_parent = bar->private->selected_items && g_list_length( bar->private->selected_items )
- ? ( NAObject * ) na_object_get_parent( bar->private->selected_items->data )
- : NULL;
- is_first_parent_writable = first_parent
- ? na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( first_parent ), NULL )
- : bar->private->is_level_zero_writable;
has_modified_items = nact_main_window_has_modified_items( NACT_MAIN_WINDOW( bar->private->window ));
g_debug( "%s: has_modified_items=%s", thisfn, has_modified_items ? "True":"False" );
@@ -103,7 +85,7 @@ nact_main_menubar_file_on_update_sensitivities( NactMenubar *bar )
* parent of the first selected row must be writable
* we must have at least one writable provider
*/
- new_item_enabled = is_first_parent_writable && bar->private->has_writable_providers;
+ new_item_enabled = bar->private->is_parent_writable && bar->private->has_writable_providers;
nact_menubar_enable_item( bar, "NewMenuItem", new_item_enabled );
nact_menubar_enable_item( bar, "NewActionItem", new_item_enabled );
@@ -111,36 +93,8 @@ nact_main_menubar_file_on_update_sensitivities( NactMenubar *bar )
* 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 = bar->private->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;
- }
- }
- }
nact_menubar_enable_item( bar, "NewProfileItem",
- new_profile_enabled &&
- selected_action != NULL &&
- na_updater_is_item_writable( bar->private->updater, NA_OBJECT_ITEM( selected_action ), NULL ));
+ bar->private->enable_new_profile && bar->private->is_action_writable );
/* save enabled if at least one item has been modified
* or level-zero has been resorted and is writable
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index db0c161..8ee2f64 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -880,9 +880,6 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
base_window_signal_connect( BASE_WINDOW( window ),
G_OBJECT( window ), IACTIONS_LIST_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_iactions_list_selection_changed ));
- tree = na_pivot_get_items( NA_PIVOT( updater ));
- g_debug( "%s: pivot_tree=%p", thisfn, ( void * ) tree );
-
nact_iaction_tab_runtime_init_toplevel( NACT_IACTION_TAB( window ));
nact_icommand_tab_runtime_init_toplevel( NACT_ICOMMAND_TAB( window ));
nact_ibasenames_tab_runtime_init_toplevel( NACT_IBASENAMES_TAB( window ));
@@ -898,7 +895,12 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
/* fill the IActionsList at last so that all signals are connected
*/
+ tree = na_updater_load_items( updater );
+ g_debug( "%s: pivot_tree=%p", thisfn, ( void * ) tree );
nact_iactions_list_runtime_init_toplevel( NACT_IACTIONS_LIST( window ), tree );
+
+ /* other initializations
+ */
nact_sort_buttons_runtime_init( window );
/* this to update the title when an item is modified
@@ -1570,6 +1572,7 @@ reload( NactMainWindow *window )
static const gchar *thisfn = "nact_main_window_reload";
NactApplication *application;
NAUpdater *updater;
+ GList *tree;
g_debug( "%s: window=%p", thisfn, ( void * ) window );
g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
@@ -1584,8 +1587,8 @@ reload( NactMainWindow *window )
application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
updater = nact_application_get_updater( application );
- na_pivot_load_items( NA_PIVOT( updater ));
- nact_iactions_list_fill( NACT_IACTIONS_LIST( window ), na_pivot_get_items( NA_PIVOT( updater )));
+ tree = na_updater_load_items( updater );
+ nact_iactions_list_fill( NACT_IACTIONS_LIST( window ), tree );
nact_iactions_list_bis_select_first_row( NACT_IACTIONS_LIST( window ));
}
}
diff --git a/src/nact/nact-menubar-priv.h b/src/nact/nact-menubar-priv.h
index 9d35738..2c3acee 100644
--- a/src/nact/nact-menubar-priv.h
+++ b/src/nact/nact-menubar-priv.h
@@ -62,7 +62,13 @@ struct _NactMenubarPrivate {
gboolean is_level_zero_writable;
gboolean has_writable_providers;
- gboolean is_parent_writable;
+ /* set when the selection changes
+ */
+ guint count_selected;
+ gboolean is_parent_writable; /* new menu/new action/paste menu or action */
+ gboolean enable_new_profile; /* new profile/paste a profile */
+ gboolean is_action_writable;
+ gboolean are_parents_writable; /* cut/delete */
/* *** */
gint selected_menus;
@@ -80,7 +86,6 @@ struct _NactMenubarPrivate {
gboolean level_zero_order_changed;
gulong popup_handler;
- guint count_selected;
GList *selected_items;
/* *** */
};
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 52a5481..31d5acc 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -689,29 +689,93 @@ on_iactions_list_count_updated( NactMainWindow *window, gint menus, gint actions
/*
* when the selection changes in the tree view, see what is selected
- * - check if the parent of the first selected item is writable
- * (File:New menu/New action)
*/
static void
on_iactions_list_selection_changed( NactMainWindow *window, GList *selected )
{
+ static const gchar *thisfn = "nact_menubar_on_iactions_list_selection_changed";
NAObject *first;
+ NAObject *selected_action;
+ GList *is;
BAR_WINDOW_VOID( window );
- g_debug( "nact_main_menubar_on_iactions_list_selection_changed: selected=%p (count=%d)",
- ( void * ) selected, g_list_length( selected ));
+ g_debug( "%s: selected=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
+
+ bar->private->count_selected = g_list_length( selected );
if( selected ){
+ /* check if the parent of the first selected item is writable
+ * (File: New menu/New action)
+ * (Edit: Paste menu or action)
+ */
first = ( NAObject *) selected->data;
if( first ){
if( NA_IS_OBJECT_PROFILE( first )){
first = NA_OBJECT( na_object_get_parent( first ));
}
- first = NA_OBJECT( na_object_get_parent( first ));
-#if 0
- bar->private->is_parent_writable = first ? na_object_is_writable( first ) : is_level_zero_writable();
-#endif
+ first = ( NAObject * ) na_object_get_parent( first );
+ bar->private->is_parent_writable = first ? na_object_is_finally_writable( first, NULL ) : bar->private->is_level_zero_writable;
+ }
+ /* check is only an action is selected, or only profile(s) of a same action
+ * (File: New profile)
+ * (Edit: Paste a profile)
+ */
+ bar->private->enable_new_profile = TRUE;
+ selected_action = NULL;
+ for( is = selected ; is ; is = is->next ){
+
+ if( NA_IS_OBJECT_MENU( is->data )){
+ bar->private->enable_new_profile = FALSE;
+ break;
+
+ } else if( NA_IS_OBJECT_ACTION( is->data )){
+ if( !selected_action ){
+ selected_action = NA_OBJECT( is->data );
+ } else {
+ bar->private->enable_new_profile = FALSE;
+ break;
+ }
+
+ } else if( NA_IS_OBJECT_PROFILE( is->data )){
+ first = NA_OBJECT( na_object_get_parent( is->data ));
+ if( !selected_action ){
+ selected_action = first;
+ } else if( selected_action != first ){
+ bar->private->enable_new_profile = FALSE;
+ break;
+ }
+ }
+ }
+ if( !selected_action ){
+ bar->private->enable_new_profile = FALSE;
+ } else {
+ bar->private->is_action_writable = na_object_is_finally_writable( selected_action, NULL );
+ }
+ /* check that selection is not empty and that each selected item is writable
+ * and that all parents are writable
+ * if some selection is at level zero, then it must be writable
+ * (Edit: Cut/Delete)
+ */
+ bar->private->are_parents_writable = TRUE;
+ for( is = selected ; is ; is = is->next ){
+ gchar *label = na_object_get_label( is->data );
+ gboolean writable = na_object_is_finally_writable( is->data, NULL );
+ g_debug( "%s: label=%s, writable=%s", thisfn, label, writable ? "True":"False" );
+ if( !na_object_is_finally_writable( is->data, NULL )){
+ bar->private->are_parents_writable = FALSE;
+ break;
+ }
+ first = ( NAObject * ) na_object_get_parent( is->data );
+ if( first ){
+ if( !na_object_is_finally_writable( first, NULL )){
+ bar->private->are_parents_writable = FALSE;
+ break;
+ }
+ } else if( !bar->private->is_level_zero_writable ){
+ bar->private->are_parents_writable = FALSE;
+ break;
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]