[nautilus-actions] NactTreeIEditable: inserting new items
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] NactTreeIEditable: inserting new items
- Date: Fri, 11 Feb 2011 00:18:24 +0000 (UTC)
commit dd7f51ef0e0af5a5f1c8ea0eb5bf56782fd9273e
Author: Pierre Wieser <pwieser trychlos org>
Date: Fri Feb 4 22:41:06 2011 +0100
NactTreeIEditable: inserting new items
src/api/na-iduplicable.h | 2 +-
src/core/na-factory-object.c | 19 +-
src/core/na-iduplicable.c | 59 +-
src/core/na-object-profile.c | 7 +-
src/core/na-object.c | 21 +-
src/nact/nact-assistant-import.c | 11 +-
src/nact/nact-clipboard.c | 2 +-
src/nact/nact-iaction-tab.c | 15 +-
src/nact/nact-ibasenames-tab.c | 13 +-
src/nact/nact-icapabilities-tab.c | 13 +-
src/nact/nact-icommand-tab.c | 17 +-
src/nact/nact-ienvironment-tab.c | 16 +-
src/nact/nact-iexecution-tab.c | 11 +-
src/nact/nact-ifolders-tab.c | 13 +-
src/nact/nact-imimetypes-tab.c | 13 +-
src/nact/nact-iproperties-tab.c | 10 +-
src/nact/nact-ischemes-tab.c | 13 +-
src/nact/nact-main-window.c | 59 ++-
src/nact/nact-main-window.h | 3 +-
src/nact/nact-menubar.c | 142 ++--
src/nact/nact-tree-ieditable.c | 1425 ++++++++++++++++---------------------
src/nact/nact-tree-ieditable.h | 20 +-
src/nact/nact-tree-model-dnd.c | 16 +-
src/nact/nact-tree-model.c | 479 ++++++-------
src/nact/nact-tree-model.h | 26 +-
src/nact/nact-tree-view.c | 222 +++++--
src/nact/nact-tree-view.h | 3 +
27 files changed, 1271 insertions(+), 1379 deletions(-)
---
diff --git a/src/api/na-iduplicable.h b/src/api/na-iduplicable.h
index 70db6d7..61b5d47 100644
--- a/src/api/na-iduplicable.h
+++ b/src/api/na-iduplicable.h
@@ -184,7 +184,7 @@ typedef struct {
}
NAIDuplicableInterface;
-#define NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED "status-changed"
+#define NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED "iduplicable-status-changed"
GType na_iduplicable_get_type( void );
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index cc8ac09..79d0b7f 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -493,12 +493,15 @@ na_factory_object_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *
gboolean
na_factory_object_is_valid( const NAIFactoryObject *object )
{
+ static const gchar *thisfn = "na_factory_object_is_valid";
gboolean is_valid;
NADataGroup *groups;
GList *list, *iv;
g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), FALSE );
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
list = g_object_get_data( G_OBJECT( object ), NA_IFACTORY_OBJECT_PROP_DATA );
is_valid = TRUE;
@@ -855,15 +858,11 @@ na_factory_object_set_from_void( NAIFactoryObject *object, const gchar *name, co
static NADataGroup *
v_get_groups( const NAIFactoryObject *object )
{
- NADataGroup *groups;
-
- groups = NULL;
-
if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups ){
- groups = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups( object );
+ return( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->get_groups( object ));
}
- return( groups );
+ return( NULL );
}
static void
@@ -891,15 +890,11 @@ v_are_equal( const NAIFactoryObject *a, const NAIFactoryObject *b )
static gboolean
v_is_valid( const NAIFactoryObject *object )
{
- gboolean is_valid;
-
- is_valid = TRUE;
-
if( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid ){
- is_valid = NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object );
+ return( NA_IFACTORY_OBJECT_GET_INTERFACE( object )->is_valid( object ));
}
- return( is_valid );
+ return( FALSE );
}
static void
diff --git a/src/core/na-iduplicable.c b/src/core/na-iduplicable.c
index 66906e0..ef30b75 100644
--- a/src/core/na-iduplicable.c
+++ b/src/core/na-iduplicable.c
@@ -46,7 +46,6 @@ typedef struct {
NAIDuplicable *origin;
gboolean modified;
gboolean valid;
- gulong status_changed_handler_id;
}
DuplicableStr;
@@ -74,8 +73,8 @@ static gboolean v_is_valid( const NAIDuplicable *object );
static DuplicableStr *get_duplicable_str( const NAIDuplicable *object );
-static void status_changed_handler( NAIDuplicable *instance, gpointer user_data );
-static void propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data );
+static void on_status_changed_class_handler( NAIDuplicable *instance );
+static void propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal );
static void release_signal_consumers( GList *consumers );
GType
@@ -139,18 +138,25 @@ interface_base_init( NAIDuplicableInterface *klass )
*
* This signal is emitted by #NAIDuplicable when the modification
* or the validity status of an object has been modified.
+ *
+ * The default class handler propagates the signal to registered
+ * consumers.
+ *
+ * Signal args: None
+ *
+ * Handler prototype:
+ * void ( *handler )( NAIDuplicable *duplicable, gpointer user_data );
*/
- st_signals[ STATUS_CHANGED ] = g_signal_new(
+ st_signals[ STATUS_CHANGED ] = g_signal_new_class_handler(
NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
G_TYPE_OBJECT,
G_SIGNAL_RUN_LAST,
- 0, /* no default handler */
+ G_CALLBACK( on_status_changed_class_handler ),
NULL,
NULL,
- g_cclosure_marshal_VOID__POINTER,
+ g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
- 1,
- G_TYPE_POINTER );
+ 0 );
st_interface = klass;
@@ -194,10 +200,6 @@ na_iduplicable_dispose( const NAIDuplicable *object )
str = get_duplicable_str( object );
- if( g_signal_handler_is_connected(( gpointer ) object, str->status_changed_handler_id )){
- g_signal_handler_disconnect(( gpointer ) object, str->status_changed_handler_id );
- }
-
g_free( str );
}
}
@@ -331,7 +333,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
changed = FALSE;
if( str->origin ){
- g_debug( "%s: origin=%p (%s)", thisfn, ( void * ) str->origin, G_OBJECT_TYPE_NAME( str->origin ));
+ g_debug( "%s: vs. origin=%p (%s)", thisfn, ( void * ) str->origin, G_OBJECT_TYPE_NAME( str->origin ));
g_return_if_fail( NA_IS_IDUPLICABLE( str->origin ));
str->modified = !v_are_equal( str->origin, object );
@@ -362,7 +364,7 @@ na_iduplicable_check_status( const NAIDuplicable *object )
}
if( changed ){
- g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, object );
+ g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
}
#if 0
@@ -509,7 +511,7 @@ na_iduplicable_set_modified( NAIDuplicable *object, gboolean modified )
if( str->modified != modified ){
str->modified = modified;
- g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, object );
+ g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
}
}
}
@@ -565,20 +567,18 @@ na_iduplicable_register_consumer( GObject *consumer )
}
static void
-status_changed_handler( NAIDuplicable *instance, gpointer user_data )
+on_status_changed_class_handler( NAIDuplicable *instance )
{
- /*g_debug( "na_iduplicable_propagate_modified_changed: instance=%p (%s), user_data=%p (%s)",
- ( void * ) instance, G_OBJECT_TYPE_NAME( instance ),
- ( void * ) user_data, G_OBJECT_TYPE_NAME( user_data ));*/
+ /*
+ static const gchar *thisfn = "na_iduplicable_on_status_changed_class_handler";
+ g_debug( "%s: instance=%p (%s)", thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
+ */
- propagate_signal_to_consumers( NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED, instance, user_data );
+ propagate_signal_to_consumers( instance, NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED );
}
-/*
- * note that propagating the signal to consumers re-triggers
- */
static void
-propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpointer user_data )
+propagate_signal_to_consumers( NAIDuplicable *instance, const gchar *signal )
{
static const gchar *thisfn = "na_iduplicable_propagate_signals_to_consumers";
GList *ic;
@@ -586,11 +586,10 @@ propagate_signal_to_consumers( const gchar *signal, NAIDuplicable *instance, gpo
g_return_if_fail( st_interface );
if( st_initialized && !st_finalized ){
-
- g_debug( "%s: signal=%s, instance=%p, user_data=%p", thisfn, signal, ( void * ) instance, ( void * ) user_data );
+ g_debug( "%s: instance=%p, signal=%s", thisfn, ( void * ) instance, signal );
for( ic = st_interface->private->consumers ; ic ; ic = ic->next ){
- g_signal_emit_by_name( ic->data, signal, user_data );
+ g_signal_emit_by_name( ic->data, signal );
}
}
}
@@ -615,12 +614,6 @@ get_duplicable_str( const NAIDuplicable *object )
str->modified = FALSE;
str->valid = TRUE;
- str->status_changed_handler_id = g_signal_connect(
- G_OBJECT( object ),
- NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
- G_CALLBACK( status_changed_handler ),
- ( gpointer ) object );
-
g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_DATA_DUPLICABLE, str );
}
diff --git a/src/core/na-object-profile.c b/src/core/na-object-profile.c
index 618f775..53518d2 100644
--- a/src/core/na-object-profile.c
+++ b/src/core/na-object-profile.c
@@ -321,13 +321,12 @@ ifactory_object_get_groups( const NAIFactoryObject *instance )
static gboolean
ifactory_object_is_valid( const NAIFactoryObject *object )
{
- static const gchar *thisfn = "na_object_profile_ifactory_object_is_valid: object";
-
- g_debug( "%s: object=%p (%s)",
- thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+ static const gchar *thisfn = "na_object_profile_ifactory_object_is_valid";
g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
return( profile_is_valid( NA_OBJECT_PROFILE( object )));
}
diff --git a/src/core/na-object.c b/src/core/na-object.c
index ee29d07..dfe7a8e 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -266,6 +266,7 @@ iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source )
static gboolean
iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
{
+ static const gchar *thisfn = "na_object_iduplicable_are_equal";
gboolean are_equal;
HierarchyIter *str;
@@ -277,6 +278,8 @@ iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b )
if( !NA_OBJECT( a )->private->dispose_has_run &&
!NA_OBJECT( b )->private->dispose_has_run ){
+ g_debug( "%s: a=%p (%s), b=%p", thisfn, ( void * ) a, G_OBJECT_TYPE_NAME( a ), ( void * ) b );
+
if( NA_IS_IFACTORY_OBJECT( a )){
are_equal = na_factory_object_are_equal( NA_IFACTORY_OBJECT( a ), NA_IFACTORY_OBJECT( b ));
@@ -316,14 +319,12 @@ iduplicable_is_valid( const NAIDuplicable *object )
gboolean is_valid;
HierarchyIter *str;
- g_debug( "%s: object=%p (%s)",
- thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
-
g_return_val_if_fail( NA_IS_OBJECT( object ), FALSE );
is_valid = FALSE;
if( !NA_OBJECT( object )->private->dispose_has_run ){
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
if( NA_IS_IFACTORY_OBJECT( object )){
is_valid = na_factory_object_is_valid( NA_IFACTORY_OBJECT( object ));
@@ -374,7 +375,7 @@ iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter
* +- valid_status = v_is_valid( object ) -> interface <structfield>NAObjectClass::is_valid</structfield>
*
* Note that the recursivity is managed here, so that we can be sure
- * that edition status of childs is actually checked before those of
+ * that edition status of children is actually checked before those of
* the parent.
*
* Since: 2.30
@@ -383,22 +384,14 @@ void
na_object_object_check_status( const NAObject *object )
{
static const gchar *thisfn = "na_object_object_check_status";
- GList *children, *ic;
g_return_if_fail( NA_IS_OBJECT( object ));
if( !object->private->dispose_has_run ){
-
- g_debug( "%s: object=%p (%s)",
- thisfn,
- ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
if( NA_IS_OBJECT_ITEM( object )){
- children = na_object_get_items( object );
-
- for( ic = children ; ic ; ic = ic->next ){
- na_object_check_status( ic->data );
- }
+ g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_check_status, NULL );
}
na_iduplicable_check_status( NA_IDUPLICABLE( object ));
diff --git a/src/nact/nact-assistant-import.c b/src/nact/nact-assistant-import.c
index c8318fc..70bb083 100644
--- a/src/nact/nact-assistant-import.c
+++ b/src/nact/nact-assistant-import.c
@@ -44,6 +44,7 @@
#include "nact-application.h"
#include "nact-assistant-import.h"
#include "nact-main-window.h"
+#include "nact-tree-ieditable.h"
/* Import Assistant
*
@@ -639,6 +640,7 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
NAImporterResult *result;
NactApplication *application;
NAUpdater *updater;
+ NactTreeView *items_view;
g_return_if_fail( NACT_IS_ASSISTANT_IMPORT( wnd ));
@@ -676,11 +678,14 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
/* then insert the list
* assuring that actions will be inserted in the same order as uris
+ *
+ * the tree view (and its underlying tree store) takes a new reference
+ * on the inserted objects; the pointers so remain valid even after
+ * having released the imported_items list
*/
imported_items = g_list_reverse( imported_items );
-#if 0
- nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( main_window ), imported_items, NULL );
-#endif
+ items_view = nact_main_window_get_items_view( NACT_MAIN_WINDOW( main_window ));
+ nact_tree_ieditable_insert_items( NACT_TREE_IEDITABLE( items_view ), imported_items, NULL );
na_object_free_items( imported_items );
}
diff --git a/src/nact/nact-clipboard.c b/src/nact/nact-clipboard.c
index 2324db5..5832d59 100644
--- a/src/nact/nact-clipboard.c
+++ b/src/nact/nact-clipboard.c
@@ -525,7 +525,7 @@ export_rows( NactClipboard *clipboard, GList *rows, const gchar *dest_folder )
if( path ){
gtk_tree_model_get_iter( model, &iter, path );
gtk_tree_path_free( path );
- gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ gtk_tree_model_get( model, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
buffer = export_row_object( clipboard, object, dest_folder, &exported, first );
if( buffer && strlen( buffer )){
data = g_string_append( data, buffer );
diff --git a/src/nact/nact-iaction-tab.c b/src/nact/nact-iaction-tab.c
index 5a93388..62b6fe7 100644
--- a/src/nact/nact-iaction-tab.c
+++ b/src/nact/nact-iaction-tab.c
@@ -67,7 +67,7 @@ static void interface_base_init( NactIActionTabInterface *klass );
static void interface_base_finalize( NactIActionTabInterface *klass );
static void on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
-static void on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selected );
+static void on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpointer user_data );
static void on_target_selection_toggled( GtkToggleButton *button, NactIActionTab *instance );
static void on_target_location_toggled( GtkToggleButton *button, NactIActionTab *instance );
@@ -217,11 +217,8 @@ nact_iaction_tab_runtime_init_toplevel( NactIActionTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
base_window_signal_connect( BASE_WINDOW( instance ),
G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
@@ -364,9 +361,10 @@ on_tree_view_content_changed( NactIActionTab *instance, NactTreeView *view, NAOb
}
static void
-on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selected )
+on_main_selection_changed( NactIActionTab *instance, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_iaction_tab_on_tab_updatable_selection_changed";
+ static const gchar *thisfn = "nact_iaction_tab_on_main_selection_changed";
+ guint count_selected;
gboolean enable_tab;
NAObjectItem *item;
gboolean editable;
@@ -383,6 +381,7 @@ on_tab_updatable_selection_changed( NactIActionTab *instance, gint count_selecte
if( st_initialized && !st_finalized ){
+ count_selected = g_list_length( selected_items );
g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
enable_tab = ( count_selected == 1 );
diff --git a/src/nact/nact-ibasenames-tab.c b/src/nact/nact-ibasenames-tab.c
index b45c1c2..c966b30 100644
--- a/src/nact/nact-ibasenames-tab.c
+++ b/src/nact/nact-ibasenames-tab.c
@@ -57,7 +57,7 @@ static GType register_type( void );
static void interface_base_init( NactIBasenamesTabInterface *klass );
static void interface_base_finalize( NactIBasenamesTabInterface *klass );
-static void on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
static void on_matchcase_toggled( GtkToggleButton *button, BaseWindow *window );
static GSList *get_basenames( void *context );
@@ -186,11 +186,8 @@ nact_ibasenames_tab_runtime_init_toplevel( NactIBasenamesTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
button = base_window_get_widget( BASE_WINDOW( instance ), "BasenamesMatchcaseButton" );
base_window_signal_connect(
@@ -238,8 +235,9 @@ nact_ibasenames_tab_dispose( NactIBasenamesTab *instance )
}
static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
{
+ guint count_selected;
NAIContext *context;
gboolean editable;
GtkToggleButton *matchcase_button;
@@ -247,6 +245,7 @@ on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
if( st_initialized && !st_finalized ){
+ count_selected = g_list_length( selected_items );
context = nact_main_tab_get_context( NACT_MAIN_WINDOW( window ), &editable );
st_on_selection_change = TRUE;
diff --git a/src/nact/nact-icapabilities-tab.c b/src/nact/nact-icapabilities-tab.c
index 5126004..58fb475 100644
--- a/src/nact/nact-icapabilities-tab.c
+++ b/src/nact/nact-icapabilities-tab.c
@@ -57,7 +57,7 @@ static GType register_type( void );
static void interface_base_init( NactICapabilitiesTabInterface *klass );
static void interface_base_finalize( NactICapabilitiesTabInterface *klass );
-static void on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_selected );
+static void on_main_selection_changed( NactICapabilitiesTab *instance, GList *selected_items, gpointer user_data );
static void on_add_clicked( GtkButton *button, BaseWindow *window );
static GSList *get_capabilities( NAIContext *context );
@@ -172,11 +172,8 @@ nact_icapabilities_tab_runtime_init_toplevel( NactICapabilitiesTab *instance )
nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
}
}
@@ -209,9 +206,9 @@ nact_icapabilities_tab_dispose( NactICapabilitiesTab *instance )
}
static void
-on_tab_updatable_selection_changed( NactICapabilitiesTab *instance, gint count_selected )
+on_main_selection_changed( NactICapabilitiesTab *instance, GList *selected_items, gpointer user_data )
{
- nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, count_selected );
+ nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, g_list_length( selected_items ));
}
static void
diff --git a/src/nact/nact-icommand-tab.c b/src/nact/nact-icommand-tab.c
index b3feee7..0c52c18 100644
--- a/src/nact/nact-icommand-tab.c
+++ b/src/nact/nact-icommand-tab.c
@@ -71,7 +71,7 @@ static void interface_base_init( NactICommandTabInterface *klass );
static void interface_base_finalize( NactICommandTabInterface *klass );
static void on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAObject *object, gpointer user_data );
-static void on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_selected );
+static void on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data );
static GtkWidget *get_label_entry( NactICommandTab *instance );
static GtkButton *get_legend_button( NactICommandTab *instance );
@@ -261,11 +261,8 @@ nact_icommand_tab_runtime_init_toplevel( NactICommandTab *instance )
"clicked",
G_CALLBACK( on_wdir_browse ));
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
base_window_signal_connect( BASE_WINDOW( instance ),
G_OBJECT( instance ), TREE_SIGNAL_CONTENT_CHANGED, G_CALLBACK( on_tree_view_content_changed ));
@@ -337,9 +334,9 @@ on_tree_view_content_changed( NactICommandTab *instance, NactTreeView *view, NAO
}
static void
-on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_selected )
+on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_icommand_tab_on_tab_updatable_selection_changed";
+ static const gchar *thisfn = "nact_icommand_tab_on_main_selection_changed";
NAObjectProfile *profile;
gboolean editable;
gboolean enable_tab;
@@ -351,8 +348,8 @@ on_tab_updatable_selection_changed( NactICommandTab *instance, gint count_select
g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
if( st_initialized && !st_finalized ){
-
- g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+ g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+ thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
g_object_get(
G_OBJECT( instance ),
diff --git a/src/nact/nact-ienvironment-tab.c b/src/nact/nact-ienvironment-tab.c
index fa8de68..69e79d0 100644
--- a/src/nact/nact-ienvironment-tab.c
+++ b/src/nact/nact-ienvironment-tab.c
@@ -106,7 +106,7 @@ static GType register_type( void );
static void interface_base_init( NactIEnvironmentTabInterface *klass );
static void interface_base_finalize( NactIEnvironmentTabInterface *klass );
-static void on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected );
+static void on_main_selection_changed( NactIEnvironmentTab *instance, GList *selected_items, gpointer user_data );
static void on_selcount_ope_changed( GtkComboBox *combo, NactIEnvironmentTab *instance );
static void on_selcount_int_changed( GtkEntry *entry, NactIEnvironmentTab *instance );
@@ -245,11 +245,8 @@ nact_ienvironment_tab_runtime_init_toplevel( NactIEnvironmentTab *instance )
if( st_initialized && !st_finalized ){
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
base_window_signal_connect_by_name( BASE_WINDOW( instance ),
"SelectionCountSigneCombobox", "changed", G_CALLBACK( on_selcount_ope_changed ));
@@ -342,9 +339,9 @@ nact_ienvironment_tab_dispose( NactIEnvironmentTab *instance )
}
static void
-on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_selected )
+on_main_selection_changed( NactIEnvironmentTab *instance, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_ienvironment_tab_on_tab_updatable_selection_changed";
+ static const gchar *thisfn = "nact_ienvironment_tab_on_main_selection_changed";
NAIContext *context;
gboolean editable;
gboolean enable_tab;
@@ -361,7 +358,8 @@ on_tab_updatable_selection_changed( NactIEnvironmentTab *instance, gint count_se
g_return_if_fail( NACT_IS_IENVIRONMENT_TAB( instance ));
if( st_initialized && !st_finalized ){
- g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+ g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+ thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
diff --git a/src/nact/nact-iexecution-tab.c b/src/nact/nact-iexecution-tab.c
index 15b9fd9..7fa0064 100644
--- a/src/nact/nact-iexecution-tab.c
+++ b/src/nact/nact-iexecution-tab.c
@@ -54,7 +54,7 @@ static GType register_type( void );
static void interface_base_init( NactIExecutionTabInterface *klass );
static void interface_base_finalize( NactIExecutionTabInterface *klass );
-static void on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_selected );
+static void on_main_selection_changed( NactIExecutionTab *instance, GList *selected_items, gpointer user_data );
static void on_normal_mode_toggled( GtkToggleButton *togglebutton, NactIExecutionTab *instance );
static void on_terminal_mode_toggled( GtkToggleButton *togglebutton, NactIExecutionTab *instance );
@@ -168,7 +168,7 @@ nact_iexecution_tab_runtime_init_toplevel( NactIExecutionTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
base_window_signal_connect( BASE_WINDOW( instance ),
- G_OBJECT( instance ), MAIN_WINDOW_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tab_updatable_selection_changed ));
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
base_window_signal_connect_by_name( BASE_WINDOW( instance ),
"ExecutionModeNormal", "toggled", G_CALLBACK( on_normal_mode_toggled ));
@@ -224,9 +224,9 @@ nact_iexecution_tab_dispose( NactIExecutionTab *instance )
}
static void
-on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_selected )
+on_main_selection_changed( NactIExecutionTab *instance, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_iexecution_tab_on_tab_updatable_selection_changed";
+ static const gchar *thisfn = "nact_iexecution_tab_on_main_selection_changed";
NAObjectProfile *profile;
gboolean editable;
gboolean enable_tab;
@@ -240,7 +240,8 @@ on_tab_updatable_selection_changed( NactIExecutionTab *instance, gint count_sele
g_return_if_fail( NACT_IS_IEXECUTION_TAB( instance ));
if( st_initialized && !st_finalized ){
- g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
+ g_debug( "%s: instance=%p, selected_items=%p (count=%d)",
+ thisfn, ( void * ) instance, ( void * ) selected_items, g_list_length( selected_items ));
g_object_get(
G_OBJECT( instance ),
diff --git a/src/nact/nact-ifolders-tab.c b/src/nact/nact-ifolders-tab.c
index 17d180d..b3b9129 100644
--- a/src/nact/nact-ifolders-tab.c
+++ b/src/nact/nact-ifolders-tab.c
@@ -62,7 +62,7 @@ static GType register_type( void );
static void interface_base_init( NactIFoldersTabInterface *klass );
static void interface_base_finalize( NactIFoldersTabInterface *klass );
-static void on_tab_updatable_selection_changed( NactIFoldersTab *instance, gint count_selected );
+static void on_main_selection_changed( NactIFoldersTab *instance, GList *selected_items, gpointer user_data );
static void on_browse_folder_clicked( GtkButton *button, BaseWindow *window );
static GSList *get_folders( void *context );
@@ -178,11 +178,8 @@ nact_ifolders_tab_runtime_init_toplevel( NactIFoldersTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
@@ -224,12 +221,14 @@ nact_ifolders_tab_dispose( NactIFoldersTab *instance )
}
static void
-on_tab_updatable_selection_changed( NactIFoldersTab *instance, gint count_selected )
+on_main_selection_changed( NactIFoldersTab *instance, GList *selected_items, gpointer user_data )
{
+ guint count_selected;
NAIContext *context;
gboolean editable;
GtkWidget *button;
+ count_selected = g_list_length( selected_items );
nact_match_list_on_selection_changed( BASE_WINDOW( instance ), ITAB_NAME, count_selected );
context = nact_main_tab_get_context( NACT_MAIN_WINDOW( instance ), &editable );
diff --git a/src/nact/nact-imimetypes-tab.c b/src/nact/nact-imimetypes-tab.c
index aa0bbba..f29ea31 100644
--- a/src/nact/nact-imimetypes-tab.c
+++ b/src/nact/nact-imimetypes-tab.c
@@ -55,7 +55,7 @@ static GType register_type( void );
static void interface_base_init( NactIMimetypesTabInterface *klass );
static void interface_base_finalize( NactIMimetypesTabInterface *klass );
-static void on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
static GSList *get_mimetypes( void *context );
static void set_mimetypes( void *context, GSList *filters );
@@ -182,11 +182,8 @@ nact_imimetypes_tab_runtime_init_toplevel( NactIMimetypesTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
}
@@ -227,9 +224,9 @@ nact_imimetypes_tab_dispose( NactIMimetypesTab *instance )
}
static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
{
- nact_match_list_on_selection_changed( window, ITAB_NAME, count_selected );
+ nact_match_list_on_selection_changed( window, ITAB_NAME, g_list_length( selected_items ));
}
static GSList *
diff --git a/src/nact/nact-iproperties-tab.c b/src/nact/nact-iproperties-tab.c
index 385f244..3a37dbe 100644
--- a/src/nact/nact-iproperties-tab.c
+++ b/src/nact/nact-iproperties-tab.c
@@ -61,7 +61,7 @@ static GType register_type( void );
static void interface_base_init( NactIPropertiesTabInterface *klass );
static void interface_base_finalize( NactIPropertiesTabInterface *klass );
-static void on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_selected );
+static void on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items, gpointer user_data );
static void on_tab_updatable_provider_changed( NactIPropertiesTab *instance, NAObjectItem *item );
static GtkButton *get_enabled_button( NactIPropertiesTab *instance );
@@ -165,7 +165,7 @@ nact_iproperties_tab_runtime_init_toplevel( NactIPropertiesTab *instance )
g_debug( "%s: instance=%p (%s)", thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
base_window_signal_connect( BASE_WINDOW( instance ),
- G_OBJECT( instance ), MAIN_WINDOW_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tab_updatable_selection_changed ));
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
base_window_signal_connect( BASE_WINDOW( instance ),
G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, G_CALLBACK( on_tab_updatable_provider_changed ));
@@ -219,9 +219,10 @@ nact_iproperties_tab_dispose( NactIPropertiesTab *instance )
}
static void
-on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_selected )
+on_main_selection_changed( NactIPropertiesTab *instance, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_iproperties_tab_on_tab_updatable_selection_changed";
+ static const gchar *thisfn = "nact_iproperties_tab_on_main_selection_changed";
+ guint count_selected;
NAObjectItem *item;
gboolean editable;
gboolean enable_tab;
@@ -238,6 +239,7 @@ on_tab_updatable_selection_changed( NactIPropertiesTab *instance, gint count_sel
g_return_if_fail( NACT_IS_IPROPERTIES_TAB( instance ));
if( st_initialized && !st_finalized ){
+ count_selected = g_list_length( selected_items );
g_debug( "%s: instance=%p (%s), count_selected=%d",
thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), count_selected );
diff --git a/src/nact/nact-ischemes-tab.c b/src/nact/nact-ischemes-tab.c
index 85aab62..b716677 100644
--- a/src/nact/nact-ischemes-tab.c
+++ b/src/nact/nact-ischemes-tab.c
@@ -58,7 +58,7 @@ static GType register_type( void );
static void interface_base_init( NactISchemesTabInterface *klass );
static void interface_base_finalize( NactISchemesTabInterface *klass );
-static void on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected );
+static void on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data );
static void on_add_from_defaults( GtkButton *button, BaseWindow *window );
static GSList *get_schemes( void *context );
@@ -174,11 +174,8 @@ nact_ischemes_tab_runtime_init_toplevel( NactISchemesTab *instance )
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- MAIN_WINDOW_SIGNAL_SELECTION_CHANGED,
- G_CALLBACK( on_tab_updatable_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( instance ),
+ G_OBJECT( instance ), MAIN_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_main_selection_changed ));
nact_match_list_init_view( BASE_WINDOW( instance ), ITAB_NAME );
@@ -218,13 +215,13 @@ nact_ischemes_tab_dispose( NactISchemesTab *instance )
}
static void
-on_tab_updatable_selection_changed( BaseWindow *window, gint count_selected )
+on_main_selection_changed( BaseWindow *window, GList *selected_items, gpointer user_data )
{
NAIContext *context;
gboolean editable;
GtkWidget *button;
- nact_match_list_on_selection_changed( window, ITAB_NAME, count_selected );
+ nact_match_list_on_selection_changed( window, ITAB_NAME, g_list_length( selected_items ));
context = nact_main_tab_get_context( NACT_MAIN_WINDOW( window ), &editable );
button = base_window_get_widget( window, "AddFromDefaultButton" );
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index e6d1fb6..8bd6bc4 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -133,6 +133,7 @@ enum {
PROVIDER_CHANGED,
ITEM_UPDATED,
ORDER_CHANGED,
+ SELECTION_CHANGED,
LAST_SIGNAL
};
@@ -169,6 +170,7 @@ static void on_base_all_widgets_showed( NactMainWindow *window, gpointer use
static void on_tree_view_modified_count_changed( NactMainWindow *window, NactTreeView *view, guint count, gpointer user_data );
static void on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GList *selected_items, gpointer user_data );
+static void on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items );
static void raz_selection_properties( NactMainWindow *window );
static void setup_current_selection( NactMainWindow *window, NAObjectId *selected_row );
static void setup_dialog_title( NactMainWindow *window );
@@ -430,6 +432,35 @@ class_init( NactMainWindowClass *klass )
G_TYPE_NONE,
1,
G_TYPE_POINTER );
+
+ /**
+ * NactMainWindow::main-selection-changed:
+ *
+ * This signal is emitted on the window parent each time the selection
+ * has changed in the treeview, after having set the current item/profile/
+ * context properties.
+ *
+ * This way, we are sure that notebook edition tabs which required to
+ * have a current item/profile/context will have it, whenever they have
+ * connected to the 'selection-changed' signal.
+ *
+ * Signal args:
+ * - a #GList of currently selected #NAObjectItems.
+ *
+ * Handler prototype:
+ * void ( *handler )( BaseWindow *window, GList *selected, gpointer user_data );
+ */
+ st_signals[ SELECTION_CHANGED ] = g_signal_new_class_handler(
+ MAIN_SIGNAL_SELECTION_CHANGED,
+ G_TYPE_OBJECT,
+ G_SIGNAL_RUN_CLEANUP,
+ G_CALLBACK( on_selection_changed_cleanup_handler ),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER );
}
static void
@@ -623,6 +654,10 @@ instance_constructed( GObject *window )
if( !self->private->dispose_has_run ){
g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
+ /* first connect to BaseWindow signals
+ * so that convenience objects instanciated later will have this same signal
+ * triggered after the one of NactMainWindow
+ */
base_window_signal_connect( BASE_WINDOW( window ),
G_OBJECT( window ), BASE_SIGNAL_INITIALIZE_GTK, G_CALLBACK( on_base_initialize_gtk_toplevel ));
@@ -646,6 +681,9 @@ instance_constructed( GObject *window )
self->private->items_view = nact_tree_view_new( BASE_WINDOW( window ), "ActionsList", TREE_MODE_EDITION );
base_window_signal_connect( BASE_WINDOW( window ),
+ G_OBJECT( window ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
+
+ base_window_signal_connect( BASE_WINDOW( window ),
G_OBJECT( window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, G_CALLBACK( on_tree_view_modified_count_changed ));
/* create the menubar
@@ -807,9 +845,6 @@ on_base_initialize_base_window( NactMainWindow *window, gpointer user_data )
gtk_paned_set_position( GTK_PANED( pane ), pos );
}
- base_window_signal_connect( BASE_WINDOW( window ),
- G_OBJECT( window ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
-
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 ));
@@ -991,9 +1026,27 @@ on_tree_view_selection_changed( NactMainWindow *window, NactTreeView *view, GLis
}
setup_dialog_title( window );
+
+ g_signal_emit_by_name( G_OBJECT( window ),
+ MAIN_SIGNAL_SELECTION_CHANGED, na_object_copyref_items( selected_items ));
}
}
+/*
+ * cleanup handler for our MAIN_SIGNAL_SELECTION_CHANGED signal
+ */
+static void
+on_selection_changed_cleanup_handler( BaseWindow *window, GList *selected_items )
+{
+ static const gchar *thisfn = "nact_mainw_window_on_selection_changed_cleanup_handler";
+
+ g_debug( "%s: window=%p, selected_items=%p (count=%u)",
+ thisfn, ( void * ) window,
+ ( void * ) selected_items, g_list_length( selected_items ));
+
+ na_object_free_items( selected_items );
+}
+
static void
raz_selection_properties( NactMainWindow *window )
{
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index 96d5beb..ede30df 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -80,7 +80,8 @@ typedef struct {
}
NactMainWindowClass;
-#define MAIN_WINDOW_SIGNAL_SELECTION_CHANGED "main-window-selection-changed"
+#define MAIN_SIGNAL_SELECTION_CHANGED "main-selection-changed"
+
#define MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED "main-window-level-zero-order-changed"
GType nact_main_window_get_type( void );
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 6ab8070..ce4f94b 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -351,6 +351,10 @@ instance_dispose( GObject *object )
g_object_unref( self->private->action_group );
g_object_unref( self->private->ui_manager );
+ if( self->private->selected_items ){
+ self->private->selected_items = na_object_free_items( self->private->selected_items );
+ }
+
/* chain up to the parent class */
if( G_OBJECT_CLASS( st_parent_class )->dispose ){
G_OBJECT_CLASS( st_parent_class )->dispose( object );
@@ -716,6 +720,9 @@ on_tree_view_focus_out( BaseWindow *window, NactTreeView *view, gpointer user_da
/*
* when the selection changes in the tree view, see what is selected
+ *
+ * It happens that this function is triggered after all tabs have already
+ * dealt with the MAIN_SIGNAL_SELECTION_CHANGED signal
*/
static void
on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data )
@@ -727,95 +734,104 @@ on_tree_view_selection_changed( BaseWindow *window, NactTreeView *view, GList *s
BAR_WINDOW_VOID( window );
- g_debug( "%s: selected=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
+ g_debug( "%s: selected_items=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
bar->private->count_selected = g_list_length( selected );
+
if( bar->private->selected_items ){
bar->private->selected_items = na_object_free_items( bar->private->selected_items );
}
bar->private->selected_items = na_object_copyref_items( selected );
+ /* check if the parent of the first selected item is writable
+ * (File: New menu/New action)
+ * (Edit: Paste menu or action)
+ */
+ first = NULL;
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 = ( 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;
+ if( NA_IS_OBJECT_PROFILE( first )){
+ first = NA_OBJECT( na_object_get_parent( first ));
}
- /* 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 ){
+ first = ( NAObject * ) na_object_get_parent( first );
+ }
+ if( first ){
+ bar->private->is_parent_writable = na_object_is_finally_writable( first, NULL );
+ } else {
+ bar->private->is_parent_writable = 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;
- if( NA_IS_OBJECT_MENU( is->data )){
+ } 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_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;
- }
+ } 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 );
+ }
+ if( selected_action ){
+ bar->private->is_action_writable = na_object_is_finally_writable( selected_action, NULL );
+ } else {
+ bar->private->enable_new_profile = FALSE;
+ }
+
+ /* 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;
}
- /* 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 ){
+ 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;
}
}
bar->private->selected_menus = 0;
bar->private->selected_actions = 0;
bar->private->selected_profiles = 0;
- na_object_item_count_items( selected, &bar->private->selected_menus, &bar->private->selected_actions, &bar->private->selected_profiles, FALSE );
- g_debug( "nact_menubar_on_iactions_list_selection_changed: menus=%d, actions=%d, profiles=%d",
- bar->private->selected_menus, bar->private->selected_actions, bar->private->selected_profiles );
+ if( selected ){
+ na_object_item_count_items( selected, &bar->private->selected_menus, &bar->private->selected_actions, &bar->private->selected_profiles, FALSE );
+ g_debug( "%s: selected_menus=%d, selected_actions=%d, selected_profiles=%d",
+ thisfn,
+ bar->private->selected_menus, bar->private->selected_actions, bar->private->selected_profiles );
+ }
g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
}
diff --git a/src/nact/nact-tree-ieditable.c b/src/nact/nact-tree-ieditable.c
index e7a1a3c..b858680 100644
--- a/src/nact/nact-tree-ieditable.c
+++ b/src/nact/nact-tree-ieditable.c
@@ -32,7 +32,10 @@
#include <config.h>
#endif
+#include <api/na-object-api.h>
+
#include "nact-tree-ieditable.h"
+#include "nact-tree-model.h"
/* private interface data
*/
@@ -43,7 +46,8 @@ struct _NactTreeIEditableInterfacePrivate {
/* data attached to the NactTreeView
*/
typedef struct {
- guint nb_modified;
+ GtkTreeView *treeview;
+ guint count_modified;
}
IEditableData;
@@ -56,7 +60,12 @@ static GType register_type( void );
static void interface_base_init( NactTreeIEditableInterface *klass );
static void interface_base_finalize( NactTreeIEditableInterface *klass );
+static void do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GList **list_parents );
+static NAObject *do_insert_into_first( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GtkTreePath **new_path );
+static GtkTreePath *get_selection_first_path( GtkTreeView *treeview );
static IEditableData *get_instance_data( NactTreeIEditable *view );
+static void increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items );
+static void increment_counters_modified( NAObject *object, IEditableData *ied );
GType
nact_tree_ieditable_get_type( void )
@@ -124,1088 +133,846 @@ interface_base_finalize( NactTreeIEditableInterface *klass )
}
/**
- * nact_tree_ieditable_view_constructed:
- * @view: the #NactTreeView which implements this interface.
- * @window: the #BaseWindow which embeds the @view.
+ * nact_tree_ieditable_initialize:
+ * @instance: the #NactTreeView which implements this interface.
+ * @treeview: the embedded #GtkTreeView tree view.
+ * @window: the #BaseWindow which embeds the @instance.
*
* Initialize the interface, mainly connecting to signals of interest.
*/
void
-nact_tree_ieditable_on_view_constructed( NactTreeView *view, BaseWindow *window )
+nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window )
{
- static const gchar *thisfn = "nact_tree_ieditable_on_view_constructed";
+ static const gchar *thisfn = "nact_tree_ieditable_initialize";
IEditableData *ied;
- g_debug( "%s: view=%p, window=%p", thisfn, ( void * ) view, ( void * ) window );
+ g_debug( "%s: instance=%p, window=%p", thisfn, ( void * ) instance, ( void * ) window );
- ied = get_instance_data( NACT_TREE_IEDITABLE( view ));
+ ied = get_instance_data( instance );
+ ied->treeview = treeview;
}
-static IEditableData *
-get_instance_data( NactTreeIEditable *view )
+/**
+ * nact_tree_ieditable_insert_at_path:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
+ * @path: insertion path.
+ *
+ * Inserts the provided @items list in the treeview.
+ *
+ * This function takes care of repositionning a new selection if
+ * possible, and refilter the display model.
+ */
+void
+nact_tree_ieditable_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *insert_path )
{
+ static const gchar *thisfn = "nact_tree_ieditable_insert_at_path";
IEditableData *ied;
+ GtkTreeModel *model;
+ GList *parents;
- ied = ( IEditableData * ) g_object_get_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE );
-
- if( !ied ){
- ied = g_new0( IEditableData, 1 );
- g_object_set_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE, ied );
- }
-
- return( ied );
-}
-
-#if 0
-/* when iterating through a selection
- */
-typedef struct {
- gboolean has_menu_or_action;
-}
- SelectionIter;
-
-/* signals
- */
-enum {
- LIST_COUNT_UPDATED,
- SELECTION_CHANGED,
- FOCUS_IN,
- FOCUS_OUT,
- COLUMN_EDITED,
- STATUS_CHANGED,
- LAST_SIGNAL
-};
+ g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-static gint st_signals[ LAST_SIGNAL ] = { 0 };
-
-static void free_items_callback( NactTreeIEditable *instance, GList *items );
-static void free_column_edited_callback( NactTreeIEditable *instance, NAObject *object, gchar *text, gint column );
-
-static gboolean are_profiles_displayed( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeIEditable *instance );
-static gboolean filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactTreeIEditable *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( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static gboolean have_filter_selection_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static void inline_edition( NactTreeIEditable *instance );
-static gboolean is_iduplicable_proxy( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid );
-static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactTreeIEditable *instance );
-static void on_edition_status_changed( NactTreeIEditable *instance, NAIDuplicable *object );
-static gboolean on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance );
-static gboolean on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance );
-static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactTreeIEditable *instance );
-static void on_label_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, NactTreeIEditable *instance );
-static void on_tab_updatable_item_updated( NactTreeIEditable *instance, NAObject *object, gboolean force_display );
-static void open_popup( NactTreeIEditable *instance, GdkEventButton *event );
+ if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ g_debug( "%s: instance=%p, items=%p (count=%d)",
+ thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
-static void
-free_items_callback( NactTreeIEditable *instance, GList *items )
-{
- g_debug( "nact_tree_ieditable_free_items_callback: selection=%p (%d items)",
- ( void * ) items, g_list_length( items ));
+ ied = get_instance_data( instance );
+ model = gtk_tree_view_get_model( ied->treeview );
+ g_return_if_fail( NACT_IS_TREE_MODEL( model ));
- na_object_free_items( items );
-}
+ do_insert_items( ied->treeview, model, items, insert_path, &parents );
-static void
-free_column_edited_callback( NactTreeIEditable *instance, NAObject *object, gchar *text, gint column )
-{
- static const gchar *thisfn = "nact_tree_ieditable_free_column_edited_callback";
+ g_list_foreach( parents, ( GFunc ) na_object_object_check_status, NULL );
+ g_list_free( parents );
- g_debug( "%s: instance=%p, object=%p (%s), text=%s, column=%d",
- thisfn, ( void * ) instance, ( void * ) object, G_OBJECT_TYPE_NAME( object ), text, column );
+ increment_counters( instance, ied, items );
- g_free( text );
+ gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
+ nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), insert_path );
+ }
}
/**
- * nact_tree_ieditable_initial_load_toplevel:
- * @instance: this #NactTreeIEditable *instance.
+ * nact_tree_ieditable_insert_items:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
+ * @sibling: the #NAObject besides which the insertion should occurs;
+ * this is mainly used for inserting duplicated items besides each of
+ * original ones; may be %NULL.
+ *
+ * Inserts the provided @items list just before the @sibling object,
+ * or at the current position in the treeview if @sibling is %NULL.
*
- * Allocates and initializes the ActionsList widget.
+ * The provided @items list is supposed to be homogeneous, i.e. referes
+ * to only profiles, or only actions or menus.
*
- * GtkTreeView is created with NactTreeModel model
- * NactTreeModel
- * implements EggTreeMultiDragSourceIface
- * is derived from GtkTreeModelFilter
- * GtkTreeModelFilter is built on top of GtkTreeStore
+ * If the @items list contains profiles, they can only be inserted
+ * into an action, or before another profile.
*
- * Please note that management mode for the list should have been set
- * before calling this function.
+ * If new item is a #NAObjectMenu or a #NAObjectAction, it will be inserted
+ * before the current action or menu.
+ *
+ * This function takes care of repositionning a new selection (if possible)
+ * on the lastly inserted item, and to refresh the display.
*/
void
-nact_tree_ieditable_initial_load_toplevel( NactTreeIEditable *instance )
+nact_tree_ieditable_insert_items( NactTreeIEditable *instance, GList *items, NAObject *sibling )
{
- static const gchar *thisfn = "nact_tree_ieditable_initial_load_toplevel";
- GtkWidget *label;
- GtkTreeView *treeview;
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
- TreeIEditableInstanceData *ialid;
+ static const gchar *thisfn = "nact_tree_ieditable_insert_items";
+ IEditableData *ied;
+ GtkTreeModel *model;
+ GtkTreePath *insert_path;
+ NAObject *object, *parent;
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ g_debug( "%s: instance=%p, items=%p (count=%d), sibling=%p",
+ thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), ( void * ) sibling );
+
+ insert_path = NULL;
+ ied = get_instance_data( instance );
+ model = gtk_tree_view_get_model( ied->treeview );
+ g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+ if( sibling ){
+ insert_path = nact_tree_model_object_to_path( NACT_TREE_MODEL( model ), sibling );
+
+ } else {
+ insert_path = get_selection_first_path( ied->treeview );
+ object = nact_tree_model_object_at_path( NACT_TREE_MODEL( model ), insert_path );
+ g_debug( "%s: current object at insertion path is %p", thisfn, ( void * ) object );
+
+ /* as a particular case, insert a new profile _into_ current action
+ */
+ if( NA_IS_OBJECT_ACTION( object ) && NA_IS_OBJECT_PROFILE( items->data )){
+ nact_tree_ieditable_insert_items_into( instance, items );
+ gtk_tree_path_free( insert_path );
+ return;
+ }
+
+ /* insert a new NAObjectItem before current NAObjectItem
+ */
+ if( NA_IS_OBJECT_PROFILE( object ) && NA_IS_OBJECT_ITEM( items->data )){
+ parent = ( NAObject * ) na_object_get_parent( object );
+ gtk_tree_path_free( insert_path );
+ insert_path = nact_tree_model_object_to_path( NACT_TREE_MODEL( model ), parent );
+ }
+ }
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- ialid->selection_changed_allowed = FALSE;
-
- /* associates the ActionsList to the label */
- label = base_window_get_widget( BASE_WINDOW( instance ), "ActionsListLabel" );
- gtk_label_set_mnemonic_widget( GTK_LABEL( label ), GTK_WIDGET( treeview ));
-
- nact_tree_model_initial_load( BASE_WINDOW( instance ), treeview );
- gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
-
- /* create visible columns on the tree view
- */
- /* icon: no header */
- column = gtk_tree_view_column_new_with_attributes(
- "icon",
- gtk_cell_renderer_pixbuf_new(),
- "pixbuf", TREE_IEDITABLE_ICON_COLUMN,
- NULL );
- gtk_tree_view_append_column( treeview, column );
-
- renderer = gtk_cell_renderer_text_new();
- column = gtk_tree_view_column_new_with_attributes(
- "label",
- renderer,
- "text", TREE_IEDITABLE_LABEL_COLUMN,
- NULL );
- gtk_tree_view_column_set_sort_column_id( column, TREE_IEDITABLE_LABEL_COLUMN );
- gtk_tree_view_column_set_cell_data_func(
- column, renderer, ( GtkTreeCellDataFunc ) display_label, instance, NULL );
- gtk_tree_view_append_column( treeview, column );
+ nact_tree_ieditable_insert_at_path( instance, items, insert_path );
+ gtk_tree_path_free( insert_path );
}
}
/**
- * nact_tree_ieditable_runtime_init_toplevel:
- * @window: this #NactTreeIEditable *instance.
- * @items: list of #NAObject actions and menus as provided by #NAPivot.
+ * nact_tree_ieditable_insert_items_into:
+ * @instance: this #NactTreeIEditable instance.
+ * @items: a list of items to be inserted (e.g. from a paste).
*
- * Allocates and initializes the ActionsList widget.
+ * Inserts the provided @items list as first children of the current item.
+ *
+ * The provided @items list is supposed to be homogeneous, i.e. referes
+ * to only profiles, or only actions or menus.
+ *
+ * If the @items list contains only profiles, they can only be inserted
+ * into an action, and the profiles will eventually be renumbered.
+ *
+ * If new item is a #NAObjectMenu or a #NAObjectAction, it will be inserted
+ * as first children of the current menu.
+ *
+ * This function takes care of repositionning a new selection as the
+ * last inserted item, and refilter the display model.
*/
void
-nact_tree_ieditable_runtime_init_toplevel( NactTreeIEditable *instance, GList *items )
+nact_tree_ieditable_insert_items_into( NactTreeIEditable *instance, GList *items )
{
- static const gchar *thisfn = "nact_tree_ieditable_runtime_init_toplevel";
- GtkTreeView *treeview;
- NactTreeModel *model;
- gboolean have_dnd;
- gboolean have_filter_selection;
- gboolean is_proxy;
- GtkTreeSelection *selection;
- TreeIEditableInstanceData *ialid;
- GtkTreeViewColumn *column;
- GList *renderers;
+ static const gchar *thisfn = "nact_tree_ieditable_insert_items_into";
+ IEditableData *ied;
+ GtkTreeModel *model;
+ GtkTreePath *insert_path;
+ GtkTreePath *new_path;
+ NAObject *parent;
- g_debug( "%s: instance=%p, items=%p (%d items)",
- thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ g_debug( "%s: instance=%p, items=%p (count=%d)",
+ thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ));
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+ insert_path = NULL;
+ ied = get_instance_data( instance );
+ model = gtk_tree_view_get_model( ied->treeview );
+ insert_path = get_selection_first_path( ied->treeview );
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- ialid->selection_changed_allowed = FALSE;
- have_dnd = have_dnd_mode( instance, ialid );
- have_filter_selection = have_filter_selection_mode( instance, ialid );
+ increment_counters( instance, ied, items );
- if( have_filter_selection ){
- selection = gtk_tree_view_get_selection( treeview );
- gtk_tree_selection_set_select_function( selection, ( GtkTreeSelectionFunc ) filter_selection, instance, NULL );
- }
+ parent = do_insert_into_first( ied->treeview, model, items, insert_path, &new_path );
- nact_tree_model_runtime_init( model, have_dnd );
-
- /* set up selection control */
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( gtk_tree_view_get_selection( treeview )),
- "changed",
- G_CALLBACK( nact_tree_ieditable_on_treeview_selection_changed ));
-
- /* catch press 'Enter' */
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( treeview ),
- "key-press-event",
- G_CALLBACK( on_key_pressed_event ));
-
- /* catch double-click */
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( treeview ),
- "button-press-event",
- G_CALLBACK( on_button_press_event ));
-
- /* updates the treeview display when an item is modified */
- ialid->tab_updated_handler = base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
- G_CALLBACK( on_tab_updatable_item_updated ));
-
- /* enable/disable edit menu item accelerators depending of
- * which widget has the focus */
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( treeview ),
- "focus-in-event",
- G_CALLBACK( on_focus_in ));
-
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( treeview ),
- "focus-out-event",
- G_CALLBACK( on_focus_out ));
-
- /* label edition: inform the corresponding tab */
- column = gtk_tree_view_get_column( treeview, TREE_IEDITABLE_LABEL_COLUMN );
- renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( renderers->data ),
- "edited",
- G_CALLBACK( on_label_edited ));
-
- /* records NactTreeIEditable as a proxy for edition status
- * modification */
- is_proxy = is_iduplicable_proxy( instance, ialid );
- if( is_proxy ){
- na_iduplicable_register_consumer( G_OBJECT( instance ));
-
- base_window_signal_connect(
- BASE_WINDOW( instance ),
- G_OBJECT( instance ),
- NA_IDUPLICABLE_SIGNAL_STATUS_CHANGED,
- G_CALLBACK( on_edition_status_changed ));
- }
+ na_object_check_status( parent );
- /* fill the model after having connected the signals
- * so that callbacks are triggered at last
- */
- nact_tree_ieditable_fill( instance, items );
+ gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
+ nact_tree_view_select_row_at_path( NACT_TREE_VIEW( instance ), new_path );
- /* force the treeview to have the focus at start
- */
- gtk_widget_grab_focus( GTK_WIDGET( treeview ));
+ gtk_tree_path_free( new_path );
+ gtk_tree_path_free( insert_path );
}
}
-/**
- * nact_tree_ieditable_all_widgets_showed:
- * @window: this #NactTreeIEditable *instance.
- */
-void
-nact_tree_ieditable_all_widgets_showed( NactTreeIEditable *instance )
+static void
+do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GList **list_parents )
{
- static const gchar *thisfn = "nact_tree_ieditable_all_widgets_showed";
- gboolean profiles_are_displayed;
- TreeIEditableInstanceData *ialid;
+ static const gchar *thisfn = "nact_tree_ieditable_do_insert_items";
+ GList *reversed;
+ GList *it;
+ GList *subitems;
+ NAObject *obj_parent;
+ gpointer updatable;
+ GtkTreePath *inserted_path;
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+ obj_parent = NULL;
+ if( list_parents ){
+ *list_parents = NULL;
+ }
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ reversed = g_list_reverse( g_list_copy( items ));
+
+ for( it = reversed ; it ; it = it->next ){
+ inserted_path = nact_tree_model_insert( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ), insert_path, &obj_parent );
+
+ g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+ ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), G_OBJECT( it->data )->ref_count );
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- profiles_are_displayed = are_profiles_displayed( instance, ialid );
+ if( list_parents ){
+ updatable = obj_parent ? obj_parent : it->data;
+ if( !g_list_find( *list_parents, updatable )){
+ *list_parents = g_list_prepend( *list_parents, updatable );
+ }
+ }
- if( profiles_are_displayed ){
- nact_tree_ieditable_priv_send_list_count_updated_signal( instance, ialid );
+ /* recursively insert subitems
+ */
+ if( NA_IS_OBJECT_ITEM( it->data ) && na_object_get_items_count( it->data )){
+ subitems = na_object_get_items( it->data );
+ do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
}
- nact_tree_ieditable_bis_select_first_row( instance );
+ gtk_tree_path_free( inserted_path );
}
+
+ g_list_free( reversed );
}
-/**
- * nact_tree_ieditable_dispose:
- * @window: this #NactTreeIEditable *instance.
- */
-void
-nact_tree_ieditable_dispose( NactTreeIEditable *instance )
+static NAObject *
+do_insert_into_first( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTreePath *insert_path, GtkTreePath **new_path )
{
- static const gchar *thisfn = "nact_tree_ieditable_dispose";
- GtkTreeView *treeview;
- NactTreeModel *model;
- TreeIEditableInstanceData *ialid;
+ static const gchar *thisfn = "nact_tree_ieditable_do_insert_into_first";
+ GList *copy;
+ GList *last;
+ NAObject *parent;
+ gchar *insert_path_str;
+ GtkTreePath *inserted_path;
+ GList *subitems;
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+ insert_path_str = gtk_tree_path_to_string( insert_path );
+ g_debug( "%s: treeview=%p, model=%p, items=%p (count=%d), insert_path=%p (%s), new_path=%p",
+ thisfn,
+ ( void * ) treeview, ( void * ) model, ( void * ) items, g_list_length( items ),
+ ( void * ) insert_path, insert_path_str, ( void * ) new_path );
+ g_free( insert_path_str );
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ parent = NULL;
+ copy = g_list_copy( items );
+ last = g_list_last( copy );
+ copy = g_list_remove_link( copy, last );
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+ inserted_path = nact_tree_model_insert_into( NACT_TREE_MODEL( model ), NA_OBJECT( last->data ), insert_path, &parent );
+ gtk_tree_view_expand_to_path( treeview, inserted_path );
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- g_list_free( ialid->modified_items );
- ialid->modified_items = NULL;
+ /* recursively insert subitems
+ */
+ if( NA_IS_OBJECT_ITEM( last->data ) && na_object_get_items_count( last->data )){
+ subitems = na_object_get_items( last->data );
+ do_insert_into_first( treeview, model, subitems, inserted_path, NULL );
+ }
- ialid->selection_changed_allowed = FALSE;
- nact_tree_model_dispose( model );
+ do_insert_items( treeview, model, copy, inserted_path, NULL );
- g_free( ialid );
+ if( new_path ){
+ *new_path = gtk_tree_path_copy( inserted_path );
}
+
+ g_list_free( copy );
+ gtk_tree_path_free( inserted_path );
+
+ return( parent );
}
-/**
- * nact_tree_ieditable_brief_tree_dump:
- * @instance: this #NactTreeIEditable implementation.
- *
- * Brief dump of the tree store content.
- */
-void
-nact_tree_ieditable_brief_tree_dump( NactTreeIEditable *instance )
+static GtkTreePath *
+get_selection_first_path( GtkTreeView *treeview )
{
- GtkTreeView *treeview;
- NactTreeModel *model;
+ GtkTreeSelection *selection;
+ GList *selected;
+ GtkTreePath *path;
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+ path = NULL;
+ selection = gtk_tree_view_get_selection( treeview );
+ selected = gtk_tree_selection_get_selected_rows( selection, NULL );
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ if( selected ){
+ path = gtk_tree_path_copy(( GtkTreePath * ) selected->data );
+
+ } else {
+ path = gtk_tree_path_new_from_string( "0" );
+ }
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
- nact_tree_model_dump( model );
+ g_list_foreach( selected, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( selected );
+
+ return( path );
+}
+
+static IEditableData *
+get_instance_data( NactTreeIEditable *view )
+{
+ IEditableData *ied;
+
+ ied = ( IEditableData * ) g_object_get_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE );
+
+ if( !ied ){
+ ied = g_new0( IEditableData, 1 );
+ g_object_set_data( G_OBJECT( view ), VIEW_DATA_IEDITABLE, ied );
}
+
+ return( ied );
}
-/**
- * nact_tree_ieditable_collapse_all:
- * @instance: this #NactTreeIEditable implementation.
- *
- * Collapse all the tree hierarchy.
- */
-void
-nact_tree_ieditable_collapse_all( NactTreeIEditable *instance )
+static void
+increment_counters( NactTreeIEditable *view, IEditableData *ied, GList *items )
{
- static const gchar *thisfn = "nact_tree_ieditable_collapse_all";
- GtkTreeView *treeview;
+ static const gchar *thisfn = "nact_tre_ieditablet_increment_counters";
+ guint modified_prev;
+ gint menus, actions, profiles;
+ BaseWindow *window;
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+ g_debug( "%s: view=%p, ied=%p, items=%p (count=%d)",
+ thisfn, ( void * ) view, ( void * ) ied, ( void * ) items, items ? g_list_length( items ) : 0 );
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ menus = 0;
+ actions = 0;
+ profiles = 0;
+ na_object_item_count_items( items, &menus, &actions, &profiles, TRUE );
+ window = nact_tree_view_get_window( NACT_TREE_VIEW( view ));
+ g_signal_emit_by_name( G_OBJECT( window ), TREE_SIGNAL_COUNT_CHANGED, view, FALSE, menus, actions, profiles );
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- gtk_tree_view_collapse_all( treeview );
+ modified_prev = ied->count_modified;
+ g_list_foreach( items, ( GFunc ) increment_counters_modified, ied );
+ if( ied->count_modified != modified_prev ){
+ g_signal_emit_by_name( G_OBJECT( window ), TREE_SIGNAL_MODIFIED_COUNT_CHANGED, view, ied->count_modified );
}
}
+static void
+increment_counters_modified( NAObject *object, IEditableData *ied )
+{
+ if( NA_IS_OBJECT_ITEM( object )){
+ if( !na_object_get_provider( object )){
+ ied->count_modified += 1;
+ }
+ }
+}
+
+#if 0
+
+/* iter on selection prototype
+ */
+typedef gboolean ( *FnIterOnSelection )( NactIActionsList *, GtkTreeView *, GtkTreeModel *, GtkTreeIter *, NAObject *, gpointer );
+
/**
- * nact_tree_ieditable_display_order_change:
- * @instance: this #NactTreeIEditable implementation.
- * @order_mode: the new order mode.
+ * nact_iactions_list_bis_clear_selection:
+ * @instance: this instance of the #NactIActionsList interface.
+ * @treeview: the #GtkTreeView.
*
- * Setup the new order mode.
+ * Clears the current selection.
*/
void
-nact_tree_ieditable_display_order_change( NactTreeIEditable *instance, gint order_mode )
+nact_iactions_list_bis_clear_selection( NactIActionsList *instance, GtkTreeView *treeview )
{
- GtkTreeView *treeview;
- NactTreeModel *model;
-
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ GtkTreeSelection *selection;
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
- nact_tree_model_display_order_change( model, order_mode );
- }
+ selection = gtk_tree_view_get_selection( treeview );
+ gtk_tree_selection_unselect_all( selection );
}
/**
- * nact_tree_ieditable_expand_all:
- * @instance: this #NactTreeIEditable implementation.
+ * nact_iactions_list_bis_collapse_to_parent:
+ * @instance: this instance of the #NactIActionsList interface.
*
- * Expand all the tree hierarchy.
+ * On left arrow, if we are on a first child, then collapse and go to
+ * the parent.
*/
void
-nact_tree_ieditable_expand_all( NactTreeIEditable *instance )
+nact_iactions_list_bis_collapse_to_parent( NactIActionsList *instance )
{
- static const gchar *thisfn = "nact_tree_ieditable_expand_all";
+ static const gchar *thisfn = "nact_iactions_list_bis_collapse_to_parent";
+ IActionsListInstanceData *ialid;
GtkTreeView *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *listrows;
+ GtkTreePath *path;
+ gint *indices;
+ GtkTreePath *parent_path;
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
+ g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
+ if( ialid->management_mode == IACTIONS_LIST_MANAGEMENT_MODE_EDITION ){
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- gtk_tree_view_expand_all( treeview );
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+ selection = gtk_tree_view_get_selection( treeview );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+ if( g_list_length( listrows ) == 1 ){
+
+ path = ( GtkTreePath * ) listrows->data;
+ /*g_debug( "%s: path_depth=%d", thisfn, gtk_tree_path_get_depth( path ));*/
+ if( gtk_tree_path_get_depth( path ) > 1 ){
+
+ indices = gtk_tree_path_get_indices( path );
+ if( indices[ gtk_tree_path_get_depth( path )-1 ] == 0 ){
+
+ parent_path = gtk_tree_path_copy( path );
+ gtk_tree_path_up( parent_path );
+ nact_iactions_list_bis_select_row_at_path( instance, treeview, model, parent_path );
+ gtk_tree_view_collapse_row( treeview, parent_path );
+ gtk_tree_path_free( parent_path );
+ }
+ }
+ }
+
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
}
}
/**
- * nact_tree_ieditable_fill:
- * @instance: this #NactTreeIEditable instance.
+ * nact_iactions_list_bis_delete:
+ * @window: this #NactIActionsList instance.
+ * @list: list of #NAObject to be deleted.
*
- * Fill the listbox with the provided list of items.
+ * Deletes the specified list from the underlying tree store.
*
- * Menus are expanded, profiles are not.
- * The selection is reset to the first line of the tree, if there is one.
+ * This function takes care of repositionning a new selection if
+ * possible, and refilter the display model.
*/
void
-nact_tree_ieditable_fill( NactTreeIEditable *instance, GList *items )
+nact_iactions_list_bis_delete( NactIActionsList *instance, GList *items, gboolean select_at_end )
{
- static const gchar *thisfn = "nact_tree_ieditable_fill";
+ static const gchar *thisfn = "nact_iactions_list_bis_delete";
GtkTreeView *treeview;
- NactTreeModel *model;
- gboolean profiles_are_displayed;
- TreeIEditableInstanceData *ialid;
-
- g_debug( "%s: instance=%p, items=%p", thisfn, ( void * ) instance, ( void * ) items );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ GtkTreeModel *model;
+ GtkTreePath *path = NULL;
+ GList *it;
+ IActionsListInstanceData *ialid;
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+ g_debug( "%s: instance=%p, items=%p (count=%d), select_at_end=%s",
+ thisfn, ( void * ) instance, ( void * ) items, g_list_length( items ), select_at_end ? "True":"False" );
+ g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
- nact_tree_ieditable_bis_clear_selection( instance, treeview );
+ if( st_iactions_list_initialized && !st_iactions_list_finalized ){
- ialid = nact_tree_ieditable_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" );
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+ model = gtk_tree_view_get_model( treeview );
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
ialid->selection_changed_allowed = FALSE;
- nact_tree_model_fill( model, items, profiles_are_displayed );
- ialid->selection_changed_allowed = TRUE;
-
- g_list_free( ialid->modified_items );
- ialid->modified_items = NULL;
-
- g_signal_emit_by_name(
- instance,
- MAIN_WINDOW_SIGNAL_LEVEL_ZERO_ORDER_CHANGED,
- GINT_TO_POINTER( FALSE ));
-
- ialid->menus = 0;
- ialid->actions = 0;
- ialid->profiles = 0;
-
- if( profiles_are_displayed ){
- na_object_item_count_items( items, &ialid->menus, &ialid->actions, &ialid->profiles, TRUE );
- nact_tree_ieditable_priv_send_list_count_updated_signal( instance, ialid );
- }
- }
-}
-
-/**
- * nact_tree_ieditable_get_management_mode:
- * @instance: this #NactTreeIEditable instance.
- *
- * Returns: the current management mode of the list.
- */
-gint
-nact_tree_ieditable_get_management_mode( NactTreeIEditable *instance )
-{
- gint mode = 0;
- TreeIEditableInstanceData *ialid;
- g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), 0 );
+ decrement_counters( instance, ialid, items );
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ for( it = items ; it ; it = it->next ){
+ if( path ){
+ gtk_tree_path_free( path );
+ }
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- mode = ialid->management_mode;
- }
+ path = nact_tree_model_remove( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ));
- return( mode );
-}
+ ialid->modified_items = nact_iactions_list_remove_rec( ialid->modified_items, NA_OBJECT( it->data ));
-/**
- * nact_tree_ieditable_has_modified_items:
- * @window: this #NactTreeIEditable instance.
- *
- * Returns: %TRUE if at least there is one modified item in the list.
- */
-gboolean
-nact_tree_ieditable_has_modified_items( NactTreeIEditable *instance )
-{
- gboolean has_modified = FALSE;
- /*GtkTreeView *treeview;
- NactTreeModel *model;*/
- TreeIEditableInstanceData *ialid;
-
- g_return_val_if_fail( NACT_IS_TREE_IEDITABLE( instance ), FALSE );
+ g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
+ ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), G_OBJECT( it->data )->ref_count );
+ }
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- has_modified = ( g_list_length( ialid->modified_items ) > 0 );
+ ialid->selection_changed_allowed = TRUE;
- /*treeview = get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
- nact_tree_model_iter( model, ( FnIterOnStore ) has_modified_iter, &has_modified );*/
+ if( path ){
+ if( select_at_end ){
+ nact_iactions_list_bis_select_row_at_path( instance, treeview, model, path );
+ }
+ gtk_tree_path_free( path );
+ }
}
-
- return( has_modified );
}
/**
- * nact_tree_ieditable_on_treeview_selection_changed:
- * @selection: current selection.
- * @instance: this instance of the #NactTreeIEditable interface.
+ * nact_iactions_list_bis_expand_to_first_child:
+ * @instance: this #NactIActionsList interface.
*
- * This is our handler for "changed" signal emitted by the treeview.
- * The handler is inhibited while filling the list (usually only at
- * runtime init), and while deleting a selection.
+ * On right arrow, expand the parent if it has childs, and select the
+ * first child.
*/
void
-nact_tree_ieditable_on_treeview_selection_changed( GtkTreeSelection *selection, NactTreeIEditable *instance )
+nact_iactions_list_bis_expand_to_first_child( NactIActionsList *instance )
{
- GList *selected_items;
- TreeIEditableInstanceData *ialid;
-
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- if( ialid->selection_changed_allowed ){
+ static const gchar *thisfn = "nact_iactions_list_bis_expand_to_first_child";
+ IActionsListInstanceData *ialid;
+ GtkTreeView *treeview;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *listrows;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GtkTreePath *child_path;
- g_debug( "nact_tree_ieditable_on_treeview_selection_changed" );
- g_signal_handler_block( instance, ialid->tab_updated_handler );
+ g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+ g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
- selected_items = nact_tree_ieditable_bis_get_selected_items( instance );
- g_debug( "nact_tree_ieditable_on_treeview_selection_changed: selection=%p (%d items)", ( void * ) selected_items, g_list_length( selected_items ));
- g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_SELECTION_CHANGED, selected_items );
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
+ if( ialid->management_mode == IACTIONS_LIST_MANAGEMENT_MODE_EDITION ){
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+ selection = gtk_tree_view_get_selection( treeview );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
- g_signal_handler_unblock( instance, ialid->tab_updated_handler );
+ if( g_list_length( listrows ) == 1 ){
+ path = ( GtkTreePath * ) listrows->data;
+ gtk_tree_model_get_iter( model, &iter, path );
+ if( gtk_tree_model_iter_has_child( model, &iter )){
+ child_path = gtk_tree_path_copy( path );
+ gtk_tree_path_append_index( child_path, 0 );
+ gtk_tree_view_expand_row( treeview, child_path, FALSE );
+ nact_iactions_list_bis_select_row_at_path( instance, treeview, model, child_path );
+ gtk_tree_path_free( child_path );
+ }
+ }
- /* selection list is freed in cleanup handler for the signal */
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
}
}
/**
- * nact_tree_ieditable_remove_rec:
- * @list: list of modified objects.
- * @object: the object to be removed from the list.
- *
- * When removing from modified list an object which is no more modified,
- * then all subitems of the object have also to be removed
+ * nact_iactions_list_bis_get_selected_items:
+ * @window: this #NactIActionsList instance.
*
- * Returns: the updated list.
- */
-GList *
-nact_tree_ieditable_remove_rec( GList *list, NAObject *object )
-{
- GList *subitems, *it;
-
- if( NA_IS_OBJECT_ITEM( object )){
- subitems = na_object_get_items( object );
- for( it = subitems ; it ; it = it->next ){
- list = nact_tree_ieditable_remove_rec( list, it->data );
- }
- }
-
- list = g_list_remove( list, object );
-
- return( list );
-}
-
-/**
- * nact_tree_ieditable_set_management_mode:
- * @instance: this #NactTreeIEditable instance.
- * @mode: management mode.
+ * Returns: the currently selected rows as a list of #NAObjects.
*
- * Set the management mode for this @instance.
+ * We acquire here a new reference on objects corresponding to actually
+ * selected rows, and their childs.
*
- * For the two known modes (edition mode, export mode), we also allow
- * multiple selection in the list.
+ * The caller may safely call na_object_free_items() on the
+ * returned list.
*/
-void
-nact_tree_ieditable_set_management_mode( NactTreeIEditable *instance, gint mode )
+GList *
+nact_iactions_list_bis_get_selected_items( NactIActionsList *instance )
{
+ GList *items = NULL;
GtkTreeView *treeview;
GtkTreeSelection *selection;
- gboolean multiple;
- TreeIEditableInstanceData *ialid;
-
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
- if( st_tree_ieditable_initialized && !st_tree_ieditable_finalized ){
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GList *it, *listrows;
+ NAObject *object;
+ GtkTreePath *path;
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- ialid->management_mode = mode;
+ g_return_val_if_fail( NACT_IS_IACTIONS_LIST( instance ), NULL );
- multiple = ( mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ||
- mode == TREE_IEDITABLE_MANAGEMENT_MODE_EXPORT );
+ if( st_iactions_list_initialized && !st_iactions_list_finalized ){
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
selection = gtk_tree_view_get_selection( treeview );
- gtk_tree_selection_set_mode( selection, multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE );
- }
-}
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+
+ for( it = listrows ; it ; it = it->next ){
+ path = ( GtkTreePath * ) it->data;
+ gtk_tree_model_get_iter( model, &iter, path );
+ gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ g_debug( "nact_iactions_list_get_selected_items: object=%p", ( void * ) object );
+ items = g_list_prepend( items, na_object_ref( object ));
+ g_object_unref( object );
+ }
-static gboolean
-are_profiles_displayed( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
- gboolean display;
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
- display = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+ items = g_list_reverse( items );
+ }
- return( display );
+ return( items );
}
-/*
- * item modified: italic
- * item not saveable (invalid): red
+/**
+ * nact_iactions_list_bis_list_modified_items:
+ * @instance: this #NactIActionsList instance.
+ *
+ * Dumps the modified items list.
*/
-static void
-display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeIEditable *instance )
+void
+nact_iactions_list_bis_list_modified_items( NactIActionsList *instance )
{
- NAObject *object;
- gchar *label;
- gboolean modified = FALSE;
- gboolean valid = TRUE;
- TreeIEditableInstanceData *ialid;
- NAObjectItem *item;
-#if 0
- gboolean writable_item;
- NactApplication *application;
- NAUpdater *updater;
-#endif
+ static const gchar *thisfn = "nact_iactions_list_bis_list_modified_items";
+ IActionsListInstanceData *ialid;
+ GList *it;
- gtk_tree_model_get( model, iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
- g_object_unref( object );
- g_return_if_fail( NA_IS_OBJECT( object ));
-
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- label = na_object_get_label( object );
- g_object_set( cell, "style-set", FALSE, NULL );
- g_object_set( cell, "foreground-set", FALSE, NULL );
- /*g_debug( "nact_tree_ieditable_display_label: %s %s", G_OBJECT_TYPE_NAME( object ), label );*/
+ g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
+ g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
- if( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ){
+ if( st_iactions_list_initialized && !st_iactions_list_finalized ){
- modified = na_object_is_modified( object );
- valid = na_object_is_valid( object );
- item = NA_IS_OBJECT_PROFILE( object ) ? na_object_get_parent( object ) : NA_OBJECT_ITEM( object );
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
- if( modified ){
- g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
+ g_debug( "%s: raw list", thisfn );
+ for( it = ialid->modified_items ; it ; it = it->next ){
+ g_debug( "%s: %p (%s)", thisfn, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ));
}
- if( !valid ){
- g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
+ g_debug( "%s: detailed list", thisfn );
+ for( it = ialid->modified_items ; it ; it = it->next ){
+ na_object_dump( it->data );
}
-
-#if 0
- application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( instance )));
- updater = nact_application_get_updater( application );
- writable_item = na_updater_is_item_writable( updater, item, NULL );
- g_object_set( cell, "editable", writable_item, NULL );
-#endif
}
-
- g_object_set( cell, "text", label, NULL );
- g_free( label );
}
-/*
- * 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 nor where to insert e.g. a mix selection.
- *
- * So a selection must first be homogeneous, i.e. it only contains
- * explicitely selected profiles _or_ menus or actions (and their childs).
+/**
+ * nact_iactions_list_bis_remove_modified:
+ * @instance: this #NactIActionsList instance.
*
- * 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
+ * Removes the saved item from the modified items list.
*/
-static gboolean
-filter_selection( GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, NactTreeIEditable *instance )
+void
+nact_iactions_list_bis_remove_modified( NactIActionsList *instance, const NAObjectItem *item )
{
- static const gchar *thisfn = "nact_tree_ieditable_filter_selection";
- GList *selected_paths;
- GtkTreeIter iter;
- NAObject *object;
+ IActionsListInstanceData *ialid;
- gtk_tree_model_get_iter( model, &iter, path );
- gtk_tree_model_get( model, &iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
- g_return_val_if_fail( object, FALSE );
- g_return_val_if_fail( NA_IS_OBJECT_ID( object ), FALSE );
- g_object_unref( object );
+ g_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
- /* 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 );
- }
-
- /* 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( filter_selection_is_implicitely_selected( object )){
- g_debug( "%s: implicitely selected item: selection not allowed", thisfn );
- return( FALSE );
- }
+ if( st_iactions_list_initialized && !st_iactions_list_finalized ){
- /* 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( path_currently_selected ||
- filter_selection_is_homogeneous( selection, object )){
+ ialid = nact_iactions_list_priv_get_instance_data( instance );
+ ialid->modified_items = g_list_remove( ialid->modified_items, item );
- filter_selection_set_implicitely_selected_childs( object, !path_currently_selected );
+ if( g_list_length( ialid->modified_items ) == 0 ){
+ g_list_free( ialid->modified_items );
+ ialid->modified_items = NULL;
+ }
}
- return( TRUE );
}
-/*
- * does the selection stay homogeneous when adding this object ?
+/**
+ * nact_iactions_list_bis_toggle_collapse:
+ * @instance: this #NactIActionsList interface.
+ *
+ * Toggle or collapse the current subtree.
*/
-static gboolean
-filter_selection_is_homogeneous( GtkTreeSelection *selection, NAObject *object )
+void
+nact_iactions_list_bis_toggle_collapse( NactIActionsList *instance )
{
- gboolean homogeneous;
+ int toggle = TOGGLE_UNDEFINED;
- if( filter_selection_has_menu_or_action( selection )){
- homogeneous = !NA_IS_OBJECT_PROFILE( object );
- } else {
- homogeneous = NA_IS_OBJECT_PROFILE( object );
- }
-
- return( homogeneous );
+ iter_on_selection( instance, ( FnIterOnSelection ) toggle_collapse_iter, &toggle );
}
-static gboolean
-filter_selection_has_menu_or_action( GtkTreeSelection *selection )
+/**
+ * nact_iactions_list_bis_toggle_collapse_object:
+ * @instance: the current instance of the #NactIActionsList interface.
+ * @item: the item to be toggled/collapsed.
+ *
+ * Collapse / expand if actions has more than one profile.
+ */
+void
+nact_iactions_list_bis_toggle_collapse_object( NactIActionsList *instance, const NAObject *item )
{
- gboolean has_menu_or_action;
- SelectionIter *str;
+ static const gchar *thisfn = "nact_iactions_list_bis_toggle_collapse";
+ GtkTreeView *treeview;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gboolean iterok, stop;
+ NAObject *iter_object;
- 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_return_if_fail( NACT_IS_IACTIONS_LIST( instance ));
+ g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
- return( has_menu_or_action );
-}
+ if( st_iactions_list_initialized && !st_iactions_list_finalized ){
-static void
-filter_selection_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, SelectionIter *str )
-{
- NAObject *object;
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+ model = gtk_tree_view_get_model( treeview );
+ iterok = gtk_tree_model_get_iter_first( model, &iter );
+ stop = FALSE;
- gtk_tree_model_get( model, iter, TREE_IEDITABLE_NAOBJECT_COLUMN, &object, -1 );
+ while( iterok && !stop ){
- if( NA_IS_OBJECT_ITEM( object )){
- str->has_menu_or_action = TRUE;
- }
+ gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &iter_object, -1 );
+ if( iter_object == item ){
- g_object_unref( object );
-}
+ if( na_object_get_items_count( item ) > 1 ){
-static gboolean
-filter_selection_is_implicitely_selected( NAObject *object )
-{
- gboolean selected;
+ GtkTreePath *path = gtk_tree_model_get_path( model, &iter );
- selected = ( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object), "nact-implicit-selection" ));
+ if( gtk_tree_view_row_expanded( GTK_TREE_VIEW( treeview ), path )){
+ gtk_tree_view_collapse_row( GTK_TREE_VIEW( treeview ), path );
+ g_debug( "%s: action=%p collapsed", thisfn, ( void * ) item );
- return( selected );
-}
+ } else {
+ gtk_tree_view_expand_row( GTK_TREE_VIEW( treeview ), path, TRUE );
+ g_debug( "%s: action=%p expanded", thisfn, ( void * ) item );
+ }
-/*
- * 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;
+ gtk_tree_path_free( path );
+ }
+ stop = TRUE;
+ }
- if( NA_IS_OBJECT_ITEM( object )){
- childs = na_object_get_items( 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 );
+ g_object_unref( iter_object );
+ iterok = gtk_tree_model_iter_next( model, &iter );
}
}
}
-static gboolean
-have_dnd_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
+static void
+decrement_counters( NactIActionsList *instance, IActionsListInstanceData *ialid, GList *items )
{
- gboolean have_dnd;
+ static const gchar *thisfn = "nact_iactions_list_decrement_counters";
+ gint menus, actions, profiles;
- have_dnd = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+ g_debug( "%s: instance=%p, ialid=%p, items=%p",
+ thisfn, ( void * ) instance, ( void * ) ialid, ( void * ) items );
- return( have_dnd );
-}
+ menus = 0;
+ actions = 0;
+ profiles = 0;
+ na_object_item_count_items( items, &menus, &actions, &profiles, TRUE );
-static gboolean
-have_filter_selection_mode( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
- gboolean have_filter;
-
- have_filter = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
+ ialid->menus -= menus;
+ ialid->actions -= actions;
+ ialid->profiles -= profiles;
- return( have_filter );
+ nact_iactions_list_priv_send_list_count_updated_signal( instance, ialid );
}
/*
- * triggered by 'F2' key
- * only in edition mode
+ * when expanding a selected row which has childs
*/
static void
-inline_edition( NactTreeIEditable *instance )
+extend_selection_to_childs( NactIActionsList *instance, GtkTreeView *treeview, GtkTreeModel *model, GtkTreeIter *parent )
{
- static const gchar *thisfn = "nact_tree_ieditable_inline_edition";
- TreeIEditableInstanceData *ialid;
- GtkTreeView *treeview;
GtkTreeSelection *selection;
- GList *listrows;
- GtkTreePath *path;
- GtkTreeViewColumn *column;
-
- g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
-
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
- if( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION ){
-
- ialid->selection_changed_allowed = FALSE;
-
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- selection = gtk_tree_view_get_selection( treeview );
- listrows = gtk_tree_selection_get_selected_rows( selection, NULL );
-
- if( g_list_length( listrows ) == 1 ){
- path = ( GtkTreePath * ) listrows->data;
- column = gtk_tree_view_get_column( treeview, TREE_IEDITABLE_LABEL_COLUMN );
- gtk_tree_view_set_cursor( treeview, path, column, TRUE );
- }
-
- g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
- g_list_free( listrows );
-
- ialid->selection_changed_allowed = TRUE;
- }
-}
-
-static gboolean
-is_iduplicable_proxy( NactTreeIEditable *instance, TreeIEditableInstanceData *ialid )
-{
- gboolean is_proxy;
-
- is_proxy = ( ialid->management_mode == TREE_IEDITABLE_MANAGEMENT_MODE_EDITION );
- g_debug( "nact_tree_ieditable_is_iduplicable_proxy: is_proxy=%s", is_proxy ? "True":"False" );
-
- return( is_proxy );
-}
-
-static gboolean
-on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactTreeIEditable *instance )
-{
- /*static const gchar *thisfn = "nact_tree_ieditable_v_on_button_pres_event";
- g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
+ GtkTreeIter iter;
+ gboolean ok;
- gboolean stop = FALSE;
+ selection = gtk_tree_view_get_selection( treeview );
- /* double-click of left button */
- if( event->type == GDK_2BUTTON_PRESS && event->button == 1 ){
- nact_tree_ieditable_bis_toggle_collapse( instance );
- stop = TRUE;
- }
+ ok = gtk_tree_model_iter_children( model, &iter, parent );
- /* single click on right button */
- if( event->type == GDK_BUTTON_PRESS && event->button == 3 ){
- open_popup( instance, event );
- stop = TRUE;
+ while( ok ){
+ GtkTreePath *path = gtk_tree_model_get_path( model, &iter );
+ gtk_tree_selection_select_path( selection, path );
+ gtk_tree_path_free( path );
+ ok = gtk_tree_model_iter_next( model, &iter );
}
-
- return( stop );
}
static void
-on_edition_status_changed( NactTreeIEditable *instance, NAIDuplicable *object )
+iter_on_selection( NactIActionsList *instance, FnIterOnSelection fn_iter, gpointer user_data )
{
GtkTreeView *treeview;
- NactTreeModel *model;
- TreeIEditableInstanceData *ialid;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *listrows, *ipath;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ NAObject *object;
+ gboolean stop = FALSE;
- ialid = nact_tree_ieditable_priv_get_instance_data( instance );
+ treeview = nact_iactions_list_priv_get_actions_list_treeview( instance );
+ selection = gtk_tree_view_get_selection( treeview );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+ listrows = g_list_reverse( listrows );
- g_debug( "nact_tree_ieditable_on_edition_status_changed: instance=%p, object=%p (%s)",
- ( void * ) instance,
- ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+ for( ipath = listrows ; !stop && ipath ; ipath = ipath->next ){
- g_return_if_fail( NA_IS_OBJECT( object ));
+ path = ( GtkTreePath * ) ipath->data;
+ gtk_tree_model_get_iter( model, &iter, path );
+ gtk_tree_model_get( model, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
- nact_tree_model_display( model, NA_OBJECT( object ));
+ stop = fn_iter( instance, treeview, model, &iter, object, user_data );
- if( na_object_is_modified( object )){
- if( !g_list_find( ialid->modified_items, object )){
- ialid->modified_items = g_list_prepend( ialid->modified_items, object );
- }
- } else {
- ialid->modified_items = nact_tree_ieditable_remove_rec( ialid->modified_items, NA_OBJECT( object ));
+ g_object_unref( object );
}
- /* do not send status-changed signal while filling the tree
- */
- if( ialid->selection_changed_allowed ){
- g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_STATUS_CHANGED, NULL );
- }
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
}
-/*
- * focus is monitored to avoid an accelerator being pressed while on a tab
- * triggers an unwaited operation on the list
- * e.g. when editing an entry field on the tab, pressing Del should _not_
- * delete current row in the list !
- */
static gboolean
-on_focus_in( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance )
+toggle_collapse_iter( NactIActionsList *instance,
+ GtkTreeView *treeview,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ NAObject *object,
+ gpointer user_data )
{
- /*static const gchar *thisfn = "nact_tree_ieditable_on_focus_in";*/
- gboolean stop = FALSE;
-
- /*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
- g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_FOCUS_IN, instance );
-
- return( stop );
-}
+ guint count;
+ guint *toggle;
-static gboolean
-on_focus_out( GtkWidget *widget, GdkEventFocus *event, NactTreeIEditable *instance )
-{
- /*static const gchar *thisfn = "nact_tree_ieditable_on_focus_out";*/
- gboolean stop = FALSE;
+ toggle = ( guint * ) user_data;
- /*g_debug( "%s: widget=%p, event=%p, instance=%p", thisfn, ( void * ) widget, ( void * ) event, ( void * ) instance );*/
- g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_FOCUS_OUT, instance );
+ if( NA_IS_OBJECT_ITEM( object )){
- return( stop );
-}
+ GtkTreePath *path = gtk_tree_model_get_path( model, iter );
-static gboolean
-on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactTreeIEditable *instance )
-{
- /*static const gchar *thisfn = "nact_tree_ieditable_v_on_key_pressed_event";
- g_debug( "%s: widget=%p, event=%p, user_data=%p", thisfn, widget, event, user_data );*/
- gboolean stop = FALSE;
+ if( NA_IS_OBJECT_ITEM( object )){
+ count = na_object_get_items_count( object );
- if( event->keyval == NACT_KEY_Return || event->keyval == NACT_KEY_KP_Enter ){
- nact_tree_ieditable_bis_toggle_collapse( instance );
- stop = TRUE;
- }
+ if(( count > 1 && NA_IS_OBJECT_ACTION( object )) ||
+ ( count > 0 && NA_IS_OBJECT_MENU( object ))){
- if( event->keyval == NACT_KEY_F2 ){
- inline_edition( instance );
- stop = TRUE;
- }
+ toggle_collapse_row( treeview, path, toggle );
+ }
+ }
- if( event->keyval == NACT_KEY_Right ){
- nact_tree_ieditable_bis_expand_to_first_child( instance );
- stop = TRUE;
- }
+ gtk_tree_path_free( path );
- if( event->keyval == NACT_KEY_Left ){
- nact_tree_ieditable_bis_collapse_to_parent( instance );
- stop = TRUE;
+ /* do not extend selection */
+ if( *toggle == TOGGLE_EXPAND && FALSE ){
+ extend_selection_to_childs( instance, treeview, model, iter );
+ }
}
- return( stop );
-}
-
-/*
- * path: path of the edited row, as a string
- * text: new text
- *
- * - inform tabs so that they can update their fields
- * data = object_at_row + new_label
- * this will trigger set the object content, and other updates
- */
-static void
-on_label_edited( GtkCellRendererText *renderer, const gchar *path_str, const gchar *text, NactTreeIEditable *instance )
-{
- GtkTreeView *treeview;
- NactTreeModel *model;
- NAObject *object;
- GtkTreePath *path;
- gchar *new_text;
-
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
- path = gtk_tree_path_new_from_string( path_str );
- object = nact_tree_model_object_at_path( model, path );
- new_text = g_strdup( text );
-
- g_signal_emit_by_name( instance, TREE_IEDITABLE_SIGNAL_COLUMN_EDITED, object, new_text, TREE_IEDITABLE_LABEL_COLUMN );
+ /* do not stop iteration */
+ return( FALSE );
}
/*
- * an item has been updated in one of the tabs
- * update the treeview to reflects its new edition status
+ * toggle mode can be undefined, collapse or expand
+ * it is set on the first row
*/
static void
-on_tab_updatable_item_updated( NactTreeIEditable *instance, NAObject *object, gboolean force_display )
+toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle )
{
- static const gchar *thisfn = "nact_tree_ieditable_on_tab_updatable_item_updated";
- GtkTreeView *treeview;
- GtkTreeModel *model;
-
- g_debug( "%s: instance=%p, object=%p (%s), force_display=%s", thisfn,
- ( void * ) instance, ( void * ) object, G_OBJECT_TYPE_NAME( object ),
- force_display ? "True":"False" );
- g_return_if_fail( NACT_IS_TREE_IEDITABLE( instance ));
- g_return_if_fail( NA_IS_OBJECT( object ));
- g_return_if_fail( NA_IS_IDUPLICABLE( object ));
-
- if( object ){
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
- model = gtk_tree_view_get_model( treeview );
- if( !na_object_check_status_up( object ) && force_display ){
- on_edition_status_changed( instance, NA_IDUPLICABLE( object ));
- }
+ if( *toggle == TOGGLE_UNDEFINED ){
+ *toggle = gtk_tree_view_row_expanded( treeview, path ) ? TOGGLE_COLLAPSE : TOGGLE_EXPAND;
}
-}
-static void
-open_popup( NactTreeIEditable *instance, GdkEventButton *event )
-{
- GtkTreeView *treeview;
- GtkTreeModel *model;
- GtkTreePath *path;
-
- treeview = nact_tree_ieditable_priv_get_actions_list_treeview( instance );
-
- if( gtk_tree_view_get_path_at_pos( treeview, event->x, event->y, &path, NULL, NULL, NULL )){
- model = gtk_tree_view_get_model( treeview );
- nact_tree_ieditable_bis_select_row_at_path( instance, treeview, model, path );
- gtk_tree_path_free( path );
- nact_menubar_open_popup( BASE_WINDOW( instance ), event );
+ if( *toggle == TOGGLE_COLLAPSE ){
+ if( gtk_tree_view_row_expanded( treeview, path )){
+ gtk_tree_view_collapse_row( treeview, path );
+ }
+ } else {
+ if( !gtk_tree_view_row_expanded( treeview, path )){
+ gtk_tree_view_expand_row( treeview, path, TRUE );
+ }
}
}
#endif
diff --git a/src/nact/nact-tree-ieditable.h b/src/nact/nact-tree-ieditable.h
index 066f61e..0c63a23 100644
--- a/src/nact/nact-tree-ieditable.h
+++ b/src/nact/nact-tree-ieditable.h
@@ -47,7 +47,9 @@
* The modified count is fully recomputed after a save.
*/
-#include "nact-tree-view.h"
+#include <api/na-object.h>
+
+#include "base-window.h"
G_BEGIN_DECLS
@@ -68,16 +70,13 @@ typedef struct {
GType nact_tree_ieditable_get_type( void );
-void nact_tree_ieditable_on_view_constructed( NactTreeView *view, BaseWindow *window );
+void nact_tree_ieditable_initialize( NactTreeIEditable *instance, GtkTreeView *treeview, BaseWindow *window );
+
+void nact_tree_ieditable_insert_at_path ( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
+void nact_tree_ieditable_insert_items ( NactTreeIEditable *instance, GList *items, NAObject *sibling );
+void nact_tree_ieditable_insert_items_into( NactTreeIEditable *instance, GList *items );
#if 0
-/* signals
- */
-#define TREE_IEDITABLE_SIGNAL_LIST_COUNT_UPDATED "nact-iactions-list-count-updated"
-#define TREE_IEDITABLE_SIGNAL_FOCUS_IN "nact-iactions-list-focus-in"
-#define TREE_IEDITABLE_SIGNAL_FOCUS_OUT "nact-iactions-list-focus-out"
-#define TREE_IEDITABLE_SIGNAL_COLUMN_EDITED "nact-iactions-list-column-edited"
-#define TREE_IEDITABLE_SIGNAL_STATUS_CHANGED "nact-iactions-list-status-changed"
void nact_tree_ieditable_initial_load_toplevel( NactTreeIEditable *instance );
void nact_tree_ieditable_runtime_init_toplevel( NactTreeIEditable *instance, GList *actions );
@@ -102,9 +101,6 @@ void nact_tree_ieditable_bis_expand_to_first_child( NactTreeIEditable *inst
NAObject *nact_tree_ieditable_bis_get_item( NactTreeIEditable *instance, const gchar *id );
GList *nact_tree_ieditable_bis_get_items( NactTreeIEditable *instance );
GList *nact_tree_ieditable_bis_get_selected_items( NactTreeIEditable *instance );
-void nact_tree_ieditable_bis_insert_at_path( NactTreeIEditable *instance, GList *items, GtkTreePath *path );
-void nact_tree_ieditable_bis_insert_items( NactTreeIEditable *instance, GList *items, NAObject *sibling );
-void nact_tree_ieditable_bis_insert_into( NactTreeIEditable *instance, GList *items );
void nact_tree_ieditable_bis_list_modified_items( NactTreeIEditable *instance );
void nact_tree_ieditable_bis_remove_modified( NactTreeIEditable *instance, const NAObjectItem *item );
void nact_tree_ieditable_bis_select_first_row( NactTreeIEditable *instance );
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 95e80d7..09fdf91 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -49,6 +49,7 @@
#include "nact-main-window.h"
#include "nact-tree-model.h"
#include "nact-tree-model-priv.h"
+#include "nact-tree-ieditable.h"
/*
* call once egg_tree_multi_drag_add_drag_support( treeview ) at init time (before gtk_main)
@@ -455,7 +456,7 @@ nact_tree_model_dnd_imulti_drag_source_row_draggable( EggTreeMultiDragSource *dr
path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
gtk_tree_model_get_iter( store, &iter, path );
- gtk_tree_model_get( store, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ gtk_tree_model_get( store, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
if( NA_IS_OBJECT_PROFILE( object )){
model->private->drag_has_profiles = TRUE;
@@ -610,7 +611,7 @@ drop_inside( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData *selecti
path = gtk_tree_row_reference_get_path(( GtkTreeRowReference * ) it->data );
if( path ){
if( gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path )){
- gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, ¤t, -1 );
+ gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, TREE_COLUMN_NAOBJECT, ¤t, -1 );
g_object_unref( current );
if( copy_data ){
@@ -732,7 +733,7 @@ is_drop_possible_before_iter( NactTreeModel *model, GtkTreeIter *iter, NactMainW
drop_ok = FALSE;
*parent = NULL;
- gtk_tree_model_get( GTK_TREE_MODEL( model ), iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ gtk_tree_model_get( GTK_TREE_MODEL( model ), iter, TREE_COLUMN_NAOBJECT, &object, -1 );
g_object_unref( object );
g_debug( "%s: current object at dest is %s", thisfn, G_OBJECT_TYPE_NAME( object ));
@@ -777,7 +778,7 @@ is_drop_possible_into_dest( NactTreeModel *model, GtkTreePath *dest, NactMainWin
if( gtk_tree_path_up( path )){
if( gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &iter, path )){
- gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ gtk_tree_model_get( GTK_TREE_MODEL( model ), &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
g_object_unref( object );
g_debug( "%s: current object at parent dest is %s", thisfn, G_OBJECT_TYPE_NAME( object ));
@@ -872,6 +873,7 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData *selec
GSList *im;
GList *imported;
const gchar *selection_data_data;
+ NactTreeView *view;
gchar *dest_str = gtk_tree_path_to_string( dest );
g_debug( "%s: model=%p, dest=%p (%s), selection_data=%p",
@@ -959,10 +961,8 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData *selec
drop_done = TRUE;
}
-#if 0
- nact_iactions_list_bis_insert_at_path( NACT_IACTIONS_LIST( main_window ), imported, dest );
- nact_tree_model_dump( model );
-#endif
+ view = nact_main_window_get_items_view( main_window );
+ nact_tree_ieditable_insert_at_path( NACT_TREE_IEDITABLE( view ), imported, dest );
na_object_free_items( imported );
na_core_utils_slist_free( parms.uris );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 57b69a2..bc80646 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -50,15 +50,9 @@ struct _NactTreeModelClassPrivate {
void *empty; /* so that gcc -pedantic is happy */
};
-/* search for an object, setting the iter if found
+/* iter on tree store
*/
-typedef struct {
- GtkTreeModel *store;
- const NAObject *object;
- gboolean found;
- GtkTreeIter *iter;
-}
- ntmSearchStruct;
+typedef gboolean ( *FnIterOnStore )( const NactTreeModel *, GtkTreeStore *, GtkTreePath *, NAObject *, gpointer );
/* getting the list of items
* - mode is the indicator of the wished content
@@ -70,7 +64,7 @@ typedef struct {
}
ntmGetItems;
-/* when iterating while searching for an object
+/* when iterating while searching for an object by id
* setting the iter if found
*/
typedef struct {
@@ -78,6 +72,16 @@ typedef struct {
NAObject *object;
GtkTreeIter *iter;
}
+ ntmFindId;
+
+/* when iterating while searching for an object by its address
+ * setting the iter if found
+ */
+typedef struct {
+ const NAObject *object;
+ GtkTreeIter *iter;
+ GtkTreePath *path;
+}
ntmFindObject;
/* dump the content of the tree
@@ -106,27 +110,26 @@ static void instance_dispose( GObject *model );
static void instance_finalize( GObject *model );
static void on_initialize_model( BaseWindow *window, gpointer user_data );
-static void dump( NactTreeModel *model );
static void append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, GtkTreeIter *iter, const NAObject *object );
static void display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object );
#if 0
+static void dump( NactTreeModel *model );
static gboolean dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
#endif
static void fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, GtkTreeIter *parent );
static gboolean filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model );
-static gboolean find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
-static gboolean get_items_iter( const NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
+static gboolean find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfo );
+static gboolean find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo );
+static gboolean get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi );
static void iter_on_store( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
static gboolean iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
static void remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
static gboolean remove_items( GtkTreeStore *store, GtkTreeIter *iter );
-static gboolean search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *iter );
-static gboolean search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmSearchStruct *ntm );
+/*static gboolean search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *iter );
+static gboolean search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *ntm );*/
static gint sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data );
-static void on_finalizing_window( NactTreeModel *model, GObject *window );
-
GType
nact_tree_model_get_type( void )
{
@@ -296,11 +299,10 @@ instance_finalize( GObject *object )
* @treeview: the #GtkTreeView widget.
* @mode: management mode.
*
- * Returns: a newly created NactTreeModel object, which will take
- * care itself of its destroy by attaching a weak reference to the
- * @window.
+ * Returns: a newly created NactTreeModel object.
*
- * The returned reference is owned by the #GtkTreeView.
+ * The returned reference is owned by the #GtkTreeView, which will automatically
+ * take care of g_object_unref() its tree model when destroyint its widget.
*/
NactTreeModel *
nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mode )
@@ -348,8 +350,6 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
g_object_set_data( G_OBJECT( window ), WINDOW_DATA_TREE_MODEL, model );
- g_object_weak_ref( G_OBJECT( window ), ( GWeakNotify ) on_finalizing_window, model );
-
/* attach the model to the tree view
*/
gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
@@ -412,22 +412,7 @@ on_initialize_model( BaseWindow *window, gpointer user_data )
}
}
-/*
- * dump:
- * @model: this #NactTreeModel instance.
- *
- * Briefly dumps the content of the tree.
- */
-static void
-dump( NactTreeModel *model )
-{
- GList *items;
-
- items = nact_tree_model_get_items( model, TREE_LIST_ALL );
- na_object_dump_tree( items );
- na_object_free_items( items );
-}
-
+#if 0
/**
* nact_tree_model_display:
* @model: this #NactTreeModel instance.
@@ -464,6 +449,7 @@ nact_tree_model_display( NactTreeModel *model, NAObject *object )
/*gtk_tree_model_filter_refilter( GTK_TREE_MODEL_FILTER( model ));*/
}
}
+#endif
/**
* nact_tree_model_display_order_change:
@@ -488,41 +474,27 @@ nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode )
case IPREFS_ORDER_ALPHA_ASCENDING:
- gtk_tree_sortable_set_sort_column_id(
- GTK_TREE_SORTABLE( store ),
- IACTIONS_LIST_LABEL_COLUMN,
- GTK_SORT_ASCENDING );
-
- gtk_tree_sortable_set_sort_func(
- GTK_TREE_SORTABLE( store ),
- IACTIONS_LIST_LABEL_COLUMN,
- ( GtkTreeIterCompareFunc ) sort_actions_list,
- NULL,
- NULL );
+ gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+ TREE_COLUMN_LABEL, GTK_SORT_ASCENDING );
+
+ gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+ TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
break;
case IPREFS_ORDER_ALPHA_DESCENDING:
- gtk_tree_sortable_set_sort_column_id(
- GTK_TREE_SORTABLE( store ),
- IACTIONS_LIST_LABEL_COLUMN,
- GTK_SORT_DESCENDING );
-
- gtk_tree_sortable_set_sort_func(
- GTK_TREE_SORTABLE( store ),
- IACTIONS_LIST_LABEL_COLUMN,
- ( GtkTreeIterCompareFunc ) sort_actions_list,
- NULL,
- NULL );
+ gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+ TREE_COLUMN_LABEL, GTK_SORT_DESCENDING );
+
+ gtk_tree_sortable_set_sort_func( GTK_TREE_SORTABLE( store ),
+ TREE_COLUMN_LABEL, ( GtkTreeIterCompareFunc ) sort_actions_list, NULL, NULL );
break;
case IPREFS_ORDER_MANUAL:
default:
- gtk_tree_sortable_set_sort_column_id(
- GTK_TREE_SORTABLE( store ),
- GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID,
- 0 );
+ gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( store ),
+ GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, 0 );
break;
}
}
@@ -551,7 +523,7 @@ nact_tree_model_fill( NactTreeModel *model, GList *items )
g_return_if_fail( NACT_IS_TREE_MODEL( model ));
- g_debug( "%s: model=%p, items=%p (%d items)",
+ g_debug( "%s: model=%p, items=%p (count=%d)",
thisfn, ( void * ) model, ( void * ) items, g_list_length( items ));
if( !model->private->dispose_has_run ){
@@ -569,70 +541,6 @@ nact_tree_model_fill( NactTreeModel *model, GList *items )
}
/**
- * nact_tree_model_get_item_by_id:
- * @model: this #NactTreeModel object.
- * @id: the searched #NAObjectItem.
- *
- * Returns: a pointer on the searched #NAObjectItem if it exists, or %NULL.
- *
- * The returned pointer is owned by the underlying tree store, and should
- * not be released by the caller.
- */
-NAObjectItem *
-nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id )
-{
- static const gchar *thisfn = "nact_tree_model_get_item_by_id";
- GtkTreeStore *store;
- ntmFindObject nfo;
-
- g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
-
- nfo.object = NULL;
-
- if( !model->private->dispose_has_run ){
- g_debug( "%s: model=%p, id=%s", thisfn, ( void * ) model, id );
-
- nfo.id = ( gchar * ) id;
- store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
- iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_item_iter, &nfo );
- }
-
- return(( NAObjectItem * ) nfo.object );
-}
-
-/**
- * nact_tree_model_get_items:
- * @model: this #NactTreeModel object.
- * @mode: the content indicator for the returned list
- *
- * Returns: the content of the current store as a newly allocated list
- * which should be na_object_free_items() by the caller.
- */
-GList *
-nact_tree_model_get_items( const NactTreeModel *model, guint mode )
-{
- static const gchar *thisfn = "nact_tree_model_get_items";
- GList *items;
- GtkTreeStore *store;
- ntmGetItems ngi;
-
- g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
-
- items = NULL;
-
- if( !model->private->dispose_has_run ){
- g_debug( "%s: model=%p, mode=%x", thisfn, ( void * ) model, mode );
-
- ngi.mode = mode;
- ngi.items = NULL;
- store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
- iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) get_items_iter, &ngi );
- }
-
- return( items );
-}
-
-/**
* nact_tree_model_insert:
* @model: this #NactTreeModel instance.
* @object: a #NAObject-derived object to be inserted.
@@ -688,7 +596,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
/* may be FALSE when store is empty */
has_sibling = gtk_tree_model_get_iter( store, &sibling_iter, path );
if( has_sibling ){
- gtk_tree_model_get( store, &sibling_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &sibling_obj, -1 );
+ gtk_tree_model_get( store, &sibling_iter, TREE_COLUMN_NAOBJECT, &sibling_obj, -1 );
g_object_unref( sibling_obj );
}
g_debug( "%s: has_sibling=%s, sibling_obj=%p", thisfn, has_sibling ? "True":"False", ( void * ) sibling_obj );
@@ -701,7 +609,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
gtk_tree_model_get_iter( store, &parent_iter, parent_path );
gtk_tree_path_free( parent_path );
- gtk_tree_model_get( store, &parent_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &parent_obj, -1 );
+ gtk_tree_model_get( store, &parent_iter, TREE_COLUMN_NAOBJECT, &parent_obj, -1 );
g_object_unref( parent_obj );
if( parent && !*parent ){
@@ -722,7 +630,7 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
GTK_TREE_STORE( store ), &iter,
has_parent ? &parent_iter : NULL,
has_sibling ? &sibling_iter : NULL );
- gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+ gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, TREE_COLUMN_NAOBJECT, object, -1 );
display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
inserted_path = gtk_tree_model_get_path( store, &iter );
@@ -770,14 +678,14 @@ nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTr
g_free( path_str );
return( NULL );
}
- gtk_tree_model_get( store, &parent_iter, IACTIONS_LIST_NAOBJECT_COLUMN, parent, -1 );
+ gtk_tree_model_get( store, &parent_iter, TREE_COLUMN_NAOBJECT, parent, -1 );
g_object_unref( *parent );
na_object_insert_item( *parent, object, NULL );
na_object_set_parent( object, *parent );
gtk_tree_store_insert_after( GTK_TREE_STORE( store ), &iter, &parent_iter, NULL );
- gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+ gtk_tree_store_set( GTK_TREE_STORE( store ), &iter, TREE_COLUMN_NAOBJECT, object, -1 );
display_item( GTK_TREE_STORE( store ), model->private->treeview, &iter, object );
new_path = gtk_tree_model_get_path( store, &iter );
@@ -787,21 +695,67 @@ nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTr
}
/**
- * nact_tree_model_iter:
- * @model: this #NactTreeModel instance.
+ * nact_tree_model_get_item_by_id:
+ * @model: this #NactTreeModel object.
+ * @id: the searched #NAObjectItem.
+ *
+ * Returns: a pointer on the searched #NAObjectItem if it exists, or %NULL.
+ *
+ * The returned pointer is owned by the underlying tree store, and should
+ * not be released by the caller.
*/
-void
-nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data )
+NAObjectItem *
+nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id )
{
+ static const gchar *thisfn = "nact_tree_model_get_item_by_id";
GtkTreeStore *store;
+ ntmFindId nfi;
- g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+ g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+ nfi.object = NULL;
if( !model->private->dispose_has_run ){
+ g_debug( "%s: model=%p, id=%s", thisfn, ( void * ) model, id );
+ nfi.id = ( gchar * ) id;
store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
- iter_on_store( model, GTK_TREE_MODEL( store ), NULL, fn, user_data );
+ iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_item_iter, &nfi );
+ }
+
+ return(( NAObjectItem * ) nfi.object );
+}
+
+/**
+ * nact_tree_model_get_items:
+ * @model: this #NactTreeModel object.
+ * @mode: the content indicator for the returned list
+ *
+ * Returns: the content of the current store as a newly allocated list
+ * which should be na_object_free_items() by the caller.
+ */
+GList *
+nact_tree_model_get_items( const NactTreeModel *model, guint mode )
+{
+ static const gchar *thisfn = "nact_tree_model_get_items";
+ GList *items;
+ GtkTreeStore *store;
+ ntmGetItems ngi;
+
+ g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+ items = NULL;
+
+ if( !model->private->dispose_has_run ){
+ g_debug( "%s: model=%p, mode=%x", thisfn, ( void * ) model, mode );
+
+ ngi.mode = mode;
+ ngi.items = NULL;
+ store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+ iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) get_items_iter, &ngi );
}
+
+ return( items );
}
/**
@@ -811,10 +765,11 @@ nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data
*
* Returns: the #NAObject at the given @path if any, or NULL.
*
- * The reference count of the object is not modified.
+ * The reference count of the object is not modified. The returned reference
+ * is owned by the tree store and should not be released by the caller.
*/
NAObject *
-nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
+nact_tree_model_object_at_path( const NactTreeModel *model, GtkTreePath *path )
{
NAObject *object;
GtkTreeModel *store;
@@ -827,9 +782,8 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
if( !model->private->dispose_has_run ){
store = gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model ));
-
if( gtk_tree_model_get_iter( store, &iter, path )){
- gtk_tree_model_get( store, &iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
+ gtk_tree_model_get( store, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
g_object_unref( object );
}
}
@@ -838,6 +792,62 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
}
/**
+ * nact_tree_model_object_to_path:
+ * @model: this #NactTreeModel.
+ * @object: the searched NAObject.
+ *
+ * Returns: a newly allocated GtkTreePath which is the current position
+ * of @object in the tree store, or %NULL.
+ *
+ * The returned path should be gtk_tree_path_free() by the caller.
+ */
+GtkTreePath *
+nact_tree_model_object_to_path( const NactTreeModel *model, const NAObject *object )
+{
+ static const gchar *thisfn = "nact_tree_model_object_to_path";
+ ntmFindObject nfo;
+ GtkTreeIter iter;
+ GtkTreeStore *store;
+
+ g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+ nfo.path = NULL;
+
+ if( !model->private->dispose_has_run ){
+ g_debug( "%s: model=%p, object=%p (%s)",
+ thisfn, ( void * ) model, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ nfo.object = object;
+ nfo.iter = &iter;
+
+ store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+ iter_on_store( model, GTK_TREE_MODEL( store ), NULL, ( FnIterOnStore ) find_object_iter, &nfo );
+ }
+
+ return( nfo.path );
+}
+
+#if 0
+/**
+ * nact_tree_model_iter:
+ * @model: this #NactTreeModel instance.
+ */
+void
+nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data )
+{
+ GtkTreeStore *store;
+
+ g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+ if( !model->private->dispose_has_run ){
+
+ store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+ iter_on_store( model, GTK_TREE_MODEL( store ), NULL, fn, user_data );
+ }
+}
+#endif
+
+/**
* nact_tree_model_remove:
* @model: this #NactTreeModel instance.
* @object: the #NAObject to be deleted.
@@ -849,28 +859,32 @@ nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path )
GtkTreePath *
nact_tree_model_remove( NactTreeModel *model, NAObject *object )
{
+ GtkTreePath *path;
static const gchar *thisfn = "nact_tree_model_remove";
GtkTreeIter iter;
GtkTreeStore *store;
NAObjectItem *parent;
- GtkTreePath *path = NULL;
- g_debug( "%s: model=%p, object=%p (%s)",
- thisfn, ( void * ) model, ( void * ) object, object ? G_OBJECT_TYPE_NAME( object ) : "(null)" );
g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+ path = NULL;
+
if( !model->private->dispose_has_run ){
+ g_debug( "%s: model=%p, object=%p (%s)",
+ thisfn, ( void * ) model, ( void * ) object, object ? G_OBJECT_TYPE_NAME( object ) : "null" );
- store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
+ path = nact_tree_model_object_to_path( model, object );
- if( search_for_object( model, GTK_TREE_MODEL( store ), object, &iter )){
+ if( path != NULL ){
+ gtk_tree_path_free( path );
+ store = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
parent = na_object_get_parent( object );
g_debug( "%s: object=%p, parent=%p", thisfn, ( void * ) object, ( void * ) parent );
if( parent ){
na_object_remove_item( parent, object );
na_object_check_status_up( parent );
}
- path = gtk_tree_model_get_path( GTK_TREE_MODEL( store ), &iter );
+ gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), &iter, path );
remove_items( store, &iter );
}
}
@@ -885,7 +899,7 @@ append_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *parent, Gt
( void * ) object, G_OBJECT( object )->ref_count, ( void * ) parent );*/
gtk_tree_store_append( model, iter, parent );
- gtk_tree_store_set( model, iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
+ gtk_tree_store_set( model, iter, TREE_COLUMN_NAOBJECT, object, -1 );
display_item( model, treeview, iter, object );
}
@@ -893,18 +907,34 @@ static void
display_item( GtkTreeStore *model, GtkTreeView *treeview, GtkTreeIter *iter, const NAObject *object )
{
gchar *label = na_object_get_label( object );
- gtk_tree_store_set( model, iter, IACTIONS_LIST_LABEL_COLUMN, label, -1 );
+ gtk_tree_store_set( model, iter, TREE_COLUMN_LABEL, label, -1 );
g_free( label );
if( NA_IS_OBJECT_ITEM( object )){
gchar *icon_name = na_object_get_icon( object );
GdkPixbuf *icon = base_gtk_utils_get_pixbuf( icon_name, GTK_WIDGET( treeview ), GTK_ICON_SIZE_MENU );
- gtk_tree_store_set( model, iter, IACTIONS_LIST_ICON_COLUMN, icon, -1 );
+ gtk_tree_store_set( model, iter, TREE_COLUMN_ICON, icon, -1 );
g_object_unref( icon );
}
}
#if 0
+/*
+ * dump:
+ * @model: this #NactTreeModel instance.
+ *
+ * Briefly dumps the content of the tree.
+ */
+static void
+dump( NactTreeModel *model )
+{
+ GList *items;
+
+ items = nact_tree_model_get_items( model, TREE_LIST_ALL );
+ na_object_dump_tree( items );
+ na_object_free_items( items );
+}
+
static gboolean
dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm )
{
@@ -966,60 +996,64 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, G
}
/*
- * only display profiles when we are in edition mode
+ * Only display profiles when we are in edition mode.
+ *
+ * This function is called as soon as a new row is created in the tree store,
+ * so is called the first time _before_ the NAObject be set on the row.
*/
static gboolean
filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model )
{
- /*static const gchar *thisfn = "nact_tree_model_filter_visible";*/
NAObject *object;
NAObjectAction *action;
gint count;
- /*g_debug( "%s: model=%p, iter=%p, window=%p", thisfn, ( void * ) model, ( void * ) iter, ( void * ) window );*/
- /*g_debug( "%s at %p", G_OBJECT_TYPE_NAME( model ), ( void * ) model );*/
- /* is a GtkTreeStore */
+ gtk_tree_model_get( store, iter, TREE_COLUMN_NAOBJECT, &object, -1 );
- gtk_tree_model_get( store, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
- g_object_unref( object );
- /*na_object_dump( object );*/
+ if( object ){
+ g_object_unref( object );
- /* an action or a menu
- */
- if( NA_IS_OBJECT_ITEM( object )){
- return( TRUE );
- }
+ /* an action or a menu are always displayed, whatever the current
+ * management mode may be
+ */
+ if( NA_IS_OBJECT_ITEM( object )){
+ return( TRUE );
+ }
- g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
+ /* profiles are just never displayed in selection mode
+ * in edition mode, they are displayed only when the action has
+ * more than one profile
+ */
+ g_return_val_if_fail( NA_IS_OBJECT_PROFILE( object ), FALSE );
- if( NACT_TREE_MODEL( model )->private->mode != TREE_MODE_EDITION ){
- return( FALSE );
- }
+ if( NACT_TREE_MODEL( model )->private->mode == TREE_MODE_SELECTION ){
+ return( FALSE );
+ }
- action = NA_OBJECT_ACTION( na_object_get_parent( object ));
- count = na_object_get_items_count( action );
- /*g_debug( "action=%p: count=%d", ( void * ) action, count );*/
- /*return( TRUE );*/
- return( count > 1 );
+ action = NA_OBJECT_ACTION( na_object_get_parent( object ));
+ count = na_object_get_items_count( action );
+ return( count > 1 );
+ }
+ return( FALSE );
}
/*
* search for an object, given its id
*/
static gboolean
-find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFindObject *nfo )
+find_item_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindId *nfi )
{
gchar *id;
gboolean found = FALSE;
if( NA_IS_OBJECT_ITEM( object )){
id = na_object_get_id( object );
- found = ( g_ascii_strcasecmp( id, nfo->id ) == 0 );
+ found = ( g_ascii_strcasecmp( id, nfi->id ) == 0 );
g_free( id );
if( found ){
- nfo->object = object;
+ nfi->object = object;
}
}
@@ -1027,6 +1061,19 @@ find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFi
return( found );
}
+static gboolean
+find_object_iter( NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmFindObject *nfo )
+{
+ if( object == nfo->object ){
+ if( gtk_tree_model_get_iter( GTK_TREE_MODEL( store ), nfo->iter, path )){
+ nfo->path = gtk_tree_path_copy( path );
+ }
+ }
+
+ /* stop iteration when found */
+ return( nfo->path != NULL );
+}
+
/*
* Builds the tree by iterating on the store
* we may want selected, modified or both, or a combination of these modes
@@ -1034,7 +1081,7 @@ find_item_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmFi
* This function is called from iter_on_store_item();
*/
static gboolean
-get_items_iter( const NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmGetItems *ngi )
+get_items_iter( const NactTreeModel *model, GtkTreeStore *store, GtkTreePath *path, NAObject *object, ntmGetItems *ngi )
{
if( ngi->mode == TREE_LIST_ALL ){
if( gtk_tree_path_get_depth( path ) == 1 ){
@@ -1080,7 +1127,7 @@ iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter
*/
path = gtk_tree_model_get_path( store, iter );
- stop = ( *fn )( model, path, object, user_data );
+ stop = ( *fn )( model, GTK_TREE_STORE( store ), path, object, user_data );
gtk_tree_path_free( path );
if( !stop ){
@@ -1097,24 +1144,24 @@ iter_on_store_item( const NactTreeModel *model, GtkTreeModel *store, GtkTreeIter
static void
remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object )
{
- ntmFindObject nfo;
+ ntmFindId nfi;
GtkTreeIter iter;
if( NA_IS_OBJECT_ITEM( object )){
- nfo.id = na_object_get_id( object );
- nfo.object = NULL;
- nfo.iter = &iter;
+ nfi.id = na_object_get_id( object );
+ nfi.object = NULL;
+ nfi.iter = &iter;
- iter_on_store( model, store, NULL, ( FnIterOnStore ) find_item_iter, &nfo );
+ iter_on_store( model, store, NULL, ( FnIterOnStore ) find_item_iter, &nfi );
- if( nfo.object ){
+ if( nfi.object ){
g_debug( "nact_tree_model_remove_if_exists: removing %s %p",
G_OBJECT_TYPE_NAME( object ), ( void * ) object );
- gtk_tree_store_remove( GTK_TREE_STORE( store ), nfo.iter );
+ gtk_tree_store_remove( GTK_TREE_STORE( store ), nfi.iter );
}
- g_free( nfo.id );
+ g_free( nfi.id );
}
}
@@ -1136,43 +1183,6 @@ remove_items( GtkTreeStore *store, GtkTreeIter *iter )
return( valid );
}
-static gboolean
-search_for_object( NactTreeModel *model, GtkTreeModel *store, const NAObject *object, GtkTreeIter *result_iter )
-{
- gboolean found = FALSE;
- ntmSearchStruct *ntm;
- GtkTreeIter iter;
-
- ntm = g_new0( ntmSearchStruct, 1 );
- ntm->store = store;
- ntm->object = object;
- ntm->found = FALSE;
- ntm->iter = &iter;
-
- iter_on_store( model, store, NULL, ( FnIterOnStore ) search_for_object_iter, ntm );
-
- if( ntm->found ){
- found = TRUE;
- memcpy( result_iter, ntm->iter, sizeof( GtkTreeIter ));
- }
-
- g_free( ntm );
- return( found );
-}
-
-static gboolean
-search_for_object_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmSearchStruct *ntm )
-{
- if( object == ntm->object ){
- if( gtk_tree_model_get_iter( ntm->store, ntm->iter, path )){
- ntm->found = TRUE;
- }
- }
-
- /* stop iteration when found */
- return( ntm->found );
-}
-
static gint
sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer user_data )
{
@@ -1182,8 +1192,8 @@ sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer
/*g_debug( "%s: model=%p, a=%p, b=%p, window=%p", thisfn, ( void * ) model, ( void * ) a, ( void * ) b, ( void * ) window );*/
- gtk_tree_model_get( model, a, IACTIONS_LIST_NAOBJECT_COLUMN, &obj_a, -1 );
- gtk_tree_model_get( model, b, IACTIONS_LIST_NAOBJECT_COLUMN, &obj_b, -1 );
+ gtk_tree_model_get( model, a, TREE_COLUMN_NAOBJECT, &obj_a, -1 );
+ gtk_tree_model_get( model, b, TREE_COLUMN_NAOBJECT, &obj_b, -1 );
g_object_unref( obj_b );
g_object_unref( obj_a );
@@ -1197,18 +1207,3 @@ sort_actions_list( GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer
/*g_debug( "%s: ret=%d", thisfn, ret );*/
return( ret );
}
-
-static void
-on_finalizing_window( NactTreeModel *model, GObject *window )
-{
- static const gchar *thisfn = "nact_tree_model_on_finalizing_window";
-
- g_return_if_fail( NACT_IS_TREE_MODEL( model ));
-
- g_debug( "%s: model=%p (%s), window=%p",
- thisfn, ( void * ) model, G_OBJECT_TYPE_NAME( model ), ( void * ) window );
-
- dump( model );
-
- g_object_unref( model );
-}
diff --git a/src/nact/nact-tree-model.h b/src/nact/nact-tree-model.h
index 2089209..4c18322 100644
--- a/src/nact/nact-tree-model.h
+++ b/src/nact/nact-tree-model.h
@@ -76,15 +76,6 @@ typedef struct {
}
NactTreeModelClass;
-/* column ordering of the tree view
- */
-enum {
- IACTIONS_LIST_ICON_COLUMN = 0,
- IACTIONS_LIST_LABEL_COLUMN,
- IACTIONS_LIST_NAOBJECT_COLUMN,
- IACTIONS_LIST_N_COLUMN
-};
-
/**
* Column ordering in the tree view
*/
@@ -104,18 +95,18 @@ enum {
TREE_LIST_ALL = 0xff,
};
-/* iter on tree store
- */
-typedef gboolean ( *FnIterOnStore )( const NactTreeModel *, GtkTreePath *, NAObject *, gpointer );
-
GType nact_tree_model_get_type( void );
NactTreeModel *nact_tree_model_new( BaseWindow *window, GtkTreeView *view, NactTreeMode mode );
-void nact_tree_model_fill( NactTreeModel *model, GList *items );
+void nact_tree_model_fill ( NactTreeModel *model, GList *items );
+GtkTreePath *nact_tree_model_insert ( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
+GtkTreePath *nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
NAObjectItem *nact_tree_model_get_item_by_id( const NactTreeModel *model, const gchar *id );
GList *nact_tree_model_get_items ( const NactTreeModel *model, guint mode );
+NAObject *nact_tree_model_object_at_path( const NactTreeModel *model, GtkTreePath *path );
+GtkTreePath *nact_tree_model_object_to_path( const NactTreeModel *model, const NAObject *object );
/* find an item
* get items (all, selected, modified)
@@ -124,12 +115,9 @@ GList *nact_tree_model_get_items ( const NactTreeModel *model, guint
*/
/* *** */
-void nact_tree_model_display( NactTreeModel *model, NAObject *object );
+/*void nact_tree_model_display( NactTreeModel *model, NAObject *object );*/
void nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode );
-GtkTreePath *nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
-GtkTreePath *nact_tree_model_insert_into( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
-void nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );
-NAObject *nact_tree_model_object_at_path( NactTreeModel *model, GtkTreePath *path );
+/*void nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );*/
GtkTreePath *nact_tree_model_remove( NactTreeModel *model, NAObject *object );
/* *** */
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index d98b8a5..3c9d78e 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -39,6 +39,7 @@
#include "nact-marshal.h"
#include "nact-tree-view.h"
#include "nact-tree-model.h"
+#include "nact-tree-ieditable.h"
/* private class data
*/
@@ -120,6 +121,7 @@ static GObjectClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( NactTreeViewClass *klass );
+static void tree_ieditable_iface_init( NactTreeIEditableInterface *iface );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
@@ -138,13 +140,13 @@ static void on_treeview_selection_changed( GtkTreeSelection *selection, Base
static void on_content_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, NAObject *edited );
static void on_selection_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, GList *selected_items );
static void clear_selection( NactTreeView *view );
+static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeView *view );
static void extend_selection_to_children( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *parent );
static GList *get_selected_items( NactTreeView *view );
static void iter_on_selection( NactTreeView *view, FnIterOnSelection fn_iter, gpointer user_data );
static void navigate_to_child( NactTreeView *view );
static void navigate_to_parent( NactTreeView *view );
static void open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event );
-static void select_row_at_path( NactTreeView *view, GtkTreePath *path );
static void select_row_at_path_by_string( NactTreeView *view, const gchar *path );
static void toggle_collapse( NactTreeView *view );
static gboolean toggle_collapse_iter( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *iter, NAObject *object, gpointer user_data );
@@ -181,10 +183,18 @@ register_type( void )
( GInstanceInitFunc ) instance_init
};
+ static const GInterfaceInfo tree_ieditable_iface_info = {
+ ( GInterfaceInitFunc ) tree_ieditable_iface_init,
+ NULL,
+ NULL
+ };
+
g_debug( "%s", thisfn );
type = g_type_register_static( G_TYPE_OBJECT, "NactTreeView", &info, 0 );
+ g_type_add_interface_static( type, NACT_TREE_IEDITABLE_TYPE, &tree_ieditable_iface_info );
+
return( type );
}
@@ -428,6 +438,14 @@ class_init( NactTreeViewClass *klass )
}
static void
+tree_ieditable_iface_init( NactTreeIEditableInterface *iface )
+{
+ static const gchar *thisfn = "nact_main_window_tree_ieditable_iface_init";
+
+ g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
+}
+
+static void
instance_init( GTypeInstance *instance, gpointer klass )
{
static const gchar *thisfn = "nact_tree_view_instance_init";
@@ -615,6 +633,7 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
GtkTreeViewColumn *column;
GtkCellRenderer *renderer;
GtkTreeSelection *selection;
+ GList *renderers;
VIEW_WINDOW_VOID( window );
@@ -657,6 +676,16 @@ on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_d
/* misc properties
*/
gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
+
+ if( view->private->mode == TREE_MODE_EDITION ){
+ nact_tree_ieditable_initialize( NACT_TREE_IEDITABLE( view ), treeview, window );
+
+ column = gtk_tree_view_get_column( treeview, TREE_COLUMN_LABEL );
+ renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
+ renderer = GTK_CELL_RENDERER( renderers->data );
+ gtk_tree_view_column_set_cell_data_func(
+ column, renderer, ( GtkTreeCellDataFunc ) display_label, view, NULL );
+ }
}
}
@@ -978,6 +1007,92 @@ nact_tree_view_get_items( const NactTreeView *view )
return( items );
}
+/**
+ * nact_tree_view_get_window:
+ * @view: this #NactTreeView instance.
+ *
+ * Returns: the #BaseWindow.
+ */
+BaseWindow *
+nact_tree_view_get_window( const NactTreeView *view )
+{
+ BaseWindow *window;
+
+ g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), NULL );
+
+ window = NULL;
+
+ if( !view->private->dispose_has_run ){
+
+ window = view->private->window;
+ }
+
+ return( window );
+}
+
+/**
+ * nact_tree_view_select_row_at_path:
+ *
+ *
+ * Select the row at the required path, or the immediate previous, or
+ * the next following, or eventually the immediate parent.
+ *
+ * If nothing can be selected (and notify is allowed), at least send a
+ * message with an empty selection.
+ */
+void
+nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path )
+{
+ static const gchar *thisfn = "nact_tree_view_select_row_at_path";
+ gchar *path_str;
+ GtkTreeIter iter;
+ GtkTreeModel *model;
+ gboolean something = FALSE;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+ if( !view->private->dispose_has_run ){
+
+ path_str = gtk_tree_path_to_string( path );
+ g_debug( "%s: view=%p, path=%s", thisfn, ( void * ) view, path_str );
+ g_free( path_str );
+
+ if( path ){
+ gtk_tree_view_expand_to_path( view->private->tree_view, path );
+ model = gtk_tree_view_get_model( view->private->tree_view );
+
+ if( gtk_tree_model_get_iter( model, &iter, path )){
+ gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+ something = TRUE;
+
+ } else if( gtk_tree_path_prev( path ) && gtk_tree_model_get_iter( model, &iter, path )){
+ gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+ something = TRUE;
+
+ } else {
+ gtk_tree_path_next( path );
+ if( gtk_tree_model_get_iter( model, &iter, path )){
+ gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+ something = TRUE;
+
+ } else if( gtk_tree_path_get_depth( path ) > 1 &&
+ gtk_tree_path_up( path ) &&
+ gtk_tree_model_get_iter( model, &iter, path )){
+
+ gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
+ something = TRUE;
+ }
+ }
+ }
+
+ if( !something ){
+ if( view->private->notify_allowed ){
+ g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, view, NULL );
+ }
+ }
+ }
+}
+
static void
clear_selection( NactTreeView *view )
{
@@ -988,6 +1103,48 @@ clear_selection( NactTreeView *view )
}
/*
+ * item modified: italic
+ * item not saveable (invalid): red
+ */
+static void
+display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, NactTreeView *view )
+{
+ NAObject *object;
+ gchar *label;
+ gboolean modified = FALSE;
+ gboolean valid = TRUE;
+ NAObjectItem *item;
+
+ g_return_if_fail( view->private->mode == TREE_MODE_EDITION );
+
+ gtk_tree_model_get( model, iter, TREE_COLUMN_NAOBJECT, &object, -1 );
+
+ if( object ){
+ g_object_unref( object );
+ g_return_if_fail( NA_IS_OBJECT( object ));
+
+ label = na_object_get_label( object );
+ g_object_set( cell, "style-set", FALSE, NULL );
+ g_object_set( cell, "foreground-set", FALSE, NULL );
+
+ modified = na_object_is_modified( object );
+ valid = na_object_is_valid( object );
+ item = NA_IS_OBJECT_PROFILE( object ) ? na_object_get_parent( object ) : NA_OBJECT_ITEM( object );
+
+ if( modified ){
+ g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
+ }
+
+ if( !valid ){
+ g_object_set( cell, "foreground", "Red", "foreground-set", TRUE, NULL );
+ }
+
+ g_object_set( cell, "text", label, NULL );
+ g_free( label );
+ }
+}
+
+/*
* when expanding a selected row which has childs
*/
static void
@@ -1115,7 +1272,7 @@ navigate_to_child( NactTreeView *view )
if( gtk_tree_model_iter_has_child( model, &iter )){
child_path = gtk_tree_path_copy( path );
gtk_tree_path_append_index( child_path, 0 );
- select_row_at_path( view, child_path );
+ nact_tree_view_select_row_at_path( view, child_path );
gtk_tree_path_free( child_path );
}
}
@@ -1157,7 +1314,7 @@ navigate_to_parent( NactTreeView *view )
} else if( gtk_tree_path_get_depth( path ) > 1 ){
parent_path = gtk_tree_path_copy( path );
gtk_tree_path_up( parent_path );
- select_row_at_path( view, parent_path );
+ nact_tree_view_select_row_at_path( view, parent_path );
gtk_tree_path_free( parent_path );
}
}
@@ -1172,75 +1329,20 @@ open_popup( BaseWindow *window, NactTreeView *view, GdkEventButton *event )
GtkTreePath *path;
if( gtk_tree_view_get_path_at_pos( view->private->tree_view, event->x, event->y, &path, NULL, NULL, NULL )){
- select_row_at_path( view, path );
+ nact_tree_view_select_row_at_path( view, path );
gtk_tree_path_free( path );
}
g_signal_emit_by_name( window, TREE_SIGNAL_CONTEXT_MENU, view, event );
}
-/*
- * Select the row at the required path, or the immediate previous, or
- * the next following, or eventually the immediate parent.
- *
- * If nothing can be selected (and notify is allowed), at least send a
- * message with an empty selection.
- */
-static void
-select_row_at_path( NactTreeView *view, GtkTreePath *path )
-{
- static const gchar *thisfn = "nact_tree_view_select_row_at_path";
- gchar *path_str;
- GtkTreeIter iter;
- GtkTreeModel *model;
- gboolean something = FALSE;
-
- path_str = gtk_tree_path_to_string( path );
- g_debug( "%s: view=%p, path=%s", thisfn, ( void * ) view, path_str );
- g_free( path_str );
-
- if( path ){
- gtk_tree_view_expand_to_path( view->private->tree_view, path );
- model = gtk_tree_view_get_model( view->private->tree_view );
-
- if( gtk_tree_model_get_iter( model, &iter, path )){
- gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
- something = TRUE;
-
- } else if( gtk_tree_path_prev( path ) && gtk_tree_model_get_iter( model, &iter, path )){
- gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
- something = TRUE;
-
- } else {
- gtk_tree_path_next( path );
- if( gtk_tree_model_get_iter( model, &iter, path )){
- gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
- something = TRUE;
-
- } else if( gtk_tree_path_get_depth( path ) > 1 &&
- gtk_tree_path_up( path ) &&
- gtk_tree_model_get_iter( model, &iter, path )){
-
- gtk_tree_view_set_cursor( view->private->tree_view, path, NULL, FALSE );
- something = TRUE;
- }
- }
- }
-
- if( !something ){
- if( view->private->notify_allowed ){
- g_signal_emit_by_name( view->private->window, TREE_SIGNAL_SELECTION_CHANGED, view, NULL );
- }
- }
-}
-
static void
select_row_at_path_by_string( NactTreeView *view, const gchar *path_str )
{
GtkTreePath *path;
path = gtk_tree_path_new_from_string( path_str );
- select_row_at_path( view, path );
+ nact_tree_view_select_row_at_path( view, path );
gtk_tree_path_free( path );
}
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index 856e4ee..0f4883b 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -112,6 +112,9 @@ void nact_tree_view_collapse_all ( const NactTreeView *view );
void nact_tree_view_expand_all ( const NactTreeView *view );
NAObjectItem *nact_tree_view_get_item_by_id( const NactTreeView *view, const gchar *id );
GList *nact_tree_view_get_items ( const NactTreeView *view );
+BaseWindow *nact_tree_view_get_window ( const NactTreeView *view );
+
+void nact_tree_view_select_row_at_path( NactTreeView *view, GtkTreePath *path );
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]