[nautilus-actions] New NactTreeView convenience class
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] New NactTreeView convenience class
- Date: Fri, 11 Feb 2011 00:18:14 +0000 (UTC)
commit f44954e16baf30056c8b1862c200c8916cae43c7
Author: Pierre <pierre vfedora13 virtuals pwi>
Date: Thu Feb 3 15:23:01 2011 +0100
New NactTreeView convenience class
ChangeLog | 76 +++
po/POTFILES.in | 6 +-
src/api/na-object-api.h | 4 +-
src/api/na-object-item.h | 6 +-
src/core/na-io-provider.c | 2 +-
src/core/na-object-item.c | 43 +-
src/core/na-object.c | 97 ++--
src/core/na-pivot.c | 14 +-
src/nact/Makefile.am | 2 +
src/nact/nact-assistant-export.c | 188 ++-----
src/nact/nact-assistant-import.c | 2 +-
src/nact/nact-iactions-list-bis.c | 2 +-
src/nact/nact-iactions-list-priv.c | 12 +
src/nact/nact-iactions-list.c | 2 +-
src/nact/nact-iactions-list.h | 5 +
src/nact/nact-main-window.c | 33 +-
src/nact/nact-main-window.h | 1 +
src/nact/nact-marshal.def | 3 +
src/nact/nact-menubar-edit.c | 14 +-
src/nact/nact-menubar-file.c | 6 +-
src/nact/nact-menubar-maintainer.c | 2 +-
src/nact/nact-menubar.c | 25 +-
src/nact/nact-tree-model-dnd.c | 2 +-
src/nact/nact-tree-model.c | 57 ++-
src/nact/nact-tree-model.h | 1 +
src/nact/nact-tree-view.c | 1072 ++++++++++++++++++++++++++++++++++++
src/nact/nact-tree-view.h | 117 ++++
src/plugin-menu/nautilus-actions.c | 2 +-
28 files changed, 1509 insertions(+), 287 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 20b067a..2d7b339 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,81 @@
2011-02-02 Pierre Wieser <pwieser trychlos org>
+ * src/nact/nact-tree-model.c:
+ * src/nact/nact-tree-model.h (nact_tree_model_get_items):
+ * src/nact/nact-tree-view.c:
+ * src/nact/nact-tree-view.h (nact_tree_view_get_items): New functions.
+
+ Allow an items list to be referenced in a new list.
+
+ * src/api/na-object-api.h (na_object_ref_items): New macro.
+
+ * src/api/na-object-item.h:
+ * src/core/na-object-item.c (na_object_item_ref_items): New function.
+
+ * src/nact/nact-assistant-export.c
+ (instance_dispose, on_tree_view_selection_changed): Updated accordingly.
+
+ Review NAObject reference management
+
+ * src/api/na-object-api.h
+ (na_object_unref_items, na_object_unref_items_rec): Removed macros.
+ (na_object_free_items): New macro.
+
+ * src/api/na-object-item.h:
+ * src/core/na-object-item.c
+ (na_object_item_unref_items, na_object_item_unref_items_rec): Removed functions.
+ (na_object_item_free_items): New function.
+
+ * src/core/na-io-provider.c (na_io_provider_load_items):
+ * src/core/na-object.c (na_object_object_ref, na_object_object_unref):
+ * src/core/na-pivot.c (instance_dispose, na_pivot_load_items,
+ na_pivot_set_new_items):
+ * src/nact/nact-assistant-import.c (assistant_apply):
+ * src/nact/nact-iactions-list-bis.c (nact_iactions_list_bis_get_items):
+ * src/nact/nact-iactions-list.c (free_items_callback):
+ * src/nact/nact-main-menubar-edit.c (nact_main_menubar_edit_on_cut,
+ nact_main_menubar_edit_on_copy, nact_main_menubar_edit_on_paste,
+ nact_main_menubar_edit_on_paste_into,
+ nact_main_menubar_edit_on_duplicate, nact_main_menubar_edit_on_delete):
+ * src/nact/nact-main-menubar-file.c
+ (nact_main_menubar_file_on_new_menu,
+ nact_main_menubar_file_on_new_action,
+ nact_main_menubar_file_on_new_profile):
+ * src/nact/nact-main-menubar-maintainer.c
+ (nact_main_menubar_maintainer_on_dump_selection):
+ * src/nact/nact-main-menubar.c (on_update_sensitivities):
+ * src/nact/nact-main-window.c (instance_dispose,
+ nact_main_window_remove_deleted, reload):
+ * src/nact/nact-tree-model-dnd.c (drop_uri_list):
+ * src/nact/nact-tree-model.c (fill_tree_store):
+ * src/nact/nact-tree-view.c (on_selection_changed_cleanup_handler):
+ * src/plugin-menu/nautilus-actions.c (get_menus_items): Updated
+ accordingl
+ * src/nact/nact-main-menubar-maintainer.c
+ (nact_main_menubar_maintainer_on_dump_selection):
+ * src/nact/nact-main-menubar.c (on_update_sensitivities):
+ * src/nact/nact-main-window.c (instance_dispose,
+ nact_main_window_remove_deleted, reload):
+ * src/nact/nact-tree-model-dnd.c (drop_uri_list):
+ * src/nact/nact-tree-model.c (fill_tree_store):
+ * src/nact/nact-tree-view.c (on_selection_changed_cleanup_handler):
+ * src/plugin-menu/nautilus-actions.c (get_menus_items):
+ Updated accordingly.
+
+ New NactTreeView convenience class
+
+ * src/nact/nact-tree-view.c:
+ * src/nact/nact-tree-view.h: New files.
+
+ * src/nact/Makefile.am:
+ * src/nact/nact-assistant-export.c:
+ * src/nact/nact-iactions-list-priv.c:
+ * src/nact/nact-iactions-list.h:
+ * src/nact/nact-marshal.list:
+ * src/nact/nact-tree-model.c: Updated accordingly.
+
+2011-02-02 Pierre Wieser <pwieser trychlos org>
+
Refactoring of menubar files:
- nact-main-menubar-*.c are renamed as nact-menubar-*.c.
- nact-main-menubar-*.h are removed.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9d7a1d4..b3e44c5 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -45,11 +45,11 @@ src/nact/nact-ifolders-tab.c
src/nact/nact-imimetypes-tab.c
src/nact/nact-iproperties-tab.c
src/nact/nact-ischemes-tab.c
-src/nact/nact-main-menubar.c
-src/nact/nact-main-menubar-edit.c
-src/nact/nact-main-menubar-file.c
src/nact/nact-main-window.c
src/nact/nact-match-list.c
+src/nact/nact-menubar.c
+src/nact/nact-menubar-edit.c
+src/nact/nact-menubar-file.c
[type: gettext/glade] src/nact/nact-preferences.ui
src/nact/nact-providers-list.c
src/nact/nact-schemes-list.c
diff --git a/src/api/na-object-api.h b/src/api/na-object-api.h
index 1c3e3c3..becbd26 100644
--- a/src/api/na-object-api.h
+++ b/src/api/na-object-api.h
@@ -132,8 +132,8 @@ G_BEGIN_DECLS
#define na_object_get_items_count( obj ) na_object_item_get_items_count( NA_OBJECT_ITEM( obj ))
#define na_object_count_items( list, cm, ca, cp, brec ) na_object_item_count_items( list, ( cm ), ( ca ), ( cp ), ( brec ))
-#define na_object_unref_items( tree ) na_object_item_unref_items( tree )
-#define na_object_unref_selected_items( tree ) na_object_item_unref_items_rec( tree )
+#define na_object_copyref_items( tree ) na_object_item_copyref_items( tree )
+#define na_object_free_items( tree ) na_object_item_free_items( tree )
#define na_object_is_finally_writable( obj, r ) na_object_item_is_finally_writable( NA_OBJECT_ITEM( obj ), ( r ))
#define na_object_set_writability_status( obj, w, r ) na_object_item_set_writability_status( NA_OBJECT_ITEM( obj ), ( w ), ( r ))
diff --git a/src/api/na-object-item.h b/src/api/na-object-item.h
index 495991f..fd125a0 100644
--- a/src/api/na-object-item.h
+++ b/src/api/na-object-item.h
@@ -103,9 +103,9 @@ void na_object_item_remove_item ( NAObjectItem *item, const NAObjectId *c
guint na_object_item_get_items_count( const NAObjectItem *item );
-void na_object_item_count_items( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
-void na_object_item_unref_items( GList *items );
-void na_object_item_unref_items_rec( GList *items );
+void na_object_item_count_items ( GList *items, gint *menus, gint *actions, gint *profiles, gboolean recurse );
+GList *na_object_item_copyref_items( GList *items );
+GList *na_object_item_free_items ( GList *items );
void na_object_item_deals_with_version ( NAObjectItem *item );
void na_object_item_rebuild_children_slist( NAObjectItem *item );
diff --git a/src/core/na-io-provider.c b/src/core/na-io-provider.c
index b107f12..fcbb37b 100644
--- a/src/core/na-io-provider.c
+++ b/src/core/na-io-provider.c
@@ -621,7 +621,7 @@ na_io_provider_is_finally_writable( const NAIOProvider *provider, guint *reason
* in display order. This tree contains #NAObjectMenu menus, along with
* #NAObjectAction actions and their #NAObjectProfile profiles.
*
- * The returned list should be na_object_unref_items() by the caller.
+ * The returned list should be na_object_free_items().
*/
GList *
na_io_provider_load_items( const NAPivot *pivot, guint loadable_set, GSList **messages )
diff --git a/src/core/na-object-item.c b/src/core/na-object-item.c
index 5b365bd..e9dc935 100644
--- a/src/core/na-object-item.c
+++ b/src/core/na-object-item.c
@@ -164,7 +164,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
static void
instance_dispose( GObject *object )
{
- static const gchar *thisfn = "na_object_item_instance_dispose";
NAObjectItem *self;
GList *children;
@@ -177,9 +176,8 @@ instance_dispose( GObject *object )
self->private->dispose_has_run = TRUE;
children = na_object_get_items( self );
- g_debug( "%s: children=%p (count=%d)", thisfn, ( void * ) children, g_list_length( children ));
na_object_set_items( self, NULL );
- na_object_unref_items( children );
+ na_object_free_items( children );
/* chain up to the parent class */
if( G_OBJECT_CLASS( st_parent_class )->dispose ){
@@ -708,42 +706,41 @@ na_object_item_count_items( GList *items, gint *menus, gint *actions, gint *prof
}
/**
- * na_object_item_unref_items:
+ * na_object_item_copyref_items:
* @items: a list of #NAObject -derived items.
*
- * Unref only the first level the #NAObject of the list, freeing the list at last.
+ * Creates a copy of the provided list, recursively incrementing the
+ * reference count of NAObjects.
*
- * This is rather only used by NAPivot.
+ * Returns: the new list, which should be na_object_free_items() by the
+ * caller.
*
- * Since: 2.30
+ * Since: 3.1.0
*/
-void
-na_object_item_unref_items( GList *items )
+GList *
+na_object_item_copyref_items( GList *items )
{
- g_list_foreach( items, ( GFunc ) g_object_unref, NULL );
- g_list_free( items );
+ GList *copy = g_list_copy( items );
+ g_list_foreach( copy, ( GFunc ) na_object_object_ref, NULL );
+ return( copy );
}
/**
- * na_object_item_unref_items_rec:
+ * na_object_item_free_items:
* @items: a list of #NAObject -derived items.
*
- * Recursively unref the #NAObject's of the list, freeing the list at last.
+ * Free the items list.
*
- * This is heavily used by NACT.
+ * Returns: a %NULL pointer.
*
- * Since: 2.30
+ * Since: 3.1.0
*/
-void
-na_object_item_unref_items_rec( GList *items )
+GList *
+na_object_item_free_items( GList *items )
{
- GList *it;
-
- for( it = items ; it ; it = it->next ){
- na_object_unref( it->data );
- }
-
+ g_list_foreach( items, ( GFunc ) na_object_object_unref, NULL );
g_list_free( items );
+ return( NULL );
}
/**
diff --git a/src/core/na-object.c b/src/core/na-object.c
index 5c73b11..ee29d07 100644
--- a/src/core/na-object.c
+++ b/src/core/na-object.c
@@ -68,27 +68,27 @@ typedef gboolean ( *HierarchyIterFunc )( GObjectClass *class, const NAObject *ob
static GObjectClass *st_parent_class = NULL;
-static GType register_type( void );
-static void class_init( NAObjectClass *klass );
-static void instance_init( GTypeInstance *instance, gpointer klass );
-static void instance_dispose( GObject *object );
-static void instance_finalize( GObject *object );
-
-static void object_dump( const NAObject *object );
-
-static void iduplicable_iface_init( NAIDuplicableInterface *iface );
-static void iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source );
-static gboolean iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b );
-static gboolean iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
-static gboolean iduplicable_is_valid( const NAIDuplicable *object );
-static gboolean iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
-
-static void push_modified_status_up( const NAObject *object, gboolean is_modified );
-static gboolean object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data );
-static gboolean dump_class_hierarchy_iter( GObjectClass *class, const NAObject *object, void *user_data );
-static void dump_tree( GList *tree, gint level );
-static void iter_on_class_hierarchy( const NAObject *object, HierarchyIterFunc pfn, void *user_data );
-static GList *build_class_hierarchy( const NAObject *object );
+static GType register_type( void );
+static void class_init( NAObjectClass *klass );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *object );
+static void instance_finalize( GObject *object );
+
+static void object_dump( const NAObject *object );
+
+static void iduplicable_iface_init( NAIDuplicableInterface *iface );
+static void iduplicable_copy( NAIDuplicable *target, const NAIDuplicable *source );
+static gboolean iduplicable_are_equal( const NAIDuplicable *a, const NAIDuplicable *b );
+static gboolean iduplicable_are_equal_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
+static gboolean iduplicable_is_valid( const NAIDuplicable *object );
+static gboolean iduplicable_is_valid_iter( GObjectClass *class, const NAObject *a, HierarchyIter *str );
+
+static void push_modified_status_up( const NAObject *object, gboolean is_modified );
+static gboolean object_copy_iter( GObjectClass *class, const NAObject *source, CopyIter *data );
+static gboolean dump_class_hierarchy_iter( GObjectClass *class, const NAObject *object, void *user_data );
+static void dump_tree( GList *tree, gint level );
+static void iter_on_class_hierarchy( const NAObject *object, HierarchyIterFunc pfn, void *user_data );
+static GList *build_class_hierarchy( const NAObject *object );
GType
na_object_object_get_type( void )
@@ -609,8 +609,8 @@ dump_tree( GList *tree, gint level )
{
GString *prefix;
gint i;
- GList *subitems, *it;
- gchar *id;
+ GList *it;
+ const NAObject *object;
gchar *label;
prefix = g_string_new( "" );
@@ -619,16 +619,14 @@ dump_tree( GList *tree, gint level )
}
for( it = tree ; it ; it = it->next ){
- id = na_object_get_id( it->data );
- label = na_object_get_label( it->data );
- g_debug( "na_object_dump_tree: %s%p (%s) %s \"%s\"",
- prefix->str, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), id, label );
- g_free( id );
+ object = ( const NAObject * ) it->data;
+ label = na_object_get_label( object );
+ g_debug( "na_object_dump_tree: %s%p (%s, ref_count=%u) '%s'", prefix->str,
+ ( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count, label );
g_free( label );
- if( NA_IS_OBJECT_ITEM( it->data )){
- subitems = na_object_get_items( it->data );
- dump_tree( subitems, level+1 );
+ if( NA_IS_OBJECT_ITEM( object )){
+ dump_tree( na_object_get_items( object ), level+1 );
}
}
@@ -680,34 +678,23 @@ na_object_object_reset_origin( NAObject *object, const NAObject *origin )
* Recursively ref the @object and all its children, incrementing their
* reference_count by 1.
*
- * Returns: a reference on the @pbject.
+ * Returns: a reference on the @object.
*
* Since: 2.30
*/
NAObject *
na_object_object_ref( NAObject *object )
{
- NAObject *ref = NULL;
- GList *children, *ic;
+ NAObject *ref;
g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
- if( !object->private->dispose_has_run ){
+ ref = NULL;
- g_debug( "na_object_object_ref: object=%p (%s, ref_count=%d)",
- ( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
+ if( !object->private->dispose_has_run ){
if( NA_IS_OBJECT_ITEM( object )){
-
- children = na_object_get_items( object );
-
- for( ic = children ; ic ; ic = ic->next ){
- /*
- g_debug( "na_object_object_ref: child=%p (%s, ref_count=%d)",
- ( void * ) ic->data, G_OBJECT_TYPE_NAME( ic->data ), G_OBJECT( ic->data )->ref_count );
- */
- na_object_ref( ic->data );
- }
+ g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_ref, NULL );
}
ref = g_object_ref( object );
@@ -728,28 +715,14 @@ na_object_object_ref( NAObject *object )
void
na_object_object_unref( NAObject *object )
{
- GList *children;
- GList *ic, *icnext;
-
g_return_if_fail( NA_IS_OBJECT( object ));
if( !object->private->dispose_has_run ){
- g_debug( "na_object_object_unref: object=%p (%s, ref_count=%d)",
- ( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
-
if( NA_IS_OBJECT_ITEM( object )){
- children = na_object_get_items( object );
-
- for( ic = children ; ic ; ic = icnext ){
- icnext = ic->next;
- g_object_unref( ic->data );
- }
+ g_list_foreach( na_object_get_items( object ), ( GFunc ) na_object_object_unref, NULL );
}
- /*g_debug( "na_object_object_unref:about_to_unref: object=%p (%s, ref_count=%d)",
- ( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );*/
-
g_object_unref( object );
}
}
diff --git a/src/core/na-pivot.c b/src/core/na-pivot.c
index 64f4685..bb94e0f 100644
--- a/src/core/na-pivot.c
+++ b/src/core/na-pivot.c
@@ -308,9 +308,10 @@ instance_dispose( GObject *object )
self->private->modules = NULL;
/* release item tree */
- g_debug( "%s: tree=%p, count=%u", thisfn, ( void * ) self->private->tree, g_list_length( self->private->tree ));
- na_object_unref_items( self->private->tree );
- self->private->tree = NULL;
+ g_debug( "%s: tree=%p (count=%u)", thisfn,
+ ( void * ) self->private->tree, g_list_length( self->private->tree ));
+ na_object_dump_tree( self->private->tree );
+ self->private->tree = na_object_free_items( self->private->tree );
/* release the settings */
g_object_unref( self->private->settings );
@@ -553,7 +554,7 @@ na_pivot_load_items( NAPivot *pivot )
g_debug( "%s: pivot=%p", thisfn, ( void * ) pivot );
messages = NULL;
- na_object_unref_items( pivot->private->tree );
+ na_object_free_items( pivot->private->tree );
pivot->private->tree = na_io_provider_load_items( pivot, pivot->private->loadable_set, &messages );
for( im = messages ; im ; im = im->next ){
@@ -569,7 +570,8 @@ na_pivot_load_items( NAPivot *pivot )
* @pivot: this #NAPivot instance.
* @tree: the new tree of items.
*
- * Replace the current list with this one.
+ * Replace the current list with this one, acquiring the full ownership
+ * of the provided @tree.
*/
void
na_pivot_set_new_items( NAPivot *pivot, GList *items )
@@ -583,7 +585,7 @@ na_pivot_set_new_items( NAPivot *pivot, GList *items )
g_debug( "%s: pivot=%p, items=%p (count=%d)",
thisfn, ( void * ) pivot, ( void * ) items, items ? g_list_length( items ) : 0 );
- na_object_unref_items( pivot->private->tree );
+ na_object_free_items( pivot->private->tree );
pivot->private->tree = items;
}
}
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 9d77dc8..446b7de 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -147,6 +147,8 @@ nautilus_actions_config_tool_SOURCES = \
nact-tree-model-dnd.c \
nact-tree-model-dnd.h \
nact-tree-model-priv.h \
+ nact-tree-view.c \
+ nact-tree-view.h \
nact-window.c \
nact-window.h \
$(BUILT_SOURCES) \
diff --git a/src/nact/nact-assistant-export.c b/src/nact/nact-assistant-export.c
index 880b200..2fb2e98 100644
--- a/src/nact/nact-assistant-export.c
+++ b/src/nact/nact-assistant-export.c
@@ -46,7 +46,7 @@
#include "nact-assistant-export.h"
#include "nact-export-ask.h"
#include "nact-export-format.h"
-#include "nact-iactions-list.h"
+#include "nact-tree-view.h"
/* Export Assistant
*
@@ -78,10 +78,12 @@ struct _NactAssistantExportClassPrivate {
/* private instance data
*/
struct _NactAssistantExportPrivate {
- gboolean dispose_has_run;
- gboolean preferences_locked;
- gchar *uri;
- GList *results;
+ gboolean dispose_has_run;
+ NactTreeView *items_view;
+ gboolean preferences_locked;
+ gchar *uri;
+ GList *selected_items;
+ GList *results;
};
typedef struct {
@@ -100,23 +102,18 @@ static BaseAssistantClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( NactAssistantExportClass *klass );
-static void iactions_list_iface_init( NactIActionsListInterface *iface );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *application );
static void instance_finalize( GObject *application );
-static void on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *toplevel );
-static void on_base_initialize_base_window( NactAssistantExport *dialog );
-static void on_base_all_widgets_showed( NactAssistantExport *dialog );
+static void on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *toplevel, gpointer user_data );
+static void on_base_initialize_base_window( NactAssistantExport *dialog, gpointer user_data );
+static void on_base_all_widgets_showed( NactAssistantExport *dialog, gpointer user_data );
-static void assist_initial_load_intro( NactAssistantExport *window, GtkAssistant *assistant );
static void assist_runtime_init_intro( NactAssistantExport *window, GtkAssistant *assistant );
-static void assist_initial_load_actions_list( NactAssistantExport *window, GtkAssistant *assistant );
static void assist_runtime_init_actions_list( NactAssistantExport *window, GtkAssistant *assistant );
-static void on_iactions_list_selection_changed( NactIActionsList *instance, GSList *selected_items );
-static gchar *on_iactions_list_get_treeview_name( NactIActionsList *instance );
-
+static void on_tree_view_selection_changed( NactAssistantExport *window, NactTreeView *view, GList *selected_items, gpointer user_data );
static void assist_initial_load_target_folder( NactAssistantExport *window, GtkAssistant *assistant );
static void assist_runtime_init_target_folder( NactAssistantExport *window, GtkAssistant *assistant );
static GtkFileChooser *get_folder_chooser( NactAssistantExport *window );
@@ -126,12 +123,6 @@ static void assist_initial_load_format( NactAssistantExport *window,
static void assist_runtime_init_format( NactAssistantExport *window, GtkAssistant *assistant );
static NAExportFormat *get_export_format( NactAssistantExport *window );
-static void assist_initial_load_confirm( NactAssistantExport *window, GtkAssistant *assistant );
-static void assist_runtime_init_confirm( NactAssistantExport *window, GtkAssistant *assistant );
-
-static void assist_initial_load_exportdone( NactAssistantExport *window, GtkAssistant *assistant );
-static void assist_runtime_init_exportdone( NactAssistantExport *window, GtkAssistant *assistant );
-
static void assistant_prepare( BaseAssistant *window, GtkAssistant *assistant, GtkWidget *page );
static void assist_prepare_confirm( NactAssistantExport *window, GtkAssistant *assistant, GtkWidget *page );
static void assistant_apply( BaseAssistant *window, GtkAssistant *assistant );
@@ -168,18 +159,10 @@ register_type( void )
( GInstanceInitFunc ) instance_init
};
- static const GInterfaceInfo iactions_list_iface_info = {
- ( GInterfaceInitFunc ) iactions_list_iface_init,
- NULL,
- NULL
- };
-
g_debug( "%s", thisfn );
type = g_type_register_static( BASE_ASSISTANT_TYPE, "NactAssistantExport", &info, 0 );
- g_type_add_interface_static( type, NACT_IACTIONS_LIST_TYPE, &iactions_list_iface_info );
-
return( type );
}
@@ -206,16 +189,6 @@ class_init( NactAssistantExportClass *klass )
}
static void
-iactions_list_iface_init( NactIActionsListInterface *iface )
-{
- static const gchar *thisfn = "nact_assistant_export_iactions_list_iface_init";
-
- g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
-
- iface->get_treeview_name = on_iactions_list_get_treeview_name;
-}
-
-static void
instance_init( GTypeInstance *instance, gpointer klass )
{
static const gchar *thisfn = "nact_assistant_export_instance_init";
@@ -257,7 +230,9 @@ instance_dispose( GObject *window )
self->private->dispose_has_run = TRUE;
- nact_iactions_list_dispose( NACT_IACTIONS_LIST( window ));
+ 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 ){
@@ -321,11 +296,13 @@ nact_assistant_export_run( BaseWindow *main_window )
BASE_PROP_WARN_ON_ESCAPE, esc_confirm,
NULL );
+ assistant->private->items_view = nact_tree_view_new( BASE_WINDOW( assistant ), "ActionsList" );
+
base_window_run( BASE_WINDOW( assistant ));
}
static void
-on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *assistant )
+on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *assistant, gpointer user_data )
{
static const gchar *thisfn = "nact_assistant_export_on_base_initialize_gtk_toplevel";
NactApplication *application;
@@ -336,7 +313,8 @@ on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *assi
g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( dialog ));
if( !dialog->private->dispose_has_run ){
- g_debug( "%s: dialog=%p, assistant=%p", thisfn, ( void * ) dialog, ( void * ) assistant );
+ g_debug( "%s: dialog=%p, assistant=%p, user_data=%p",
+ thisfn, ( void * ) dialog, ( void * ) assistant, ( void * ) user_data );
application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( dialog )));
updater = nact_application_get_updater( application );
@@ -345,17 +323,13 @@ on_base_initialize_gtk_toplevel( NactAssistantExport *dialog, GtkAssistant *assi
are_locked = na_settings_get_boolean( settings, NA_IPREFS_ADMIN_PREFERENCES_LOCKED, NULL, &mandatory );
dialog->private->preferences_locked = are_locked && mandatory;
- assist_initial_load_intro( dialog, assistant );
- assist_initial_load_actions_list( dialog, assistant );
assist_initial_load_target_folder( dialog, assistant );
assist_initial_load_format( dialog, assistant );
- assist_initial_load_confirm( dialog, assistant );
- assist_initial_load_exportdone( dialog, assistant );
}
}
static void
-on_base_initialize_base_window( NactAssistantExport *dialog )
+on_base_initialize_base_window( NactAssistantExport *dialog, gpointer user_data )
{
static const gchar *thisfn = "nact_assistant_export_on_base_initialize_base_window";
GtkAssistant *assistant;
@@ -363,42 +337,42 @@ on_base_initialize_base_window( NactAssistantExport *dialog )
g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( dialog ));
if( !dialog->private->dispose_has_run ){
- g_debug( "%s: dialog=%p", thisfn, ( void * ) dialog );
+ g_debug( "%s: dialog=%p, user_data=%p", thisfn, ( void * ) dialog, ( void * ) user_data );
assistant = GTK_ASSISTANT( base_window_get_gtk_toplevel( BASE_WINDOW( dialog )));
base_window_signal_connect( BASE_WINDOW( dialog ),
- G_OBJECT( dialog ), IACTIONS_LIST_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_iactions_list_selection_changed ));
+ G_OBJECT( dialog ), TREE_SIGNAL_SELECTION_CHANGED, G_CALLBACK( on_tree_view_selection_changed ));
assist_runtime_init_intro( dialog, assistant );
assist_runtime_init_actions_list( dialog, assistant );
assist_runtime_init_target_folder( dialog, assistant );
assist_runtime_init_format( dialog, assistant );
- assist_runtime_init_confirm( dialog, assistant );
- assist_runtime_init_exportdone( dialog, assistant );
}
}
static void
-on_base_all_widgets_showed( NactAssistantExport *dialog )
+on_base_all_widgets_showed( NactAssistantExport *dialog, gpointer user_data )
{
static const gchar *thisfn = "nact_assistant_export_on_base_all_widgets_showed";
+ NactMainWindow *main_window;
+ GList *items;
g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( dialog ));
if( !dialog->private->dispose_has_run ){
- g_debug( "%s: dialog=%p", thisfn, ( void * ) dialog );
-
- nact_iactions_list_bis_select_first_row( NACT_IACTIONS_LIST( dialog ));
+ g_debug( "%s: dialog=%p, user_data=%p", thisfn, ( void * ) dialog, ( void * ) user_data );
+
+ /* setup the data here so that we are sure all companion objects
+ * have connected their signal handlers
+ */
+ main_window = NACT_MAIN_WINDOW( base_window_get_parent( BASE_WINDOW( dialog )));
+ items = nact_main_window_get_current_items( main_window );
+ nact_tree_view_fill( dialog->private->items_view, items );
}
}
static void
-assist_initial_load_intro( NactAssistantExport *window, GtkAssistant *assistant )
-{
-}
-
-static void
assist_runtime_init_intro( NactAssistantExport *window, GtkAssistant *assistant )
{
static const gchar *thisfn = "nact_assistant_export_runtime_init_intro";
@@ -411,71 +385,45 @@ assist_runtime_init_intro( NactAssistantExport *window, GtkAssistant *assistant
}
static void
-assist_initial_load_actions_list( NactAssistantExport *window, GtkAssistant *assistant )
-{
- g_assert( NACT_IS_IACTIONS_LIST( window ));
-
- nact_iactions_list_set_management_mode( NACT_IACTIONS_LIST( window ), IACTIONS_LIST_MANAGEMENT_MODE_EXPORT );
- nact_iactions_list_initial_load_toplevel( NACT_IACTIONS_LIST( window ));
-}
-
-static void
assist_runtime_init_actions_list( NactAssistantExport *window, GtkAssistant *assistant )
{
- BaseWindow *parent;
- GList *tree;
GtkWidget *content;
- parent = base_window_get_parent( BASE_WINDOW( window ));
- g_assert( NACT_IS_MAIN_WINDOW( parent ));
- g_assert( NACT_IS_IACTIONS_LIST( parent ));
- tree = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( parent ));
-
- nact_iactions_list_runtime_init_toplevel( NACT_IACTIONS_LIST( window ), tree );
-
content = gtk_assistant_get_nth_page( assistant, ASSIST_PAGE_ACTIONS_SELECTION );
-
gtk_assistant_set_page_complete( assistant, content, FALSE );
}
static void
-on_iactions_list_selection_changed( NactIActionsList *instance, GSList *selected_items )
+on_tree_view_selection_changed( NactAssistantExport *instance, NactTreeView *view, GList *selected_items, gpointer user_data )
{
- static const gchar *thisfn = "nact_assistant_export_on_actions_list_selection_changed";
-
- g_debug( "%s: selection=%p, selected_items=%p (count=%d)",
- thisfn, ( void * ) instance, ( void * ) selected_items, g_slist_length( selected_items ));
-
+ static const gchar *thisfn = "nact_assistant_export_on_tree_view_selection_changed";
GtkAssistant *assistant;
gint pos;
gboolean enabled;
GtkWidget *content;
- g_assert( NACT_IS_ASSISTANT_EXPORT( instance ));
+ g_return_if_fail( NACT_IS_ASSISTANT_EXPORT( instance ));
+
+ g_debug( "%s: instance=%p, view=%p, selected_items=%p (count=%d), user_data=%p",
+ thisfn, ( void * ) instance, ( void * ) view,
+ ( void * ) selected_items, g_list_length( selected_items ), ( void * ) user_data );
+
+ if( instance->private->selected_items ){
+ instance->private->selected_items = na_object_free_items( instance->private->selected_items );
+ }
+
assistant = GTK_ASSISTANT( base_window_get_gtk_toplevel( BASE_WINDOW( instance )));
pos = gtk_assistant_get_current_page( assistant );
- if( pos == ASSIST_PAGE_ACTIONS_SELECTION ){
-
- enabled = ( g_slist_length( selected_items ) > 0 );
+ if( pos == ASSIST_PAGE_ACTIONS_SELECTION ){
+ enabled = ( g_list_length( selected_items ) > 0 );
+ instance->private->selected_items = na_object_copyref_items( selected_items );
content = gtk_assistant_get_nth_page( assistant, pos );
gtk_assistant_set_page_complete( assistant, content, enabled );
gtk_assistant_update_buttons_state( assistant );
}
}
-static gchar *
-on_iactions_list_get_treeview_name( NactIActionsList *instance )
-{
- gchar *name = NULL;
-
- g_return_val_if_fail( NACT_IS_ASSISTANT_EXPORT( instance ), NULL );
-
- name = g_strdup( "ActionsList" );
-
- return( name );
-}
-
static void
assist_initial_load_target_folder( NactAssistantExport *window, GtkAssistant *assistant )
{
@@ -507,11 +455,8 @@ assist_runtime_init_target_folder( NactAssistantExport *window, GtkAssistant *as
}
g_free( uri );
- base_window_signal_connect(
- BASE_WINDOW( window ),
- G_OBJECT( chooser ),
- "selection-changed",
- G_CALLBACK( on_folder_selection_changed ));
+ base_window_signal_connect( BASE_WINDOW( window ),
+ G_OBJECT( chooser ), "selection-changed", G_CALLBACK( on_folder_selection_changed ));
content = gtk_assistant_get_nth_page( assistant, ASSIST_PAGE_FOLDER_SELECTION );
gtk_assistant_set_page_complete( assistant, content, FALSE );
@@ -621,26 +566,6 @@ get_export_format( NactAssistantExport *window )
}
static void
-assist_initial_load_confirm( NactAssistantExport *window, GtkAssistant *assistant )
-{
-}
-
-static void
-assist_runtime_init_confirm( NactAssistantExport *window, GtkAssistant *assistant )
-{
-}
-
-static void
-assist_initial_load_exportdone( NactAssistantExport *window, GtkAssistant *assistant )
-{
-}
-
-static void
-assist_runtime_init_exportdone( NactAssistantExport *window, GtkAssistant *assistant )
-{
-}
-
-static void
assistant_prepare( BaseAssistant *window, GtkAssistant *assistant, GtkWidget *page )
{
/*static const gchar *thisfn = "nact_assistant_export_on_prepare";
@@ -670,7 +595,7 @@ assist_prepare_confirm( NactAssistantExport *window, GtkAssistant *assistant, Gt
gchar *label_item;
gchar *label11, *label12;
gchar *label21, *label22;
- GList *items, *it;
+ GList *it;
NAExportFormat *format;
GtkLabel *confirm_label;
NactApplication *application;
@@ -686,13 +611,11 @@ assist_prepare_confirm( NactAssistantExport *window, GtkAssistant *assistant, Gt
text = g_string_new( "" );
g_string_printf( text, "<b>%s</b>\n\n", _( "About to export selected items:" ));
- items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
- for( it = items ; it ; it = it->next ){
+ for( it = window->private->selected_items ; it ; it = it->next ){
label_item = na_object_get_label( it->data );
g_string_append_printf( text, "\t%s\n", label_item );
g_free( label_item );
}
- na_object_unref_selected_items( items );
g_assert( window->private->uri && strlen( window->private->uri ));
@@ -731,7 +654,7 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
{
static const gchar *thisfn = "nact_assistant_export_on_apply";
NactAssistantExport *window;
- GList *actions, *ia;
+ GList *ia;
ExportStruct *str;
NactApplication *application;
NAUpdater *updater;
@@ -745,12 +668,11 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
updater = nact_application_get_updater( application );
- actions = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
first = TRUE;
g_return_if_fail( window->private->uri && strlen( window->private->uri ));
- for( ia = actions ; ia ; ia = ia->next ){
+ for( ia = window->private->selected_items ; ia ; ia = ia->next ){
str = g_new0( ExportStruct, 1 );
window->private->results = g_list_append( window->private->results, str );
@@ -772,8 +694,6 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
first = FALSE;
}
-
- na_object_unref_selected_items( actions );
}
static void
diff --git a/src/nact/nact-assistant-import.c b/src/nact/nact-assistant-import.c
index e092027..a76d34d 100644
--- a/src/nact/nact-assistant-import.c
+++ b/src/nact/nact-assistant-import.c
@@ -680,7 +680,7 @@ assistant_apply( BaseAssistant *wnd, GtkAssistant *assistant )
*/
imported_items = g_list_reverse( imported_items );
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( main_window ), imported_items, NULL );
- na_object_unref_items( imported_items );
+ na_object_free_items( imported_items );
}
static NAObjectItem *
diff --git a/src/nact/nact-iactions-list-bis.c b/src/nact/nact-iactions-list-bis.c
index 776bebb..730b45f 100644
--- a/src/nact/nact-iactions-list-bis.c
+++ b/src/nact/nact-iactions-list-bis.c
@@ -341,7 +341,7 @@ nact_iactions_list_bis_get_items( NactIActionsList *instance )
* We acquire here a new reference on objects corresponding to actually
* selected rows, and their childs.
*
- * The caller may safely call na_object_free_items_list() on the
+ * The caller may safely call na_object_free_items() on the
* returned list.
*/
GList *
diff --git a/src/nact/nact-iactions-list-priv.c b/src/nact/nact-iactions-list-priv.c
index dc63960..d300693 100644
--- a/src/nact/nact-iactions-list-priv.c
+++ b/src/nact/nact-iactions-list-priv.c
@@ -34,6 +34,7 @@
#include "base-window.h"
#include "nact-iactions-list-priv.h"
+#include "nact-tree-view.h"
#define IACTIONS_LIST_DATA_INSTANCE "nact-iactions-list-instance-data"
@@ -60,11 +61,17 @@ nact_iactions_list_priv_get_actions_list_treeview( NactIActionsList *instance )
* @instance: this #NactIActionsList interface.
*
* Returns a pointer to the data associated to this instance of the interface.
+ *
+ * During the transition phase (refactoring of IActionsList interface to
+ * TreeView class), the function tests if a TreeView is defined in this
+ * instance. If yes, then it asks the object to fillup out structure with
+ * its own data.
*/
IActionsListInstanceData *
nact_iactions_list_priv_get_instance_data( NactIActionsList *instance )
{
IActionsListInstanceData *ialid;
+ NactTreeView *view;
ialid = ( IActionsListInstanceData * ) g_object_get_data( G_OBJECT( instance ), IACTIONS_LIST_DATA_INSTANCE );
@@ -73,6 +80,11 @@ nact_iactions_list_priv_get_instance_data( NactIActionsList *instance )
g_object_set_data( G_OBJECT( instance ), IACTIONS_LIST_DATA_INSTANCE, ialid );
}
+ view = ( NactTreeView * ) g_object_get_data( G_OBJECT( instance ), "window-data-tree-view" );
+ if( view && NACT_IS_TREE_VIEW( view )){
+ nact_tree_view_setup_ialid( view, ialid );
+ }
+
return( ialid );
}
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 69818d5..a5b11a9 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -291,7 +291,7 @@ free_items_callback( NactIActionsList *instance, GList *items )
g_debug( "nact_iactions_list_free_items_callback: selection=%p (%d items)",
( void * ) items, g_list_length( items ));
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
}
static void
diff --git a/src/nact/nact-iactions-list.h b/src/nact/nact-iactions-list.h
index 4ba4385..8904e3d 100644
--- a/src/nact/nact-iactions-list.h
+++ b/src/nact/nact-iactions-list.h
@@ -48,6 +48,11 @@
* refilled on demand.
* Counters are then incremented in nact_iactions_list_insert() and
* nact_iactions_list_delete() functions.
+ *
+ * As of 3.1.0, the IActionsList interface is going to be replaced
+ * by a NactItemsTreeView class, itself derived from NactTreeView.
+ * During the transition phase, the interface stays being initialized
+ * as well as the two classes are instanciated.
*/
#include <gtk/gtk.h>
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index aad8615..479ff93 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -726,7 +726,7 @@ instance_dispose( GObject *window )
for( it = self->private->deleted ; it ; it = it->next ){
g_debug( "nact_main_window_instance_dispose: deleted=%p (%s)", ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ));
}
- na_object_unref_items( self->private->deleted );
+ na_object_free_items( self->private->deleted );
nact_iactions_list_dispose( NACT_IACTIONS_LIST( window ));
nact_sort_buttons_dispose( self );
@@ -1108,8 +1108,7 @@ reload_items( NactMainWindow *window )
window->private->selected_item = NULL;
window->private->selected_profile = NULL;
- na_object_unref_items( window->private->deleted );
- window->private->deleted = NULL;
+ window->private->deleted = na_object_free_items( window->private->deleted );
tree = na_updater_load_items( window->private->updater );
nact_iactions_list_fill( NACT_IACTIONS_LIST( window ), tree );
@@ -1192,6 +1191,29 @@ on_delete_event( GtkWidget *toplevel, GdkEvent *event, NactMainWindow *window )
}
/**
+ * nact_main_window_get_current_items:
+ * @window: this #NactMainWindow instance.
+ *
+ * Returns: The current content of the items tree view.
+ */
+GList *
+nact_main_window_get_current_items( const NactMainWindow *window )
+{
+ GList *items;
+
+ g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), NULL );
+
+ items = NULL;
+
+ if( !window->private->dispose_has_run ){
+
+ items = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( window ));
+ }
+
+ return( items );
+}
+
+/**
* nact_main_window_has_modified_items:
* @window: this #NactMainWindow instance.
*
@@ -1303,14 +1325,13 @@ nact_main_window_remove_deleted( NactMainWindow *window, GSList **messages )
delete_ok = actually_delete_item( window, item, window->private->updater, ¬_deleted, messages );
}
- na_object_unref_items( window->private->deleted );
- window->private->deleted = NULL;
+ window->private->deleted = na_object_free_items( window->private->deleted );
setup_dialog_title( window );
if( g_list_length( not_deleted )){
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), not_deleted, NULL );
- na_object_unref_items( not_deleted );
+ na_object_free_items( not_deleted );
}
}
diff --git a/src/nact/nact-main-window.h b/src/nact/nact-main-window.h
index 63f8696..e40c3f0 100644
--- a/src/nact/nact-main-window.h
+++ b/src/nact/nact-main-window.h
@@ -90,6 +90,7 @@ NactMainWindow *nact_main_window_new( const NactApplication *application );
NactClipboard *nact_main_window_get_clipboard ( const NactMainWindow *window );
NAObjectItem *nact_main_window_get_item ( const NactMainWindow *window, const gchar *id );
+GList *nact_main_window_get_current_items ( const NactMainWindow *window );
gboolean nact_main_window_has_modified_items( const NactMainWindow *window );
void nact_main_window_move_to_deleted ( NactMainWindow *window, GList *items );
void nact_main_window_reload ( NactMainWindow *window );
diff --git a/src/nact/nact-marshal.def b/src/nact/nact-marshal.def
index 7308c2e..ed28f49 100644
--- a/src/nact/nact-marshal.def
+++ b/src/nact/nact-marshal.def
@@ -1,3 +1,6 @@
+# NactTreeView:: signals
+VOID:POINTER,POINTER
+#
# NactIActionsList::nact-iactions-list-count-updated
VOID:INT,INT,INT
#
diff --git a/src/nact/nact-menubar-edit.c b/src/nact/nact-menubar-edit.c
index f1e2d62..5729782 100644
--- a/src/nact/nact-menubar-edit.c
+++ b/src/nact/nact-menubar-edit.c
@@ -224,7 +224,7 @@ nact_menubar_edit_on_cut( GtkAction *gtk_action, NactMainWindow *window )
nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
}
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
}
/**
@@ -256,7 +256,7 @@ nact_menubar_edit_on_copy( GtkAction *gtk_action, NactMainWindow *window )
clipboard = nact_main_window_get_clipboard( window );
nact_clipboard_primary_set( clipboard, items, CLIPBOARD_MODE_COPY );
update_clipboard_counters( window );
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
g_signal_emit_by_name( bar, MENUBAR_SIGNAL_UPDATE_SENSITIVITIES );
}
@@ -288,7 +288,7 @@ nact_menubar_edit_on_paste( GtkAction *gtk_action, NactMainWindow *window )
items = prepare_for_paste( window );
if( items ){
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
- na_object_unref_items( items );
+ na_object_free_items( items );
}
}
@@ -319,7 +319,7 @@ nact_menubar_edit_on_paste_into( GtkAction *gtk_action, NactMainWindow *window )
items = prepare_for_paste( window );
if( items ){
nact_iactions_list_bis_insert_into( NACT_IACTIONS_LIST( window ), items );
- na_object_unref_items( items );
+ na_object_free_items( items );
}
}
@@ -413,10 +413,10 @@ nact_menubar_edit_on_duplicate( GtkAction *gtk_action, NactMainWindow *window )
na_object_check_status( obj );
dup = g_list_prepend( NULL, obj );
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), dup, it->data );
- na_object_unref_items( dup );
+ na_object_free_items( dup );
}
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
}
/**
@@ -472,7 +472,7 @@ nact_menubar_edit_on_delete( GtkAction *gtk_action, NactMainWindow *window )
nact_iactions_list_bis_delete( NACT_IACTIONS_LIST( window ), to_delete, TRUE );
}
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
}
static GList *
diff --git a/src/nact/nact-menubar-file.c b/src/nact/nact-menubar-file.c
index a0a7242..695b434 100644
--- a/src/nact/nact-menubar-file.c
+++ b/src/nact/nact-menubar-file.c
@@ -124,7 +124,7 @@ nact_menubar_file_on_new_menu( GtkAction *gtk_action, NactMainWindow *window )
na_object_check_status( menu );
items = g_list_prepend( NULL, menu );
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
- na_object_unref_items( items );
+ na_object_free_items( items );
}
/**
@@ -147,7 +147,7 @@ nact_menubar_file_on_new_action( GtkAction *gtk_action, NactMainWindow *window )
na_object_check_status( action );
items = g_list_prepend( NULL, action );
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
- na_object_unref_items( items );
+ na_object_free_items( items );
}
/**
@@ -186,7 +186,7 @@ nact_menubar_file_on_new_profile( GtkAction *gtk_action, NactMainWindow *window
items = g_list_prepend( NULL, profile );
nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
- na_object_unref_items( items );
+ na_object_free_items( items );
}
/**
diff --git a/src/nact/nact-menubar-maintainer.c b/src/nact/nact-menubar-maintainer.c
index abe68f5..75d13e8 100644
--- a/src/nact/nact-menubar-maintainer.c
+++ b/src/nact/nact-menubar-maintainer.c
@@ -68,7 +68,7 @@ nact_menubar_maintainer_on_dump_selection( GtkAction *action, NactMainWindow *wi
na_object_dump( it->data );
}
- na_object_unref_selected_items( items );
+ na_object_free_items( items );
}
/**
diff --git a/src/nact/nact-menubar.c b/src/nact/nact-menubar.c
index 8b2f66b..865c5a4 100644
--- a/src/nact/nact-menubar.c
+++ b/src/nact/nact-menubar.c
@@ -34,25 +34,15 @@
#include <glib/gi18n.h>
-#include <api/na-object-api.h>
-
-#include "nact-application.h"
-#include "nact-menubar-priv.h"
-
-/* *** */
-#include <api/na-core-utils.h>
-
-#include <core/na-factory-object.h>
-#include <core/na-iprefs.h>
#include <core/na-io-provider.h>
-#include "nact-iactions-list.h"
-#include "nact-clipboard.h"
+#include "nact-application.h"
#include "nact-main-statusbar.h"
#include "nact-main-toolbar.h"
#include "nact-main-tab.h"
+#include "nact-menubar-priv.h"
#include "nact-sort-buttons.h"
-/* *** */
+#include "nact-iactions-list.h"
/* private class data
*/
@@ -704,17 +694,10 @@ on_iactions_list_selection_changed( NactMainWindow *window, GList *selected )
g_debug( "%s: selected=%p (count=%d)", thisfn, ( void * ) selected, g_list_length( selected ));
bar->private->count_selected = g_list_length( selected );
-#if 0
if( bar->private->selected_items ){
bar->private->selected_items = na_object_free_items( bar->private->selected_items );
}
- bar->private->selected_items = na_object_ref_items( selected );
-#else
- if( bar->private->selected_items ){
- na_object_unref_selected_items( bar->private->selected_items );
- }
- bar->private->selected_items = nact_iactions_list_bis_get_selected_items( NACT_IACTIONS_LIST( window ));
-#endif
+ bar->private->selected_items = na_object_copyref_items( selected );
if( selected ){
/* check if the parent of the first selected item is writable
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 540d7cc..1857cf6 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -960,7 +960,7 @@ drop_uri_list( NactTreeModel *model, GtkTreePath *dest, GtkSelectionData *selec
nact_iactions_list_bis_insert_at_path( NACT_IACTIONS_LIST( main_window ), imported, dest );
nact_tree_model_dump( model );
- na_object_unref_items( imported );
+ na_object_free_items( imported );
na_core_utils_slist_free( parms.uris );
for( it = parms.results ; it ; it = it->next ){
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 8a2b949..b389773 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -102,8 +102,9 @@ static NactTreeModel *tree_model_new( BaseWindow *window, GtkTreeView *treeview
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 );
static gboolean dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpStruct *ntm );
-static void fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, gboolean only_actions, GtkTreeIter *parent );
+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 get_items_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, GList **items );
static void iter_on_store( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data );
static gboolean iter_on_store_item( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter, FnIterOnStore fn, gpointer user_data );
static void remove_if_exists( NactTreeModel *model, GtkTreeModel *store, const NAObject *object );
@@ -296,7 +297,6 @@ tree_model_new( BaseWindow *window, GtkTreeView *treeview )
g_debug( "%s: window=%p, treeview=%p", thisfn, ( void * ) window, ( void * ) treeview );
g_return_val_if_fail( BASE_IS_WINDOW( window ), NULL );
- g_return_val_if_fail( NACT_IS_IACTIONS_LIST( window ), NULL );
g_return_val_if_fail( GTK_IS_TREE_VIEW( treeview ), NULL );
ts_model = gtk_tree_store_new(
@@ -346,7 +346,6 @@ nact_tree_model_initial_load( BaseWindow *window, GtkTreeView *treeview )
g_debug( "%s: window=%p, treeview=%p", thisfn, ( void * ) window, ( void * ) treeview );
g_return_if_fail( BASE_IS_WINDOW( window ));
- g_return_if_fail( NACT_IS_IACTIONS_LIST( window ));
g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
model = tree_model_new( window, treeview );
@@ -615,13 +614,39 @@ nact_tree_model_fill( NactTreeModel *model, GList *items, gboolean are_profiles_
for( it = items ; it ; it = it->next ){
duplicate = ( NAObject * ) na_object_duplicate( it->data );
na_object_check_status( duplicate );
- fill_tree_store( ts_model, model->private->treeview, duplicate, are_profiles_displayed, NULL );
+ fill_tree_store( ts_model, model->private->treeview, duplicate, NULL );
na_object_unref( duplicate );
}
}
}
/**
+ * nact_tree_model_get_items:
+ * @model: this #NactTreeModel object.
+ *
+ * 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( NactTreeModel *model )
+{
+ GList *items;
+ GtkTreeStore *store;
+
+ g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+
+ items = NULL;
+
+ 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, ( FnIterOnStore ) get_items_iter, &items );
+ }
+
+ return( items );
+}
+
+/**
* nact_tree_model_insert:
* @model: this #NactTreeModel instance.
* @object: a #NAObject-derived object to be inserted.
@@ -925,8 +950,7 @@ dump_store( NactTreeModel *model, GtkTreePath *path, NAObject *object, ntmDumpSt
}
static void
-fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
- NAObject *object, gboolean are_profiles_displayed, GtkTreeIter *parent )
+fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview, NAObject *object, GtkTreeIter *parent )
{
static const gchar *thisfn = "nact_tree_model_fill_tree_store";
GList *subitems, *it;
@@ -941,7 +965,7 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
append_item( model, treeview, parent, &iter, object );
subitems = na_object_get_items( object );
for( it = subitems ; it ; it = it->next ){
- fill_tree_store( model, treeview, it->data, are_profiles_displayed, &iter );
+ fill_tree_store( model, treeview, it->data, &iter );
}
} else {
@@ -998,6 +1022,20 @@ filter_visible( GtkTreeModel *store, GtkTreeIter *iter, NactTreeModel *model )
return( FALSE );
}
+/*
+ * builds the tree by iterating on the store
+ */
+static gboolean
+get_items_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, GList **items )
+{
+ if( gtk_tree_path_get_depth( path ) == 1 ){
+ *items = g_list_prepend( *items, na_object_ref( object ));
+ }
+
+ /* don't stop iteration */
+ return( FALSE );
+}
+
static void
iter_on_store( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *parent, FnIterOnStore fn, gpointer user_data )
{
@@ -1019,18 +1057,17 @@ iter_on_store_item( NactTreeModel *model, GtkTreeModel *store, GtkTreeIter *iter
GtkTreePath *path;
gboolean stop;
- gtk_tree_model_get( store, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
/* unreffing as soon as we got the pointer so that the ref count is
* unchanged in dump_store
*/
+ gtk_tree_model_get( store, iter, IACTIONS_LIST_NAOBJECT_COLUMN, &object, -1 );
g_object_unref( object );
+
g_debug( "nact_tree_model_iter_on_store_item: object=%p (%s, ref_count=%d)",
( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );
path = gtk_tree_model_get_path( store, iter );
-
stop = ( *fn )( model, path, object, user_data );
-
gtk_tree_path_free( path );
if( !stop ){
diff --git a/src/nact/nact-tree-model.h b/src/nact/nact-tree-model.h
index b2b9b76..68f4564 100644
--- a/src/nact/nact-tree-model.h
+++ b/src/nact/nact-tree-model.h
@@ -101,6 +101,7 @@ void nact_tree_model_display( NactTreeModel *model, NAObject *object );
void nact_tree_model_display_order_change( NactTreeModel *model, gint order_mode );
void nact_tree_model_dump( NactTreeModel *model );
void nact_tree_model_fill( NactTreeModel *model, GList *items, gboolean are_profiles_displayed );
+GList *nact_tree_model_get_items( NactTreeModel *model );
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 );
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
new file mode 100644
index 0000000..54f5539
--- /dev/null
+++ b/src/nact/nact-tree-view.c
@@ -0,0 +1,1072 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <api/na-object-api.h>
+
+#include "base-keysyms.h"
+#include "nact-application.h"
+#include "nact-marshal.h"
+#include "nact-tree-view.h"
+#include "nact-tree-model.h"
+
+#include "nact-iactions-list.h"
+
+/* private class data
+ */
+struct _NactTreeViewClassPrivate {
+ void *empty; /* so that gcc -pedantic is happy */
+};
+
+/* private instance data
+ */
+struct _NactTreeViewPrivate {
+ gboolean dispose_has_run;
+
+ /* properties set at instanciation time
+ */
+ BaseWindow *window;
+ gchar *widget_name;
+ gboolean have_dnd;
+ gboolean display_profiles;
+
+ /* runtime data
+ */
+ GtkTreeView *tree_view;
+ gboolean notify_allowed;
+};
+
+/* instance properties
+ */
+enum {
+ TREE_PROP_0,
+
+ TREE_PROP_WINDOW_ID,
+ TREE_PROP_WIDGET_NAME_ID,
+ TREE_PROP_HAVE_DND_ID,
+ TREE_PROP_DISPLAY_PROFILES_ID,
+
+ TREE_PROP_N_PROPERTIES
+};
+
+/* signals
+ */
+enum {
+ CONTENT_CHANGED,
+ SELECTION_CHANGED,
+ LAST_SIGNAL
+};
+
+/* when toggle collapse/expand rows, we want all rows have the same
+ * behavior, e.g. all rows collapse, or all rows expand
+ * this behavior is fixed by the first rows which will actually be
+ * toggled
+ */
+enum {
+ TOGGLE_UNDEFINED,
+ TOGGLE_COLLAPSE,
+ TOGGLE_EXPAND
+};
+
+/* iter on selection prototype
+ */
+typedef gboolean ( *FnIterOnSelection )( NactTreeView *, GtkTreeModel *, GtkTreeIter *, NAObject *, gpointer );
+
+#define WINDOW_DATA_TREE_VIEW "window-data-tree-view"
+
+#define VIEW_WINDOW_VOID( window ) \
+ g_return_if_fail( BASE_IS_WINDOW( window )); \
+ NactTreeView *view = ( NactTreeView * ) g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ); \
+ g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+#define VIEW_WINDOW_VALUE( window, value ) \
+ g_return_val_if_fail( BASE_IS_WINDOW( window ), value ); \
+ NactTreeView *view = ( NactTreeView * ) g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_VIEW ); \
+ g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), value );
+
+static gint st_signals[ LAST_SIGNAL ] = { 0 };
+static GObjectClass *st_parent_class = NULL;
+
+static GType register_type( void );
+static void class_init( NactTreeViewClass *klass );
+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 );
+static void instance_constructed( GObject *object );
+static void instance_dispose( GObject *application );
+static void instance_finalize( GObject *application );
+
+static void on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_data );
+static void on_base_initialize_view( BaseWindow *window, gpointer user_data );
+static void on_base_all_widgets_showed( BaseWindow *window, gpointer user_data );
+static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window );
+static void on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
+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 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 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 );
+static void toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle );
+static void on_finalizing_window( NactTreeView *view, GObject *window );
+
+GType
+nact_tree_view_get_type( void )
+{
+ static GType type = 0;
+
+ if( !type ){
+ type = register_type();
+ }
+
+ return( type );
+}
+
+static GType
+register_type( void )
+{
+ static const gchar *thisfn = "nact_tree_view_register_type";
+ GType type;
+
+ static GTypeInfo info = {
+ sizeof( NactTreeViewClass ),
+ ( GBaseInitFunc ) NULL,
+ ( GBaseFinalizeFunc ) NULL,
+ ( GClassInitFunc ) class_init,
+ NULL,
+ NULL,
+ sizeof( NactTreeView ),
+ 0,
+ ( GInstanceInitFunc ) instance_init
+ };
+
+ g_debug( "%s", thisfn );
+
+ type = g_type_register_static( G_TYPE_OBJECT, "NactTreeView", &info, 0 );
+
+ return( type );
+}
+
+static void
+class_init( NactTreeViewClass *klass )
+{
+ static const gchar *thisfn = "nact_tree_view_class_init";
+ GObjectClass *object_class;
+
+ g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
+
+ st_parent_class = g_type_class_peek_parent( klass );
+
+ object_class = G_OBJECT_CLASS( klass );
+ object_class->get_property = instance_get_property;
+ object_class->set_property = instance_set_property;
+ object_class->constructed = instance_constructed;
+ object_class->dispose = instance_dispose;
+ object_class->finalize = instance_finalize;
+
+ g_object_class_install_property( object_class, TREE_PROP_WINDOW_ID,
+ g_param_spec_pointer(
+ TREE_PROP_WINDOW,
+ "BaseWindow",
+ "The BaseWindow parent",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ g_object_class_install_property( object_class, TREE_PROP_WIDGET_NAME_ID,
+ g_param_spec_string(
+ TREE_PROP_WIDGET_NAME,
+ "Widget name",
+ "The name of GtkTreeView widget",
+ "",
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ g_object_class_install_property( object_class, TREE_PROP_HAVE_DND_ID,
+ g_param_spec_boolean(
+ TREE_PROP_HAVE_DND,
+ "Have DnD",
+ "Whether Drag and Drop operations are implemented",
+ FALSE,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ g_object_class_install_property( object_class, TREE_PROP_DISPLAY_PROFILES_ID,
+ g_param_spec_boolean(
+ TREE_PROP_DISPLAY_PROFILES,
+ "Display profiles",
+ "Whether actions profiles are displayed",
+ FALSE,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ /**
+ * NactTreeView::tree-signal-content-changed:
+ *
+ * This signal is emitted on the BaseWindow parent when the content
+ * of the tree changes. It may change in two occurrences:
+ * - the whole model is refilled with a new items list;
+ * - a row is edited.
+ *
+ * Signal args:
+ * - a pointer on the view
+ * - a poointer on the edited NAObject element, or NULL if the whole
+ * list has changed.
+ *
+ * Handler prototype:
+ * void ( *handler )( BaseWindow *window, NactTreeView *view, NAObject *edited, gpointer user_data );
+ */
+ st_signals[ CONTENT_CHANGED ] = g_signal_new_class_handler(
+ TREE_SIGNAL_CONTENT_CHANGED,
+ G_TYPE_OBJECT,
+ G_SIGNAL_RUN_CLEANUP,
+ G_CALLBACK( on_content_changed_cleanup_handler ),
+ NULL,
+ NULL,
+ nact_cclosure_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, G_TYPE_POINTER );
+
+ /**
+ * NactTreeView::tree-signal-selection-changed:
+ *
+ * This signal is emitted on the BaseWindow parent each time the selection
+ * has changed in the treeview.
+ *
+ * Signal args:
+ * - a pointer on the view
+ * - a #GList of currently selected #NAObjectItems.
+ *
+ * Handler prototype:
+ * void ( *handler )( BaseWindow *window, NactTreeView *view, GList *selected, gpointer user_data );
+ */
+ st_signals[ SELECTION_CHANGED ] = g_signal_new_class_handler(
+ TREE_SIGNAL_SELECTION_CHANGED,
+ G_TYPE_OBJECT,
+ G_SIGNAL_RUN_CLEANUP,
+ G_CALLBACK( on_selection_changed_cleanup_handler ),
+ NULL,
+ NULL,
+ nact_cclosure_marshal_VOID__POINTER_POINTER,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_POINTER, G_TYPE_POINTER );
+
+ klass->private = g_new0( NactTreeViewClassPrivate, 1 );
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+ static const gchar *thisfn = "nact_tree_view_instance_init";
+ NactTreeView *self;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( instance ));
+
+ g_debug( "%s: instance=%p (%s), klass=%p",
+ thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
+
+ self = NACT_TREE_VIEW( instance );
+
+ self->private = g_new0( NactTreeViewPrivate, 1 );
+
+ self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+ NactTreeView *self;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( object ));
+ self = NACT_TREE_VIEW( object );
+
+ if( !self->private->dispose_has_run ){
+
+ switch( property_id ){
+ case TREE_PROP_WINDOW_ID:
+ g_value_set_pointer( value, self->private->window );
+ break;
+
+ case TREE_PROP_WIDGET_NAME_ID:
+ g_value_set_string( value, self->private->widget_name );
+ break;
+
+ case TREE_PROP_HAVE_DND_ID:
+ g_value_set_boolean( value, self->private->have_dnd );
+ break;
+
+ case TREE_PROP_DISPLAY_PROFILES_ID:
+ g_value_set_boolean( value, self->private->display_profiles );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+ break;
+ }
+ }
+}
+
+static void
+instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
+{
+ NactTreeView *self;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( object ));
+ self = NACT_TREE_VIEW( object );
+
+ if( !self->private->dispose_has_run ){
+
+ switch( property_id ){
+ case TREE_PROP_WINDOW_ID:
+ self->private->window = g_value_get_pointer( value );
+ break;
+
+ case TREE_PROP_WIDGET_NAME_ID:
+ g_free( self->private->widget_name );
+ self->private->widget_name = g_value_dup_string( value );
+ break;
+
+ case TREE_PROP_HAVE_DND_ID:
+ self->private->have_dnd = g_value_get_boolean( value );
+ break;
+
+ case TREE_PROP_DISPLAY_PROFILES_ID:
+ self->private->display_profiles = g_value_get_boolean( value );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+ break;
+ }
+ }
+}
+
+static void
+instance_constructed( GObject *object )
+{
+ static const gchar *thisfn = "nact_tree_view_instance_constructed";
+ NactTreeView *self;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( object ));
+ self = NACT_TREE_VIEW( object );
+
+ if( !self->private->dispose_has_run ){
+ g_debug( "%s: object=%p", thisfn, ( void * ) object );
+
+ base_window_signal_connect( self->private->window,
+ G_OBJECT( self->private->window ), BASE_SIGNAL_INITIALIZE_GTK, G_CALLBACK( on_base_initialize_gtk ));
+
+ base_window_signal_connect( self->private->window,
+ G_OBJECT( self->private->window ), BASE_SIGNAL_INITIALIZE_WINDOW, G_CALLBACK( on_base_initialize_view ));
+
+ base_window_signal_connect( self->private->window,
+ G_OBJECT( self->private->window ), BASE_SIGNAL_ALL_WIDGETS_SHOWED, G_CALLBACK( on_base_all_widgets_showed ));
+
+ g_object_set_data( G_OBJECT( self->private->window ), WINDOW_DATA_TREE_VIEW, self );
+
+ g_object_weak_ref( G_OBJECT( self->private->window ), ( GWeakNotify ) on_finalizing_window, self );
+
+ /* chain up to the parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->constructed ){
+ G_OBJECT_CLASS( st_parent_class )->constructed( object );
+ }
+ }
+}
+
+static void
+instance_dispose( GObject *object )
+{
+ static const gchar *thisfn = "nact_tree_view_instance_dispose";
+ NactTreeView *self;
+ NactTreeModel *model;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( object ));
+
+ self = NACT_TREE_VIEW( object );
+
+ if( !self->private->dispose_has_run ){
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+
+ self->private->dispose_has_run = TRUE;
+
+ model = NACT_TREE_MODEL( gtk_tree_view_get_model( self->private->tree_view ));
+ nact_tree_model_dispose( model );
+
+ /* chain up to the parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->dispose ){
+ G_OBJECT_CLASS( st_parent_class )->dispose( object );
+ }
+ }
+}
+
+static void
+instance_finalize( GObject *instance )
+{
+ static const gchar *thisfn = "nact_tree_view_instance_finalize";
+ NactTreeView *self;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( instance ));
+
+ g_debug( "%s: instance=%p (%s)", thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
+
+ self = NACT_TREE_VIEW( instance );
+
+ g_free( self->private->widget_name );
+
+ g_free( self->private );
+
+ /* chain call to parent class */
+ if( G_OBJECT_CLASS( st_parent_class )->finalize ){
+ G_OBJECT_CLASS( st_parent_class )->finalize( instance );
+ }
+}
+
+/**
+ * nact_tree_view_new:
+ * @window: the BaseWindow which embeds the tree view.
+ * @treeview_name: the GtkTreeView widget name.
+ *
+ * Returns: a newly allocated NactTreeView object, which will be owned
+ * by the caller. It is useless to unref it as it will automatically
+ * auto-destroys itself at @window finalization.
+ */
+NactTreeView *
+nact_tree_view_new( BaseWindow *window, const gchar *treeview_name )
+{
+ NactTreeView *view;
+
+ view = g_object_new( NACT_TREE_VIEW_TYPE,
+ TREE_PROP_WINDOW, window,
+ TREE_PROP_WIDGET_NAME, treeview_name,
+ NULL );
+
+ return( view );
+}
+
+static void
+on_base_initialize_gtk( BaseWindow *window, GtkWindow *toplevel, gpointer user_data )
+{
+ static const gchar *thisfn = "nact_tree_view_on_base_initialize_gtk";
+ GtkTreeView *treeview;
+ GtkWidget *label;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeSelection *selection;
+
+ VIEW_WINDOW_VOID( window );
+
+ g_debug( "%s: window=%p (%s), toplevel=%p (%s), user_data=%p",
+ thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ),
+ ( void * ) toplevel, G_OBJECT_TYPE_NAME( toplevel ), ( void * ) user_data );
+
+ if( !view->private->dispose_has_run ){
+
+ treeview = GTK_TREE_VIEW( base_window_get_widget( window, view->private->widget_name ));
+
+ /* associates the ItemsView to the label */
+ label = base_window_get_widget( window, "ActionsListLabel" );
+ gtk_label_set_mnemonic_widget( GTK_LABEL( label ), GTK_WIDGET( treeview ));
+
+ nact_tree_model_initial_load( window, treeview );
+ gtk_tree_view_set_enable_tree_lines( treeview, TRUE );
+
+ /* create visible columns on the tree view
+ */
+ column = gtk_tree_view_column_new_with_attributes(
+ "icon",
+ gtk_cell_renderer_pixbuf_new(),
+ "pixbuf", TREE_COLUMN_ICON,
+ 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_COLUMN_LABEL,
+ NULL );
+ gtk_tree_view_column_set_sort_column_id( column, TREE_COLUMN_LABEL );
+ gtk_tree_view_append_column( treeview, column );
+
+ /* allow multiple selection
+ */
+ selection = gtk_tree_view_get_selection( treeview );
+ gtk_tree_selection_set_mode( selection, GTK_SELECTION_MULTIPLE );
+ }
+}
+
+static void
+on_base_initialize_view( BaseWindow *window, gpointer user_data )
+{
+ static const gchar *thisfn = "nact_tree_view_on_base_initialize_view";
+ GtkTreeView *treeview;
+ NactTreeModel *model;
+ GtkTreeSelection *selection;
+
+ VIEW_WINDOW_VOID( window );
+
+ g_debug( "%s: window=%p (%s), user_data=%p",
+ thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
+
+ if( !view->private->dispose_has_run ){
+
+ treeview = GTK_TREE_VIEW( base_window_get_widget( window, view->private->widget_name ));
+ view->private->tree_view = treeview;
+
+ model = NACT_TREE_MODEL( gtk_tree_view_get_model( treeview ));
+ nact_tree_model_runtime_init( model, view->private->have_dnd );
+
+ /* set up selection control */
+ selection = gtk_tree_view_get_selection( treeview );
+ base_window_signal_connect( window,
+ G_OBJECT( selection ), "changed", G_CALLBACK( on_treeview_selection_changed ));
+
+ /* expand/collapse with the keyboard */
+ base_window_signal_connect( window,
+ G_OBJECT( treeview ), "key-press-event", G_CALLBACK( on_key_pressed_event ));
+ }
+}
+
+static void
+on_base_all_widgets_showed( BaseWindow *window, gpointer user_data )
+{
+ static const gchar *thisfn = "nact_tree_view_on_base_all_widgets_showed";
+
+ VIEW_WINDOW_VOID( window );
+
+ g_debug( "%s: window=%p (%s), user_data=%p",
+ thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ), ( void * ) user_data );
+
+ if( !view->private->dispose_has_run ){
+
+ /* force the treeview to have the focus at start
+ * and select the first row if it exists
+ */
+ gtk_widget_grab_focus( GTK_WIDGET( view->private->tree_view ));
+ view->private->notify_allowed = TRUE;
+ select_row_at_path_by_string( view, "0" );
+ }
+}
+
+static gboolean
+on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window )
+{
+ gboolean stop = FALSE;
+
+ VIEW_WINDOW_VALUE( window, FALSE );
+
+ if( !view->private->dispose_has_run ){
+
+ if( event->keyval == NACT_KEY_Return || event->keyval == NACT_KEY_KP_Enter ){
+ toggle_collapse( view );
+ stop = TRUE;
+ }
+ if( event->keyval == NACT_KEY_Right ){
+ navigate_to_child( view );
+ stop = TRUE;
+ }
+ if( event->keyval == NACT_KEY_Left ){
+ navigate_to_parent( view );
+ stop = TRUE;
+ }
+ }
+
+ return( stop );
+}
+
+/*
+ * handles the "changed" signal emitted on the GtkTreeSelection
+ */
+static void
+on_treeview_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
+{
+ static const gchar *thisfn = "nact_tree_view_on_treeview_selection_changed";
+ GList *selected_items;
+
+ VIEW_WINDOW_VOID( window );
+
+ g_debug( "%s: selection=%p, window=%p", thisfn, ( void * ) selection, ( void * ) window );
+
+ if( !view->private->dispose_has_run ){
+
+ if( view->private->notify_allowed ){
+ selected_items = get_selected_items( view );
+ g_signal_emit_by_name( window, TREE_SIGNAL_SELECTION_CHANGED, view, selected_items );
+ }
+ }
+}
+
+/*
+ * cleanup handler for our TREE_SIGNAL_CONTENT_CHANGED signal
+ */
+static void
+on_content_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, NAObject *edited )
+{
+ static const gchar *thisfn = "nact_tree_view_on_content_changed_cleanup_handler";
+
+ g_debug( "%s: window=%p, view=%p, edited=%p",
+ thisfn, ( void * ) window, ( void * ) view, ( void * ) edited );
+
+ if( edited ){
+ na_object_unref( edited );
+ }
+}
+
+/*
+ * cleanup handler for our TREE_SIGNAL_SELECTION_CHANGED signal
+ */
+static void
+on_selection_changed_cleanup_handler( BaseWindow *window, NactTreeView *view, GList *selected_items )
+{
+ static const gchar *thisfn = "nact_tree_view_on_selection_changed_cleanup_handler";
+
+ g_debug( "%s: window=%p, view=%p, selected_items=%p (count=%u)",
+ thisfn, ( void * ) window, ( void * ) view,
+ ( void * ) selected_items, g_list_length( selected_items ));
+
+ na_object_free_items( selected_items );
+}
+
+/**
+ * nact_tree_view_fill:
+ * @view: this #NactTreeView instance.
+ *
+ * Fill the tree view with the provided list of items.
+ *
+ * Notification of selection changes is temporary suspended during the
+ * fillup of the list, so that client is not cluttered with tons of
+ * selection-changed messages.
+ */
+void
+nact_tree_view_fill( NactTreeView *view, GList *items )
+{
+ static const gchar *thisfn = "nact_tree_view_fill";
+ NactTreeModel *model;
+ gboolean prev;
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+ if( !view->private->dispose_has_run ){
+ g_debug( "%s: view=%p, items=%p (count=%u)",
+ thisfn, ( void * ) view, ( void * ) items, g_list_length( items ));
+
+ clear_selection( view );
+ prev = view->private->notify_allowed;
+ view->private->notify_allowed = FALSE;
+ model = NACT_TREE_MODEL( gtk_tree_view_get_model( view->private->tree_view ));
+ nact_tree_model_fill( model, items, view->private->display_profiles );
+ view->private->notify_allowed = prev;
+
+ if( view->private->notify_allowed ){
+ g_signal_emit_by_name( view->private->window, TREE_SIGNAL_CONTENT_CHANGED, view, NULL );
+ }
+ }
+}
+
+/**
+ * nact_tree_view_get_items:
+ * @view: this #NactTreeView instance.
+ *
+ * Returns: the content of the current tree as a newly allocated list
+ * which should be na_object_free_items() by the caller.
+ */
+GList *
+nact_tree_view_get_items( NactTreeView *view )
+{
+ GList *items;
+ NactTreeModel *model;
+
+ g_return_val_if_fail( NACT_IS_TREE_VIEW( view ), NULL );
+
+ items = NULL;
+
+ if( !view->private->dispose_has_run ){
+
+ model = NACT_TREE_MODEL( gtk_tree_view_get_model( view->private->tree_view ));
+ items = nact_tree_model_get_items( model );
+ }
+
+ return( items );
+}
+
+static void
+clear_selection( NactTreeView *view )
+{
+ GtkTreeSelection *selection;
+
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ gtk_tree_selection_unselect_all( selection );
+}
+
+/*
+ * when expanding a selected row which has childs
+ */
+static void
+extend_selection_to_children( NactTreeView *view, GtkTreeModel *model, GtkTreeIter *parent )
+{
+ GtkTreeSelection *selection;
+ GtkTreeIter iter;
+ gboolean ok;
+
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ ok = gtk_tree_model_iter_children( model, &iter, parent );
+
+ 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 );
+ }
+}
+
+/*
+ * get_selected_items:
+ * @view: this #NactTreeView instance.
+ *
+ * We acquire here a new reference on objects corresponding to actually
+ * selected rows, and their children.
+ *
+ * Returns: the currently selected rows as a #GList of #NAObjectItems
+ * which should be na_object_free_items() by the caller.
+ */
+static GList *
+get_selected_items( NactTreeView *view )
+{
+ static const gchar *thisfn = "nact_tree_view_get_selected_items";
+ GList *items;
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GList *it, *listrows;
+ NAObjectId *object;
+
+ items = NULL;
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ 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, TREE_COLUMN_NAOBJECT, &object, -1 );
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
+ items = g_list_prepend( items, na_object_ref( object ));
+ g_object_unref( object );
+ }
+
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
+
+ return( g_list_reverse( items ));
+}
+
+static void
+iter_on_selection( NactTreeView *view, FnIterOnSelection fn_iter, gpointer user_data )
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *listrows, *ipath;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ NAObject *object;
+ gboolean stop;
+
+ stop = FALSE;
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+ listrows = g_list_reverse( listrows );
+
+ for( ipath = listrows ; !stop && ipath ; ipath = ipath->next ){
+ path = ( GtkTreePath * ) ipath->data;
+ gtk_tree_model_get_iter( model, &iter, path );
+ gtk_tree_model_get( model, &iter, TREE_COLUMN_NAOBJECT, &object, -1 );
+
+ stop = fn_iter( view, model, &iter, object, user_data );
+
+ g_object_unref( object );
+ }
+
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
+}
+
+/*
+ * navigate_to_child:
+ * @view: this #NactTreeView object.
+ *
+ * On right arrow, if collapsed, then expand
+ * if already expanded, then goto first child
+ *
+ * Note:
+ * a row which does not have any child is always considered as collapsed;
+ * trying to expand it has no visible effect.
+ */
+static void
+navigate_to_child( NactTreeView *view )
+{
+ GtkTreeSelection *selection;
+ GList *listrows;
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ GtkTreePath *child_path;
+
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+
+ if( g_list_length( listrows ) == 1 ){
+ path = ( GtkTreePath * ) listrows->data;
+
+ if( !gtk_tree_view_row_expanded( view->private->tree_view, path )){
+ gtk_tree_view_expand_row( view->private->tree_view, path, FALSE );
+
+ } else {
+ 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 );
+ select_row_at_path( view, child_path );
+ gtk_tree_path_free( child_path );
+ }
+ }
+ }
+
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
+}
+
+/*
+ * navigate_to_parent:
+ * @view: this #NactTreeView object.
+ *
+ * On left arrow, go to the parent.
+ * if already on a parent, collapse it
+ * if already collapsed, up to the next parent
+ *
+ * e.g. path="2:0", depth=2
+ * this means that depth is always >= 1, with depth=1 being the root.
+ */
+static void
+navigate_to_parent( NactTreeView *view )
+{
+ GtkTreeSelection *selection;
+ GtkTreeModel *model;
+ GList *listrows;
+ GtkTreePath *path;
+ GtkTreePath *parent_path;
+
+ selection = gtk_tree_view_get_selection( view->private->tree_view );
+ listrows = gtk_tree_selection_get_selected_rows( selection, &model );
+
+ if( g_list_length( listrows ) == 1 ){
+ path = ( GtkTreePath * ) listrows->data;
+
+ if( gtk_tree_view_row_expanded( view->private->tree_view, path )){
+ gtk_tree_view_collapse_row( view->private->tree_view, path );
+
+ } 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 );
+ gtk_tree_path_free( parent_path );
+ }
+ }
+
+ g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( listrows );
+}
+
+/*
+ * 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 );
+ gtk_tree_path_free( path );
+}
+
+/*
+ * Toggle or collapse the current subtree.
+ */
+static void
+toggle_collapse( NactTreeView *view )
+{
+ guint toggle = TOGGLE_UNDEFINED;
+
+ iter_on_selection( view, ( FnIterOnSelection ) toggle_collapse_iter, &toggle );
+}
+
+static gboolean
+toggle_collapse_iter( NactTreeView *view, GtkTreeModel *model,
+ GtkTreeIter *iter, NAObject *object, gpointer user_data )
+{
+ guint count;
+ guint *toggle;
+
+ toggle = ( guint * ) user_data;
+
+ if( NA_IS_OBJECT_ITEM( object )){
+ GtkTreePath *path = gtk_tree_model_get_path( model, iter );
+ count = na_object_get_items_count( object );
+
+ if(( count > 1 && NA_IS_OBJECT_ACTION( object )) ||
+ ( count > 0 && NA_IS_OBJECT_MENU( object ))){
+
+ toggle_collapse_row( view->private->tree_view, path, toggle );
+ }
+
+ gtk_tree_path_free( path );
+
+ /* do not extend selection to children */
+ if( 0 ){
+ if( *toggle == TOGGLE_EXPAND ){
+ extend_selection_to_children( view, model, iter );
+ }
+ }
+ }
+
+ /* do not stop iteration */
+ return( FALSE );
+}
+
+/*
+ * toggle mode can be undefined, collapse or expand
+ * it is set on the first row
+ */
+static void
+toggle_collapse_row( GtkTreeView *treeview, GtkTreePath *path, guint *toggle )
+{
+ if( *toggle == TOGGLE_UNDEFINED ){
+ *toggle = gtk_tree_view_row_expanded( treeview, path ) ? TOGGLE_COLLAPSE : TOGGLE_EXPAND;
+ }
+
+ 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 );
+ }
+ }
+}
+
+static void
+on_finalizing_window( NactTreeView *view, GObject *window )
+{
+ static const gchar *thisfn = "nact_tree_view_on_finalizing_window";
+
+ g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+ g_debug( "%s: view=%p (%s), window=%p",
+ thisfn, ( void * ) view, G_OBJECT_TYPE_NAME( view ), ( void * ) window );
+
+ g_object_unref( view );
+}
+
+void
+nact_tree_view_setup_ialid( const NactTreeView *view, IActionsListInstanceData *ialid )
+{
+ g_return_if_fail( NACT_IS_TREE_VIEW( view ));
+
+ if( !view->private->dispose_has_run ){
+
+ ialid->management_mode = IACTIONS_LIST_MANAGEMENT_MODE_EXPORT;
+ /*ialid->menus;*/
+ /*ialid->actions;*/
+ /*ialid->profiles;*/
+ ialid->selection_changed_allowed = view->private->notify_allowed;
+ /*ialid->tab_updated_handler;*/
+ /*ialid->modified_items;*/
+ }
+}
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
new file mode 100644
index 0000000..8390dea
--- /dev/null
+++ b/src/nact/nact-tree-view.h
@@ -0,0 +1,117 @@
+/*
+ * Nautilus-Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
+ *
+ * This Program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This Program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifndef __NACT_TREE_VIEW_H__
+#define __NACT_TREE_VIEW_H__
+
+/*
+ * SECTION: nact-tree-view
+ * @title: NactTreeView
+ * @short_description: The Tree View Base Class Definition
+ * @include: nact-tree-view.h
+ *
+ * This is a convenience class to manage a read-only items tree view.
+ */
+
+#include "base-window.h"
+
+G_BEGIN_DECLS
+
+#define NACT_TREE_VIEW_TYPE ( nact_tree_view_get_type())
+#define NACT_TREE_VIEW( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, NACT_TREE_VIEW_TYPE, NactTreeView ))
+#define NACT_TREE_VIEW_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, NACT_TREE_VIEW_TYPE, NactTreeViewClass ))
+#define NACT_IS_TREE_VIEW( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, NACT_TREE_VIEW_TYPE ))
+#define NACT_IS_TREE_VIEW_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), NACT_TREE_VIEW_TYPE ))
+#define NACT_TREE_VIEW_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), NACT_TREE_VIEW_TYPE, NactTreeViewClass ))
+
+typedef struct _NactTreeViewPrivate NactTreeViewPrivate;
+
+typedef struct {
+ /*< private >*/
+ GObject parent;
+ NactTreeViewPrivate *private;
+}
+ NactTreeView;
+
+typedef struct _NactTreeViewClassPrivate NactTreeViewClassPrivate;
+
+typedef struct {
+ /*< private >*/
+ GObjectClass parent;
+ NactTreeViewClassPrivate *private;
+}
+ NactTreeViewClass;
+
+/**
+ * Properties defined by the NactTreeView class.
+ * They should be provided at object instantiation time.
+ *
+ * @TREE_PROP_WINDOW: the BaseWindow parent.
+ * @TREE_PROP_WIDGET_NAME: the widget name.
+ * @TREE_PROP_HAVE_DND: whether drag and drop is implemented.
+ * @TREE_PROP_DISPLAY_PROFILES: whether profiles are displayed.
+ */
+#define TREE_PROP_WINDOW "tree-prop-window"
+#define TREE_PROP_WIDGET_NAME "tree-prop-widget-name"
+#define TREE_PROP_HAVE_DND "tree-prop-have-dnd"
+#define TREE_PROP_DISPLAY_PROFILES "tree-prop-display-profiles"
+
+/**
+ * Column ordering in the tree view
+ */
+enum {
+ TREE_COLUMN_ICON = 0,
+ TREE_COLUMN_LABEL,
+ TREE_COLUMN_NAOBJECT,
+ TREE_N_COLUMN
+};
+
+/**
+ * Signals emitted by the NactTreeView instance.
+ */
+#define TREE_SIGNAL_CONTENT_CHANGED "tree-signal-content-changed"
+#define TREE_SIGNAL_SELECTION_CHANGED "tree-signal-selection-changed"
+
+GType nact_tree_view_get_type( void );
+
+NactTreeView *nact_tree_view_new( BaseWindow *window, const gchar *treeview_name );
+
+void nact_tree_view_fill ( NactTreeView *view, GList *items );
+GList *nact_tree_view_get_items( NactTreeView *view );
+
+/* special transition phase
+ */
+#include "nact-iactions-list-priv.h"
+
+void nact_tree_view_setup_ialid( const NactTreeView *view, IActionsListInstanceData *ialid );
+
+G_END_DECLS
+
+#endif /* __NACT_TREE_VIEW_H__ */
diff --git a/src/plugin-menu/nautilus-actions.c b/src/plugin-menu/nautilus-actions.c
index da37329..4e4b10a 100644
--- a/src/plugin-menu/nautilus-actions.c
+++ b/src/plugin-menu/nautilus-actions.c
@@ -487,7 +487,7 @@ get_menus_items( NautilusActions *plugin, guint target, GList *selection )
menus_list = build_nautilus_menus( plugin, copy_tree, target, selection, tokens );
- na_object_unref_items( copy_tree );
+ na_object_free_items( copy_tree );
g_object_unref( tokens );
if( target != ITEM_TARGET_TOOLBAR ){
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]