[nautilus-actions] Able to import v2 schemas



commit b5a4d3d52b551787902ec598af1c65cfe500f5a8
Author: pierre <pierre vfedora10 virtuals pwi>
Date:   Wed Feb 24 16:48:35 2010 +0100

    Able to import v2 schemas

 ChangeLog                                 |   13 ++
 exports/config_1af5a47e-96d9_v1.4.schemas |  137 ++++++++------
 src/api/na-data-boxed.h                   |    7 +-
 src/api/na-ifactory-object-data.h         |    3 +-
 src/core/na-data-boxed.c                  |   22 +++
 src/core/na-factory-object.c              |    5 +-
 src/core/na-object-action.c               |   11 +-
 src/core/na-object-id-factory.c           |   15 --
 src/core/na-object-item-factory.c         |   15 ++
 src/core/na-object-profile-factory.c      |   15 ++
 src/io-xml/naxml-provider.c               |    2 +-
 src/io-xml/naxml-reader.c                 |  288 +++++++++++++++++++++++++----
 src/io-xml/naxml-reader.h                 |    6 +-
 13 files changed, 419 insertions(+), 120 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 437e404..d52a558 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2009-02-24 Pierre Wieser <pwieser trychlos org>
 
+	* exports/config_1af5a47e-96d9_v1.4.schemas:
+	* src/api/na-data-boxed.h:
+	* src/api/na-ifactory-object-data.h:
+	* src/core/na-data-boxed.c:
+	* src/core/na-factory-object.c:
+	* src/core/na-object-action.c:
+	* src/core/na-object-id-factory.c:
+	* src/core/na-object-item-factory.c:
+	* src/core/na-object-profile-factory.c:
+	* src/io-xml/naxml-provider.c:
+	* src/io-xml/naxml-reader.c:
+	* src/io-xml/naxml-reader.h: Able to import two profiles.
+
 	* src/api/na-data-boxed.h:
 	* src/api/na-gconf-utils.h:
 	* src/core/na-data-boxed.c:
diff --git a/exports/config_1af5a47e-96d9_v1.4.schemas b/exports/config_1af5a47e-96d9_v1.4.schemas
index e9cff62..2a91706 100644
--- a/exports/config_1af5a47e-96d9_v1.4.schemas
+++ b/exports/config_1af5a47e-96d9_v1.4.schemas
@@ -2,63 +2,53 @@
 <gconfschemafile>
   <schemalist>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/version</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/version</applyto>
-      <type>string</type>
-      <locale name="C">
-        <short>The version of the configuration format</short>
-        <long>The version of the configuration format that will be used to manage backward compatibility</long>
-      </locale>
-      <default>1.0</default>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/label</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/label</applyto>
       <owner>nautilus-actions</owner>
-    </schema>
-    <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/label</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/label</applyto>
       <type>string</type>
       <locale name="C">
-        <default>Action version 1.0</default>
+        <default>Action from v1.4.1</default>
         <short>The label of the menu item</short>
         <long>The label of the menu item that will appear in the Nautilus popup menu when the selection matches the appearance condition settings</long>
       </locale>
-      <owner>nautilus-actions</owner>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/tooltip</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/tooltip</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/tooltip</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/tooltip</applyto>
+      <owner>nautilus-actions</owner>
       <type>string</type>
       <locale name="C">
-        <default>Let us test read/import/export/NACT v1.0 action</default>
+        <default>Action from v1.4.1</default>
         <short>The tooltip of the menu item</short>
         <long>The tooltip of the menu item that will appear in the Nautilus statusbar when the user points to the Nautilus popup menu item with his/her mouse</long>
       </locale>
-      <owner>nautilus-actions</owner>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/icon</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/icon</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/icon</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/icon</applyto>
+      <owner>nautilus-actions</owner>
       <type>string</type>
       <locale name="C">
         <short>The icon of the menu item</short>
         <long>The icon of the menu item that will appear next to the label in the Nautilus popup menu when the selection matches the appearance conditions settings</long>
       </locale>
-      <default>gtk-justify-center</default>
-      <owner>nautilus-actions</owner>
+      <default>gtk-about</default>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/path</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/path</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/path</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/path</applyto>
+      <owner>nautilus-actions</owner>
       <type>string</type>
       <locale name="C">
         <short>The path of the command</short>
         <long>The path of the command to start when the user select the menu item in the Nautilus popup menu</long>
       </locale>
       <default>/bin/ls</default>
-      <owner>nautilus-actions</owner>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/parameters</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/parameters</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/parameters</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/parameters</applyto>
+      <owner>nautilus-actions</owner>
       <type>string</type>
       <locale name="C">
         <short>The parameters of the command</short>
@@ -68,32 +58,55 @@ The parameters can contain some special tokens which are replaced by Nautilus in
 
 %d: base folder of the selected file(s)
 %f: the name of the selected file or the first one if many are selected
-%h: hostname of the URI
 %m: space-separated list of the basenames of the selected file(s)/folder(s)
 %M: space-separated list of the selected file(s)/folder(s), with their full paths
