[nautilus-actions] Import/export .desktop files
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Import/export .desktop files
- Date: Wed, 28 Jul 2010 20:59:24 +0000 (UTC)
commit 21e2b4d05d727f16ada4116ca66258a4b1f751c5
Author: Pierre Wieser <pwieser trychlos org>
Date: Wed Jul 28 22:58:59 2010 +0200
Import/export .desktop files
This commit defines the global structure of import/export operations for .desktop files.
Only the import operation is actually defined.
ChangeLog | 42 +++++++++
doc/export-format-id | 3 +-
po/POTFILES.in | 1 +
src/api/na-core-utils.h | 6 +-
src/api/na-iimporter.h | 27 +++++-
src/core/na-core-utils.c | 45 ++++++++++
src/core/na-iimporter.c | 111 ++++++++++++++++++++++++
src/io-desktop/Makefile.am | 2 +
src/io-desktop/nadp-desktop-file.c | 142 +++++++++++++++++++++++-------
src/io-desktop/nadp-desktop-file.h | 3 +-
src/io-desktop/nadp-desktop-provider.c | 100 +++++++++++++++++++---
src/io-desktop/nadp-reader.c | 99 +++++++++++++++++++--
src/io-desktop/nadp-reader.h | 5 +-
src/io-desktop/nadp-utils.c | 43 ++++++++--
src/io-desktop/nadp-utils.h | 3 +-
src/io-desktop/nadp-writer.c | 137 ++++++++++++++++++++++-------
src/io-desktop/nadp-writer.h | 14 ++-
src/io-xml/naxml-formats.c | 3 +
src/io-xml/naxml-reader.c | 149 ++++++--------------------------
19 files changed, 702 insertions(+), 233 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 29eb8f6..d9a0e15 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,47 @@
2010-07-28 Pierre Wieser <pwieser trychlos org>
+ Import/export .desktop files.
+
+ * doc/export-format-id: Declare the new export format.
+
+ * po/POTFILES.in: Add a file.
+
+ * src/api/na-core-utils.h:
+ * src/core/na-core-utils.c
+ (na_core_utils_slist_add_message, na_core_utils_file_load_from_uri):
+ New functions.
+
+ * src/api/na-iimporter.h:
+ * src/core/na-iimporter.c (na_iimporter_manage_import_mode):
+ New function.
+
+ * src/io-desktop/nadp-formats.c:
+ * src/io-desktop/nadp-formats.h: New files.
+
+ * src/io-desktop/Makefile.am: Updated accordingly.
+
+ * src/io-desktop/nadp-desktop-file.c:
+ * src/io-desktop/nadp-desktop-file.h
+ (nadp_desktop_file_new_from_uri): New function.
+ (nadp_desktop_file_get_key_file_path): Renamed as nadp_desktop_file_get_key_file_uri().
+
+ * src/io-desktop/nadp-desktop-provider.c:
+ Declare NAIImporterInterface and NAIExporterInterface interfaces.
+
+ * src/io-desktop/nadp-reader.c:
+ * src/io-desktop/nadp-reader.h
+ (nadp_reader_iimporter_import_from_uri): New function.
+
+ * src/io-desktop/nadp-utils.c:
+ * src/io-desktop/nadp-utils.h
+ (nadp_utils_is_writable_file): Renamed as nadp_utils_uri_is_writable().
+ (nadp_utils_uri_delete): New function.
+
+ * src/io-desktop/nadp-writer.c:
+ * src/io-desktop/nadp-writer.h
+ (nadp_writer_iexporter_export_to_buffer, nadp_writer_iexporter_export_to_file):
+ New functions.
+
* src/nact/nact-add-scheme-dialog.c:
Prevent a default scheme to be inserted twice.
diff --git a/doc/export-format-id b/doc/export-format-id
index 9f8bd94..2d3ff62 100644
--- a/doc/export-format-id
+++ b/doc/export-format-id
@@ -8,8 +8,9 @@ please contact the maintainers (see nautilus-actions.doap).
format id module holder allocated
------------- ------------------ ---------------- ----------
Ask reserved id Nautilus-Actions 2010-02-15
+Desktop1 NA Desktop module Nautilus-Actions 2010-07-28
GConfSchemaV1 NA XML module Nautilus-Actions 2010-02-15
GConfSchemaV1 NA XML module Nautilus-Actions 2010-02-15
GConfEntry NA XML module Nautilus-Actions 2010-02-15
-Last updated: 2010, Feb. 15th
+Last updated: 2010, July 28th.
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9ce916c..aeaa66f 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -2,6 +2,7 @@ data/nautilus-actions-prefs.schemas.in
src/core/na-exporter.c
src/core/na-iabout.c
src/core/na-icontext-factory.c
+src/core/na-iimporter.c
src/core/na-importer-ask.c
src/core/na-importer-ask.ui
src/core/na-io-provider.c
diff --git a/src/api/na-core-utils.h b/src/api/na-core-utils.h
index 07fba06..1fff3fa 100644
--- a/src/api/na-core-utils.h
+++ b/src/api/na-core-utils.h
@@ -55,6 +55,7 @@ gchar *na_core_utils_str_remove_suffix( const gchar *string, const gchar *suff
/* some functions to get or set GSList list of strings
*/
+void na_core_utils_slist_add_message( GSList **list, const gchar *format, ... );
GSList *na_core_utils_slist_duplicate( GSList *list );
void na_core_utils_slist_dump( const gchar *prefix, GSList *list );
GSList *na_core_utils_slist_from_array( const gchar **str_array );
@@ -86,8 +87,9 @@ void na_core_utils_dir_split_ext( const gchar *string, gchar **first, gchar
/* file management
*/
-gboolean na_core_utils_file_delete( const gchar *path );
-gboolean na_core_utils_file_exists( const gchar *path );
+gboolean na_core_utils_file_delete ( const gchar *path );
+gboolean na_core_utils_file_exists ( const gchar *path );
+gchar *na_core_utils_file_load_from_uri( const gchar *uri, gsize *length );
/* miscellaneous
*/
diff --git a/src/api/na-iimporter.h b/src/api/na-iimporter.h
index 7a5aace..01e4705 100644
--- a/src/api/na-iimporter.h
+++ b/src/api/na-iimporter.h
@@ -50,10 +50,11 @@ G_BEGIN_DECLS
#define NA_IS_IIMPORTER( instance ) ( G_TYPE_CHECK_INSTANCE_TYPE( instance, NA_IIMPORTER_TYPE ))
#define NA_IIMPORTER_GET_INTERFACE( instance ) ( G_TYPE_INSTANCE_GET_INTERFACE(( instance ), NA_IIMPORTER_TYPE, NAIImporterInterface ))
-typedef struct NAIImporter NAIImporter;
-typedef struct NAIImporterInterfacePrivate NAIImporterInterfacePrivate;
+typedef struct NAIImporter NAIImporter;
+typedef struct NAIImporterInterfacePrivate NAIImporterInterfacePrivate;
-typedef struct NAIImporterImportFromUriParms NAIImporterImportFromUriParms;
+typedef struct NAIImporterImportFromUriParms NAIImporterImportFromUriParms;
+typedef struct NAIImporterManageImportModeParms NAIImporterManageImportModeParms;
typedef struct {
GTypeInterface parent;
@@ -155,10 +156,30 @@ struct NAIImporterImportFromUriParms {
* but shouldn't reinitialize it. */
};
+/*
+ * parameters used when managing import mode
+ */
+struct NAIImporterManageImportModeParms {
+ guint version; /* i 1: version of this structure */
+ NAObjectItem *imported; /* i 1: the imported NAObjectItem-derived object */
+ guint asked_mode; /* i 1: asked import mode */
+ NAIImporterCheckFn check_fn; /* i 1: a function to check the existence of the imported id */
+ void *check_fn_data; /* i 1: data function */
+ NAIImporterAskUserFn ask_fn; /* i 1: a function to ask the user what to do in case of a duplicate id */
+ void *ask_fn_data; /* i 1: data function */
+ gboolean exist; /* o1: whether the imported Id already existed */
+ guint import_mode; /* o1: actually used import mode */
+ GSList *messages; /* io1: a #GSList list of localized strings;
+ * the provider may append messages to this list,
+ * but shouldn't reinitialize it. */
+};
+
GType na_iimporter_get_type( void );
guint na_iimporter_import_from_uri( const NAIImporter *importer, NAIImporterImportFromUriParms *parms );
+guint na_iimporter_manage_import_mode( NAIImporterManageImportModeParms *parms );
+
G_END_DECLS
#endif /* __NAUTILUS_ACTIONS_API_NA_IIMPORTER_H__ */
diff --git a/src/core/na-core-utils.c b/src/core/na-core-utils.c
index f56af6a..e276f42 100644
--- a/src/core/na-core-utils.c
+++ b/src/core/na-core-utils.c
@@ -209,6 +209,19 @@ na_core_utils_str_remove_suffix( const gchar *string, const gchar *suffix )
return( removed );
}
+void
+na_core_utils_slist_add_message( GSList **messages, const gchar *format, ... )
+{
+ va_list va;
+ gchar *tmp;
+
+ va_start( va, format );
+ tmp = g_markup_vprintf_escaped( format, va );
+ va_end( va );
+
+ *messages = g_slist_append( *messages, tmp );
+}
+
/**
* na_core_utils_slist_duplicate:
* @source_slist: the #GSList to be duplicated.
@@ -869,6 +882,38 @@ na_core_utils_file_exists( const gchar *fname )
}
/**
+ * na_core_utils_file_load_from_uri:
+ * @uri: the URI the file must be loaded from.
+ * @length: a pointer to the length of the readen content.
+ *
+ * Loads the file into a newly allocated buffer, and set up the length of the
+ * readen content if not %NULL.
+ *
+ * Returns: the newly allocated buffer which contains the file content, or %NULL.
+ * This buffer should be g_free() by the caller.
+ */
+gchar *
+na_core_utils_file_load_from_uri( const gchar *uri, gsize *length )
+{
+ gchar *data;
+ GFile *file;
+
+ file = g_file_new_for_uri( uri );
+
+ if( !g_file_load_contents( file, NULL, &data, length, NULL, NULL )){
+ g_free( data );
+ data = NULL;
+ if( length ){
+ *length = 0;
+ }
+ }
+
+ g_object_unref( file );
+
+ return( data );
+}
+
+/**
* na_core_utils_print_version:
*
* Print a version message on the console
diff --git a/src/core/na-iimporter.c b/src/core/na-iimporter.c
index f57eebd..482881b 100644
--- a/src/core/na-iimporter.c
+++ b/src/core/na-iimporter.c
@@ -32,7 +32,11 @@
#include <config.h>
#endif
+#include <glib/gi18n.h>
+
+#include <api/na-core-utils.h>
#include <api/na-iimporter.h>
+#include <api/na-object-api.h>
/* private interface data
*/
@@ -49,6 +53,8 @@ static void interface_base_finalize( NAIImporterInterface *klass );
static guint iimporter_get_version( const NAIImporter *instance );
+static void renumber_label_item( NAIImporterManageImportModeParms *parms );
+
/**
* na_iimporter_get_type:
*
@@ -169,3 +175,108 @@ na_iimporter_import_from_uri( const NAIImporter *importer, NAIImporterImportFrom
return( code );
}
+
+/*
+ * Returns IMPORTER_CODE_OK if we can safely insert the action
+ * - the id doesn't already exist
+ * - the id already exist, but import mode is renumber
+ * - the id already exists, but import mode is override
+ *
+ * Returns IMPORTER_CODE_CANCELLED if user chooses to cancel the operation
+ */
+guint
+na_iimporter_manage_import_mode( NAIImporterManageImportModeParms *parms )
+{
+ guint code;
+ NAObjectItem *exists;
+ guint mode;
+ gchar *id;
+
+ g_return_val_if_fail( parms->imported != NULL, IMPORTER_CODE_CANCELLED );
+
+ code = IMPORTER_CODE_OK;
+ exists = NULL;
+ mode = 0;
+
+ if( parms->check_fn ){
+ exists = ( *parms->check_fn )( parms->imported, parms->check_fn_data );
+
+ } else {
+ renumber_label_item( parms );
+ na_core_utils_slist_add_message( &parms->messages, "%s", _( "Item was renumbered because the caller did not provide any check function." ));
+ parms->import_mode = IMPORTER_MODE_RENUMBER;
+ }
+
+ if( exists ){
+ parms->exist = TRUE;
+
+ if( parms->asked_mode == IMPORTER_MODE_ASK ){
+ if( parms->ask_fn ){
+ mode = ( *parms->ask_fn )( parms->imported, exists, parms->ask_fn_data );
+
+ } else {
+ renumber_label_item( parms );
+ na_core_utils_slist_add_message( &parms->messages, "%s", _( "Item was renumbered because the caller did not provide any ask user function." ));
+ parms->import_mode = IMPORTER_MODE_RENUMBER;
+ }
+
+ } else {
+ mode = parms->asked_mode;
+ }
+ }
+
+ /* mode is only set if asked mode is ask user and an ask function was provided
+ * or if asked mode was not ask user
+ */
+ if( mode ){
+ parms->import_mode = mode;
+
+ switch( mode ){
+ case IMPORTER_MODE_RENUMBER:
+ renumber_label_item( parms );
+ if( parms->asked_mode == IMPORTER_MODE_ASK ){
+ na_core_utils_slist_add_message( &parms->messages, "%s", _( "Item was renumbered due to user request." ));
+ }
+ break;
+
+ case IMPORTER_MODE_OVERRIDE:
+ if( parms->asked_mode == IMPORTER_MODE_ASK ){
+ na_core_utils_slist_add_message( &parms->messages, "%s", _( "Existing item was overriden due to user request." ));
+ }
+ break;
+
+ case IMPORTER_MODE_NO_IMPORT:
+ default:
+ id = na_object_get_id( parms->imported );
+ na_core_utils_slist_add_message( &parms->messages, _( "Item %s already exists." ), id );
+ if( parms->asked_mode == IMPORTER_MODE_ASK ){
+ na_core_utils_slist_add_message( &parms->messages, "%s", _( "Import was canceled due to user request." ));
+ }
+ g_free( id );
+ code = IMPORTER_CODE_CANCELLED;
+ }
+ }
+
+ return( code );
+}
+
+/*
+ * renumber the item, and set a new label
+ */
+static void
+renumber_label_item( NAIImporterManageImportModeParms *parms )
+{
+ gchar *label, *tmp;
+
+ na_object_set_new_id( parms->imported, NULL );
+
+ label = na_object_get_label( parms->imported );
+
+ /* i18n: the action has been renumbered during import operation */
+ tmp = g_strdup_printf( "%s %s", label, _( "(renumbered)" ));
+
+ na_object_set_label( parms->imported, tmp );
+
+ g_free( tmp );
+ g_free( label );
+}
diff --git a/src/io-desktop/Makefile.am b/src/io-desktop/Makefile.am
index d872003..da57973 100644
--- a/src/io-desktop/Makefile.am
+++ b/src/io-desktop/Makefile.am
@@ -40,6 +40,8 @@ libna_io_desktop_la_SOURCES = \
nadp-desktop-file.h \
nadp-desktop-provider.c \
nadp-desktop-provider.h \
+ nadp-formats.c \
+ nadp-formats.h \
nadp-keys.c \
nadp-keys.h \
nadp-module.c \
diff --git a/src/io-desktop/nadp-desktop-file.c b/src/io-desktop/nadp-desktop-file.c
index 193aee1..e44b00f 100644
--- a/src/io-desktop/nadp-desktop-file.c
+++ b/src/io-desktop/nadp-desktop-file.c
@@ -52,7 +52,7 @@ struct NadpDesktopFileClassPrivate {
struct NadpDesktopFilePrivate {
gboolean dispose_has_run;
gchar *id;
- gchar *path;
+ gchar *uri;
GKeyFile *key_file;
};
@@ -64,8 +64,9 @@ static void instance_init( GTypeInstance *instance, gpointer klass )
static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
-static NadpDesktopFile *ndf_new( const gchar *path );
+static NadpDesktopFile *ndf_new( const gchar *uri );
static gchar *path2id( const gchar *path );
+static gchar *uri2id( const gchar *uri );
static gboolean check_key_file( NadpDesktopFile *ndf );
GType
@@ -169,7 +170,7 @@ instance_finalize( GObject *object )
self = NADP_DESKTOP_FILE( object );
g_free( self->private->id );
- g_free( self->private->path );
+ g_free( self->private->uri );
if( self->private->key_file ){
g_key_file_free( self->private->key_file );
@@ -197,14 +198,25 @@ nadp_desktop_file_new_from_path( const gchar *path )
static const gchar *thisfn = "nadp_desktop_file_new_from_path";
NadpDesktopFile *ndf;
GError *error;
+ gchar *uri;
ndf = NULL;
g_debug( "%s: path=%s", thisfn, path );
g_return_val_if_fail( path && g_utf8_strlen( path, -1 ) && g_path_is_absolute( path ), ndf );
- ndf = ndf_new( path );
-
error = NULL;
+ uri = g_filename_to_uri( path, NULL, &error );
+ if( !uri || error ){
+ g_warning( "%s: %s: %s", thisfn, path, error->message );
+ g_error_free( error );
+ g_free( uri );
+ return( NULL );
+ }
+
+ ndf = ndf_new( uri );
+
+ g_free( uri );
+
g_key_file_load_from_file( ndf->private->key_file, path, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error );
if( error ){
g_warning( "%s: %s: %s", thisfn, path, error->message );
@@ -222,6 +234,50 @@ nadp_desktop_file_new_from_path( const gchar *path )
}
/**
+ * nadp_desktop_file_new_from_uri:
+ * @uri: the URI the desktop file should be loaded from.
+ *
+ * Retuns: a newly allocated #NadpDesktopFile object, or %NULL.
+ *
+ * Key file has been loaded, and first validity checks made.
+ */
+NadpDesktopFile *
+nadp_desktop_file_new_from_uri( const gchar *uri )
+{
+ static const gchar *thisfn = "nadp_desktop_file_new_from_uri";
+ NadpDesktopFile *ndf;
+ GError *error;
+ gchar *data;
+ gsize length;
+
+ ndf = NULL;
+ g_debug( "%s: uri=%s", thisfn, uri );
+ g_return_val_if_fail( uri && g_utf8_strlen( uri, -1 ), ndf );
+
+ ndf = ndf_new( uri );
+ data = na_core_utils_file_load_from_uri( uri, &length );
+
+ error = NULL;
+ g_key_file_load_from_data( ndf->private->key_file, data, length, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error );
+ if( error ){
+ g_warning( "%s: %s", thisfn, error->message );
+ g_error_free( error );
+ g_object_unref( ndf );
+ g_free( data );
+ return( NULL );
+ }
+
+ g_free( data );
+
+ if( !check_key_file( ndf )){
+ g_object_unref( ndf );
+ return( NULL );
+ }
+
+ return( ndf );
+}
+
+/**
* nadp_desktop_file_new_for_write:
* @path: the full pathname of a .desktop file.
*
@@ -232,66 +288,67 @@ nadp_desktop_file_new_for_write( const gchar *path )
{
static const gchar *thisfn = "nadp_desktop_file_new_for_write";
NadpDesktopFile *ndf;
+ GError *error;
+ gchar *uri;
ndf = NULL;
g_debug( "%s: path=%s", thisfn, path );
g_return_val_if_fail( path && g_utf8_strlen( path, -1 ) && g_path_is_absolute( path ), ndf );
- ndf = ndf_new( path );
+ error = NULL;
+ uri = g_filename_to_uri( path, NULL, &error );
+ if( !uri || error ){
+ g_warning( "%s: %s: %s", thisfn, path, error->message );
+ g_error_free( error );
+ g_free( uri );
+ return( NULL );
+ }
+
+ ndf = ndf_new( uri );
+
+ g_free( uri );
return( ndf );
}
/**
- * nadp_desktop_file_get_key_file_path:
+ * nadp_desktop_file_get_key_file_uri:
* @ndf: the #NadpDesktopFile instance.
*
- * Returns: the full pathname of the key file, as a newly allocated
+ * Returns: the URI of the key file, as a newly allocated
* string which should be g_free() by the caller.
*/
gchar *
-nadp_desktop_file_get_key_file_path( const NadpDesktopFile *ndf )
+nadp_desktop_file_get_key_file_uri( const NadpDesktopFile *ndf )
{
- gchar *path;
+ gchar *uri;
g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), NULL );
- path = NULL;
+ uri = NULL;
if( !ndf->private->dispose_has_run ){
- path = g_strdup( ndf->private->path );
+ uri = g_strdup( ndf->private->uri );
}
- return( path );
+ return( uri );
}
-/*
- * ndf_new:
- * @path: the full pathname of a .desktop file.
- *
- * Retuns: a newly allocated #NadpDesktopFile object.
- */
static NadpDesktopFile *
-ndf_new( const gchar *path )
+ndf_new( const gchar *uri )
{
NadpDesktopFile *ndf;
ndf = g_object_new( NADP_DESKTOP_FILE_TYPE, NULL );
- ndf->private->id = path2id( path );
- ndf->private->path = g_strdup( path );
+ ndf->private->id = uri2id( uri );
+ ndf->private->uri = g_strdup( uri );
return( ndf );
}
/*
- * path2id:
- * @path: a full pathname.
- *
- * Returns: the id of the file, as a newly allocated string which
- * should be g_free() by the caller.
- *
* The id of the file is equal to the basename, minus the suffix.
*/
static gchar *
@@ -307,6 +364,23 @@ path2id( const gchar *path )
return( id );
}
+static gchar *
+uri2id( const gchar *uri )
+{
+ gchar *path;
+ gchar *id;
+
+ id = NULL;
+ path = g_filename_from_uri( uri, NULL, NULL );
+
+ if( path ){
+ id = path2id( path );
+ g_free( path );
+ }
+
+ return( id );
+}
+
static gboolean
check_key_file( NadpDesktopFile *ndf )
{
@@ -320,11 +394,11 @@ check_key_file( NadpDesktopFile *ndf )
ret = TRUE;
error = NULL;
- /* start group must be 'Desktop Entry' */
+ /* start group must be [Desktop Entry] */
start_group = g_key_file_get_start_group( ndf->private->key_file );
if( strcmp( start_group, NADP_GROUP_DESKTOP )){
g_warning( "%s: %s: invalid start group, found %s, waited for %s",
- thisfn, ndf->private->path, start_group, NADP_GROUP_DESKTOP );
+ thisfn, ndf->private->uri, start_group, NADP_GROUP_DESKTOP );
ret = FALSE;
}
@@ -332,17 +406,17 @@ check_key_file( NadpDesktopFile *ndf )
if( ret ){
has_key = g_key_file_has_key( ndf->private->key_file, start_group, NADP_KEY_HIDDEN, &error );
if( error ){
- g_warning( "%s: %s: %s", thisfn, ndf->private->path, error->message );
+ g_warning( "%s: %s: %s", thisfn, ndf->private->uri, error->message );
ret = FALSE;
} else if( has_key ){
hidden = g_key_file_get_boolean( ndf->private->key_file, start_group, NADP_KEY_HIDDEN, &error );
if( error ){
- g_warning( "%s: %s: %s", thisfn, ndf->private->path, error->message );
+ g_warning( "%s: %s: %s", thisfn, ndf->private->uri, error->message );
ret = FALSE;
} else if( hidden ){
- g_debug( "%s: %s: Hidden=true", thisfn, ndf->private->path );
+ g_debug( "%s: %s: Hidden=true", thisfn, ndf->private->uri );
ret = FALSE;
}
}
@@ -917,7 +991,7 @@ nadp_desktop_file_write( NadpDesktopFile *ndf )
if( !ndf->private->dispose_has_run ){
data = g_key_file_to_data( ndf->private->key_file, NULL, NULL );
- file = g_file_new_for_path( ndf->private->path );
+ file = g_file_new_for_uri( ndf->private->uri );
stream = g_file_replace( file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error );
if( error ){
diff --git a/src/io-desktop/nadp-desktop-file.h b/src/io-desktop/nadp-desktop-file.h
index e2bcf3b..812d019 100644
--- a/src/io-desktop/nadp-desktop-file.h
+++ b/src/io-desktop/nadp-desktop-file.h
@@ -75,9 +75,10 @@ typedef struct {
GType nadp_desktop_file_get_type ( void );
NadpDesktopFile *nadp_desktop_file_new_from_path ( const gchar *path );
+NadpDesktopFile *nadp_desktop_file_new_from_uri ( const gchar *uri );
NadpDesktopFile *nadp_desktop_file_new_for_write ( const gchar *path );
-gchar *nadp_desktop_file_get_key_file_path( const NadpDesktopFile *ndf );
+gchar *nadp_desktop_file_get_key_file_uri ( const NadpDesktopFile *ndf );
gboolean nadp_desktop_file_write ( NadpDesktopFile *ndf );
gchar *nadp_desktop_file_get_file_type ( const NadpDesktopFile *ndf );
diff --git a/src/io-desktop/nadp-desktop-provider.c b/src/io-desktop/nadp-desktop-provider.c
index 5014995..0a198b5 100644
--- a/src/io-desktop/nadp-desktop-provider.c
+++ b/src/io-desktop/nadp-desktop-provider.c
@@ -36,7 +36,6 @@
#include <string.h>
#include <api/na-core-utils.h>
-#include <api/na-iio-provider.h>
#include <api/na-ifactory-provider.h>
#include "nadp-desktop-provider.h"
@@ -51,26 +50,36 @@ struct NadpDesktopProviderClassPrivate {
void *empty; /* so that gcc -pedantic is happy */
};
+extern NAIExporterFormat nadp_formats[];
+
static GType st_module_type = 0;
static GObjectClass *st_parent_class = NULL;
static guint st_timeout_msec = 100;
static guint st_timeout_usec = 100000;
-static void class_init( NadpDesktopProviderClass *klass );
-static void instance_init( GTypeInstance *instance, gpointer klass );
-static void instance_dispose( GObject *object );
-static void instance_finalize( GObject *object );
+static void class_init( NadpDesktopProviderClass *klass );
+static void instance_init( GTypeInstance *instance, gpointer klass );
+static void instance_dispose( GObject *object );
+static void instance_finalize( GObject *object );
+
+static void iio_provider_iface_init( NAIIOProviderInterface *iface );
+static gchar *iio_provider_get_id( const NAIIOProvider *provider );
+static gchar *iio_provider_get_name( const NAIIOProvider *provider );
+static guint iio_provider_get_version( const NAIIOProvider *provider );
+
+static void ifactory_provider_iface_init( NAIFactoryProviderInterface *iface );
+static guint ifactory_provider_get_version( const NAIFactoryProvider *reader );
-static void iio_provider_iface_init( NAIIOProviderInterface *iface );
-static gchar *iio_provider_get_id( const NAIIOProvider *provider );
-static gchar *iio_provider_get_name( const NAIIOProvider *provider );
-static guint iio_provider_get_version( const NAIIOProvider *provider );
+static void iimporter_iface_init( NAIImporterInterface *iface );
+static guint iimporter_get_version( const NAIImporter *importer );
-static void ifactory_provider_iface_init( NAIFactoryProviderInterface *iface );
-static guint ifactory_provider_get_version( const NAIFactoryProvider *reader );
+static void iexporter_iface_init( NAIExporterInterface *iface );
+static guint iexporter_get_version( const NAIExporter *exporter );
+static gchar *iexporter_get_name( const NAIExporter *exporter );
+static const NAIExporterFormat *iexporter_get_formats( const NAIExporter *exporter );
-static gboolean on_monitor_timeout( NadpDesktopProvider *provider );
-static gulong time_val_diff( const GTimeVal *recent, const GTimeVal *old );
+static gboolean on_monitor_timeout( NadpDesktopProvider *provider );
+static gulong time_val_diff( const GTimeVal *recent, const GTimeVal *old );
GType
nadp_desktop_provider_get_type( void )
@@ -107,6 +116,18 @@ nadp_desktop_provider_register_type( GTypeModule *module )
NULL
};
+ static const GInterfaceInfo iimporter_iface_info = {
+ ( GInterfaceInitFunc ) iimporter_iface_init,
+ NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo iexporter_iface_info = {
+ ( GInterfaceInitFunc ) iexporter_iface_init,
+ NULL,
+ NULL
+ };
+
g_debug( "%s", thisfn );
st_module_type = g_type_module_register_type( module, G_TYPE_OBJECT, "NadpDesktopProvider", &info, 0 );
@@ -114,6 +135,10 @@ nadp_desktop_provider_register_type( GTypeModule *module )
g_type_module_add_interface( module, st_module_type, NA_IIO_PROVIDER_TYPE, &iio_provider_iface_info );
g_type_module_add_interface( module, st_module_type, NA_IFACTORY_PROVIDER_TYPE, &ifactory_provider_iface_info );
+
+ g_type_module_add_interface( module, st_module_type, NA_IIMPORTER_TYPE, &iimporter_iface_info );
+
+ g_type_module_add_interface( module, st_module_type, NA_IEXPORTER_TYPE, &iexporter_iface_info );
}
static void
@@ -247,6 +272,55 @@ ifactory_provider_get_version( const NAIFactoryProvider *reader )
return( 1 );
}
+static void
+iimporter_iface_init( NAIImporterInterface *iface )
+{
+ static const gchar *thisfn = "nadp_desktop_provider_iimporter_iface_init";
+
+ g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
+
+ iface->get_version = iimporter_get_version;
+ iface->import_from_uri = nadp_reader_iimporter_import_from_uri;
+}
+
+static guint
+iimporter_get_version( const NAIImporter *importer )
+{
+ return( 1 );
+}
+
+static void
+iexporter_iface_init( NAIExporterInterface *iface )
+{
+ static const gchar *thisfn = "nadp_desktop_iexporter_iface_init";
+
+ g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
+
+ iface->get_version = iexporter_get_version;
+ iface->get_name = iexporter_get_name;
+ iface->get_formats = iexporter_get_formats;
+ iface->to_file = nadp_writer_iexporter_export_to_file;
+ iface->to_buffer = nadp_writer_iexporter_export_to_buffer;
+}
+
+static guint
+iexporter_get_version( const NAIExporter *exporter )
+{
+ return( 1 );
+}
+
+static gchar *
+iexporter_get_name( const NAIExporter *exporter )
+{
+ return( g_strdup( "NA Desktop Exporter" ));
+}
+
+static const NAIExporterFormat *
+iexporter_get_formats( const NAIExporter *exporter )
+{
+ return( nadp_formats );
+}
+
/**
* nadp_desktop_provider_add_monitor:
* @provider: this #NadpDesktopProvider object.
diff --git a/src/io-desktop/nadp-reader.c b/src/io-desktop/nadp-reader.c
index fa79767..8847193 100644
--- a/src/io-desktop/nadp-reader.c
+++ b/src/io-desktop/nadp-reader.c
@@ -66,6 +66,7 @@ static void get_list_of_desktop_files( const NadpDesktopProvider *p
static gboolean is_already_loaded( const NadpDesktopProvider *provider, GList *files, const gchar *desktop_id );
static GList *desktop_path_from_id( const NadpDesktopProvider *provider, GList *files, const gchar *dir, const gchar *id );
static NAIFactoryObject *item_from_desktop_path( const NadpDesktopProvider *provider, DesktopPath *dps, GSList **messages );
+static NAIFactoryObject *item_from_desktop_file( const NadpDesktopProvider *provider, NadpDesktopFile *ndf, GSList **messages );
static void desktop_weak_notify( NadpDesktopFile *ndf, GObject *item );
static void free_desktop_paths( GList *paths );
@@ -251,18 +252,29 @@ desktop_path_from_id( const NadpDesktopProvider *provider, GList *files, const g
static NAIFactoryObject *
item_from_desktop_path( const NadpDesktopProvider *provider, DesktopPath *dps, GSList **messages )
{
- static const gchar *thisfn = "nadp_reader_item_from_desktop_path";
- NAIFactoryObject *item;
NadpDesktopFile *ndf;
- gchar *type;
- NadpReaderData *reader_data;
- gchar *id;
ndf = nadp_desktop_file_new_from_path( dps->path );
if( !ndf ){
return( NULL );
}
+ return( item_from_desktop_file( provider, ndf, messages ));
+}
+
+/*
+ * Returns a newly allocated NAIFactoryObject-derived object, initialized
+ * from the .desktop file
+ */
+static NAIFactoryObject *
+item_from_desktop_file( const NadpDesktopProvider *provider, NadpDesktopFile *ndf, GSList **messages )
+{
+ static const gchar *thisfn = "nadp_reader_item_from_desktop_file";
+ NAIFactoryObject *item;
+ gchar *type;
+ NadpReaderData *reader_data;
+ gchar *id;
+
item = NULL;
type = nadp_desktop_file_get_file_type( ndf );
@@ -323,6 +335,75 @@ free_desktop_paths( GList *paths )
g_list_free( paths );
}
+/**
+ * nadp_reader_iimporter_import_from_uri:
+ * @instance: the #NAIImporter provider.
+ * @parms: a #NAIImporterUriParms structure.
+ *
+ * Imports an item.
+ *
+ * Returns: the import operation code.
+ *
+ * As soon as we have a valid .desktop file, we are most probably willing
+ * to successfully import an action or a menu of it.
+ *
+ * GLib does not have any primitive to load a key file from an uri.
+ * So we have to load the file into memory, and then try to load the key
+ * file from the memory data.
+ */
+guint
+nadp_reader_iimporter_import_from_uri( const NAIImporter *instance, NAIImporterImportFromUriParms *parms )
+{
+ static const gchar *thisfn = "nadp_reader_iimporter_import_from_uri";
+ guint code;
+ NadpDesktopFile *ndf;
+ NAIImporterManageImportModeParms manage_parms;
+
+ g_debug( "%s: instance=%p, parms=%p", thisfn, ( void * ) instance, ( void * ) parms );
+
+ g_return_val_if_fail( NA_IS_IIMPORTER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
+ g_return_val_if_fail( NADP_IS_DESKTOP_PROVIDER( instance ), IMPORTER_CODE_PROGRAM_ERROR );
+
+ code = IMPORTER_CODE_NOT_WILLING_TO;
+
+ ndf = nadp_desktop_file_new_from_uri( parms->uri );
+ if( ndf ){
+ parms->exist = FALSE;
+ parms->import_mode = IMPORTER_MODE_NO_IMPORT;
+ parms->imported = ( NAObjectItem * ) item_from_desktop_file(
+ ( const NadpDesktopProvider * ) NADP_DESKTOP_PROVIDER( instance ),
+ ndf, &parms->messages );
+
+ if( parms->imported ){
+ code = IMPORTER_CODE_OK;
+ g_return_val_if_fail( NA_IS_OBJECT_ITEM( parms->imported ), IMPORTER_CODE_NOT_WILLING_TO );
+
+ manage_parms.version = 1;
+ manage_parms.imported = parms->imported;
+ manage_parms.check_fn = parms->check_fn;
+ manage_parms.check_fn_data = parms->check_fn_data;
+ manage_parms.ask_fn = parms->ask_fn;
+ manage_parms.ask_fn_data = parms->ask_fn_data;
+ manage_parms.asked_mode = parms->asked_mode;
+ manage_parms.messages = parms->messages;
+
+ code = na_iimporter_manage_import_mode( &manage_parms );
+
+ parms->exist = manage_parms.exist;
+ parms->import_mode = manage_parms.import_mode;
+ }
+
+ if( code != IMPORTER_CODE_OK ){
+ if( parms->imported ){
+ g_object_unref( parms->imported );
+ parms->imported = NULL;
+ }
+ }
+ }
+
+ return( code );
+}
+
/*
* at this time, the object has been allocated and its id has been set
* read here the subitems key, which may be 'Profiles' or 'ItemsList'
@@ -533,13 +614,13 @@ static gboolean
read_done_item_is_writable( const NAIFactoryProvider *provider, NAObjectItem *item, NadpReaderData *reader_data, GSList **messages )
{
NadpDesktopFile *ndf;
- gchar *path;
+ gchar *uri;
gboolean writable;
ndf = reader_data->ndf;
- path = nadp_desktop_file_get_key_file_path( ndf );
- writable = nadp_utils_is_writable_file( path );
- g_free( path );
+ uri = nadp_desktop_file_get_key_file_uri( ndf );
+ writable = nadp_utils_uri_is_writable( uri );
+ g_free( uri );
return( writable );
}
diff --git a/src/io-desktop/nadp-reader.h b/src/io-desktop/nadp-reader.h
index 4af4f92..673cd4f 100644
--- a/src/io-desktop/nadp-reader.h
+++ b/src/io-desktop/nadp-reader.h
@@ -32,10 +32,13 @@
#define __NADP_READER_H__
#include <api/na-iio-provider.h>
+#include <api/na-iimporter.h>
G_BEGIN_DECLS
-GList *nadp_iio_provider_read_items( const NAIIOProvider *provider, GSList **messages );
+GList *nadp_iio_provider_read_items ( const NAIIOProvider *provider, GSList **messages );
+
+guint nadp_reader_iimporter_import_from_uri ( const NAIImporter *instance, NAIImporterImportFromUriParms *parms );
void nadp_reader_ifactory_provider_read_start( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, GSList **messages );
NADataBoxed *nadp_reader_ifactory_provider_read_data ( const NAIFactoryProvider *reader, void *reader_data, const NAIFactoryObject *serializable, const NADataDef *iddef, GSList **messages );
diff --git a/src/io-desktop/nadp-utils.c b/src/io-desktop/nadp-utils.c
index 24e4ff4..455f7a4 100644
--- a/src/io-desktop/nadp-utils.c
+++ b/src/io-desktop/nadp-utils.c
@@ -35,6 +35,7 @@
#include <errno.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
+#include <string.h>
#include <uuid/uuid.h>
#include <api/na-core-utils.h>
@@ -67,8 +68,35 @@ nadp_utils_gslist_remove_from( GSList *list, const gchar *string )
}
/**
- * nadp_utils_is_writable_file:
- * @path: the path of the file to be tested.
+ *
+ */
+gboolean
+nadp_utils_uri_delete( const gchar *uri )
+{
+ gboolean deleted;
+ gchar *scheme;
+ gchar *path;
+
+ deleted = FALSE;
+ scheme = g_uri_parse_scheme( uri );
+
+ if( !strcmp( scheme, "file" )){
+ path = g_filename_from_uri( uri, NULL, NULL );
+
+ if( path ){
+ deleted = na_core_utils_file_delete( path );
+ g_free( path );
+ }
+ }
+
+ g_free( scheme );
+
+ return( deleted );
+}
+
+/**
+ * nadp_utils_uri_is_writable:
+ * @uri: the URI of the file to be tested.
*
* Returns: %TRUE if the file is writable, %FALSE else.
*
@@ -79,19 +107,19 @@ nadp_utils_gslist_remove_from( GSList *list, const gchar *string )
* There is no "super-test". Just try...
*/
gboolean
-nadp_utils_is_writable_file( const gchar *path )
+nadp_utils_uri_is_writable( const gchar *uri )
{
- static const gchar *thisfn = "nadp_utils_is_writable_file";
+ static const gchar *thisfn = "nadp_utils_uri_is_writable";
GFile *file;
GError *error = NULL;
GFileInfo *info;
gboolean writable;
- if( !path || !g_utf8_strlen( path, -1 )){
+ if( !uri || !g_utf8_strlen( uri, -1 )){
return( FALSE );
}
- file = g_file_new_for_path( path );
+ file = g_file_new_for_uri( uri );
info = g_file_query_info( file,
G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "," G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NONE, NULL, &error );
@@ -105,8 +133,9 @@ nadp_utils_is_writable_file( const gchar *path )
writable = g_file_info_get_attribute_boolean( info, G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE );
if( !writable ){
- g_debug( "%s: %s is not writable", thisfn, path );
+ g_debug( "%s: %s is not writable", thisfn, uri );
}
+
g_object_unref( info );
return( writable );
diff --git a/src/io-desktop/nadp-utils.h b/src/io-desktop/nadp-utils.h
index 6457146..2a06c7b 100644
--- a/src/io-desktop/nadp-utils.h
+++ b/src/io-desktop/nadp-utils.h
@@ -35,7 +35,8 @@ G_BEGIN_DECLS
GSList *nadp_utils_gslist_remove_from( GSList *list, const gchar *string );
-gboolean nadp_utils_is_writable_file( const gchar *path );
+gboolean nadp_utils_uri_delete ( const gchar *uri );
+gboolean nadp_utils_uri_is_writable( const gchar *uri );
G_END_DECLS
diff --git a/src/io-desktop/nadp-writer.c b/src/io-desktop/nadp-writer.c
index ec9266a..b8cbfa4 100644
--- a/src/io-desktop/nadp-writer.c
+++ b/src/io-desktop/nadp-writer.c
@@ -43,6 +43,7 @@
#include "nadp-desktop-file.h"
#include "nadp-desktop-provider.h"
#include "nadp-keys.h"
+#include "nadp-utils.h"
#include "nadp-writer.h"
#include "nadp-xdg-dirs.h"
@@ -226,7 +227,7 @@ nadp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem
guint ret;
NadpDesktopProvider *self;
NadpDesktopFile *ndf;
- gchar *path;
+ gchar *uri;
g_debug( "%s: provider=%p (%s), item=%p (%s), messages=%p",
thisfn,
@@ -250,11 +251,11 @@ nadp_iio_provider_delete_item( const NAIIOProvider *provider, const NAObjectItem
if( ndf ){
g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), ret );
- path = nadp_desktop_file_get_key_file_path( ndf );
- if( na_core_utils_file_delete( path )){
+ uri = nadp_desktop_file_get_key_file_uri( ndf );
+ if( nadp_utils_uri_delete( uri )){
ret = NA_IIO_PROVIDER_CODE_OK;
}
- g_free( path );
+ g_free( uri );
} else {
g_warning( "%s: NadpDesktopFile is null", thisfn );
@@ -317,47 +318,117 @@ nadp_iio_provider_duplicate_data( const NAIIOProvider *provider, NAObjectItem *d
return( NA_IIO_PROVIDER_CODE_OK );
}
-#if 0
-/*
- * the item comes from being readen from a desktop file
- * -> see if this desktop file is writable ?
+/**
+ * nadp_writer_iexporter_export_to_buffer:
+ * @instance: this #NAIExporter instance.
+ * @parms: a #NAIExporterBufferParms structure.
*
- * This is only used to setup the 'read-only' initial status of the
- * NAObjectItem - We don't care of all events which can suddenly make
- * this item becomes readonly (eventually we will deal for errors,
- * and reset the flag at this time)
+ * Export the specified 'item' to a newly allocated buffer.
+ */
+guint
+nadp_writer_iexporter_export_to_buffer( const NAIExporter *instance, NAIExporterBufferParms *parms )
+{
+ static const gchar *thisfn = "nadp_writer_iexporter_export_to_buffer";
+ guint code;
+
+ g_debug( "%s: instance=%p, parms=%p", thisfn, ( void * ) instance, ( void * ) parms );
+
+ code = NA_IEXPORTER_CODE_OK;
+ /*
+ NAXMLWriter *writer;
+
+ if( !parms->exported || !NA_IS_OBJECT_ITEM( parms->exported )){
+ code = NA_IEXPORTER_CODE_INVALID_ITEM;
+ }
+
+ if( code == NA_IEXPORTER_CODE_OK ){
+ writer = NAXML_WRITER( g_object_new( NAXML_WRITER_TYPE, NULL ));
+
+ writer->private->provider = ( NAIExporter * ) instance;
+ writer->private->exported = parms->exported;
+ writer->private->messages = parms->messages;
+ writer->private->fn_str = find_export_format_fn( parms->format );
+ writer->private->buffer = NULL;
+
+ if( !writer->private->fn_str ){
+ code = NA_IEXPORTER_CODE_INVALID_FORMAT;
+
+ } else {
+ code = writer_to_buffer( writer );
+ if( code == NA_IEXPORTER_CODE_OK ){
+ parms->buffer = writer->private->buffer;
+ }
+ }
+
+ g_object_unref( writer );
+ }
+ */
+
+ g_debug( "%s: returning code=%u", thisfn, code );
+ return( code );
+}
+
+/**
+ * nadp_writer_iexporter_export_to_file:
+ * @instance: this #NAIExporter instance.
+ * @parms: a #NAIExporterFileParms structure.
*
- * Internal function: do not call from outside the instance.
+ * Export the specified 'item' to a newly created file.
*/
-gboolean
-nadp_writer_desktop_is_writable( const NAIIOProvider *provider, const NAObjectItem *item )
+guint
+nadp_writer_iexporter_export_to_file( const NAIExporter *instance, NAIExporterFileParms *parms )
{
- static const gchar *thisfn = "nadp_writer_desktop_is_writable";
- gboolean writable;
- NadpDesktopFile *ndf;
- gchar *path;
+ static const gchar *thisfn = "nadp_writer_iexporter_export_to_file";
+ guint code;
- writable = FALSE;
- g_return_val_if_fail( NADP_IS_DESKTOP_PROVIDER( provider ), writable );
- g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), writable );
+ g_debug( "%s: instance=%p, parms=%p", thisfn, ( void * ) instance, ( void * ) parms );
- if( NA_IS_OBJECT_MENU( item )){
- g_warning( "%s: menu are not yet handled by Desktop provider", thisfn );
- return( FALSE );
+ code = NA_IEXPORTER_CODE_OK;
+
+ /*
+ NAXMLWriter *writer;
+ gchar *filename;
+
+ if( !parms->exported || !NA_IS_OBJECT_ITEM( parms->exported )){
+ code = NA_IEXPORTER_CODE_INVALID_ITEM;
}
- ndf = ( NadpDesktopFile * ) na_object_get_provider_data( item );
+ if( code == NA_IEXPORTER_CODE_OK ){
+ writer = NAXML_WRITER( g_object_new( NAXML_WRITER_TYPE, NULL ));
- if( ndf ){
- g_return_val_if_fail( NADP_IS_DESKTOP_FILE( ndf ), writable );
- path = nadp_desktop_file_get_key_file_path( ndf );
- writable = nadp_utils_is_writable_file( path );
- g_free( path );
+ writer->private->provider = ( NAIExporter * ) instance;
+ writer->private->exported = parms->exported;
+ writer->private->messages = parms->messages;
+ writer->private->fn_str = find_export_format_fn( parms->format );
+ writer->private->buffer = NULL;
+
+ if( !writer->private->fn_str ){
+ code = NA_IEXPORTER_CODE_INVALID_FORMAT;
+
+ } else {
+ code = writer_to_buffer( writer );
+
+ if( code == NA_IEXPORTER_CODE_OK ){
+ filename = get_output_fname( parms->exported, parms->folder, parms->format );
+
+ if( filename ){
+ parms->basename = g_path_get_basename( filename );
+ output_xml_to_file(
+ writer->private->buffer, filename, parms->messages ? &writer->private->messages : NULL );
+ g_free( filename );
+ }
+ }
+
+ g_free( writer->private->buffer );
+ }
+
+ g_object_unref( writer );
}
+ */
- return( writable );
+ g_debug( "%s: returning code=%u", thisfn, code );
+ return( code );
}
-#endif
guint
nadp_writer_ifactory_provider_write_start( const NAIFactoryProvider *provider, void *writer_data,
diff --git a/src/io-desktop/nadp-writer.h b/src/io-desktop/nadp-writer.h
index 6dfe1a9..af96b13 100644
--- a/src/io-desktop/nadp-writer.h
+++ b/src/io-desktop/nadp-writer.h
@@ -32,15 +32,19 @@
#define __NADP_WRITER_H__
#include <api/na-iio-provider.h>
+#include <api/na-iexporter.h>
G_BEGIN_DECLS
-gboolean nadp_iio_provider_is_willing_to_write( const NAIIOProvider *provider );
-gboolean nadp_iio_provider_is_able_to_write ( const NAIIOProvider *provider );
+gboolean nadp_iio_provider_is_willing_to_write ( const NAIIOProvider *provider );
+gboolean nadp_iio_provider_is_able_to_write ( const NAIIOProvider *provider );
-guint nadp_iio_provider_write_item ( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages );
-guint nadp_iio_provider_delete_item ( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages );
-guint nadp_iio_provider_duplicate_data( const NAIIOProvider *provider, NAObjectItem *dest, const NAObjectItem *source, GSList **messages );
+guint nadp_iio_provider_write_item ( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages );
+guint nadp_iio_provider_delete_item ( const NAIIOProvider *provider, const NAObjectItem *item, GSList **messages );
+guint nadp_iio_provider_duplicate_data ( const NAIIOProvider *provider, NAObjectItem *dest, const NAObjectItem *source, GSList **messages );
+
+guint nadp_writer_iexporter_export_to_buffer( const NAIExporter *instance, NAIExporterBufferParms *parms );
+guint nadp_writer_iexporter_export_to_file ( const NAIExporter *instance, NAIExporterFileParms *parms );
guint nadp_writer_ifactory_provider_write_start(
const NAIFactoryProvider *provider, void *writer_data, const NAIFactoryObject *object,
diff --git a/src/io-xml/naxml-formats.c b/src/io-xml/naxml-formats.c
index 519fafb..f6ffd1f 100644
--- a/src/io-xml/naxml-formats.c
+++ b/src/io-xml/naxml-formats.c
@@ -49,6 +49,7 @@ NAIExporterFormat naxml_formats[] = {
N_( "This used to be the historical export format.\n" \
"The exported schema file may later be imported via :\n" \
"- Import assistant of the Nautilus Actions Configuration Tool,\n" \
+ "- drag-n-drop into the Nautilus Actions Configuration Tool,\n" \
"- or via the gconftool-2 --import-schema-file command-line tool." ) },
/* GCONF_SCHEMA_V2: the lightest schema still compatible with gconftool-2 --install-schema-file
@@ -62,6 +63,7 @@ NAIExporterFormat naxml_formats[] = {
"Tool versions.\n"
"The exported schema file may later be imported via :\n" \
"- Import assistant of the Nautilus Actions Configuration Tool,\n" \
+ "- drag-n-drop into the Nautilus Actions Configuration Tool,\n" \
"- or via the gconftool-2 --import-schema-file command-line tool." ) },
/* GCONF_ENTRY: not a schema, but a dump of the GConf entry
@@ -76,6 +78,7 @@ NAIExporterFormat naxml_formats[] = {
"though it may still be imported via standard GConf command-line tools.\n" \
"The exported dump file may later be imported via :\n" \
"- Import assistant of a compatible Nautilus Actions Configuration Tool,\n" \
+ "- drag-n-drop into the Nautilus Actions Configuration Tool,\n" \
"- or via the gconftool-2 --load command-line tool." ) },
{ NULL }
diff --git a/src/io-xml/naxml-reader.c b/src/io-xml/naxml-reader.c
index 7367144..060395d 100644
--- a/src/io-xml/naxml-reader.c
+++ b/src/io-xml/naxml-reader.c
@@ -144,7 +144,6 @@ static RootNodeStr st_root_node_str[] = {
{ NULL }
};
-#define ERR_ITEM_ID_ALREADY_EXISTS _( "Item ID %s already exists." )
#define ERR_ITEM_ID_NOT_FOUND _( "Item ID not found." )
#define ERR_MENU_UNWAITED _( "Unwaited key path %s while importing a menu." )
#define ERR_NODE_ALREADY_FOUND _( "Element %s at line %d already found, ignored." )
@@ -167,7 +166,6 @@ static guint reader_parse_xmldoc( NAXMLReader *reader );
static guint iter_on_root_children( NAXMLReader *reader, xmlNode *root );
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 gchar *get_value_from_child_node( xmlNode *node, const gchar *child );
@@ -175,7 +173,6 @@ static gchar *get_value_from_child_child_node( xmlNode *node, const gchar
static gboolean is_profile_path( NAXMLReader *reader, xmlChar *text );
static guint manage_import_mode( NAXMLReader *reader );
static void publish_undealt_nodes( NAXMLReader *reader );
-static void renumber_label_item( NAXMLReader *reader );
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 );
@@ -371,7 +368,7 @@ reader_parse_xmldoc( NAXMLReader *reader )
if( !doc ){
xmlErrorPtr error = xmlGetLastError();
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_XMLDOC_UNABLE_TOPARSE, error->message );
xmlResetError( error );
code = IMPORTER_CODE_NOT_WILLING_TO;
@@ -393,7 +390,7 @@ reader_parse_xmldoc( NAXMLReader *reader )
if( !found ){
gchar *node_list = build_root_node_list();
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_ROOT_UNKNOWN,
( const char * ) root_node->name, root_node->line, node_list );
g_free( node_list );
@@ -441,14 +438,14 @@ iter_on_root_children( NAXMLReader *reader, xmlNode *root )
}
if( strxcmp( iter->name, reader->private->root_node_str->list_key )){
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_UNKNOWN,
( const char * ) iter->name, iter->line, reader->private->root_node_str->list_key );
continue;
}
if( found ){
- add_message( reader, ERR_NODE_ALREADY_FOUND, ( const char * ) iter->name, iter->line );
+ na_core_utils_slist_add_message( &reader->private->parms->messages, ERR_NODE_ALREADY_FOUND, ( const char * ) iter->name, iter->line );
continue;
}
@@ -515,7 +512,7 @@ iter_on_list_children( NAXMLReader *reader, xmlNode *list )
}
if( strxcmp( iter->name, reader->private->root_node_str->element_key )){
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_UNKNOWN,
( const char * ) iter->name, iter->line, reader->private->root_node_str->element_key );
continue;
@@ -546,7 +543,7 @@ iter_on_list_children( NAXMLReader *reader, xmlNode *list )
*/
if( code == IMPORTER_CODE_OK ){
if( !reader->private->item_id || !strlen( reader->private->item_id )){
- add_message( reader, ERR_ITEM_ID_NOT_FOUND );
+ na_core_utils_slist_add_message( &reader->private->parms->messages, ERR_ITEM_ID_NOT_FOUND );
code = IMPORTER_CODE_NO_ITEM_ID;
}
}
@@ -880,7 +877,7 @@ schema_parse_schema_content( NAXMLReader *reader, xmlNode *schema )
if( !str ){
gchar *node_list = build_key_node_list( naxml_schema_key_schema_str );
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_UNKNOWN,
( const char * ) iter->name, iter->line, node_list );
g_free( node_list );
@@ -889,7 +886,7 @@ schema_parse_schema_content( NAXMLReader *reader, xmlNode *schema )
}
if( str->reader_found ){
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_ALREADY_FOUND,
( const char * ) iter->name, iter->line );
reader->private->node_ok = FALSE;
@@ -945,7 +942,7 @@ schema_check_for_id( NAXMLReader *reader, xmlNode *iter )
if( reader->private->item_id ){
if( strcmp( reader->private->item_id, id ) != 0 ){
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_INVALID_ID,
reader->private->item_id, id, iter->line );
reader->private->node_ok = FALSE;
@@ -978,7 +975,7 @@ schema_check_for_type( NAXMLReader *reader, xmlNode *iter )
reader->private->parms->imported = NA_OBJECT_ITEM( na_object_menu_new());
} else {
- add_message( reader, ERR_NODE_UNKNOWN_TYPE, type, iter->line );
+ na_core_utils_slist_add_message( &reader->private->parms->messages, ERR_NODE_UNKNOWN_TYPE, type, iter->line );
reader->private->node_ok = FALSE;
}
@@ -1050,7 +1047,7 @@ dump_parse_entry_content( NAXMLReader *reader, xmlNode *entry )
if( !str ){
gchar *node_list = build_key_node_list( naxml_dump_key_entry_str );
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_UNKNOWN,
( const char * ) iter->name, iter->line, node_list );
g_free( node_list );
@@ -1059,7 +1056,7 @@ dump_parse_entry_content( NAXMLReader *reader, xmlNode *entry )
}
if( str->reader_found ){
- add_message( reader,
+ na_core_utils_slist_add_message( &reader->private->parms->messages,
ERR_NODE_ALREADY_FOUND,
( const char * ) iter->name, iter->line );
reader->private->node_ok = FALSE;
@@ -1102,7 +1099,7 @@ dump_check_for_type( NAXMLReader *reader, xmlNode *key_node )
reader->private->parms->imported = NA_OBJECT_ITEM( na_object_menu_new());
} else {
- add_message( reader, ERR_NODE_UNKNOWN_TYPE, type, key_node->line );
+ na_core_utils_slist_add_message( &reader->private->parms->messages, ERR_NODE_UNKNOWN_TYPE, type, key_node->line );
reader->private->node_ok = FALSE;
}
@@ -1170,19 +1167,6 @@ dump_read_value( NAXMLReader *reader, xmlNode *node, const NADataDef *def )
return( string );
}
-static void
-add_message( NAXMLReader *reader, const gchar *format, ... )
-{
- va_list va;
- gchar *tmp;
-
- va_start( va, format );
- tmp = g_markup_vprintf_escaped( format, va );
- va_end( va );
-
- reader->private->parms->messages = g_slist_append( reader->private->parms->messages, tmp );
-}
-
static gchar *
build_key_node_list( NAXMLKeyStr *strlist )
{
@@ -1285,85 +1269,25 @@ is_profile_path( NAXMLReader *reader, xmlChar *text )
return( is_profile );
}
-/*
- * returns IMPORTER_CODE_OK if we can safely insert the action
- * - the id doesn't already exist
- * - the id already exist, but import mode is renumber
- * - the id already exists, but import mode is override
- *
- * returns IMPORTER_CODE_CANCELLED if user chooses to cancel the operation
- */
static guint
manage_import_mode( NAXMLReader *reader )
{
+ NAIImporterManageImportModeParms parms;
guint code;
- NAObjectItem *exists;
- guint mode;
- gchar *id;
-
- code = IMPORTER_CODE_OK;
- exists = NULL;
- mode = 0;
- if( reader->private->parms->check_fn ){
- exists = ( *reader->private->parms->check_fn )
- ( reader->private->parms->imported, reader->private->parms->check_fn_data );
+ parms.version = 1;
+ parms.imported = reader->private->parms->imported;
+ parms.check_fn = reader->private->parms->check_fn;
+ parms.check_fn_data = reader->private->parms->check_fn_data;
+ parms.ask_fn = reader->private->parms->ask_fn;
+ parms.ask_fn_data = reader->private->parms->ask_fn_data;
+ parms.asked_mode = reader->private->parms->asked_mode;
+ parms.messages = reader->private->parms->messages;
- } else {
- renumber_label_item( reader );
- add_message( reader, "%s", _( "Item was renumbered because the caller did not provide any check function." ));
- reader->private->parms->import_mode = IMPORTER_MODE_RENUMBER;
- }
-
- if( exists ){
- reader->private->parms->exist = TRUE;
+ code = na_iimporter_manage_import_mode( &parms );
- if( reader->private->parms->asked_mode == IMPORTER_MODE_ASK ){
- if( reader->private->parms->ask_fn ){
- mode = ( *reader->private->parms->ask_fn )( reader->private->parms->imported, exists, reader->private->parms->ask_fn_data );
-
- } else {
- renumber_label_item( reader );
- add_message( reader, "%s", _( "Item was renumbered because the caller did not provide any ask user function." ));
- reader->private->parms->import_mode = IMPORTER_MODE_RENUMBER;
- }
-
- } else {
- mode = reader->private->parms->asked_mode;
- }
- }
-
- /* mode is only set if asked mode is ask user and an ask function was provided
- * or if asked mode was not ask user
- */
- if( mode ){
- reader->private->parms->import_mode = mode;
-
- switch( mode ){
- case IMPORTER_MODE_RENUMBER:
- renumber_label_item( reader );
- if( reader->private->parms->asked_mode == IMPORTER_MODE_ASK ){
- add_message( reader, "%s", _( "Item was renumbered due to user request." ));
- }
- break;
-
- case IMPORTER_MODE_OVERRIDE:
- if( reader->private->parms->asked_mode == IMPORTER_MODE_ASK ){
- add_message( reader, "%s", _( "Existing item was overriden due to user request." ));
- }
- break;
-
- case IMPORTER_MODE_NO_IMPORT:
- default:
- id = na_object_get_id( reader->private->parms->imported );
- add_message( reader, ERR_ITEM_ID_ALREADY_EXISTS, id );
- if( reader->private->parms->asked_mode == IMPORTER_MODE_ASK ){
- add_message( reader, "%s", _( "Import was canceled due to user request." ));
- }
- g_free( id );
- code = IMPORTER_CODE_CANCELLED;
- }
- }
+ reader->private->parms->exist = parms.exist;
+ reader->private->parms->import_mode = parms.import_mode;
return( code );
}
@@ -1379,33 +1303,12 @@ publish_undealt_nodes( NAXMLReader *reader )
for( iter = reader->private->nodes ; iter ; iter = iter->next ){
xmlNode *node = ( xmlNode * ) iter->data;
text = xmlNodeGetContent( node );
- add_message( reader, WARN_UNDEALT_NODE, ( const gchar * ) text, node->line );
+ na_core_utils_slist_add_message( &reader->private->parms->messages, WARN_UNDEALT_NODE, ( const gchar * ) text, node->line );
xmlFree( text );
}
}
/*
- * renumber the item, and set a new label
- */
-static void
-renumber_label_item( NAXMLReader *reader )
-{
- gchar *label, *tmp;
-
- na_object_set_new_id( reader->private->parms->imported, NULL );
-
- label = na_object_get_label( reader->private->parms->imported );
-
- /* i18n: the action has been renumbered during import operation */
- tmp = g_strdup_printf( "%s %s", label, _( "(renumbered)" ));
-
- na_object_set_label( reader->private->parms->imported, tmp );
-
- g_free( tmp );
- g_free( label );
-}
-
-/*
* data are reset before first run on nodes for an item
*/
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]