Create import/export assistants
[nautilus-actions.git] / src / nact / nact-gconf-writer.c
blob9ffd256c7d10b0bf1814e4708d589f790ef30b50
1 /*
2 * Nautilus Actions
3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
9 * This Program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
14 * This Program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public
20 * License along with this Library; see the file COPYING. If not,
21 * write to the Free Software Foundation, Inc., 59 Temple Place,
22 * Suite 330, Boston, MA 02111-1307, USA.
24 * Authors:
25 * Frederic Ruaudel <grumz@grumz.net>
26 * Rodrigo Moya <rodrigo@gnome-db.org>
27 * Pierre Wieser <pwieser@trychlos.org>
28 * ... and many others (see AUTHORS)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <libxml/tree.h>
37 #include <common/na-gconf-keys.h>
38 #include <common/na-utils.h>
40 #include "nact-gconf-keys.h"
41 #include "nact-gconf-writer.h"
43 /* private class data
45 struct NactGConfWriterClassPrivate {
48 /* private instance data
50 struct NactGConfWriterPrivate {
51 gboolean dispose_has_run;
52 gchar *uuid;
55 /* instance properties
57 enum {
58 PROP_GCONF_WRITER_UUID = 1
61 #define PROP_GCONF_WRITER_UUID_STR "gconf-writer-uuid"
63 static GObjectClass *st_parent_class = NULL;
65 static GType register_type( void );
66 static void class_init( NactGConfWriterClass *klass );
67 static void instance_init( GTypeInstance *instance, gpointer klass );
68 static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
69 static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
70 static void instance_dispose( GObject *object );
71 static void instance_finalize( GObject *object );
73 static NactGConfWriter *gconf_writer_new( const gchar *uuid );
74 static xmlDocPtr create_xml( NactGConfWriter *writer, NAAction *action );
75 static void create_schema_entry(
76 NactGConfWriter *writer,
77 const gchar *profile_name,
78 const gchar *key,
79 const gchar *value,
80 xmlDocPtr doc,
81 xmlNodePtr list_node,
82 const gchar *type,
83 gboolean is_l10n_value );
85 GType
86 nact_gconf_writer_get_type( void )
88 static GType object_type = 0;
90 if( !object_type ){
91 object_type = register_type();
94 return( object_type );
97 static GType
98 register_type( void )
100 static GTypeInfo info = {
101 sizeof( NactGConfWriterClass ),
102 NULL,
103 NULL,
104 ( GClassInitFunc ) class_init,
105 NULL,
106 NULL,
107 sizeof( NactGConfWriter ),
109 ( GInstanceInitFunc ) instance_init
112 GType type = g_type_register_static( G_TYPE_OBJECT, "NactGConfWriter", &info, 0 );
114 return( type );
117 static void
118 class_init( NactGConfWriterClass *klass )
120 static const gchar *thisfn = "nact_gconf_writer_class_init";
121 g_debug( "%s: klass=%p", thisfn, klass );
123 st_parent_class = g_type_class_peek_parent( klass );
125 GObjectClass *object_class = G_OBJECT_CLASS( klass );
126 object_class->dispose = instance_dispose;
127 object_class->finalize = instance_finalize;
128 object_class->get_property = instance_get_property;
129 object_class->set_property = instance_set_property;
131 GParamSpec *spec;
132 spec = g_param_spec_string(
133 PROP_GCONF_WRITER_UUID_STR,
134 PROP_GCONF_WRITER_UUID_STR,
135 "UUID of the action", "",
136 G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
137 g_object_class_install_property( object_class, PROP_GCONF_WRITER_UUID, spec );
139 klass->private = g_new0( NactGConfWriterClassPrivate, 1 );
142 static void
143 instance_init( GTypeInstance *instance, gpointer klass )
145 static const gchar *thisfn = "nact_gconf_writer_instance_init";
146 g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
148 g_assert( NACT_IS_GCONF_WRITER( instance ));
149 NactGConfWriter *self = NACT_GCONF_WRITER( instance );
151 self->private = g_new0( NactGConfWriterPrivate, 1 );
153 self->private->dispose_has_run = FALSE;
156 static void
157 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
159 g_assert( NACT_IS_GCONF_WRITER( object ));
160 NactGConfWriter *self = NACT_GCONF_WRITER( object );
162 switch( property_id ){
163 case PROP_GCONF_WRITER_UUID:
164 g_value_set_string( value, self->private->uuid );
165 break;
167 default:
168 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
169 break;
173 static void
174 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
176 g_assert( NACT_IS_GCONF_WRITER( object ));
177 NactGConfWriter *self = NACT_GCONF_WRITER( object );
179 switch( property_id ){
180 case PROP_GCONF_WRITER_UUID:
181 g_free( self->private->uuid );
182 self->private->uuid = g_value_dup_string( value );
183 break;
185 default:
186 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
187 break;
191 static void
192 instance_dispose( GObject *object )
194 g_assert( NACT_IS_GCONF_WRITER( object ));
195 NactGConfWriter *self = NACT_GCONF_WRITER( object );
197 if( !self->private->dispose_has_run ){
199 self->private->dispose_has_run = TRUE;
201 /* chain up to the parent class */
202 G_OBJECT_CLASS( st_parent_class )->dispose( object );
206 static void
207 instance_finalize( GObject *object )
209 g_assert( NACT_IS_GCONF_WRITER( object ));
210 NactGConfWriter *self = NACT_GCONF_WRITER( object );
212 g_free( self->private->uuid );
214 g_free( self->private );
216 /* chain call to parent class */
217 if( st_parent_class->finalize ){
218 G_OBJECT_CLASS( st_parent_class )->finalize( object );
222 static NactGConfWriter *
223 gconf_writer_new( const gchar *uuid )
225 return( g_object_new( NACT_GCONF_WRITER_TYPE, PROP_GCONF_WRITER_UUID_STR, uuid, NULL ));
229 * Export the specified action as a GConf schema.
231 * Returns the written filename.
233 gchar *
234 nact_gconf_writer_export( NAAction *action, const gchar *folder, gchar **msg )
236 gchar *uuid = na_action_get_uuid( action );
237 NactGConfWriter *writer = gconf_writer_new( uuid );
238 g_free( uuid );
240 xmlDocPtr doc = create_xml( writer, action );
242 /* generate the filename name and save the xml document into it */
243 gchar *filename = g_strdup_printf( "%s/action-%s.xml", folder, writer->private->uuid );
245 if( xmlSaveFormatFileEnc( filename, doc, "UTF-8", 1 ) == -1 ){
246 g_free( filename );
247 filename = NULL;
249 xmlFreeDoc (doc);
250 xmlCleanupParser();
252 g_object_unref( writer );
254 return( filename );
257 static xmlDocPtr
258 create_xml( NactGConfWriter *writer, NAAction *action )
260 xmlDocPtr doc = xmlNewDoc( BAD_CAST( "1.0" ));
261 xmlNodePtr root_node = xmlNewNode( NULL, BAD_CAST( NACT_GCONF_XML_ROOT ));
262 xmlDocSetRootElement( doc, root_node );
263 xmlNodePtr list_node = xmlNewChild( root_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_LIST ), NULL );
265 /* version */
266 gchar *version = na_action_get_version( action );
267 create_schema_entry( writer, NULL, ACTION_VERSION_ENTRY, version, doc, list_node, "string", FALSE );
268 g_free( version );
270 /* label */
271 gchar *label = na_action_get_label( action );
272 create_schema_entry( writer, NULL, ACTION_LABEL_ENTRY, label, doc, list_node, "string", TRUE );
273 g_free( label );
275 /* tooltip */
276 gchar *tooltip = na_action_get_tooltip( action );
277 create_schema_entry( writer, NULL, ACTION_TOOLTIP_ENTRY, tooltip, doc, list_node, "string", TRUE );
278 g_free( tooltip );
280 /* icon name */
281 gchar *icon = na_action_get_icon( action );
282 create_schema_entry( writer, NULL, ACTION_ICON_ENTRY, icon, doc, list_node, "string", FALSE );
283 g_free( icon );
285 GSList *profiles = na_action_get_profiles( action );
286 GSList *ip;
288 for( ip = profiles ; ip ; ip = ip->next ){
290 NAActionProfile *profile = NA_ACTION_PROFILE( ip->data );
291 gchar *profile_dir = na_action_profile_get_name( profile );
293 /* profile label */
294 gchar *profile_label = na_action_profile_get_label( profile );
295 create_schema_entry( writer, profile_dir, ACTION_PROFILE_LABEL_ENTRY, profile_label, doc, list_node, "string", TRUE );
296 g_free( profile_label );
298 /* path */
299 gchar *path = na_action_profile_get_path( profile );
300 create_schema_entry( writer, profile_dir, ACTION_PATH_ENTRY, path, doc, list_node, "string", FALSE );
301 g_free( path );
303 /* parameters */
304 gchar *parameters = na_action_profile_get_parameters( profile );
305 create_schema_entry( writer, profile_dir, ACTION_PARAMETERS_ENTRY, parameters, doc, list_node, "string", FALSE );
306 g_free( parameters );
308 /* basenames */
309 GSList *basenames = na_action_profile_get_basenames( profile );
310 gchar *text = na_utils_gslist_to_schema( basenames );
311 create_schema_entry( writer, profile_dir, ACTION_BASENAMES_ENTRY, text, doc, list_node, "list", FALSE );
312 g_free( text );
313 na_utils_free_string_list( basenames );
315 /* match_case */
316 gboolean match = na_action_profile_get_matchcase( profile );
317 text = na_utils_boolean_to_schema( match );
318 create_schema_entry( writer, profile_dir, ACTION_MATCHCASE_ENTRY, text, doc, list_node, "bool", FALSE );
319 g_free( text );
321 /* mimetypes */
322 GSList *mimetypes = na_action_profile_get_mimetypes( profile );
323 text = na_utils_gslist_to_schema( mimetypes );
324 create_schema_entry( writer, profile_dir, ACTION_MIMETYPES_ENTRY, text, doc, list_node, "list", FALSE );
325 g_free( text );
326 na_utils_free_string_list( mimetypes );
328 /* is_file */
329 gboolean isfile = na_action_profile_get_is_file( profile );
330 text = na_utils_boolean_to_schema( isfile );
331 create_schema_entry( writer, profile_dir, ACTION_ISFILE_ENTRY, text, doc, list_node, "bool", FALSE );
332 g_free( text );
334 /* is_dir */
335 gboolean isdir = na_action_profile_get_is_dir( profile );
336 text = na_utils_boolean_to_schema( isdir );
337 create_schema_entry( writer, profile_dir, ACTION_ISDIR_ENTRY, text, doc, list_node, "bool", FALSE );
338 g_free( text );
340 /* accept-multiple-files */
341 gboolean mutiple = na_action_profile_get_multiple( profile );
342 text = na_utils_boolean_to_schema( mutiple );
343 create_schema_entry( writer, profile_dir, ACTION_MULTIPLE_ENTRY, text, doc, list_node, "bool", FALSE );
344 g_free( text );
346 /* schemes */
347 GSList *schemes = na_action_profile_get_schemes( profile );
348 text = na_utils_gslist_to_schema( schemes );
349 create_schema_entry( writer, profile_dir, ACTION_SCHEMES_ENTRY, text, doc, list_node, "list", FALSE );
350 g_free( text );
351 na_utils_free_string_list( schemes );
353 g_free( profile_dir );
356 return( doc );
359 static void
360 create_schema_entry( NactGConfWriter *writer,
361 const gchar *profile_name, const gchar *key, const gchar *value,
362 xmlDocPtr doc, xmlNodePtr list_node, const gchar *type, gboolean is_l10n_value )
364 gchar *path = NULL;
365 if( profile_name ){
366 path = g_build_path( "/", NA_GCONF_CONFIG_PATH, writer->private->uuid, profile_name, key, NULL );
367 } else {
368 path = g_build_path( "/", NA_GCONF_CONFIG_PATH, writer->private->uuid, key, NULL );
371 xmlNodePtr schema_node = xmlNewChild( list_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_ENTRY ), NULL );
373 /*xmlChar *content = BAD_CAST( g_build_path( "/", NACT_GCONF_SCHEMA_PREFIX, path, NULL ));
374 xmlNewChild( schema_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_KEY ), content );
375 xmlFree( content );*/
377 xmlNewChild( schema_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_APPLYTO ), BAD_CAST( path ));
379 /*xmlNewChild( schema_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_TYPE ), BAD_CAST( type ));*/
381 /*if( !g_ascii_strcasecmp( type, "list" )){
382 xmlNewChild( schema_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_LIST_TYPE ), BAD_CAST( "string" ));
385 /* if the default value must be localized, put it in the <locale> element
387 xmlNodePtr value_root_node = schema_node;
388 if( is_l10n_value ){
389 xmlNodePtr locale_node = xmlNewChild( schema_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_LOCALE ), NULL );
390 xmlNewProp( locale_node, BAD_CAST( "name" ), BAD_CAST( "C" ));
391 value_root_node = locale_node;
394 /* encode special chars <, >, &, ...
396 xmlChar *encoded_content = xmlEncodeSpecialChars( doc, BAD_CAST( value ));
397 xmlNewChild( value_root_node, NULL, BAD_CAST( NACT_GCONF_XML_SCHEMA_DFT ), encoded_content );
398 xmlFree( encoded_content );
400 g_free( path );