Commit a7ffd68d authored by Pierre Wieser's avatar Pierre Wieser

Refactoring: update menu bar management

parent 29d5cf08
2009-02-17 Pierre Wieser <pwieser@trychlos.org>
* src/api/na-object-action.h:
* src/api/na-object-api.h:
* src/api/na-object-id.h:
* src/api/na-object-item.h:
* src/api/na-object-profile.h:
* src/api/na-object.h:
* src/core/na-object-action.c:
* src/core/na-object-id.c:
* src/core/na-object-item.c:
* src/core/na-object-profile.c:
* src/core/na-object.c:
* src/core/na-pivot.c:
* src/core/na-pivot.h:
* src/core/na-updater.c:
* src/core/na-updater.h:
* src/nact/nact-export-format.c:
* src/nact/nact-main-menubar.c: Update menu bar.
* src/nact/nact-iprefs.c: Update NactIPrefs interface.
* src/api/na-core-utils.h:
......
......@@ -28,8 +28,8 @@
* ... and many others (see AUTHORS)
*/
#ifndef __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__
#define __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__
#ifndef __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__
#define __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__
/**
* SECTION: na_object_action
......@@ -73,15 +73,16 @@ typedef struct {
}
NAObjectActionClass;
GType na_object_action_get_type( void );
GType na_object_action_get_type( void );
NAObjectAction *na_object_action_new( void );
NAObjectAction *na_object_action_new_with_profile( void );
gchar *na_object_action_get_new_profile_name( const NAObjectAction *action );
void na_object_action_attach_profile( NAObjectAction *action, NAObjectProfile *profile );
gboolean na_object_action_is_candidate( const NAObjectAction *action, gint target );
G_END_DECLS
#endif /* __NAUTILUS_OBJECT_ACTIONS_API_NA_OBJECT_ACTION_H__ */
#endif /* __NAUTILUS_ACTIONS_API_NA_OBJECT_ACTION_H__ */
......@@ -62,6 +62,8 @@ G_BEGIN_DECLS
#define na_object_set_origin( obj, origin ) na_iduplicable_set_origin( NA_IDUPLICABLE( obj ), ( NAIDuplicable * )( origin ))
#define na_object_reset_origin( obj, origin ) na_object_object_reset_origin( NA_OBJECT( obj ), ( NAObject * )( origin ))
/* NAObject
*/
#define na_object_dump( obj ) na_object_object_dump( NA_OBJECT( obj ))
......@@ -84,6 +86,11 @@ G_BEGIN_DECLS
#define na_object_sort_alpha_asc( a, b ) na_object_id_sort_alpha_asc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
#define na_object_sort_alpha_desc( a, b ) na_object_id_sort_alpha_desc( NA_OBJECT_ID( a ), NA_OBJECT_ID( b ))
#define na_object_prepare_for_paste( obj, relabel, renumber, action ) \
na_object_id_prepare_for_paste( NA_OBJECT_ID( obj ), ( relabel ), ( renumber ), ( NAObjectId * )( action ))
#define na_object_set_copy_of_label( obj ) na_object_id_set_copy_of_label( NA_OBJECT_ID( obj ))
#define na_object_set_new_id( obj, parent ) na_object_id_set_new_id( NA_OBJECT_ID( obj ), ( NAObjectId * )( parent ))
/* NAObjectItem
*/
#define na_object_get_tooltip( obj ) (( gchar * ) na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLTIP ))
......@@ -105,7 +112,11 @@ G_BEGIN_DECLS
#define na_object_set_provider_data( obj, data ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_PROVIDER_DATA, ( const void * )( data ))
#define na_object_get_item( obj, id ) na_object_item_get_item( NA_OBJECT_ITEM( obj ),( const gchar * )( id ))
#define na_object_get_position( obj, child ) na_object_item_get_position( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
#define na_object_append_item( obj, child ) na_object_item_append_item( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
#define na_object_insert_at( obj, child, pos ) na_object_item_insert_at( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ), ( pos ))
#define na_object_remove_item( obj, child ) na_object_item_remove_item( NA_OBJECT_ITEM( obj ), NA_OBJECT_ID( child ))
#define na_object_build_items_slist( obj ) na_object_item_build_items_slist( NA_OBJECT_ITEM( obj ))
#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 ))
......@@ -119,6 +130,7 @@ G_BEGIN_DECLS
#define na_object_is_target_toolbar( obj ) (( gboolean ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_TOOLBAR )))
#define na_object_get_toolbar_label( obj ) (( gchar * ) na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_LABEL ))
#define na_object_is_toolbar_same_label( obj ) (( gboolean ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_SAME_LABEL )))
#define na_object_get_last_allocated( obj ) (( guint ) GPOINTER_TO_UINT( na_idata_factory_get( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED )))
#define na_object_set_version( obj, version ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_VERSION, ( const void * )( version ))
#define na_object_set_target_selection( obj, target ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_SELECTION, ( const void * ) GUINT_TO_POINTER( target ))
......@@ -126,7 +138,9 @@ G_BEGIN_DECLS
#define na_object_set_target_toolbar( obj, target ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TARGET_TOOLBAR, ( const void * ) GUINT_TO_POINTER( target ))
#define na_object_set_toolbar_label( obj, label ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_LABEL, ( const void * )( label ))
#define na_object_set_toolbar_same_label( obj, same ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_TOOLBAR_SAME_LABEL, ( const void * ) GUINT_TO_POINTER( same ))
#define na_object_set_last_allocated( obj, last ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( last ))
#define na_object_reset_last_allocated( obj ) na_idata_factory_set( NA_IDATA_FACTORY( obj ), NADF_DATA_LAST_ALLOCATED, ( const void * ) GUINT_TO_POINTER( 0 ))
#define na_object_attach_profile( obj, profile ) na_object_action_attach_profile( NA_OBJECT_ACTION( obj ), NA_OBJECT_PROFILE( profile ))
/* NAObjectProfile
......
......@@ -65,6 +65,24 @@ typedef struct NAObjectIdClassPrivate NAObjectIdClassPrivate;
typedef struct {
NAObjectClass parent;
NAObjectIdClassPrivate *private;
/**
* new_id:
* @object: a #NAObjectId object.
* @new_parent: possibly the new #NAObjectId parent, or NULL.
* If not NULL, this should actually be a #NAObjectItem.
*
* Returns: a new id suitable for this @object.
*
* If @object is a #NAObjectProfile, then @new_parent must be a
* not null #NAObjectAction. This function ensures that the new
* profile name does not already exist in the given @new_parent.
*
* This is a pure virtual function which should be implemented by
* the actual class. Actually, we asks for the most-derived class
* which implements this function.
*/
gchar * ( *new_id )( const NAObjectId *object, const NAObjectId *new_parent );
}
NAObjectIdClass;
......@@ -73,6 +91,10 @@ GType na_object_id_get_type( void );
gint na_object_id_sort_alpha_asc ( const NAObjectId *a, const NAObjectId *b );
gint na_object_id_sort_alpha_desc( const NAObjectId *a, const NAObjectId *b );
void na_object_id_prepare_for_paste( NAObjectId *object, gboolean relabel, gboolean renumber, NAObjectId *action );
void na_object_id_set_copy_of_label( NAObjectId *object );
void na_object_id_set_new_id ( NAObjectId *object, const NAObjectId *new_parent );
G_END_DECLS
#endif /* __NAUTILUS_ACTIONS_API_NA_OBJECT_ID_H__ */
......@@ -80,8 +80,11 @@ GType na_object_item_get_type( void );
void na_object_item_copy ( NAObjectItem *item, const NAObjectItem *source );
gboolean na_object_item_are_equal( const NAObjectItem *a, const NAObjectItem *b );
NAObjectId *na_object_item_get_item ( const NAObjectItem *item, const gchar *id );
void na_object_item_append_item( NAObjectItem *object, const NAObjectId *item );
NAObjectId *na_object_item_get_item ( const NAObjectItem *item, const gchar *id );
gint na_object_item_get_position( const NAObjectItem *item, const NAObjectId *child );
void na_object_item_append_item ( NAObjectItem *object, const NAObjectId *item );
void na_object_item_insert_at ( NAObjectItem *object, const NAObjectId *item, gint pos );
void na_object_item_remove_item ( NAObjectItem *object, const NAObjectId *item );
GSList *na_object_item_build_items_slist( const NAObjectItem *item );
......
......@@ -67,6 +67,10 @@ typedef struct {
}
NAObjectProfileClass;
/* default prefix for profile name
*/
#define NA_PROFILE_DEFAULT_PREFIX "profile-"
GType na_object_profile_get_type( void );
NAObjectProfile *na_object_profile_new( void );
......
......@@ -138,6 +138,8 @@ GType na_object_object_get_type( void );
void na_object_object_check_status ( const NAObject *object );
gboolean na_object_object_check_status_up( const NAObject *object );
void na_object_object_reset_origin ( NAObject *object, const NAObject *origin );
NAObject *na_object_object_ref ( NAObject *object );
void na_object_object_unref( NAObject *object );
......@@ -145,9 +147,8 @@ void na_object_object_dump ( const NAObject *object );
void na_object_object_dump_norec( const NAObject *object );
void na_object_object_dump_tree ( GList *tree );
#if 0
GList *na_object_object_get_hierarchy( const NAObject *object );
#endif
GList *na_object_object_get_hierarchy( const NAObject *object );
void na_object_free_hierarchy( GList *hierarchy );
G_END_DECLS
......
......@@ -343,6 +343,57 @@ na_object_action_new_with_profile( void )
return( action );
}
/**
* na_object_action_get_new_profile_name:
* @action: the #NAObjectAction object which will receive a new profile.
*
* Returns a name suitable as a new profile name.
*
* The search is made by iterating over the standard profile name
* prefix : basically, we increment a counter until finding a name
* which is not yet allocated. The provided name is so only suitable
* for the specified @action.
*
* Returns: a newly allocated profile name, which should be g_free() by
* the caller.
*
* When inserting a list of profiles in the action, we iter first for
* new names, before actually do the insertion. We so keep the last
* allocated name to avoid to allocate the same one twice.
*/
gchar *
na_object_action_get_new_profile_name( const NAObjectAction *action )
{
int i;
gboolean ok = FALSE;
gchar *candidate = NULL;
guint last_allocated;
g_return_val_if_fail( NA_IS_OBJECT_ACTION( action ), NULL );
if( !action->private->dispose_has_run ){
last_allocated = na_object_get_last_allocated( action );
for( i = last_allocated + 1 ; !ok ; ++i ){
g_free( candidate );
candidate = g_strdup_printf( "%s%d", NA_PROFILE_DEFAULT_PREFIX, i );
if( !na_object_get_item( action, candidate )){
ok = TRUE;
na_object_set_last_allocated( action, i );
}
}
if( !ok ){
g_free( candidate );
candidate = NULL;
}
}
return( candidate );
}
/**
* na_object_action_attach_profile:
* @action: the #NAObjectAction action to which the profile will be attached.
......
......@@ -32,6 +32,8 @@
#include <config.h>
#endif
#include <glib/gi18n.h>
#include <api/na-object-api.h>
/* private class data
......@@ -52,11 +54,13 @@ struct NAObjectIdPrivate {
static NAObjectClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( NAObjectIdClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static GType register_type( void );
static void class_init( NAObjectIdClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static gchar *v_new_id( const NAObjectId *object, const NAObjectId *new_parent );
GType
na_object_id_get_type( void )
......@@ -116,6 +120,8 @@ class_init( NAObjectIdClass *klass )
naobject_class->are_equal = NULL;
naobject_class->is_valid = NULL;
klass->new_id = NULL;
klass->private = g_new0( NAObjectIdClassPrivate, 1 );
}
......@@ -223,3 +229,146 @@ na_object_id_sort_alpha_desc( const NAObjectId *a, const NAObjectId *b )
{
return( -1 * na_object_id_sort_alpha_asc( a, b ));
}
/**
* na_object_id_prepare_for_paste:
* @object: the #NAObjectId object to be pasted.
* @relabel: whether this object should be relabeled when pasted.
* @relabel: whether this item should be renumbered ?
* @action: if @object is a #NAObjectProfile, the parent #NAObjectAction.
*
* Prepares @object to be pasted.
*
* If a #NAObjectProfile, then @object is attached to the specified
* #NAObjectAction @action. The identifier is always renumbered to be
* suitable with the already existing profiles.
*
* If a #NAObjectAction or a #NAObjectMenu, a new UUID is allocated if
* and only if @relabel is %TRUE.
*
* Actual relabeling takes place if @relabel is %TRUE, depending of the
* user preferences.
*/
void
na_object_id_prepare_for_paste( NAObjectId *object, gboolean relabel, gboolean renumber, NAObjectId *action )
{
static const gchar *thisfn = "na_object_id_prepare_for_paste";
GList *subitems, *it;
g_debug( "%s: object=%p, relabel=%s, renumber=%s, action=%p",
thisfn, ( void * ) object, relabel ? "True":"False", renumber ? "True":"False", ( void * ) action );
g_return_if_fail( NA_IS_OBJECT_ID( object ));
g_return_if_fail( !action || NA_IS_OBJECT_ACTION( action ));
if( !object->private->dispose_has_run ){
if( NA_IS_OBJECT_PROFILE( object )){
na_object_set_parent( object, action );
na_object_set_new_id( object, action );
if( renumber && relabel ){
na_object_set_copy_of_label( object );
}
} else {
if( renumber ){
na_object_set_new_id( object, NULL );
if( relabel ){
na_object_set_copy_of_label( object );
}
na_object_set_provider( object, NULL );
na_object_set_readonly( object, FALSE );
}
if( NA_IS_OBJECT_MENU( object )){
subitems = na_object_get_items( object );
for( it = subitems ; it ; it = it->next ){
na_object_prepare_for_paste( it->data, relabel, renumber, NULL );
}
}
}
}
}
/**
* na_object_id_set_copy_of_label:
* @object: the #NAObjectId object whose label is to be changed.
*
* Sets the 'Copy of' label.
*/
void
na_object_id_set_copy_of_label( NAObjectId *object )
{
gchar *label, *new_label;
g_return_if_fail( NA_IS_OBJECT_ID( object ));
if( !object->private->dispose_has_run ){
label = na_object_get_label( object );
/* i18n: copied items have a label as 'Copy of original label' */
new_label = g_strdup_printf( _( "Copy of %s" ), label );
na_object_set_label( object, new_label );
g_free( new_label );
g_free( label );
}
}
/**
* na_object_id_set_new_id:
* @object: the #NAObjectId object whose internal identifiant is to be
* set.
* @new_parent: if @object is a #NAObjectProfile, then @new_parent
* should be set to the #NAObjectActio new parent. Else, it would not
* be possible to allocate a new profile id compatible with already
* existing ones.
*
* Request a new id to the derived class, and set it.
*/
void
na_object_id_set_new_id( NAObjectId *object, const NAObjectId *new_parent )
{
gchar *id;
g_return_if_fail( NA_IS_OBJECT_ID( object ));
g_return_if_fail( !new_parent || NA_IS_OBJECT_ID( new_parent ));
if( !object->private->dispose_has_run ){
id = v_new_id( object, new_parent );
if( id ){
na_object_set_id( object, id );
g_free( id );
}
}
}
static gchar *
v_new_id( const NAObjectId *object, const NAObjectId *new_parent )
{
gchar *new_id;
GList *hierarchy, *ih;
gboolean found;
found = FALSE;
new_id = NULL;
hierarchy = g_list_reverse( na_object_get_hierarchy( NA_OBJECT( object )));
/*g_debug( "na_object_id_most_derived_id: object=%p (%s)",
( void * ) object, G_OBJECT_TYPE_NAME( object ));*/
for( ih = hierarchy ; ih && !found ; ih = ih->next ){
if( NA_OBJECT_ID_CLASS( ih->data )->new_id ){
new_id = NA_OBJECT_ID_CLASS( ih->data )->new_id( object, new_parent );
found = TRUE;
}
if( G_OBJECT_CLASS_TYPE( ih->data ) == NA_OBJECT_ID_TYPE ){
break;
}
}
na_object_free_hierarchy( hierarchy );
return( new_id );
}
......@@ -33,6 +33,7 @@
#endif
#include <string.h>
#include <uuid/uuid.h>
#include <api/na-object-api.h>
......@@ -59,11 +60,13 @@ struct NAObjectItemPrivate {
static NAObjectIdClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( NAObjectItemClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static GType register_type( void );
static void class_init( NAObjectItemClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static gchar *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
GType
na_object_item_get_type( void )
......@@ -108,6 +111,7 @@ class_init( NAObjectItemClass *klass )
static const gchar *thisfn = "na_object_item_class_init";
GObjectClass *object_class;
NAObjectClass *naobject_class;
NAObjectIdClass *naobjectid_class;
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
......@@ -123,6 +127,9 @@ class_init( NAObjectItemClass *klass )
naobject_class->are_equal = NULL;
naobject_class->is_valid = NULL;
naobjectid_class = NA_OBJECT_ID_CLASS( klass );
naobjectid_class->new_id = object_id_new_id;
klass->private = g_new0( NAObjectItemClassPrivate, 1 );
}
......@@ -182,6 +189,39 @@ instance_finalize( GObject *object )
}
}
/*
* new_parent is not relevant when allocating a new UUID for an action
* or a menu ; it may safely be left as NULL though there is no gain to
* check this
*/
static gchar *
object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
{
GList *childs, *it;
uuid_t uuid;
gchar uuid_str[64];
gchar *new_uuid = NULL;
g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), NULL );
if( !NA_OBJECT_ITEM( item )->private->dispose_has_run ){
/* recurse into NAObjectItems childs
* i.e., if a menu, recurse into embedded actions
*/
childs = na_object_get_items( item );
for( it = childs ; it ; it = it->next ){
na_object_set_new_id( it->data, new_parent );
}
uuid_generate( uuid );
uuid_unparse_lower( uuid, uuid_str );
new_uuid = g_strdup( uuid_str );
}
return( new_uuid );
}
/**
* na_object_item_copy:
* @item: the target #NAObjectItem instance.
......@@ -353,6 +393,36 @@ na_object_item_get_item( const NAObjectItem *item, const gchar *id )
return( found );
}
/**
* na_object_item_get_position:
* @object: this #NAObjectItem object.
* @child: a #NAObjectId-derived child.
*
* Returns: the position of @child in the subitems list of @object,
* starting from zero, or -1 if not found.
*/
gint
na_object_item_get_position( const NAObjectItem *object, const NAObjectId *child )
{
gint pos = -1;
GList *childs;
g_return_val_if_fail( NA_IS_OBJECT_ITEM( object ), pos );
g_return_val_if_fail( NA_IS_OBJECT_ID( child ), pos );
if( !child ){
return( pos );
}
if( !object->private->dispose_has_run ){
childs = na_object_get_items( object );
pos = g_list_index( childs, ( gconstpointer ) child );
}
return( pos );
}
/**
* na_object_item_append_item:
* @item: the #NAObjectItem to which add the subitem.
......@@ -384,6 +454,69 @@ na_object_item_append_item( NAObjectItem *item, const NAObjectId *child )
}
}
/**
* na_object_item_insert_at:
* @item: the #NAObjectItem in which add the subitem.
* @object: a #NAObjectId-derived to be inserted in the list of subitems.
* @pos: the position at which the @object child should be inserted.
*
* Inserts a new @object in the list of subitems of @item.
*
* Doesn't modify the reference count on @object.
*/
void
na_object_item_insert_at( NAObjectItem *item, const NAObjectId *object, gint pos )
{
GList *childs, *it;
gint i;
g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
g_return_if_fail( NA_IS_OBJECT_ID( object ));
if( !item->private->dispose_has_run ){
childs = na_object_get_items( item );
if( pos == -1 || pos >= g_list_length( childs )){
na_object_append_item( item, object );
} else {
i = 0;
for( it = childs ; it && i <= pos ; it = it->next ){
if( i == pos ){
childs = g_list_insert_before( childs, it, ( gpointer ) object );
}
i += 1;
}
na_object_set_items( item, childs );
}
}
}
/**
* na_object_item_remove_item:
* @item: the #NAObjectItem from which the subitem must be removed.
* @object: a #NAObjectId-derived to be removed from the list of subitems.
*
* Removes an @object from the list of subitems of @item.
*
* Doesn't modify the reference count on @object.
*/
void
na_object_item_remove_item( NAObjectItem *item, const NAObjectId *object )
{
GList *childs;
g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
g_return_if_fail( NA_IS_OBJECT_ID( object ));
if( !item->private->dispose_has_run ){
childs = na_object_get_items( item );
childs = g_list_remove( childs, ( gconstpointer ) object );
na_object_set_items( item, childs );
}
}
/**
* na_object_item_build_items_slist:
* @item: this #NAObjectItem object.
......
......@@ -82,6 +82,8 @@ static gchar *idata_factory_get_default( const NAIDataFactory *instance, const
static void idata_factory_read_done( NAIDataFactory *instance, const NAIIOFactory *reader, void *reader_data, GSList **messages );
static void idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer, void *writer_data, GSList **messages );
static gchar *object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent );
static gboolean is_target_background_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
static gboolean is_target_toolbar_candidate( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
static gboolean is_current_folder_inside( const NAObjectProfile *profile, NautilusFileInfo *current_folder );
......@@ -149,6 +151,7 @@ class_init( NAObjectProfileClass *klass )
static const gchar *thisfn = "na_object_profile_class_init";
GObjectClass *object_class;
NAObjectClass *naobject_class;
NAObjectIdClass *naobjectid_class;
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
......@@ -166,6 +169,9 @@ class_init( NAObjectProfileClass *klass )
naobject_class->are_equal = NULL;
naobject_class->is_valid = NULL;
naobjectid_class = NA_OBJECT_ID_CLASS( klass );
naobjectid_class->new_id = object_id_new_id;
klass->private = g_new0( NAObjectProfileClassPrivate, 1 );
na_data_factory_properties( object_class );
......@@ -314,6 +320,26 @@ idata_factory_write_done( NAIDataFactory *instance, const NAIIOFactory *writer,
}
/*
* new_parent is specifically set to be able to allocate a new id for
* the current profile into the target parent
*/
static gchar *
object_id_new_id( const NAObjectId *item, const NAObjectId *new_parent )
{
gchar *id = NULL;
g_return_val_if_fail( NA_IS_OBJECT_PROFILE( item ), NULL );
g_return_val_if_fail( new_parent && NA_IS_OBJECT_ACTION( new_parent ), NULL );
if( !NA_OBJECT_PROFILE( item )->private->dispose_has_run ){
id = na_object_action_get_new_profile_name( NA_OBJECT_ACTION( new_parent ));
}
return( id );
}
/**
* na_object_profile_new:
*
......
......@@ -545,38 +545,44 @@ dump_tree( GList *tree, gint level )
}
/**
* na_object_get_hierarchy:
* na_object_object_reset_origin:
* @object: a #NAObject-derived object.
* @origin: must be a duplication of @object.
*
* Returns the class hierarchy,
* from the topmost base class, to the most-derived one.
* Recursively reset origin of @object and its childs to @origin and
* its childs), so that @origin appear as the actual origin of @object.
*
* The returned list should be released with g_list_free() by the caller.
* The origin of @origin itself is set to NULL.
*
* This only works if @origin has just been duplicated from @object,
* and thus we do not have to check if childs lists are equal.
*/
#if 0
GList *
na_object_object_get_hierarchy( const NAObject *object )
void
na_object_object_reset_origin( NAObject *object, const NAObject *origin )
{
GList *hierarchy = NULL;
GObjectClass *class;
g_return_val_if_fail( NA_IS_OBJECT( object ), NULL );
if( !object->private->dispose_has_run ){
GList *origin_childs, *iorig;
GList *object_childs, *iobj;
NAObject *orig_object;
class = G_OBJECT_GET_CLASS( object );
g_return_if_fail( NA_IS_OBJECT( origin ));
g_return_if_fail( NA_IS_OBJECT( object ));
while( G_OBJECT_CLASS_TYPE( class ) != NA_OBJECT_TYPE ){
if( !object->private->dispose_has_run && !origin->private->dispose_has_run ){
hierarchy = g_list_prepend( hierarchy, class );
class = g_type_class_peek_parent( class );
origin_childs = na_object_get_items( origin );
object_childs = na_object_get_items( object );
for( iorig = origin_childs, iobj = object_childs ; iorig && iobj ; iorig = iorig->next, iobj = iobj->next ){
orig_object = ( NAObject * ) na_object_get_origin( iorig->data );
g_return_if_fail( orig_object == iobj->data );
na_object_reset_origin( iobj->data, iorig->data );
}
hierarchy = g_list_prepend( hierarchy, class );
orig_object = ( NAObject * ) na_object_get_origin( origin );
g_return_if_fail( orig_object == object );
na_iduplicable_set_origin( NA_IDUPLICABLE( object ), NA_IDUPLICABLE( origin ));
na_iduplicable_set_origin( NA_IDUPLICABLE( origin ), NULL );
}
return( hierarchy );
}
#endif
/**
* na_object_object_ref:
......@@ -693,3 +699,35 @@ build_class_hierarchy( const NAObject *object )
return( hierarchy );
}
/**
* na_object_object_get_hierarchy:
*
* Returns the class hierarchy,
* from the topmost base class, to the most-derived one.