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.
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)
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"
45 struct NactGConfWriterClassPrivate
{
48 /* private instance data
50 struct NactGConfWriterPrivate
{
51 gboolean dispose_has_run
;
55 /* instance properties
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
,
83 gboolean is_l10n_value
);
86 nact_gconf_writer_get_type( void )
88 static GType object_type
= 0;
91 object_type
= register_type();
94 return( object_type
);
100 static GTypeInfo info
= {
101 sizeof( NactGConfWriterClass
),
104 ( GClassInitFunc
) class_init
,
107 sizeof( NactGConfWriter
),
109 ( GInstanceInitFunc
) instance_init
112 GType type
= g_type_register_static( G_TYPE_OBJECT
, "NactGConfWriter", &info
, 0 );
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
;
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 );
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
;
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
);
168 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
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
);
186 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
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
);
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.
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
);
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 ){
252 g_object_unref( writer
);
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
);
266 gchar
*version
= na_action_get_version( action
);
267 create_schema_entry( writer
, NULL
, ACTION_VERSION_ENTRY
, version
, doc
, list_node
, "string", FALSE
);
271 gchar
*label
= na_action_get_label( action
);
272 create_schema_entry( writer
, NULL
, ACTION_LABEL_ENTRY
, label
, doc
, list_node
, "string", TRUE
);
276 gchar
*tooltip
= na_action_get_tooltip( action
);
277 create_schema_entry( writer
, NULL
, ACTION_TOOLTIP_ENTRY
, tooltip
, doc
, list_node
, "string", TRUE
);
281 gchar
*icon
= na_action_get_icon( action
);
282 create_schema_entry( writer
, NULL
, ACTION_ICON_ENTRY
, icon
, doc
, list_node
, "string", FALSE
);
285 GSList
*profiles
= na_action_get_profiles( action
);
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
);
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
);
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
);
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
);
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
);
313 na_utils_free_string_list( basenames
);
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
);
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
);
326 na_utils_free_string_list( mimetypes
);
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
);
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
);
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
);
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
);
351 na_utils_free_string_list( schemes
);
353 g_free( profile_dir
);
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
)
366 path
= g_build_path( "/", NA_GCONF_CONFIG_PATH
, writer
->private->uuid
, profile_name
, key
, NULL
);
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
;
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
);