-%s: scheme of the URI
-%u: URI
-%U: username of the URI
+%u: GnomeVFS URI
+%s: scheme of the GnomeVFS URI
+%h: hostname of the GnomeVFS URI
+%U: username of the :%s/GnomeVFS URI
 %%: a percent sign</long>
       </locale>
-      <default>%h %M</default>
-      <owner>nautilus-actions</owner>
+      <default>%u</default>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/basenames</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/basenames</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/basenames</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/basenames</applyto>
+      <owner>nautilus-actions</owner>
       <type>list</type>
       <list_type>string</list_type>
       <locale name="C">
         <short>The list of pattern to match the selected file(s)/folder(s)</short>
         <long>A list of strings with joker '*' or '?' to match the name of the selected file(s)/folder(s). Each selected items must match at least one of the filename patterns for the action to appear</long>
       </locale>
-      <default>[*.c]</default>
+      <default>[*]</default>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/matchcase</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/matchcase</applyto>
+      <owner>nautilus-actions</owner>
+      <type>bool</type>
+      <locale name="C">
+        <short>'true' if the filename patterns have to be case sensitive, 'false' otherwise</short>
+        <long>If you need to match a filename in a case-sensitive manner, set this key to 'true'. If you also want, for example '*.jpg' to match 'photo.JPG', set 'false'</long>
+      </locale>
+      <default>true</default>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/mimetypes</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/mimetypes</applyto>
       <owner>nautilus-actions</owner>
