[nautilus-actions] NactTreeModel: code review



commit b825f5e7b06b6a764fb758b11098a190dfbd2926
Author: Pierre Wieser <pwieser trychlos org>
Date:   Mon Jan 30 07:24:49 2012 +0100

    NactTreeModel: code review

 ChangeLog                       |   14 ++
 po/POTFILES.in                  |    1 +
 src/nact/nact-main-window.c     |    6 +-
 src/nact/nact-tree-model-dnd.c  |  128 ++++++++++-------
 src/nact/nact-tree-model-priv.h |    9 --
 src/nact/nact-tree-model.c      |  299 ++++++++++++++++++++++++++-------------
 src/nact/nact-tree-view.c       |   14 +-
 src/nact/nact-tree-view.h       |    2 +-
 8 files changed, 305 insertions(+), 168 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e226f9a..7ec4440 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2012-01-30 Pierre Wieser <pwieser trychlos org>
 
+	* src/nact/nact-tree-model.c: Define window, treeview and mode properties.
+	(instance_constructed): Initialize DnD interface.
+	(instance_dispose): Clear the GtkTreeStore.
+
+	* po/POTFILES.in: Updated accordingly.
+
+	* src/nact/nact-main-window.c: Instanciate a window, not an application.
+
+	* src/nact/nact-tree-model-dnd.c: Debug NactTreeModel reference count.
+
+	* src/nact/nact-tree-model-priv.h: Get rid of WINDOW_DATA_TREE_MODEL data.
+
+	* src/nact/nact-tree-view.c (instance_dispose): No more clear the store.
+
 	* src/core/na-data-boxed.c (instance_init, instance_finalize):
 	* src/core/na-object-id.c (instance_dispose):
 	* src/core/na-object.c (instance_init, instance_dispose,
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 12ca5c2..235b223 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -58,6 +58,7 @@ src/nact/nact-menubar-file.c
 src/nact/nact-preferences-editor.c
 src/nact/nact-providers-list.c
 src/nact/nact-schemes-list.c
+src/nact/nact-tree-model.c
 src/nact/nact-tree-model-dnd.c
 src/nact/nact-tree-view.c
 [type: gettext/glade] src/nact/nautilus-actions-config-tool.ui
diff --git a/src/nact/nact-main-window.c b/src/nact/nact-main-window.c
index b2f90f4..4e6223f 100644
--- a/src/nact/nact-main-window.c
+++ b/src/nact/nact-main-window.c
@@ -174,9 +174,9 @@ static void       iproperties_tab_iface_init( NactIPropertiesTabInterface *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 );
-static void       instance_constructed( GObject *application );
-static void       instance_dispose( GObject *application );
-static void       instance_finalize( GObject *application );
+static void       instance_constructed( GObject *window );
+static void       instance_dispose( GObject *window );
+static void       instance_finalize( GObject *window );
 
 static void       on_base_initialize_gtk( NactMainWindow *window, GtkWindow *toplevel, gpointer user_data );
 static void       on_base_initialize_window( NactMainWindow *window, gpointer user_data );
diff --git a/src/nact/nact-tree-model-dnd.c b/src/nact/nact-tree-model-dnd.c
index 492960c..2bba001 100644
--- a/src/nact/nact-tree-model-dnd.c
+++ b/src/nact/nact-tree-model-dnd.c
@@ -107,7 +107,7 @@ static GtkTargetEntry dnd_source_formats[] = {
  * - of course, the same special XdndNautilusAction format for internal move/copy
  * - a list of uris, to be imported
  * - a XML buffer, to be imported
- * - a plain text, which we are goint to try to import as a XML description
+ * - a plain text, which we are going to try to import as a XML description
  */
 GtkTargetEntry tree_model_dnd_dest_formats[] = {
 	{ "XdndNautilusActions", 0, NACT_XCHANGE_FORMAT_NACT },
@@ -140,8 +140,9 @@ static guint         target_atom_to_id( GdkAtom atom );
  * @dest:
  * @selection_data:
  *
- * Called when a drop from the outside occurs in the treeview;
- * this may be an import action, or a move/copy inside of the tree.
+ * Called when a drop occurs in the treeview;
+ * this may be an import action from the outside world, or a move/copy
+ * inside of the tree.
  *
  * Returns: %TRUE if the specified rows were successfully inserted at
  * the given dest, %FALSE else.
@@ -161,6 +162,7 @@ nact_tree_model_dnd_idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, G
 {
 	static const gchar *thisfn = "nact_tree_model_dnd_idrag_dest_drag_data_received";
 	gboolean result = FALSE;
+	NactTreeModel *model;
 	gchar *atom_name;
 	guint info;
 	gchar *path_str;
@@ -170,49 +172,59 @@ nact_tree_model_dnd_idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, G
 	gint selection_data_format;
 	gint selection_data_length;
 
-	g_debug( "%s: drag_dest=%p, dest=%p, selection_data=%p", thisfn, ( void * ) drag_dest, ( void * ) dest, ( void * ) selection_data );
-	g_return_val_if_fail( NACT_IS_TREE_MODEL( drag_dest ), FALSE );
+	g_return_val_if_fail( NACT_IS_TREE_MODEL( drag_dest ), result );
 
-	selection_data_selection = gtk_selection_data_get_selection( selection_data );
-	atom_name = gdk_atom_name( selection_data_selection );
-	g_debug( "%s: selection=%s", thisfn, atom_name );
-	g_free( atom_name );
+	model = NACT_TREE_MODEL( drag_dest );
 
-	selection_data_target = gtk_selection_data_get_target( selection_data );
-	atom_name = gdk_atom_name( selection_data_target );
-	g_debug( "%s: target=%s", thisfn, atom_name );
-	g_free( atom_name );
+	if( !model->private->dispose_has_run ){
 
-	selection_data_type = gtk_selection_data_get_data_type( selection_data );
-	atom_name = gdk_atom_name( selection_data_type );
-	g_debug( "%s: type=%s", thisfn, atom_name );
-	g_free( atom_name );
+		g_debug( "%s: drag_dest=%p (ref_count=%d), dest=%p, selection_data=%p",
+				thisfn,
+				( void * ) drag_dest, G_OBJECT( drag_dest )->ref_count,
+				( void * ) dest,
+				( void * ) selection_data );
 
-	selection_data_format = gtk_selection_data_get_format( selection_data );
-	selection_data_length = gtk_selection_data_get_length( selection_data );
-	g_debug( "%s: format=%d, length=%d", thisfn, selection_data_format, selection_data_length );
+		selection_data_selection = gtk_selection_data_get_selection( selection_data );
+		atom_name = gdk_atom_name( selection_data_selection );
+		g_debug( "%s: selection=%s", thisfn, atom_name );
+		g_free( atom_name );
 
-	info = target_atom_to_id( selection_data_type );
-	g_debug( "%s: info=%u", thisfn, info );
+		selection_data_target = gtk_selection_data_get_target( selection_data );
+		atom_name = gdk_atom_name( selection_data_target );
+		g_debug( "%s: target=%s", thisfn, atom_name );
+		g_free( atom_name );
 
-	path_str = gtk_tree_path_to_string( dest );
-	g_debug( "%s: dest_path=%s", thisfn, path_str );
-	g_free( path_str );
+		selection_data_type = gtk_selection_data_get_data_type( selection_data );
+		atom_name = gdk_atom_name( selection_data_type );
+		g_debug( "%s: type=%s", thisfn, atom_name );
+		g_free( atom_name );
 
-	switch( info ){
-		case NACT_XCHANGE_FORMAT_NACT:
-			result = drop_inside( NACT_TREE_MODEL( drag_dest ), dest, selection_data );
-			break;
+		selection_data_format = gtk_selection_data_get_format( selection_data );
+		selection_data_length = gtk_selection_data_get_length( selection_data );
+		g_debug( "%s: format=%d, length=%d", thisfn, selection_data_format, selection_data_length );
 
-		/* drop some actions from outside
-		 * most probably from the file manager as a list of uris
-		 */
-		case NACT_XCHANGE_FORMAT_URI_LIST:
-			result = drop_uri_list( NACT_TREE_MODEL( drag_dest ), dest, selection_data );
-			break;
+		info = target_atom_to_id( selection_data_type );
+		g_debug( "%s: info=%u", thisfn, info );
 
-		default:
-			break;
+		path_str = gtk_tree_path_to_string( dest );
+		g_debug( "%s: dest_path=%s", thisfn, path_str );
+		g_free( path_str );
+
+		switch( info ){
+			case NACT_XCHANGE_FORMAT_NACT:
+				result = drop_inside( model, dest, selection_data );
+				break;
+
+			/* drop some actions from outside
+			 * most probably from the file manager as a list of uris
+			 */
+			case NACT_XCHANGE_FORMAT_URI_LIST:
+				result = drop_uri_list( model, dest, selection_data );
+				break;
+
+			default:
+				break;
+		}
 	}
 
 	return( result );
@@ -302,9 +314,13 @@ nact_tree_model_dnd_imulti_drag_source_drag_data_get( EggTreeMultiDragSource *dr
 #endif
 
 	atom_name = gdk_atom_name( selection_data_target );
-	g_debug( "%s: drag_source=%p, context=%p, suggested action=%d, selection_data=%p, rows=%p (count=%d), atom=%s",
-			thisfn, ( void * ) drag_source, ( void * ) context, ( int ) context_suggested_action,
-			( void * ) selection_data, ( void * ) rows, g_list_length( rows ),
+	g_debug( "%s: drag_source=%p (ref_count=%d), context=%p, suggested action=%d, selection_data=%p, rows=%p (count=%d), atom=%s",
+			thisfn,
+			( void * ) drag_source, G_OBJECT( drag_source )->ref_count,
+			( void * ) context,
+			( int ) context_suggested_action,
+			( void * ) selection_data,
+			( void * ) rows, g_list_length( rows ),
 			atom_name );
 	g_free( atom_name );
 
@@ -421,8 +437,10 @@ nact_tree_model_dnd_imulti_drag_source_row_draggable( EggTreeMultiDragSource *dr
 	NAObject *object;
 	GList *it;
 
-	g_debug( "%s: drag_source=%p, rows=%p (%d items)",
-			thisfn, ( void * ) drag_source, ( void * ) rows, g_list_length( rows ));
+	g_debug( "%s: drag_source=%p (ref_count=%d), rows=%p (%d items)",
+			thisfn,
+			( void * ) drag_source, G_OBJECT( drag_source )->ref_count,
+			( void * ) rows, g_list_length( rows ));
 
 	g_return_val_if_fail( NACT_IS_TREE_MODEL( drag_source ), FALSE );
 	model = NACT_TREE_MODEL( drag_source );
@@ -466,14 +484,19 @@ nact_tree_model_dnd_on_drag_begin( GtkWidget *widget, GdkDragContext *context, B
 	NactTreeModel *model;
 	GdkWindow *context_source_window;
 
-	g_debug( "%s: widget=%p, context=%p, window=%p",
-			thisfn, ( void * ) widget, ( void * ) context, ( void * ) window );
-
-	model = NACT_TREE_MODEL( gtk_tree_view_get_model( GTK_TREE_VIEW( widget )));
+	g_return_if_fail( GTK_IS_TREE_VIEW( widget ));
+	model = ( NactTreeModel * ) gtk_tree_view_get_model( GTK_TREE_VIEW( widget ));
 	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
 
 	if( !model->private->dispose_has_run ){
 
+		g_debug( "%s: widget=%p, context=%p, window=%p, model=%p (ref_count=%d)",
+				thisfn,
+				( void * ) widget,
+				( void * ) context,
+				( void * ) window,
+				( void * ) model, G_OBJECT( model )->ref_count );
+
 		model->private->drag_highlight = FALSE;
 		model->private->drag_drop = FALSE;
 
@@ -504,14 +527,19 @@ nact_tree_model_dnd_on_drag_end( GtkWidget *widget, GdkDragContext *context, Bas
 	NactTreeModel *model;
 	GdkWindow *context_source_window;
 
-	g_debug( "%s: widget=%p, context=%p, window=%p",
-			thisfn, ( void * ) widget, ( void * ) context, ( void * ) window );
-
-	model = NACT_TREE_MODEL( gtk_tree_view_get_model( GTK_TREE_VIEW( widget )));
+	g_return_if_fail( GTK_IS_TREE_VIEW( widget ));
+	model = ( NactTreeModel * ) gtk_tree_view_get_model( GTK_TREE_VIEW( widget ));
 	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
 
 	if( !model->private->dispose_has_run ){
 
+		g_debug( "%s: widget=%p, context=%p, window=%p, model=%p (ref_count=%d)",
+				thisfn,
+				( void * ) widget,
+				( void * ) context,
+				( void * ) window,
+				( void * ) model, G_OBJECT( model )->ref_count );
+
 		nact_clipboard_dnd_drag_end( model->private->clipboard );
 		nact_clipboard_dnd_clear( model->private->clipboard );
 
diff --git a/src/nact/nact-tree-model-priv.h b/src/nact/nact-tree-model-priv.h
index e9d8f1b..261aff6 100644
--- a/src/nact/nact-tree-model-priv.h
+++ b/src/nact/nact-tree-model-priv.h
@@ -62,15 +62,6 @@ struct _NactTreeModelPrivate {
 	gboolean       drag_drop;			/* defined for on_drag_motion handler */
 };
 
-/* the NactTreeModel is attached to the BaseWindow which embeds the NactTreeView
- */
-#define WINDOW_DATA_TREE_MODEL			"window-data-tree-model"
-
-#define WINDOW_MODEL_VOID( window ) \
-	g_return_if_fail( BASE_IS_WINDOW( window )); \
-	NactTreeModel *model = ( NactTreeModel * ) g_object_get_data( G_OBJECT( window ), WINDOW_DATA_TREE_MODEL ); \
-	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
-
 #define TREE_MODEL_STATUSBAR_CONTEXT	"nact-tree-model-statusbar-context"
 
 gboolean       nact_tree_model_dnd_idrag_dest_drag_data_received( GtkTreeDragDest *drag_dest, GtkTreePath *dest, GtkSelectionData  *selection_data );
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 20ae21a..ceb3800 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -32,6 +32,7 @@
 #include <config.h>
 #endif
 
+#include <glib/gi18n.h>
 #include <string.h>
 
 #include <api/na-object-api.h>
@@ -51,6 +52,21 @@ struct _NactTreeModelClassPrivate {
 	void *empty;						/* so that gcc -pedantic is happy */
 };
 
+/* instance properties
+ */
+#define TREE_PROP_TREEVIEW				"tree-prop-treeview"
+#define TREE_PROP_MODE					"tree-prop-mode"
+
+enum {
+	TREE_PROP_0,
+
+	TREE_PROP_WINDOW_ID,
+	TREE_PROP_TREEVIEW_ID,
+	TREE_PROP_MODE_ID,
+
+	TREE_PROP_N_PROPERTIES
+};
+
 /* iter on tree store
  */
 typedef gboolean ( *FnIterOnStore )( const NactTreeModel *, GtkTreeStore *, GtkTreePath *, NAObject *, gpointer );
@@ -107,12 +123,14 @@ static void     class_init( NactTreeModelClass *klass );
 static void     imulti_drag_source_init( EggTreeMultiDragSourceIface *iface, void *user_data );
 static void     idrag_dest_init( GtkTreeDragDestIface *iface, void *user_data );
 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 *model );
 static void     instance_dispose( GObject *model );
 static void     instance_finalize( GObject *model );
 
-static void     on_initialize_model( BaseWindow *window, gpointer user_data );
 static void     on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpointer new_value, gboolean mandatory, NactTreeModel *model );
-static void     on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, gpointer user_data );
+static void     on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, 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 );
@@ -196,9 +214,34 @@ class_init( NactTreeModelClass *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,
+					_( "Parent BaseWindow" ),
+					_( "A pointer (not a reference) to the BaseWindow parent of thE embedding treeview" ),
+					G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+	g_object_class_install_property( object_class, TREE_PROP_TREEVIEW_ID,
+			g_param_spec_pointer(
+					TREE_PROP_TREEVIEW,
+					_( "Embedding GtkTreeView" ),
+					_( "The GtkTreeView which relies on this NactTreeModel" ),
+					G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+	g_object_class_install_property( object_class, TREE_PROP_MODE_ID,
+			g_param_spec_uint(
+					TREE_PROP_MODE,
+					_( "Edition mode" ),
+					_( "Edition vs. Selection mode" ),
+					0, TREE_MODE_N_MODES, 0,
+					G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
 	klass->private = g_new0( NactTreeModelClassPrivate, 1 );
 }
 
@@ -247,10 +290,149 @@ instance_init( GTypeInstance *instance, gpointer klass )
 }
 
 static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+	NactTreeModel *self;
+
+	g_return_if_fail( NACT_IS_TREE_MODEL( object ));
+	self = NACT_TREE_MODEL( 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_TREEVIEW_ID:
+				g_value_set_pointer( value, self->private->treeview );
+				break;
+
+			case TREE_PROP_MODE_ID:
+				g_value_set_uint( value, self->private->mode );
+				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 )
+{
+	NactTreeModel *self;
+
+	g_return_if_fail( NACT_IS_TREE_MODEL( object ));
+	self = NACT_TREE_MODEL( 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_TREEVIEW_ID:
+				self->private->treeview = g_value_get_pointer( value );
+				break;
+
+			case TREE_PROP_MODE_ID:
+				self->private->mode = g_value_get_uint( value );
+				break;
+
+			default:
+				G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+				break;
+		}
+	}
+}
+
+/*
+ * Initializes the tree model.
+ *
+ * We use drag and drop:
+ * - inside of treeview, for duplicating items, or moving items between menus
+ * - from treeview to the outside world (e.g. Nautilus) to export actions
+ * - from outside world (e.g. Nautilus) to import actions
+ */
+static void
+instance_constructed( GObject *model )
+{
+	static const gchar *thisfn = "nact_tree_model_instance_constructed";
+	NactTreeModelPrivate *priv;
+
+	g_return_if_fail( NACT_IS_TREE_MODEL( model ));
+
+	priv = NACT_TREE_MODEL( model )->private;
+
+	if( !priv->dispose_has_run ){
+
+		/* chain up to the parent class */
+		if( G_OBJECT_CLASS( st_parent_class )->constructed ){
+			G_OBJECT_CLASS( st_parent_class )->constructed( model );
+		}
+
+		g_debug( "%s: model=%p (%s)", thisfn, ( void * ) model, G_OBJECT_TYPE_NAME( model ));
+
+		priv->clipboard = nact_clipboard_new( priv->window );
+
+		if( priv->mode == TREE_MODE_EDITION ){
+
+			egg_tree_multi_drag_add_drag_support(
+					EGG_TREE_MULTI_DRAG_SOURCE( model ),
+					priv->treeview );
+
+			gtk_tree_view_enable_model_drag_dest(
+					priv->treeview,
+					tree_model_dnd_dest_formats,
+					tree_model_dnd_dest_formats_count,
+					nact_tree_model_dnd_imulti_drag_source_get_drag_actions( EGG_TREE_MULTI_DRAG_SOURCE( model )));
+
+			base_window_signal_connect(
+					priv->window,
+					G_OBJECT( priv->treeview ),
+					"drag-begin",
+					G_CALLBACK( nact_tree_model_dnd_on_drag_begin ));
+
+			/* connect: implies that we have to do all hard stuff
+			 * connect_after: no more triggers drag-drop signal
+			 */
+			/*base_window_signal_connect_after( window,
+					G_OBJECT( model->private->treeview ), "drag-motion", G_CALLBACK( on_drag_motion ));*/
+
+			/*base_window_signal_connect( window,
+					G_OBJECT( model->private->treeview ), "drag-drop", G_CALLBACK( on_drag_drop ));*/
+
+			base_window_signal_connect(
+					priv->window,
+					G_OBJECT( priv->treeview ),
+					"drag-end",
+					G_CALLBACK( nact_tree_model_dnd_on_drag_end ));
+
+			na_settings_register_key_callback(
+					NA_IPREFS_ITEMS_LIST_ORDER_MODE,
+					G_CALLBACK( on_settings_order_mode_changed ),
+					model );
+
+			base_window_signal_connect_with_data(
+					priv->window,
+					G_OBJECT( priv->window ),
+					TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
+					G_CALLBACK( on_tab_updatable_item_updated ),
+					model );
+		}
+
+	}
+}
+
+static void
 instance_dispose( GObject *object )
 {
 	static const gchar *thisfn = "nact_tree_model_instance_dispose";
 	NactTreeModel *self;
+	GtkTreeStore *ts_model;
 
 	g_return_if_fail( NACT_IS_TREE_MODEL( object ));
 
@@ -261,6 +443,10 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
+		ts_model = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( self )));
+		gtk_tree_store_clear( ts_model );
+		g_debug( "%s: tree store cleared", thisfn );
+
 		g_object_unref( self->private->clipboard );
 
 		/* chain up to the parent class */
@@ -324,7 +510,12 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
 
 	/* create the filter model
 	 */
-	model = g_object_new( NACT_TYPE_TREE_MODEL, "child-model", ts_model, NULL );
+	model = g_object_new( NACT_TYPE_TREE_MODEL,
+			"child-model",      ts_model,
+			TREE_PROP_WINDOW,   window,
+			TREE_PROP_TREEVIEW, treeview,
+			TREE_PROP_MODE,     mode,
+			NULL );
 	g_object_unref( ts_model );
 
 	gtk_tree_model_filter_set_visible_func(
@@ -335,98 +526,10 @@ nact_tree_model_new( BaseWindow *window, GtkTreeView *treeview, NactTreeMode mod
 	order_mode = na_iprefs_get_order_mode( NULL );
 	display_order_change( model, order_mode );
 
-	/* setup instanciation time data
-	 */
-	model->private->window = window;
-	model->private->treeview = treeview;
-	model->private->mode = mode;
-	model->private->clipboard = nact_clipboard_new( window );
-
-	g_object_set_data( G_OBJECT( window ), WINDOW_DATA_TREE_MODEL, model );
-
-	/* attach the model to the tree view
-	 */
-	gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
-	g_object_unref( model );
-
-	/* This function used (Gtk2) to connect to base-runtime-init signal in
-	 * order to initialize the model.
-	 * With Gtk3, we are only called from NactMainWindow::on_base_runtime_init()
-	 * callback, so too late to connect to this signal. We so called directly
-	 * the function
-	 */
-	on_initialize_model( window, NULL );
-
 	return( model );
 }
 
 /*
- * on_initialize_model:
- * @window: the #BaseWindow which embeds the tree view.
- * @user_data: not used (this same @window).
- *
- * Initializes the tree model.
- *
- * We use drag and drop:
- * - inside of treeview, for duplicating items, or moving items between menus
- * - from treeview to the outside world (e.g. Nautilus) to export actions
- * - from outside world (e.g. Nautilus) to import actions
- */
-static void
-on_initialize_model( BaseWindow *window, gpointer user_data )
-{
-	static const gchar *thisfn = "nact_tree_model_on_initialize_model";
-
-	WINDOW_MODEL_VOID( window );
-
-	g_debug( "%s: window=%p (%s), user_data=%p, model=%p (%s)",
-			thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ),
-			( void * ) user_data, ( void * ) model, G_OBJECT_TYPE_NAME( model ));
-
-	if( !model->private->dispose_has_run ){
-
-		if( model->private->mode == TREE_MODE_EDITION ){
-
-			egg_tree_multi_drag_add_drag_support(
-					EGG_TREE_MULTI_DRAG_SOURCE( model ), model->private->treeview );
-
-			gtk_tree_view_enable_model_drag_dest( model->private->treeview,
-				tree_model_dnd_dest_formats, tree_model_dnd_dest_formats_count,
-				nact_tree_model_dnd_imulti_drag_source_get_drag_actions( EGG_TREE_MULTI_DRAG_SOURCE( model )));
-
-			base_window_signal_connect( window,
-					G_OBJECT( model->private->treeview ), "drag-begin", G_CALLBACK( nact_tree_model_dnd_on_drag_begin ));
-
-			/* connect: implies that we have to do all hard stuff
-			 * connect_after: no more triggers drag-drop signal
-			 */
-			/*base_window_signal_connect_after( window,
-					G_OBJECT( model->private->treeview ), "drag-motion", G_CALLBACK( on_drag_motion ));*/
-
-			/*base_window_signal_connect( window,
-					G_OBJECT( model->private->treeview ), "drag-drop", G_CALLBACK( on_drag_drop ));*/
-
-			base_window_signal_connect(
-					window,
-					G_OBJECT( model->private->treeview ),
-					"drag-end",
-					G_CALLBACK( nact_tree_model_dnd_on_drag_end ));
-
-			na_settings_register_key_callback(
-					NA_IPREFS_ITEMS_LIST_ORDER_MODE,
-					G_CALLBACK( on_settings_order_mode_changed ),
-					model );
-
-			base_window_signal_connect(
-					window,
-					G_OBJECT( window ),
-					TAB_UPDATABLE_SIGNAL_ITEM_UPDATED,
-					G_CALLBACK( on_tab_updatable_item_updated ));
-		}
-	}
-}
-
-/*
  * NASettings callback for a change on NA_IPREFS_ITEMS_LIST_ORDER_MODE key
  */
 static void
@@ -455,19 +558,21 @@ on_settings_order_mode_changed( const gchar *group, const gchar *key, gconstpoin
  * if force_display is true, then refresh the display of the view
  */
 static void
-on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, gpointer user_data )
+on_tab_updatable_item_updated( BaseWindow *window, NAIContext *context, guint data, NactTreeModel *model )
 {
 	static const gchar *thisfn = "nact_tree_model_on_tab_updatable_item_updated";
 	GtkTreePath *path;
 	GtkTreeStore *store;
 	GtkTreeIter iter;
 
-	WINDOW_MODEL_VOID( window );
-
 	if( !model->private->dispose_has_run ){
-		g_debug( "%s: window=%p, context=%p (%s), data=%u, user_data=%p",
-				thisfn, ( void * ) window, ( void * ) context, G_OBJECT_TYPE_NAME( context ),
-				data, ( void * ) user_data );
+
+		g_debug( "%s: window=%p, context=%p (%s), data=%u, model=%p",
+				thisfn,
+				( void * ) window,
+				( void * ) context, G_OBJECT_TYPE_NAME( context ),
+				data,
+				( void * ) model );
 
 		if( data & ( MAIN_DATA_LABEL | MAIN_DATA_ICON )){
 			path = nact_tree_model_object_to_path( model, ( NAObject * ) context );
diff --git a/src/nact/nact-tree-view.c b/src/nact/nact-tree-view.c
index 058203d..6ff8ea7 100644
--- a/src/nact/nact-tree-view.c
+++ b/src/nact/nact-tree-view.c
@@ -591,8 +591,6 @@ instance_dispose( GObject *object )
 {
 	static const gchar *thisfn = "nact_tree_view_instance_dispose";
 	NactTreeView *self;
-	NactTreeModel *model;
-	GtkTreeStore *ts_model;
 
 	g_return_if_fail( NACT_IS_TREE_VIEW( object ));
 
@@ -603,11 +601,6 @@ instance_dispose( GObject *object )
 
 		self->private->dispose_has_run = TRUE;
 
-		model = NACT_TREE_MODEL( gtk_tree_view_get_model( self->private->tree_view ));
-		ts_model = GTK_TREE_STORE( gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model )));
-		gtk_tree_store_clear( ts_model );
-		g_debug( "%s: tree store cleared", thisfn );
-
 		if( self->private->mode == TREE_MODE_EDITION ){
 			nact_tree_ieditable_terminate( NACT_TREE_IEDITABLE( self ));
 		}
@@ -686,6 +679,7 @@ initialize_gtk( NactTreeView *items_view )
 {
 	static const gchar *thisfn = "nact_tree_view_initialize_gtk";
 	GtkTreeView *treeview;
+	NactTreeModel *model;
 	GtkWidget *label;
 	GtkTreeViewColumn *column;
 	GtkCellRenderer *renderer;
@@ -695,7 +689,10 @@ initialize_gtk( NactTreeView *items_view )
 	g_debug( "%s: items_view=%p", thisfn, ( void * ) items_view );
 
 	treeview = GTK_TREE_VIEW( get_tree_view( items_view ));
-	nact_tree_model_new( items_view->private->window, treeview, items_view->private->mode );
+	model = nact_tree_model_new( items_view->private->window, treeview, items_view->private->mode );
+	gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
+	g_object_unref( model );
+	g_debug( "%s: nact_tree_model_ref_count=%d", thisfn, G_OBJECT( model )->ref_count );
 
 	/* associates the ItemsView to the label */
 	label = na_gtk_utils_find_widget_by_name( items_view->private->parent, "ActionsListLabel" );
@@ -962,6 +959,7 @@ nact_tree_view_fill( NactTreeView *view, GList *items )
 		view->private->notify_allowed = FALSE;
 		model = NACT_TREE_MODEL( gtk_tree_view_get_model( view->private->tree_view ));
 		nact_tree_model_fill( model, items );
+		g_debug( "%s: nact_tree_model_ref_count=%d", thisfn, G_OBJECT( model )->ref_count );
 
 		view->private->notify_allowed = TRUE;
 		na_object_count_items( items, &nb_menus, &nb_actions, &nb_profiles );
diff --git a/src/nact/nact-tree-view.h b/src/nact/nact-tree-view.h
index e4b4770..100b218 100644
--- a/src/nact/nact-tree-view.h
+++ b/src/nact/nact-tree-view.h
@@ -126,7 +126,7 @@ enum {
 
 /**
  * The NactTreeView is attached to the parent BaseWindow via a GObject data.
- * Only NactTreeIEditable interface should use it.
+ * Only NactTreeView itself and NactTreeIEditable interface should use it.
  */
 #define WINDOW_DATA_TREE_VIEW					"window-data-tree-view"
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]