[nautilus-actions] Fix check_edition_status dynamic
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Fix check_edition_status dynamic
- Date: Sat, 26 Sep 2009 22:48:35 +0000 (UTC)
commit 7feb513f5947889ee49b4ae96033976b74f5ae07
Author: Pierre Wieser <pwieser trychlos org>
Date: Mon Sep 21 06:57:05 2009 +0200
Fix check_edition_status dynamic
Also fix selection of newly inserted profile.
ChangeLog | 38 +++++++++++++++
src/common/na-gconf-provider.c | 9 ++--
src/common/na-iduplicable.c | 81 +++++++++++++++++++++++++++++--
src/common/na-iduplicable.h | 3 +
src/common/na-iio-provider.c | 37 +++++++++-----
src/common/na-obj-action.c | 26 ++++++++++-
src/common/na-object-item.c | 26 +++++++---
src/common/na-object.c | 11 +++--
src/nact/nact-iactions-list.c | 103 +++++++++++++++++++++++++++++----------
src/nact/nact-main-menubar.c | 22 ++++++--
src/nact/nact-tree-model.c | 30 +++++++-----
src/nact/nact-tree-model.h | 2 +-
12 files changed, 304 insertions(+), 84 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index b337b63..9e40140 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,41 @@
+2009-09-21 Pierre Wieser <pwieser trychlos org>
+
+ * src/common/na-gconf-provider.c (write_item_menu):
+ Fix memory leak.
+
+ * src/common/na-iduplicable.c:
+ * src/common/na-iduplicable.h:
+ Emits a signal for each modification of one of the status.
+ Do not use NA_xx macros when returning a pointer that may be NULL.
+
+ * src/common/na-iio-provider.c (build_hierarchy):
+ Defaults to keep the whole list when there is no level-zero pref.
+
+ * src/common/na-obj-action.c:
+ Version number is not localized, so compare should be ascii.
+ Action inherits from edition status of its profiles.
+
+ * src/common/na-object-item.c:
+ Optimizes check of edition status of subitems.
+
+ * src/common/na-object.c:
+ No more over-checks edition status of item's childs.
+
+ * src/nact/nact-iactions-list.c:
+ When duplicating an object, try to insert the new one besides
+ the original one.
+
+ * src/nact/nact-main-menubar.c (on_new_profile_activated):
+ Setup edition status of new profile.
+
+ * src/nact/nact-main-menubar.c (save_object_item):
+ Cleanup the code.
+
+ * src/nact/nact-tree-model.c:
+ * src/nact/nact-tree-model.h (nact_tree_model_insert):
+ Returns the path string of the newly inserted row, as it appears
+ more liable that an iter after child model conversion.
+
2009-09-20 Pierre Wieser <pwieser trychlos org>
* src/common/na-object-item.c (object_id_new_id):
diff --git a/src/common/na-gconf-provider.c b/src/common/na-gconf-provider.c
index 5b6c124..2b470f5 100644
--- a/src/common/na-gconf-provider.c
+++ b/src/common/na-gconf-provider.c
@@ -835,18 +835,17 @@ write_item_menu( NAGConfProvider *provider, const NAObjectMenu *menu, gchar **me
{
gchar *uuid;
gboolean ret;
- GSList *ids;
if( !write_object_item( provider, NA_OBJECT_ITEM( menu ), message )){
return( FALSE );
}
uuid = na_object_get_id( NA_OBJECT( menu ));
- ids = na_object_menu_rebuild_items_list( menu );
- ret = write_list( provider, uuid, NULL, MENU_ITEMS_ENTRY, ids, message );
- na_utils_free_string_list( ids );
- g_free( uuid );
+ ret =
+ write_list( provider, uuid, NULL, MENU_ITEMS_ENTRY, na_object_menu_rebuild_items_list( menu ), message );
+
+ g_free( uuid );
return( ret );
}
diff --git a/src/common/na-iduplicable.c b/src/common/na-iduplicable.c
index 8e6d9c6..dcef11b 100644
--- a/src/common/na-iduplicable.c
+++ b/src/common/na-iduplicable.c
@@ -46,8 +46,17 @@ struct NAIDuplicableInterfacePrivate {
#define NA_IDUPLICABLE_PROP_IS_MODIFIED "na-iduplicable-is-modified"
#define NA_IDUPLICABLE_PROP_IS_VALID "na-iduplicable-is-valid"
+/* signals emitted on NAIDuplicable when a status changes
+ */
+enum {
+ MODIFIED_CHANGED,
+ VALID_CHANGED,
+ LAST_SIGNAL
+};
+
static gboolean st_initialized = FALSE;
static gboolean st_finalized = FALSE ;
+static gint st_signals[ LAST_SIGNAL ] = { 0 };
static GType register_type( void );
static void interface_base_init( NAIDuplicableInterface *klass );
@@ -115,6 +124,42 @@ interface_base_init( NAIDuplicableInterface *klass )
klass->private = g_new0( NAIDuplicableInterfacePrivate, 1 );
+ /**
+ * na-iduplicable-modified-changed:
+ *
+ * This signal is emitted byIDuplicable when the modification
+ * status of an object has been modified.
+ */
+ st_signals[ MODIFIED_CHANGED ] = g_signal_new(
+ NA_IDUPLICABLE_SIGNAL_MODIFIED_CHANGED,
+ G_TYPE_OBJECT,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER );
+
+ /**
+ * na-iduplicable-valid-changed:
+ *
+ * This signal is emitted byIDuplicable when the validity
+ * status of an object has been modified.
+ */
+ st_signals[ VALID_CHANGED ] = g_signal_new(
+ NA_IDUPLICABLE_SIGNAL_VALID_CHANGED,
+ G_TYPE_OBJECT,
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_POINTER );
+
st_initialized = TRUE;
}
}
@@ -239,23 +284,25 @@ na_iduplicable_duplicate( const NAIDuplicable *object )
void
na_iduplicable_check_edition_status( const NAIDuplicable *object )
{
- /*static const gchar *thisfn = "na_iduplicable_check_edition_status";
- g_debug( "%s: object=%p", thisfn, object );*/
+ static const gchar *thisfn = "na_iduplicable_check_edition_status";
gboolean modified = TRUE;
NAIDuplicable *origin;
gboolean valid;
+ g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
g_return_if_fail( st_initialized && !st_finalized );
g_return_if_fail( NA_IS_IDUPLICABLE( object ));
origin = get_origin( object );
if( origin ){
- modified = !v_are_equal( object, origin );
+ modified = !v_are_equal( origin, object );
}
set_modified( object, modified );
valid = v_is_valid( object );
set_valid( object, valid );
+ g_debug( "%s: object=%p, modified=%s, valid=%s",
+ thisfn, ( void * ) object, modified ? "True":"False", valid ? "True":"False" );
}
/**
@@ -394,10 +441,15 @@ get_modified( const NAIDuplicable *object )
return(( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_MODIFIED )));
}
+/*
+ * do not use here NA_IDUPLICABLE macro as it may return a (valid) NULL
+ * value
+ */
static NAIDuplicable *
get_origin( const NAIDuplicable *object )
{
- return( NA_IDUPLICABLE( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN )));
+ /*return( NA_IDUPLICABLE( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN )));*/
+ return(( NAIDuplicable * ) g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_ORIGIN ));
}
static gboolean
@@ -406,10 +458,22 @@ get_valid( const NAIDuplicable *object )
return(( gboolean ) GPOINTER_TO_UINT( g_object_get_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_VALID )));
}
+/*
+ * I'd wish simulate the behavior of GObject property which is able to
+ * send a message each time a property is changed ; but these data are
+ * not properties of NAObject
+ */
static void
set_modified( const NAIDuplicable *object, gboolean is_modified )
{
- g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_MODIFIED, GUINT_TO_POINTER( is_modified ));
+ gboolean was_modified = get_modified( object );
+
+ if( was_modified != is_modified ){
+ g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_MODIFIED, GUINT_TO_POINTER( is_modified ));
+ g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_MODIFIED_CHANGED, object );
+ g_debug( "na_iduplicable_set_modified: object=%p (%s) modified=%s",
+ ( void * ) object, G_OBJECT_TYPE_NAME( object ), is_modified ? "True":"False" );
+ }
}
static void
@@ -421,5 +485,10 @@ set_origin( const NAIDuplicable *object, const NAIDuplicable *origin )
static void
set_valid( const NAIDuplicable *object, gboolean is_valid )
{
- g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_VALID, GUINT_TO_POINTER( is_valid ));
+ gboolean was_valid = get_valid( object );
+
+ if( was_valid != is_valid ){
+ g_object_set_data( G_OBJECT( object ), NA_IDUPLICABLE_PROP_IS_VALID, GUINT_TO_POINTER( is_valid ));
+ g_signal_emit_by_name( G_OBJECT( object ), NA_IDUPLICABLE_SIGNAL_VALID_CHANGED, object );
+ }
}
diff --git a/src/common/na-iduplicable.h b/src/common/na-iduplicable.h
index ea638f5..2c869bb 100644
--- a/src/common/na-iduplicable.h
+++ b/src/common/na-iduplicable.h
@@ -142,6 +142,9 @@ typedef struct {
}
NAIDuplicableInterface;
+#define NA_IDUPLICABLE_SIGNAL_MODIFIED_CHANGED "na-iduplicable-modified-changed"
+#define NA_IDUPLICABLE_SIGNAL_VALID_CHANGED "na-iduplicable-valid-changed"
+
GType na_iduplicable_get_type( void );
void na_iduplicable_init( NAIDuplicable *object );
diff --git a/src/common/na-iio-provider.c b/src/common/na-iio-provider.c
index e7f5081..ca17012 100644
--- a/src/common/na-iio-provider.c
+++ b/src/common/na-iio-provider.c
@@ -197,23 +197,32 @@ build_hierarchy( GList *tree, GSList *level_zero )
hierarchy = NULL;
- for( ilevel = level_zero ; ilevel ; ilevel = ilevel->next ){
- g_debug( "na_iio_provider_build_hierarchy: next_level_zero uuid is %s", ( gchar * ) ilevel->data );
- it = g_list_find_custom( tree, ilevel->data, ( GCompareFunc ) search_item );
- if( it ){
- hierarchy = g_list_append( hierarchy, g_object_ref( it->data ));
- g_debug( "na_iio_provider_build_hierarchy: appending %s at %p to hierarchy %p",
- G_OBJECT_TYPE_NAME( it->data ), ( void * ) it->data, ( void * ) hierarchy );
-
- if( NA_IS_OBJECT_MENU( it->data )){
- subitems_ids = na_object_menu_get_items_list( NA_OBJECT_MENU( it->data ));
- subitems = build_hierarchy( tree, subitems_ids );
- na_object_set_items( it->data, subitems );
- na_object_free_items( subitems );
- na_utils_free_string_list( subitems_ids );
+ if( g_slist_length( level_zero )){
+ for( ilevel = level_zero ; ilevel ; ilevel = ilevel->next ){
+ g_debug( "na_iio_provider_build_hierarchy: next_level_zero uuid is %s", ( gchar * ) ilevel->data );
+ it = g_list_find_custom( tree, ilevel->data, ( GCompareFunc ) search_item );
+ if( it ){
+ hierarchy = g_list_append( hierarchy, g_object_ref( it->data ));
+ g_debug( "na_iio_provider_build_hierarchy: appending %s at %p to hierarchy %p",
+ G_OBJECT_TYPE_NAME( it->data ), ( void * ) it->data, ( void * ) hierarchy );
+
+ if( NA_IS_OBJECT_MENU( it->data )){
+ subitems_ids = na_object_menu_get_items_list( NA_OBJECT_MENU( it->data ));
+ subitems = build_hierarchy( tree, subitems_ids );
+ na_object_set_items( it->data, subitems );
+ na_object_free_items( subitems );
+ na_utils_free_string_list( subitems_ids );
+ }
}
}
}
+ /* if level-zero list is empty, we consider that all actions go to it
+ */
+ else {
+ for( it = tree ; it ; it = it->next ){
+ hierarchy = g_list_append( hierarchy, g_object_ref( it->data ));
+ }
+ }
return( hierarchy );
}
diff --git a/src/common/na-obj-action.c b/src/common/na-obj-action.c
index 8231003..5bc235f 100644
--- a/src/common/na-obj-action.c
+++ b/src/common/na-obj-action.c
@@ -547,11 +547,21 @@ object_copy( NAObject *target, const NAObject *source )
/*g_debug( "na_object_action_object_copy: end" );*/
}
+/*
+ * note 1: version is not localized (see configure.ac)
+ *
+ * note 2: when checking for equality of profiles, we know that NAObjectItem
+ * has already checked their edition status, and assert that profiles lists
+ * were the sames ; we so only report the modification status to the action
+ */
static gboolean
object_are_equal( const NAObject *a, const NAObject *b )
{
NAObjectAction *first, *second;
gboolean equal = TRUE;
+ GList *profiles, *ip;
+ gchar *id;
+ NAObjectProfile *profile;
g_return_val_if_fail( NA_IS_OBJECT_ACTION( a ), FALSE );
g_return_val_if_fail( !NA_OBJECT_ACTION( a )->private->dispose_has_run, FALSE );
@@ -562,7 +572,21 @@ object_are_equal( const NAObject *a, const NAObject *b )
second = NA_OBJECT_ACTION( b );
if( equal ){
- equal = ( g_utf8_collate( first->private->version, second->private->version ) == 0 );
+ equal = ( strcmp( first->private->version, second->private->version ) == 0 );
+ }
+
+ if( equal ){
+ profiles = na_object_get_items( a );
+ for( ip = profiles ; ip ; ip = ip->next ){
+ id = na_object_get_id( ip->data );
+ profile = NA_OBJECT_PROFILE( na_object_get_item( b, id ));
+ equal = !na_object_is_modified( profile );
+ if( !equal ){
+ g_debug( "na_object_action_are_equal: profile=%p, equal=False", ( void * ) profile );
+ }
+ g_free( id );
+ }
+ na_object_free_items( profiles );
}
/*g_debug( "na_object_action_are_equal: %s", equal ? "True":"False" );*/
diff --git a/src/common/na-object-item.c b/src/common/na-object-item.c
index 0426209..bcf7d0c 100644
--- a/src/common/na-object-item.c
+++ b/src/common/na-object-item.c
@@ -826,7 +826,19 @@ object_copy( NAObject *target, const NAObject *source )
}
/*
- * note that provider is not consider as pertinent here
+ * @a: original object.
+ * @b: the object which has been initially duplicated from @a, and is
+ * being checked for modification status.
+ *
+ * note 1: The provider is not considered as pertinent here
+ *
+ * note 2: NAObjectItem recursively checks for equality in subitems.
+ * Nonetheless, the modification status of subitems doesn't have any
+ * impact on this object itself, provided that subitems lists are
+ * themselves identical
+ *
+ * note 3: Only NAObjectAction is modified that one of the profiles are
+ * modified (because they are saved as a whole)
*/
static gboolean
object_are_equal( const NAObject *a, const NAObject *b )
@@ -860,11 +872,12 @@ object_are_equal( const NAObject *a, const NAObject *b )
for( it = NA_OBJECT_ITEM( a )->private->items ; it && equal ; it = it->next ){
first_obj = NA_OBJECT( it->data );
first_id = na_object_get_id( first_obj );
- second_obj = NA_OBJECT( na_object_get_item( b, first_id ));
+ second_obj = ( NAObject * ) na_object_get_item( b, first_id );
g_free( first_id );
if( second_obj ){
- equal = na_object_iduplicable_are_equal( first_obj, second_obj );
+ na_object_check_edition_status( second_obj );
} else {
+ g_debug( "na_object_item_are_equal: object=%p (%s), equal=False", ( void * ) b, G_OBJECT_TYPE_NAME( b ));
equal = FALSE;
}
}
@@ -874,11 +887,10 @@ object_are_equal( const NAObject *a, const NAObject *b )
for( it = NA_OBJECT_ITEM( b )->private->items ; it && equal ; it = it->next ){
second_obj = NA_OBJECT( it->data );
second_id = na_object_get_id( second_obj );
- first_obj = NA_OBJECT( na_object_get_item( a, second_id ));
+ first_obj = ( NAObject * ) na_object_get_item( a, second_id );
g_free( second_id );
- if( first_obj ){
- equal = na_object_iduplicable_are_equal( first_obj, second_obj );
- } else {
+ if( !first_obj ){
+ g_debug( "na_object_item_are_equal: object=%p (%s), equal=False", ( void * ) b, G_OBJECT_TYPE_NAME( b ));
equal = FALSE;
}
}
diff --git a/src/common/na-object.c b/src/common/na-object.c
index 46922f4..165da3e 100644
--- a/src/common/na-object.c
+++ b/src/common/na-object.c
@@ -635,17 +635,17 @@ do_is_valid( const NAObject *object )
void
na_object_iduplicable_check_edition_status( const NAObject *object )
{
- GList *childs, *ic;
+ /*GList *childs, *ic;*/
g_return_if_fail( NA_IS_OBJECT( object ));
g_return_if_fail( !object->private->dispose_has_run );
na_iduplicable_check_edition_status( NA_IDUPLICABLE( object ));
- childs = v_get_childs( object );
+ /*childs = v_get_childs( object );
for( ic = childs ; ic ; ic = ic->next ){
na_iduplicable_check_edition_status( NA_IDUPLICABLE( ic->data ));
- }
+ }*/
}
/**
@@ -696,6 +696,8 @@ na_object_iduplicable_is_valid( const NAObject *object )
* Returns the original object which was at the origin of @object.
*
* Returns: a #NAObject, or NULL.
+ *
+ * Do not use here NA_OBJECT macro as it may return a (valid) NULL value
*/
NAObject *
na_object_iduplicable_get_origin( const NAObject *object )
@@ -703,7 +705,8 @@ na_object_iduplicable_get_origin( const NAObject *object )
g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
g_return_val_if_fail( !object->private->dispose_has_run, NULL );
- return( NA_OBJECT( na_iduplicable_get_origin( NA_IDUPLICABLE( object ))));
+ /*return( NA_OBJECT( na_iduplicable_get_origin( NA_IDUPLICABLE( object ))));*/
+ return(( NAObject * ) na_iduplicable_get_origin( NA_IDUPLICABLE( object )));
}
/**
diff --git a/src/nact/nact-iactions-list.c b/src/nact/nact-iactions-list.c
index 8d23fc4..5dc466c 100644
--- a/src/nact/nact-iactions-list.c
+++ b/src/nact/nact-iactions-list.c
@@ -35,6 +35,7 @@
#include <gdk/gdkkeysyms.h>
#include <string.h>
+#include <common/na-iduplicable.h>
#include <common/na-object-api.h>
#include <common/na-obj-action.h>
#include <common/na-obj-menu.h>
@@ -85,6 +86,15 @@ typedef struct {
}
SelectionIter;
+/* when iterating while searching for the path of an object
+ */
+typedef struct {
+ NAObject *object;
+ gboolean found;
+ GtkTreePath *path;
+}
+ ObjectToPathIter;
+
/* data set against GObject
*/
#define SELECTION_CHANGED_SIGNAL_MODE "nact-iactions-list-selection-changed-signal-mode"
@@ -114,6 +124,8 @@ static gboolean have_dnd_mode( NactIActionsList *instance );
static gboolean have_filter_selection_mode( NactIActionsList *instance );
static gboolean is_selection_changed_authorized( NactIActionsList *instance );
static void iter_on_selection( NactIActionsList *instance, FnIterOnSelection fn_iter, gpointer user_data );
+static GtkTreePath *object_to_path( NactIActionsList *instance, NactTreeModel *model, NAObject *object );
+static gboolean object_to_path_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ObjectToPathIter *otp );
static gboolean on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactIActionsList *instance );
static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, NactIActionsList *instance );
static void on_treeview_selection_changed( GtkTreeSelection *selection, NactIActionsList *instance );
@@ -657,14 +669,18 @@ nact_iactions_list_insert_items( NactIActionsList *instance, GList *items, NAObj
model = gtk_tree_view_get_model( treeview );
g_return_if_fail( NACT_IS_TREE_MODEL( model ));
- selection = gtk_tree_view_get_selection( treeview );
- list_selected = gtk_tree_selection_get_selected_rows( selection, NULL );
- if( g_list_length( list_selected )){
- insert_path = gtk_tree_path_copy(( GtkTreePath * ) list_selected->data );
- }
+ if( sibling ){
+ insert_path = object_to_path( instance, NACT_TREE_MODEL( model ), sibling );
- g_list_foreach( list_selected, ( GFunc ) gtk_tree_path_free, NULL );
- g_list_free( list_selected );
+ } else {
+ selection = gtk_tree_view_get_selection( treeview );
+ list_selected = gtk_tree_selection_get_selected_rows( selection, NULL );
+ if( g_list_length( list_selected )){
+ insert_path = gtk_tree_path_copy(( GtkTreePath * ) list_selected->data );
+ }
+ g_list_foreach( list_selected, ( GFunc ) gtk_tree_path_free, NULL );
+ g_list_free( list_selected );
+ }
last_path = do_insert_items( treeview, model, items, insert_path, 0, &parents );
@@ -684,10 +700,10 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
{
static const gchar *thisfn = "nact_iactions_list_do_insert_items";
guint nb_profiles, nb_actions, nb_menus;
- GtkTreeIter iter;
GList *it;
GList *subitems;
- GtkTreePath *newpath;
+ gchar *inserted_path_str;
+ GtkTreePath *inserted_path;
NAObject *obj_parent;
GtkTreePath *returned_path;
@@ -707,17 +723,15 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
* from store to filter_model, and ran through filter_visible function
* we so cannot rely on it if object is a profile inserted at level > 0
*/
- nact_tree_model_insert( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ), path, &iter, &obj_parent );
+ inserted_path_str = nact_tree_model_insert( NACT_TREE_MODEL( model ), NA_OBJECT( it->data ), path, &obj_parent );
+ g_debug( "%s: inserted_path=%s", thisfn, inserted_path_str );
- newpath = NULL;
- if( !NA_IS_OBJECT_PROFILE( it->data ) || level == 0 ){
- newpath = gtk_tree_model_get_path( model, &iter );
- }
+ inserted_path = gtk_tree_path_new_from_string( inserted_path_str );
if( level == 0 ){
- gtk_tree_view_expand_to_path( treeview, newpath );
+ gtk_tree_view_expand_to_path( treeview, inserted_path );
gtk_tree_path_free( returned_path );
- returned_path = gtk_tree_path_copy( newpath );
+ returned_path = gtk_tree_path_copy( inserted_path );
}
*parents = do_insert_items_add_parent( *parents, treeview, model, obj_parent );
@@ -726,13 +740,12 @@ do_insert_items( GtkTreeView *treeview, GtkTreeModel *model, GList *items, GtkTr
*/
if( NA_IS_OBJECT_ITEM( it->data )){
subitems = na_object_get_items( it->data );
- do_insert_items( treeview, model, subitems, newpath, level+1, parents );
+ do_insert_items( treeview, model, subitems, inserted_path, level+1, parents );
na_object_free_items( subitems );
}
- if( newpath ){
- gtk_tree_path_free( newpath );
- }
+ gtk_tree_path_free( inserted_path );
+ g_free( inserted_path_str );
}
}
@@ -1185,6 +1198,40 @@ iter_on_selection( NactIActionsList *instance, FnIterOnSelection fn_iter, gpoint
g_list_free( listrows );
}
+static GtkTreePath *
+object_to_path( NactIActionsList *instance, NactTreeModel *model, NAObject *object )
+{
+ ObjectToPathIter *otp;
+ GtkTreePath *path = NULL;
+
+ otp = g_new0( ObjectToPathIter, 1 );
+ otp->object = object;
+ otp->found = FALSE;
+ otp->path = NULL;
+
+ nact_tree_model_iter( model, ( FnIterOnStore ) object_to_path_iter, otp );
+
+ if( otp->found ){
+ path = gtk_tree_path_copy( otp->path );
+ gtk_tree_path_free( otp->path );
+ }
+
+ g_free( otp );
+
+ return( path );
+}
+
+static gboolean
+object_to_path_iter( NactTreeModel *model, GtkTreePath *path, NAObject *object, ObjectToPathIter *otp )
+{
+ if( object == otp->object ){
+ otp->found = TRUE;
+ otp->path = gtk_tree_path_copy( path );
+ }
+
+ return( otp->found );
+}
+
static gboolean
on_button_press_event( GtkWidget *widget, GdkEventButton *event, NactIActionsList *instance )
{
@@ -1254,20 +1301,22 @@ on_iactions_list_item_updated( NactIActionsList *instance, NAObject *object )
static void
on_iactions_list_item_updated_treeview( NactIActionsList *instance, NAObject *object )
{
- NAObject *item;
+ NAObjectAction *item;
GtkTreeView *treeview;
GtkTreeModel *model;
if( object ){
- item = NA_IS_OBJECT_PROFILE( object )
- ? NA_OBJECT( na_object_profile_get_action( NA_OBJECT_PROFILE( object )))
- : object;
-
- na_object_check_edition_status( item );
-
treeview = get_actions_list_treeview( instance );
model = gtk_tree_view_get_model( treeview );
+
+ na_object_check_edition_status( object );
nact_tree_model_display( NACT_TREE_MODEL( model ), object );
+
+ if( NA_IS_OBJECT_PROFILE( object )){
+ item = na_object_profile_get_action( NA_OBJECT_PROFILE( object ));
+ na_object_check_edition_status( item );
+ nact_tree_model_display( NACT_TREE_MODEL( model ), NA_OBJECT( item ));
+ }
}
}
diff --git a/src/nact/nact-main-menubar.c b/src/nact/nact-main-menubar.c
index 22543a2..7a57eb4 100644
--- a/src/nact/nact-main-menubar.c
+++ b/src/nact/nact-main-menubar.c
@@ -322,6 +322,7 @@ on_new_profile_activated( GtkAction *gtk_action, NactMainWindow *window )
/*na_object_action_attach_profile( action, profile );*/
na_object_profile_set_action( profile, action );
na_object_set_id( profile, name );
+ na_object_check_edition_status( profile );
items = g_list_prepend( NULL, profile );
nact_iactions_list_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
@@ -380,24 +381,33 @@ static void
save_object_item( NactMainWindow *window, NAPivot *pivot, NAObjectItem *object )
{
GList *items, *it;
+ NAObjectItem *origin;
+ NAObjectItem *dup_pivot;
if( na_object_is_modified( NA_OBJECT( object )) &&
na_object_is_valid( NA_OBJECT( object )) &&
nact_window_save_item( NACT_WINDOW( window ), object )){
- NAObjectItem *origin = NA_OBJECT_ITEM( na_object_get_origin( NA_OBJECT( object )));
+ g_debug( "save_object_item: about to get origin" );
+ /* do not use OA_OBJECT_ITEM macro as this may return a (valid)
+ * NULL value
+ */
+ origin = ( NAObjectItem * ) na_object_get_origin( object );
if( origin ){
- na_object_copy( NA_OBJECT( origin ), NA_OBJECT( object ));
+ g_debug( "save_object_item: about to copy to origin" );
+ na_object_copy( origin, object );
} else {
- NAObjectItem *dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( NA_OBJECT( object )));
- na_object_set_origin( NA_OBJECT( dup_pivot ), NULL );
- na_object_set_origin( NA_OBJECT( object ), NA_OBJECT( dup_pivot ));
+ g_debug( "save_object_item: about to duplicate" );
+ dup_pivot = NA_OBJECT_ITEM( na_object_duplicate( object ));
+ na_object_set_origin( dup_pivot, NULL );
+ na_object_set_origin( object, dup_pivot );
na_pivot_add_item( pivot, NA_OBJECT( dup_pivot ));
}
- na_object_check_edition_status( NA_OBJECT( object ));
+ g_debug( "save_object_item: about to check edition status" );
+ na_object_check_edition_status( object );
}
/* Profiles are saved with their actions
diff --git a/src/nact/nact-tree-model.c b/src/nact/nact-tree-model.c
index 8992695..d86f935 100644
--- a/src/nact/nact-tree-model.c
+++ b/src/nact/nact-tree-model.c
@@ -620,11 +620,13 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
* @object: a #NAObject-derived object to be inserted.
* @path: the #GtkTreePath of the beginning of the current selection,
* or NULL.
- * @iter: set to the new row
* @obj_parent: set to the parent or the object itself.
*
* Insert a new row at the given position.
*
+ * Returns: the path string of the inserted row as a newly allocated
+ * string. The returned path should be g_free() by the caller.
+ *
* +--------------------+----------------------+----------------------+----------------------+
* | inserted object -> | action | profile | menu |
* +--------------------+----------------------+----------------------+----------------------+
@@ -643,9 +645,13 @@ fill_tree_store( GtkTreeStore *model, GtkTreeView *treeview,
* insert_before : parent=NULL , sibling_from_path (or null if path was null)
* insert_before_parent: parent=NULL , sibling_from_parent_path
* insert_as_last_child: parent_from_path, sibling=NULL
+ *
+ * Gtk API uses to returns iter ; but at least when inserting a new profile in an action, we
+ * may have store_iter_path="0:1" (good), but iter_path="0:0" (bad) - so we return rather a
+ * string path
*/
-void
-nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, GtkTreeIter *iter, NAObject **obj_parent )
+gchar *
+nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **obj_parent )
{
static const gchar *thisfn = "nact_tree_model_insert";
gchar *path_str;
@@ -659,16 +665,14 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
gboolean has_sibling_iter;
path_str = path ? gtk_tree_path_to_string( path ) : NULL;
- g_debug( "%s: model=%p, object=%p (%s), path=%p (%s), iter=%p",
+ g_debug( "%s: model=%p, object=%p (%s), path=%p (%s)",
thisfn, ( void * ) model,
( void * ) object, G_OBJECT_TYPE_NAME( object ),
- ( void * ) path, path_str,
- ( void * ) iter );
+ ( void * ) path, path_str );
g_free( path_str );
- g_return_if_fail( NACT_IS_TREE_MODEL( model ));
- g_return_if_fail( NA_IS_OBJECT( object ));
- g_return_if_fail( iter );
+ g_return_val_if_fail( NACT_IS_TREE_MODEL( model ), NULL );
+ g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
store = gtk_tree_model_filter_get_model( GTK_TREE_MODEL_FILTER( model ));
has_parent_iter = FALSE;
@@ -679,8 +683,8 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
gtk_tree_model_get_iter( GTK_TREE_MODEL( model ), &select_iter, path );
gtk_tree_model_get( GTK_TREE_MODEL( model ), &select_iter, IACTIONS_LIST_NAOBJECT_COLUMN, &select_object, -1 );
- g_return_if_fail( select_object );
- g_return_if_fail( NA_IS_OBJECT( select_object ));
+ g_return_val_if_fail( select_object, NULL );
+ g_return_val_if_fail( NA_IS_OBJECT( select_object ), NULL );
if( NA_IS_OBJECT_ACTION( object )){
insert_get_iters_action( GTK_TREE_MODEL( store ), select_object, path, object, &parent_iter, &has_parent_iter, &sibling_iter, &has_sibling_iter, obj_parent );
@@ -697,14 +701,14 @@ nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePat
g_object_unref( select_object );
} else {
- g_return_if_fail( NA_IS_OBJECT_ITEM( object ));
+ g_return_val_if_fail( NA_IS_OBJECT_ITEM( object ), NULL );
}
gtk_tree_store_insert_before( GTK_TREE_STORE( store ), &store_iter, has_parent_iter ? &parent_iter : NULL, has_sibling_iter ? &sibling_iter : NULL );
gtk_tree_store_set( GTK_TREE_STORE( store ), &store_iter, IACTIONS_LIST_NAOBJECT_COLUMN, object, -1 );
display_item( GTK_TREE_STORE( store ), model->private->treeview, &store_iter, object );
- gtk_tree_model_filter_convert_child_iter_to_iter( GTK_TREE_MODEL_FILTER( model ), iter, &store_iter );
+ return( gtk_tree_model_get_string_from_iter( store, &store_iter ));
}
static void
diff --git a/src/nact/nact-tree-model.h b/src/nact/nact-tree-model.h
index 82c8f41..5cf9522 100644
--- a/src/nact/nact-tree-model.h
+++ b/src/nact/nact-tree-model.h
@@ -94,7 +94,7 @@ void nact_tree_model_dispose( NactTreeModel *model );
void nact_tree_model_display( NactTreeModel *model, NAObject *object );
void nact_tree_model_dump( NactTreeModel *model );
void nact_tree_model_fill( NactTreeModel *model, GList *items, gboolean only_actions);
-void nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, GtkTreeIter *iter, NAObject **parent );
+gchar *nact_tree_model_insert( NactTreeModel *model, const NAObject *object, GtkTreePath *path, NAObject **parent );
void nact_tree_model_iter( NactTreeModel *model, FnIterOnStore fn, gpointer user_data );
void nact_tree_model_remove( NactTreeModel *model, GList *selected );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]