+      <type>list</type>
+      <list_type>string</list_type>
+      <locale name="C">
+        <short>The list of patterns to match the mimetypes of the selected file(s)</short>
+        <long>A list of strings with joker '*' or '?' to match the mimetypes of the selected file(s). Each selected items must match at least one of the mimetype patterns for the action to appear</long>
+      </locale>
+      <default>[*/*]</default>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/isfile</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/isfile</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/isfile</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/isfile</applyto>
+      <owner>nautilus-actions</owner>
       <type>bool</type>
       <locale name="C">
         <short>'true' if the selection can have files, 'false' otherwise</short>
@@ -101,15 +114,15 @@ The parameters can contain some special tokens which are replaced by Nautilus in
 
 isfile=TRUE and isdir=FALSE: the selection may hold only files
 isfile=FALSE and isdir=TRUE: the selection may hold only folders
-isfile=TRUE and isdir=TRUE: the selection may hold both files and folders
+isfile=TRUE and isdir=TRUE': the selection may hold both files and folders
 isfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration will never appear)</long>
       </locale>
       <default>true</default>
-      <owner>nautilus-actions</owner>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/isdir</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/isdir</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/isdir</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/isdir</applyto>
+      <owner>nautilus-actions</owner>
       <type>bool</type>
       <locale name="C">
         <short>'true' if the selection can have folders, 'false' otherwise</short>
@@ -117,33 +130,33 @@ isfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration
 
 isfile=TRUE and isdir=FALSE: the selection may hold only files
 isfile=FALSE and isdir=TRUE: the selection may hold only folders
-isfile=TRUE and isdir=TRUE: the selection may hold both files and folders
+isfile=TRUE and isdir=TRUE': the selection may hold both files and folders
 isfile=FALSE and isdir=FALSE: this is an invalid combination (your configuration will never appear)</long>
       </locale>
-      <default>false</default>
-      <owner>nautilus-actions</owner>
+      <default>true</default>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/accept-multiple-files</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/accept-multiple-files</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/accept-multiple-files</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/accept-multiple-files</applyto>
+      <owner>nautilus-actions</owner>
       <type>bool</type>
       <locale name="C">
         <short>'true' if the selection can have several items, 'false' otherwise</short>
         <long>If you need one or more files or folders to be selected, set this key to 'true'. If you want just one file or folder, set 'false'</long>
       </locale>
-      <default>false</default>
-      <owner>nautilus-actions</owner>
+      <default>true</default>
     </schema>
     <schema>
-      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/schemes</key>
-      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1/schemes</applyto>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/schemes</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/schemes</applyto>
+      <owner>nautilus-actions</owner>
       <type>list</type>
       <list_type>string</list_type>
       <locale name="C">
-        <short>The list of schemes where the selected files should be located</short>
-        <long>Defines the list of valid schemes to be matched against the selected items. The scheme is the protocol used to access the files. The keyword to use is the one used in the URI.
+        <short>The list of GnomeVFS schemes where the selected files should be located</short>
+        <long>Defines the list of valid GnomeVFS schemes to be matched against the selected items. The GnomeVFS scheme is the protocol used to access the files. The keyword to use is the one used in the GnomeVFS URI.
 
-Examples of valid URI include:
+Examples of GnomeVFS URI include: 
 file:///tmp/foo.txt
 sftp:///root test example net/tmp/foo.txt
 
@@ -153,12 +166,22 @@ The most common schemes are:
 'sftp': files accessed via SSH
 'ftp': files accessed via FTP
 'smb': files accessed via Samba (Windows share)
-'dav': files accessed via WebDAV
+'dav': files accessed via WebDav
 
-All schemes used by Nautilus can be used here.</long>
+All GnomeVFS schemes used by Nautilus can be used here.</long>
       </locale>
-      <default>[smb]</default>
+      <default>[file,sftp,smb]</default>
+    </schema>
+    <schema>
+      <key>/schemas/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/version</key>
+      <applyto>/apps/nautilus-actions/configurations/1af5a47e-96d9_v1.4/version</applyto>
       <owner>nautilus-actions</owner>
+      <type>string</type>
+      <locale name="C">
+        <short>The version of the configuration format</short>
+        <long>The version of the configuration format that will be used to manage backward compatibility</long>
+      </locale>
+      <default>1.1</default>
     </schema>
   </schemalist>
 </gconfschemafile>
diff --git a/src/api/na-data-boxed.h b/src/api/na-data-boxed.h
index 0b6b3e5..2d97fce 100644
--- a/src/api/na-data-boxed.h
+++ b/src/api/na-data-boxed.h
@@ -80,19 +80,18 @@ gboolean     na_data_boxed_are_equal      ( const NADataBoxed *a, const NADataBo
 gboolean     na_data_boxed_is_valid       ( const NADataBoxed *boxed );
 void         na_data_boxed_dump           ( const NADataBoxed *boxed );
 
+void         na_data_boxed_set_data_def   ( NADataBoxed *boxed, const NADataDef *def );
+
 gchar       *na_data_boxed_get_as_string  ( const NADataBoxed *boxed );
 void        *na_data_boxed_get_as_void    ( const NADataBoxed *boxed );
 void         na_data_boxed_get_as_value   ( const NADataBoxed *boxed, GValue *value );
 
 void         na_data_boxed_set_default    ( NADataBoxed *boxed );
 void         na_data_boxed_set_from_boxed ( NADataBoxed *boxed, const NADataBoxed *value );
+void         na_data_boxed_set_from_string( NADataBoxed *boxed, const gchar *value );
 void         na_data_boxed_set_from_value ( NADataBoxed *boxed, const GValue *value );
 void         na_data_boxed_set_from_void  ( NADataBoxed *boxed, const void *value );
 
-/* -- */
-
-void         na_data_boxed_set_from_string( NADataBoxed *boxed, const gchar *value );
-
 G_END_DECLS
 
 #endif /* __NAUTILUS_ACTIONS_API_NA_DATA_BOXED_H__ */
diff --git a/src/api/na-ifactory-object-data.h b/src/api/na-ifactory-object-data.h
index 8949fbf..944625b 100644
--- a/src/api/na-ifactory-object-data.h
+++ b/src/api/na-ifactory-object-data.h
@@ -43,10 +43,10 @@ G_BEGIN_DECLS
 
 #define NA_FACTORY_OBJECT_ID_GROUP			"na-factory-group-id"
 #define NAFO_DATA_ID						"na-factory-data-id"
-#define NAFO_DATA_LABEL						"na-factory-data-label"
 #define NAFO_DATA_PARENT					"na-factory-data-parent"
 
 #define NA_FACTORY_OBJECT_ITEM_GROUP		"na-factory-group-item"
+#define NAFO_DATA_LABEL						"na-factory-data-label"
 #define NAFO_DATA_TOOLTIP					"na-factory-data-tooltip"
 #define NAFO_DATA_ICON						"na-factory-data-icon"
 #define NAFO_DATA_DESCRIPTION				"na-factory-data-description"
@@ -71,6 +71,7 @@ G_BEGIN_DECLS
 #define NA_FACTORY_OBJECT_MENU_GROUP		"na-factory-group-menu"
 
 #define NA_FACTORY_OBJECT_PROFILE_GROUP		"na-factory-group-profile"
+#define NAFO_DATA_DESCNAME					"na-factory-data-descname"
 #define NAFO_DATA_PATH						"na-factory-data-path"
 #define NAFO_DATA_PARAMETERS				"na-factory-data-parameters"
 #define NAFO_DATA_BASENAMES					"na-factory-data-basenames"
diff --git a/src/core/na-data-boxed.c b/src/core/na-data-boxed.c
index ebbabd8..3a341a6 100644
--- a/src/core/na-data-boxed.c
+++ b/src/core/na-data-boxed.c
@@ -516,6 +516,28 @@ na_data_boxed_is_valid( const NADataBoxed *boxed )
 }
 
 /**
+ * na_data_boxed_set_data_def:
+ * @boxed: this #NADataBoxed object.
+ * @def: the new #NADataDef to be set.
+ *
+ * Changes the #NADataDef a @boxed points to:
+ * -> the new type must be the same that the previous one.
+ * -> value is unchanged.
+ */
+void
+na_data_boxed_set_data_def( NADataBoxed *boxed, const NADataDef *new_def )
+{
+	g_return_if_fail( NA_IS_DATA_BOXED( boxed ));
+	g_return_if_fail( new_def != NULL );
+	g_return_if_fail( new_def->type == boxed->private->def->type );
+
+	if( !boxed->private->dispose_has_run ){
+
+		boxed->private->def = ( NADataDef * ) new_def;
+	}
+}
+
+/**
  * na_data_boxed_dump:
  * @boxed: this #NADataBoxed object.
  *
diff --git a/src/core/na-factory-object.c b/src/core/na-factory-object.c
index 0b886a9..614cdbc 100644
--- a/src/core/na-factory-object.c
+++ b/src/core/na-factory-object.c
@@ -337,6 +337,10 @@ na_factory_object_move_boxed( NAIFactoryObject *target, const NAIFactoryObject *
 			g_object_set_data( G_OBJECT( source ), NA_IFACTORY_OBJECT_PROP_DATA, src_list );
 
 			attach_boxed_to_object( target, boxed );
+
+			NADataDef *src_def = na_data_boxed_get_data_def( boxed );
+			NADataDef *tgt_def = na_factory_object_get_data_def( target, src_def->name );
+			na_data_boxed_set_data_def( boxed, tgt_def );
 		}
 	}
 }
@@ -591,7 +595,6 @@ na_factory_object_read_item( NAIFactoryObject *serializable, const NAIFactoryPro
 		NADataGroup *groups = v_get_groups( serializable );
 
 		if( groups ){
-			free_data_boxed_list( serializable );
 			v_read_start( serializable, reader, reader_data, messages );
 
 			NafoRWIter *iter = g_new0( NafoRWIter, 1 );
diff --git a/src/core/na-object-action.c b/src/core/na-object-action.c
index 4496267..c8ebbf2 100644
--- a/src/core/na-object-action.c
+++ b/src/core/na-object-action.c
@@ -371,12 +371,15 @@ ifactory_object_write_done( NAIFactoryObject *instance, const NAIFactoryProvider
 static gboolean
 check_for_obsoleted_iter( const NAIFactoryObject *object, NADataBoxed *boxed, IterForObsoletedParms *parms )
 {
-	NADataDef *def = na_data_boxed_get_data_def( boxed );
+	NADataDef *action_def = na_data_boxed_get_data_def( boxed );
 
-	if( def->obsoleted ){
-		NADataDef *profile_def = na_factory_object_get_data_def( NA_IFACTORY_OBJECT( parms->profile ), def->name );
+	if( action_def->obsoleted ){
+		NADataDef *profile_def = na_factory_object_get_data_def( NA_IFACTORY_OBJECT( parms->profile ), action_def->name );
 
-		if( profile_def ){
+		if( profile_def && !profile_def->obsoleted ){
+			g_debug( "na_object_action_check_for_obsoleted_iter: " \
+					 "boxed=%p (%s) marked to be moved from action body to profile",
+							 ( void * ) boxed, action_def->name );
 			parms->moved =g_list_prepend( parms->moved, boxed );
 		}
 	}
diff --git a/src/core/na-object-id-factory.c b/src/core/na-object-id-factory.c
index aaf8663..1a301a5 100644
--- a/src/core/na-object-id-factory.c
+++ b/src/core/na-object-id-factory.c
@@ -54,21 +54,6 @@ NADataDef data_def_id [] = {
 				NULL,
 				FALSE },
 
-	{ NAFO_DATA_LABEL,
-				TRUE,
-				"NAObjectId label",
-				"Main label of the NAObjectId object. " \
-				"Serves as a default for the toolbar label of an action.",
-				NAFD_TYPE_LOCALE_STRING,
-				"",
-				TRUE,
-				TRUE,
-				FALSE,
-				TRUE,
-				"label",
-				NULL,
-				FALSE },
-
 	{ NAFO_DATA_PARENT,
 				FALSE,
 				"NAObjectId Parent",
diff --git a/src/core/na-object-item-factory.c b/src/core/na-object-item-factory.c
index 03ba724..0d72f32 100644
--- a/src/core/na-object-item-factory.c
+++ b/src/core/na-object-item-factory.c
@@ -40,6 +40,21 @@ static void free_items_list( void * list );
 
 NADataDef data_def_item [] = {
 
+	{ NAFO_DATA_LABEL,
+				TRUE,
+				"NAObjectItem label",
+				"Main label of the NAObjectItem object. " \
+				"Serves as a default for the toolbar label of an action.",
+				NAFD_TYPE_LOCALE_STRING,
+				"",
+				TRUE,
+				TRUE,
+				FALSE,
+				TRUE,
+				"label",
+				NULL,
+				FALSE },
+
 	{ NAFO_DATA_TOOLTIP,
 				TRUE,
 				"Item tooltip",
diff --git a/src/core/na-object-profile-factory.c b/src/core/na-object-profile-factory.c
index bffa5a9..9f81b95 100644
--- a/src/core/na-object-profile-factory.c
+++ b/src/core/na-object-profile-factory.c
@@ -40,6 +40,21 @@ extern NADataDef data_def_id [];			/* defined in na-object-id-factory.c */
 
 static NADataDef data_def_profile [] = {
 
+	{ NAFO_DATA_DESCNAME,
+				TRUE,
+				"NAObjectProfile label",
+				"Main label of the NAObjectProfile profile. " \
+				"May be used as a description for the function of the profile.",
+				NAFD_TYPE_LOCALE_STRING,
+				"",
+				TRUE,
+				TRUE,
+				FALSE,
+				TRUE,
+				"desc-name",
+				NULL,
+				FALSE },
+
 	{ NAFO_DATA_PATH,
 				TRUE,
 				"Command path",
diff --git a/src/io-xml/naxml-provider.c b/src/io-xml/naxml-provider.c
index 1664ddb..ddf04cf 100644
--- a/src/io-xml/naxml-provider.c
+++ b/src/io-xml/naxml-provider.c
@@ -281,7 +281,7 @@ ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
 	g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
 
 	iface->get_version = ifactory_provider_get_version;
-	iface->read_start = NULL;
+	iface->read_start = naxml_reader_read_start;
 	iface->read_data = naxml_reader_read_data;
 	iface->read_done = naxml_reader_read_done;
 	iface->write_start = NULL;
diff --git a/src/io-xml/naxml-reader.c b/src/io-xml/naxml-reader.c
index c87d256..cfe01d0 100644
--- a/src/io-xml/naxml-reader.c
+++ b/src/io-xml/naxml-reader.c
@@ -57,6 +57,8 @@ typedef struct {
 	gchar     *root_key;
 	gchar     *list_key;
 	gchar     *element_key;
+	gchar     *key_entry;
+	guint      key_length;
 	guint   ( *fn_root_parms )     ( NAXMLReader *, xmlNode * );
 	guint   ( *fn_list_parms )     ( NAXMLReader *, xmlNode * );
 	guint   ( *fn_element_parms )  ( NAXMLReader *, xmlNode * );
@@ -90,8 +92,6 @@ struct NAXMLReaderPrivate {
 	gboolean      node_ok;
 };
 
-#define SCHEMA_PATH_ID_IDX		4		/* index of item id in a GConf schema key path */
-
 extern NAXMLKeyStr naxml_schema_key_schema_str[];
 
 static GObjectClass *st_parent_class = NULL;
@@ -120,6 +120,8 @@ static RootNodeStr st_root_node_str[] = {
 	{ NAXML_KEY_SCHEMA_ROOT,
 			NAXML_KEY_SCHEMA_LIST,
 			NAXML_KEY_SCHEMA_NODE,
+			NAXML_KEY_SCHEMA_NODE_APPLYTO,
+			6,
 			NULL,
 			NULL,
 			NULL,
@@ -129,6 +131,8 @@ static RootNodeStr st_root_node_str[] = {
 	{ NAXML_KEY_DUMP_ROOT,
 			NAXML_KEY_DUMP_LIST,
 			NAXML_KEY_DUMP_NODE,
+			NAXML_KEY_DUMP_NODE_KEY,
+			1,
 			NULL,
 			dump_parse_list_parms,
 			NULL,
@@ -182,12 +186,12 @@ static GConfReaderStruct reader_str[] = {
 #define ERR_NODE_ALREADY_FOUND		_( "Element %s at line %d already found, ignored." )
 /* i18n: do not translate keywords 'Action' nor 'Menu' */
 #define ERR_NODE_UNKNOWN_TYPE		_( "Unknown type %s found at line %d, while waiting for Action or Menu." )
-#define ERR_PATH_LENGTH				_( "Too many elements in key path %s." )
 #define ERR_MENU_UNWAITED			_( "Unwaited key path %s while importing a menu." )
 #define ERR_ITEM_ID_NOT_FOUND		_( "Item ID not found." )
 #define ERR_NODE_INVALID_ID			_( "Invalid Item ID: waited for %s, found %s at line %d." )
 
 #if 0
+#define ERR_PATH_LENGTH				_( "Too many elements in key path %s." )
 #define ERR_ITEM_LABEL_NOT_FOUND	_( "Item label not found." )
 #define ERR_IGNORED_SCHEMA			_( "Schema is ignored at line %d." )
 #define ERR_UNEXPECTED_NODE			_( "Unexpected '%s' node found at line %d." )
@@ -200,7 +204,12 @@ static GConfReaderStruct reader_str[] = {
 #define ERR_VALUE_ALREADY_SET		_( "Value '%s' already set: new value ignored at line %d." )
 #endif
 
-static void          factory_provider_read_done_action( NAXMLReader *reader, GSList **messages );
+static gboolean      read_data_is_path_adhoc_for_object( NAXMLReader *reader, const NAIFactoryObject *object, xmlChar *text );
+static NADataBoxed  *read_data_boxed_from_node( NAXMLReader *reader, xmlChar *text, xmlNode *parent, const NADataDef *def );
+static void          read_done_object_action( NAXMLReader *reader, NAObjectAction *action );
+static void          read_done_object_profile( NAXMLReader *reader, NAObjectProfile *profile );
+static gchar        *read_done_get_next_profile_id( NAXMLReader *reader );
+static void          read_done_load_profile( NAXMLReader *reader, const gchar *profile_id );
 
 static guint         reader_parse_xmldoc( NAXMLReader *reader );
 static guint         iter_on_root_children( NAXMLReader *reader, xmlNode *root );
@@ -209,6 +218,7 @@ static guint         iter_on_list_children( NAXMLReader *reader, xmlNode *first
 static void          add_message( NAXMLReader *reader, const gchar *format, ... );
 static gchar        *build_key_node_list( NAXMLKeyStr *strlist );
 static gchar        *build_root_node_list( void );
+static gboolean      is_profile_path( NAXMLReader *reader, xmlChar *text );
 static void          reset_node_data( NAXMLReader *reader );
 static xmlNode      *search_for_child_node( xmlNode *node, const gchar *key );
 static int           strxcmp( const xmlChar *a, const char *b );
@@ -620,9 +630,12 @@ iter_on_list_children( NAXMLReader *reader, xmlNode *list )
 		if( !reader->private->type_found ){
 			reader->private->parms->item = NA_OBJECT_ITEM( na_object_action_new());
 		}
+	}
+
+	/* now load the data
+	 */
+	if( code == IMPORTER_CODE_OK ){
 
-		/* now load the data
-		 */
 		na_object_set_id( reader->private->parms->item, reader->private->item_id );
 
 		na_ifactory_provider_read_item(
@@ -796,6 +809,22 @@ iter_on_elements_list( NAXMLReader *reader )
 }
 #endif
 
+void
+naxml_reader_read_start( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  )
+{
+	static const gchar *thisfn = "naxml_reader_read_start";
+
+	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider ));
+	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
+
+	g_debug( "%s: provider=%p, reader_data=%p, object=%p (%s), messages=%p",
+			thisfn,
+			( void * ) provider,
+			( void * ) reader_data,
+			( void * ) object, G_OBJECT_TYPE_NAME( object ),
+			( void * ) messages );
+}
+
 /*
  * this callback function is called by NAIFactoryObject once for each
  * serializable data for the object
@@ -804,50 +833,123 @@ NADataBoxed *
 naxml_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages )
 {
 	static const gchar *thisfn = "naxml_reader_read_data";
+	xmlNode *parent_node;
 	GList *ielt;
 
 	g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( provider ), NULL );
 	g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object ), NULL );
 
-	g_debug( "%s: data=%s", thisfn, def->name );
+	g_debug( "%s: reader_data=%p, object=%p (%s), data=%s",
+			thisfn, ( void * ) reader_data, ( void * ) object, G_OBJECT_TYPE_NAME( object ), def->name );
 
 	if( !def->gconf_entry || !strlen( def->gconf_entry )){
 		g_warning( "%s: GConf entry is not set for NADataDef %s", thisfn, def->name );
 		return( NULL );
 	}
 
-	gboolean found = FALSE;
 	NADataBoxed *boxed = NULL;
 	NAXMLReader *reader = NAXML_READER( reader_data );
 
-	for( ielt = reader->private->nodes ; ielt && !found ; ielt = ielt->next ){
+	/*g_debug( "naxml_reader_read_data: nodes=%p (count=%d)",
+				 ( void * ) reader->private->nodes, g_list_length( reader->private->nodes ));*/
+	for( ielt = reader->private->nodes ; ielt && !boxed ; ielt = ielt->next ){
 
-		xmlNode *schema = ( xmlNode * ) ielt->data;
-		xmlNode *applyto = search_for_child_node( schema, NAXML_KEY_SCHEMA_NODE_APPLYTO );
+		parent_node = ( xmlNode * ) ielt->data;
+		xmlNode *entry_node = search_for_child_node( parent_node, reader->private->root_node_str->key_entry );
 
-		if( !applyto ){
-			g_warning( "%s: no 'applyto' node in schema at line %u", thisfn, schema->line );
+		if( !entry_node ){
+			g_warning( "%s: no '%s' child in node at line %u", thisfn, reader->private->root_node_str->key_entry, parent_node->line );
 
 		} else {
-			xmlChar *text = xmlNodeGetContent( applyto );
-			gchar *entry = g_path_get_basename(( const gchar * ) text );
+			xmlChar *text = xmlNodeGetContent( entry_node );
+			/*g_debug( "naxml_reader_read_data: trying %s", ( const gchar * ) text );*/
 
-			if( !strcmp( entry, def->gconf_entry )){
-				found = TRUE;
-
-				if( reader->private->root_node_str->fn_get_value ){
-					gchar *value = ( *reader->private->root_node_str->fn_get_value )( reader, schema, def );
-					boxed = na_data_boxed_new( def );
-					na_data_boxed_set_from_string( boxed, value );
-					g_free( value );
-				}
+			if( read_data_is_path_adhoc_for_object( reader, object, text )){
+				boxed = read_data_boxed_from_node( reader, text, parent_node, def );
 			}
 
-			g_free( entry );
 			xmlFree( text );
 		}
 	}
 
+	if( boxed ){
+		reader->private->nodes = g_list_remove( reader->private->nodes, parent_node );
+	}
+
+	return( boxed );
+}
+
+static gboolean
+read_data_is_path_adhoc_for_object( NAXMLReader *reader, const NAIFactoryObject *object, xmlChar *text )
+{
+	gboolean adhoc;
+	GSList *path_slist;
+	guint path_length;
+	gchar *node_profile_id;
+	gchar *factory_profile_id;
+
+	adhoc = TRUE;
+	path_slist = na_core_utils_slist_from_split(( const gchar * ) text, "/" );
+	path_length = g_slist_length( path_slist );
+
+	if( NA_IS_OBJECT_ITEM( object )){
+		if( path_length != reader->private->root_node_str->key_length ){
+			adhoc = FALSE;
+		}
+
+	} else if( !is_profile_path( reader, text )){
+		adhoc = FALSE;
+		/*g_debug( "%s not adhoc as not profile path", ( const gchar * ) text );*/
+
+	} else {
+		gchar *key_dirname = g_path_get_dirname(( const gchar * ) text );
+		node_profile_id = g_path_get_basename( key_dirname );
+		g_free( key_dirname );
+
+		factory_profile_id = na_object_get_id( object );
+
+		if( strcmp( node_profile_id, factory_profile_id ) != 0 ){
+			adhoc = FALSE;
+			/*g_debug( "%s not adhoc (%s) as not searched profile %s",
+					( const gchar * ) text, node_profile_id, factory_profile_id );*/
+		}
+
+		g_free( factory_profile_id );
+		g_free( node_profile_id );
+}
+
+	na_core_utils_slist_free( path_slist );
+
+	return( adhoc );
+}
+
+static NADataBoxed *
+read_data_boxed_from_node( NAXMLReader *reader, xmlChar *text, xmlNode *parent, const NADataDef *def )
+{
+	NADataBoxed *boxed;
+	gchar *entry;
+	gchar *value;
+
+	boxed = NULL;
+	entry = g_path_get_basename(( const gchar * ) text );
+
+	/*g_debug( "read_data_boxed_from_node: node_entry=%s def_gconf=%s",
+			entry, def->gconf_entry );*/
+
+	/* read the value
+	 */
+	if( !strcmp( entry, def->gconf_entry )){
+
+		if( reader->private->root_node_str->fn_get_value ){
+			value = ( *reader->private->root_node_str->fn_get_value )( reader, parent, def );
+			boxed = na_data_boxed_new( def );
+			na_data_boxed_set_from_string( boxed, value );
+			g_free( value );
+		}
+	}
+
+	g_free( entry );
+
 	return( boxed );
 }
 
@@ -862,21 +964,122 @@ naxml_reader_read_done( const NAIFactoryProvider *provider, void *reader_data, c
 	g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider ));
 	g_return_if_fail( NA_IS_IFACTORY_OBJECT( object ));
 
-	g_debug( "%s: provider=%p, reader_data=%p, object=%p, messages=%p",
-			thisfn, ( void * ) provider, ( void * ) reader_data, ( void * ) object, ( void * ) messages );
+	g_debug( "%s: provider=%p, reader_data=%p, object=%p (%s), messages=%p",
+			thisfn,
+			( void * ) provider,
+			( void * ) reader_data,
+			( void * ) object, G_OBJECT_TYPE_NAME( object ),
+			( void * ) messages );
 
 	if( NA_IS_OBJECT_ACTION( object )){
-		factory_provider_read_done_action( NAXML_READER( reader_data ), messages );
+		read_done_object_action( NAXML_READER( reader_data ), NA_OBJECT_ACTION( object ));
 	}
+
+	if( NA_IS_OBJECT_PROFILE( object )){
+		read_done_object_profile( NAXML_READER( reader_data ), NA_OBJECT_PROFILE( object ));
+	}
+
+	g_debug( "quitting naxml_read_done for %s at %p", G_OBJECT_TYPE_NAME( object ), ( void * ) object );
 }
 
+/*
+ * if we have detected a pre-v2 action, then the action_read_done() function
+ * has already allocated and define the corresponding profile
+ * -> deals here with v2 and post, i.e. with profiles
+ *
+ * Also note that profiles order has been introduced in 2.29 serie
+ */
 static void
-factory_provider_read_done_action( NAXMLReader *reader, GSList **messages )
+read_done_object_action( NAXMLReader *reader, NAObjectAction *action )
 {
-	/* do we have a pre-v2 action ?
-	 */
+	GSList *order, *ip;
+	gchar *profile_id;
+
+	if( !na_object_get_items_count( reader->private->parms->item )){
+
+		/* first attach potential ordered profiles
+		 */
+		order = na_object_get_items_slist( reader->private->parms->item );
+		for( ip = order ; ip ; ip = ip->next ){
+			read_done_load_profile( reader, ( const gchar * ) ip->data );
+		}
+
+		/* then attach unordered ones
+		 */
+		while( 1 ){
+			profile_id = read_done_get_next_profile_id( reader );
+
+			if( profile_id ){
+				read_done_load_profile( reader, profile_id );
+				g_free( profile_id );
+
+			} else {
+				break;
+			}
+		}
+	}
+}
+
+static void
+read_done_object_profile( NAXMLReader *reader, NAObjectProfile *profile )
+{
+	na_object_attach_profile( reader->private->parms->item, profile );
+}
+
+/*
+ * return the first profile id found in the nodes
+ */
+static gchar *
+read_done_get_next_profile_id( NAXMLReader *reader )
+{
+	gchar *profile_id;
+	GList *ip;
+
+	profile_id = NULL;
+
+	/*g_debug( "read_done_get_next_profile_id: nodes=%p (count=%d)",
+			( void * ) reader->private->nodes, g_list_length( reader->private->nodes ));*/
+	for( ip = reader->private->nodes ; ip && !profile_id ; ip = ip->next ){
+		xmlNode *parent_node = ( xmlNode * ) ip->data;
+		xmlNode *entry_node = search_for_child_node( parent_node, reader->private->root_node_str->key_entry );
+		xmlChar *text = xmlNodeGetContent( entry_node );
+
+		/*g_debug( "text=%s, is_profile=%s",
+					( const gchar * ) text, is_profile_path( reader, text ) ? "True":"False" );*/
+
+		if( is_profile_path( reader, text )){
+			gchar *name = g_path_get_dirname(( const gchar * ) text );
+			profile_id = g_path_get_basename( name );
+			g_free( name );
+
+			if( na_object_get_item( reader->private->parms->item, profile_id )){
+				g_free( profile_id );
+				profile_id = NULL;
+			}
+		}
+
+		xmlFree( text );
+	}
 
+	return( profile_id );
 }
+
+static void
+read_done_load_profile( NAXMLReader *reader, const gchar *profile_id )
+{
+	/*g_debug( "naxml_reader_read_done_load_profile: profile_id=%s", profile_id );*/
+
+	NAObjectProfile *profile = na_object_profile_new();
+
+	na_object_set_id( profile, profile_id );
+
+	na_ifactory_provider_read_item(
+			NA_IFACTORY_PROVIDER( reader->private->importer ),
+			reader,
+			NA_IFACTORY_OBJECT( profile ),
+			&reader->private->parms->messages );
+}
+
 /*
  * 'key' and 'applyto' keys: check the id
  * 'applyto' key: check for type
@@ -960,15 +1163,15 @@ schema_parse_schema_content( NAXMLReader *reader, xmlNode *schema )
 static void
 schema_check_for_id( NAXMLReader *reader, xmlNode *iter )
 {
-	guint idx = 1;
+	guint idx = 0;
 
 	if( !strxcmp( iter->name, NAXML_KEY_SCHEMA_NODE_KEY )){
-		idx = 2;
+		idx = 1;
 	}
 
 	xmlChar *text = xmlNodeGetContent( iter );
 	gchar **path_elts = g_strsplit(( const gchar * ) text, "/", -1 );
-	gchar *id = g_strdup( path_elts[ SCHEMA_PATH_ID_IDX+idx-1 ] );
+	gchar *id = g_strdup( path_elts[ reader->private->root_node_str->key_length+idx-2 ] );
 	g_strfreev( path_elts );
 	xmlFree( text );
 
@@ -1970,6 +2173,23 @@ build_root_node_list( void )
 	return( g_string_free( string, FALSE ));
 }
 
+static gboolean
+is_profile_path( NAXMLReader *reader, xmlChar *text )
+{
+	gboolean is_profile;
+	GSList *path_slist;
+	guint path_length;
+
+	path_slist = na_core_utils_slist_from_split(( const gchar * ) text, "/" );
+	path_length = g_slist_length( path_slist );
+
+	is_profile = ( path_length == 1+reader->private->root_node_str->key_length );
+
+	na_core_utils_slist_free( path_slist );
+
+	return( is_profile );
+}
+
 #if 0
 static void
 free_naxml_element_str( NAXMLElementStr *str, void *data )
diff --git a/src/io-xml/naxml-reader.h b/src/io-xml/naxml-reader.h
index 0072a9b..ff18998 100644
--- a/src/io-xml/naxml-reader.h
+++ b/src/io-xml/naxml-reader.h
@@ -77,9 +77,9 @@ GType        naxml_reader_get_type( void );
 
 guint        naxml_reader_import_from_uri( const NAIImporter *instance, NAIImporterParms *parms );
 
-NADataBoxed *naxml_reader_read_data( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages );
-
-void         naxml_reader_read_done( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
+void         naxml_reader_read_start( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
+NADataBoxed *naxml_reader_read_data ( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, const NADataDef *def, GSList **messages );
+void         naxml_reader_read_done ( const NAIFactoryProvider *provider, void *reader_data, const NAIFactoryObject *object, GSList **messages  );
 
 G_END_DECLS
 



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