Fix string errors reported by Christian Kirbach
[nautilus-actions.git] / src / core / na-io-provider.c
blob52fe556e1d829a7b82d1f4847a5486c4d0afde27
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, 2010, 2011 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 <glib/gi18n.h>
36 #include <string.h>
38 #include <api/na-iio-provider.h>
39 #include <api/na-object-api.h>
40 #include <api/na-core-utils.h>
42 #include "na-iprefs.h"
43 #include "na-io-provider.h"
45 /* private class data
47 struct _NAIOProviderClassPrivate {
48 void *empty; /* so that gcc -pedantic is happy */
51 /* private instance data
53 struct _NAIOProviderPrivate {
54 gboolean dispose_has_run;
55 gchar *id;
56 NAIIOProvider *provider;
57 gulong item_changed_handler;
60 /* NAIOProvider properties
62 enum {
63 IO_PROVIDER_PROP_ID_ID = 1,
66 #define IO_PROVIDER_PROP_ID "na-io-provider-prop-id"
68 static GObjectClass *st_parent_class = NULL;
69 static GList *st_io_providers = NULL;
71 static GType register_type( void );
72 static void class_init( NAIOProviderClass *klass );
73 static void instance_init( GTypeInstance *instance, gpointer klass );
74 static void instance_constructed( GObject *object );
75 static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
76 static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
77 static void instance_dispose( GObject *object );
78 static void instance_finalize( GObject *object );
80 #if 0
81 static void dump( const NAIOProvider *provider );
82 static void dump_providers_list( GList *providers );
83 #endif
84 static NAIOProvider *io_provider_new( const NAPivot *pivot, NAIIOProvider *module, const gchar *id );
85 static GList *io_providers_list_add_from_plugins( const NAPivot *pivot, GList *list );
86 static GList *io_providers_list_add_from_prefs( const NAPivot *pivot, GList *objects_list );
87 static GList *io_providers_list_add_from_write_order( const NAPivot *pivot, GList *objects_list );
88 static GList *io_providers_list_append_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id );
89 static void io_providers_list_set_module( const NAPivot *pivot, NAIOProvider *provider_object, NAIIOProvider *provider_module );
90 static gboolean is_really_writable( const NAIOProvider *provider, const NAPivot *pivot );
91 static GList *load_items_filter_unwanted_items( const NAPivot *pivot, GList *merged, guint loadable_set );
92 static GList *load_items_filter_unwanted_items_rec( GList *merged, guint loadable_set );
93 static GList *load_items_get_merged_list( const NAPivot *pivot, guint loadable_set, GSList **messages );
94 static GList *load_items_hierarchy_build( GList **tree, GSList *level_zero, gboolean list_if_empty, NAObjectItem *parent );
95 static GList *load_items_hierarchy_sort( const NAPivot *pivot, GList *tree, GCompareFunc fn );
96 static gint peek_item_by_id_compare( const NAObject *obj, const gchar *id );
97 static NAIOProvider *peek_provider_by_id( const GList *providers, const gchar *id );
99 GType
100 na_io_provider_get_type( void )
102 static GType object_type = 0;
104 if( !object_type ){
105 object_type = register_type();
108 return( object_type );
111 static GType
112 register_type( void )
114 static const gchar *thisfn = "na_io_provider_register_type";
115 GType type;
117 static GTypeInfo info = {
118 sizeof( NAIOProviderClass ),
119 ( GBaseInitFunc ) NULL,
120 ( GBaseFinalizeFunc ) NULL,
121 ( GClassInitFunc ) class_init,
122 NULL,
123 NULL,
124 sizeof( NAIOProvider ),
126 ( GInstanceInitFunc ) instance_init
129 g_debug( "%s", thisfn );
131 type = g_type_register_static( G_TYPE_OBJECT, "NAIOProvider", &info, 0 );
133 return( type );
136 static void
137 class_init( NAIOProviderClass *klass )
139 static const gchar *thisfn = "na_io_provider_class_init";
140 GObjectClass *object_class;
141 GParamSpec *spec;
143 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
145 st_parent_class = g_type_class_peek_parent( klass );
147 object_class = G_OBJECT_CLASS( klass );
148 object_class->constructed = instance_constructed;
149 object_class->set_property = instance_set_property;
150 object_class->get_property = instance_get_property;
151 object_class->dispose = instance_dispose;
152 object_class->finalize = instance_finalize;
154 spec = g_param_spec_string(
155 IO_PROVIDER_PROP_ID,
156 "I/O Provider Id",
157 "Internal identifier of the I/O provider (e.g. 'na-gconf')", "",
158 G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
159 g_object_class_install_property( object_class, IO_PROVIDER_PROP_ID_ID, spec );
161 klass->private = g_new0( NAIOProviderClassPrivate, 1 );
164 static void
165 instance_init( GTypeInstance *instance, gpointer klass )
167 static const gchar *thisfn = "na_io_provider_instance_init";
168 NAIOProvider *self;
170 g_return_if_fail( NA_IS_IO_PROVIDER( instance ));
172 g_debug( "%s: instance=%p (%s), klass=%p",
173 thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
175 self = NA_IO_PROVIDER( instance );
177 self->private = g_new0( NAIOProviderPrivate, 1 );
179 self->private->dispose_has_run = FALSE;
180 self->private->id = NULL;
181 self->private->provider = NULL;
182 self->private->item_changed_handler = 0;
185 static void
186 instance_constructed( GObject *object )
188 static const gchar *thisfn = "na_io_provider_instance_constructed";
189 NAIOProvider *self;
191 g_return_if_fail( NA_IS_IO_PROVIDER( object ));
193 self = NA_IO_PROVIDER( object );
195 if( !self->private->dispose_has_run ){
197 g_debug( "%s: object=%p, id=%s", thisfn, ( void * ) object, self->private->id );
199 /* chain up to the parent class */
200 if( G_OBJECT_CLASS( st_parent_class )->constructed ){
201 G_OBJECT_CLASS( st_parent_class )->constructed( object );
206 static void
207 instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
209 NAIOProvider *self;
211 g_return_if_fail( NA_IS_IO_PROVIDER( object ));
212 self = NA_IO_PROVIDER( object );
214 if( !self->private->dispose_has_run ){
216 switch( property_id ){
217 case IO_PROVIDER_PROP_ID_ID:
218 g_value_set_string( value, self->private->id );
219 break;
221 default:
222 G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
223 break;
228 static void
229 instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
231 NAIOProvider *self;
233 g_return_if_fail( NA_IS_IO_PROVIDER( object ));
234 self = NA_IO_PROVIDER( object );
236 if( !self->private->dispose_has_run ){
238 switch( property_id ){
239 case IO_PROVIDER_PROP_ID_ID:
240 g_free( self->private->id );
241 self->private->id = g_value_dup_string( value );
242 break;
247 static void
248 instance_dispose( GObject *object )
250 static const gchar *thisfn = "na_io_provider_instance_dispose";
251 NAIOProvider *self;
253 g_return_if_fail( NA_IS_IO_PROVIDER( object ));
255 self = NA_IO_PROVIDER( object );
257 if( !self->private->dispose_has_run ){
259 g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
261 self->private->dispose_has_run = TRUE;
263 if( self->private->provider ){
264 if( g_signal_handler_is_connected( self->private->provider, self->private->item_changed_handler )){
265 g_signal_handler_disconnect( self->private->provider, self->private->item_changed_handler );
267 g_object_unref( self->private->provider );
270 /* chain up to the parent class */
271 if( G_OBJECT_CLASS( st_parent_class )->dispose ){
272 G_OBJECT_CLASS( st_parent_class )->dispose( object );
277 static void
278 instance_finalize( GObject *object )
280 static const gchar *thisfn = "na_io_provider_instance_finalize";
281 NAIOProvider *self;
283 g_return_if_fail( NA_IS_IO_PROVIDER( object ));
285 g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
287 self = NA_IO_PROVIDER( object );
289 g_free( self->private->id );
291 g_free( self->private );
293 /* chain call to parent class */
294 if( G_OBJECT_CLASS( st_parent_class )->finalize ){
295 G_OBJECT_CLASS( st_parent_class )->finalize( object );
300 * na_io_provider_find_writable_io_provider:
301 * @pivot: the #NAPivot instance.
303 * Returns: the first willing and able to write I/O provider, or NULL.
305 * The returned provider is owned by NAIOProvider class, and should not
306 * be released by the caller.
308 NAIOProvider *
309 na_io_provider_find_writable_io_provider( const NAPivot *pivot )
311 const GList *providers;
312 const GList *ip;
313 NAIOProvider *provider;
315 providers = na_io_provider_get_io_providers_list( pivot );
316 provider = NULL;
318 for( ip = providers ; ip && !provider ; ip = ip->next ){
319 if( is_really_writable( NA_IO_PROVIDER( ip->data ), pivot )){
320 provider = NA_IO_PROVIDER( ip->data );
324 return( provider );
328 * na_io_provider_find_io_provider_by_id:
329 * @pivot: the #NAPivot instance.
330 * @id: the identifier of the searched I/O provider.
332 * Returns: the I/O provider, or NULL.
334 * The returned provider is owned by NAIOProvider class, and should not
335 * be released by the caller.
337 NAIOProvider *
338 na_io_provider_find_io_provider_by_id( const NAPivot *pivot, const gchar *id )
340 const GList *providers;
341 const GList *ip;
342 NAIOProvider *provider;
343 NAIOProvider *found;
345 providers = na_io_provider_get_io_providers_list( pivot );
346 found = NULL;
348 for( ip = providers ; ip && !found ; ip = ip->next ){
349 provider = NA_IO_PROVIDER( ip->data );
350 if( !strcmp( provider->private->id, id )){
351 found = provider;
355 return( found );
359 * na_io_provider_get_io_providers_list:
360 * @pivot: the current #NAPivot instance.
362 * Build (if not already done) the ordered list of currently avialable
363 * NAIOProvider objects.
365 * A NAIOProvider object may be created:
366 * - either because we have loaded a plugin which claims to implement the
367 * NAIIOProvider interface;
368 * - or because an i/o provider identifier has been found in preferences.
370 * The objects in this list must be in write order:
371 * - when loading items, items are ordered depending of menus items list
372 * and of level zero defined order;
373 * - when writing a new item, there is a 'writable-order' preference.
375 * Returns: the list of I/O providers.
377 * The returned list is owned by #NAIOProvider class, and should not be
378 * released by the caller.
380 const GList *
381 na_io_provider_get_io_providers_list( const NAPivot *pivot )
383 g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
385 if( !st_io_providers ){
386 st_io_providers = io_providers_list_add_from_write_order( pivot, NULL );
387 st_io_providers = io_providers_list_add_from_plugins( pivot, st_io_providers );
388 st_io_providers = io_providers_list_add_from_prefs( pivot, st_io_providers );
391 return( st_io_providers );
395 * na_io_provider_unref_io_providers_list:
397 * Called by on #NAPivot dispose(), free here resources allocated to
398 * the I/O providers.
400 void
401 na_io_provider_unref_io_providers_list( void )
403 g_list_foreach( st_io_providers, ( GFunc ) g_object_unref, NULL );
404 g_list_free( st_io_providers );
405 st_io_providers = NULL;
409 * na_io_provider_get_id:
410 * @provider: this #NAIOProvider.
412 * Returns: the internal id of this #NAIIOProvider, as a newly
413 * allocated string which should be g_free() by the caller.
415 gchar *
416 na_io_provider_get_id( const NAIOProvider *provider )
418 gchar *id;
420 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), NULL );
422 id = NULL;
424 if( !provider->private->dispose_has_run ){
426 id = g_strdup( provider->private->id );
429 return( id );
433 * na_io_provider_get_name:
434 * @provider: this #NAIOProvider.
436 * Returns: the displayable name of this #NAIIOProvider, as a newly
437 * allocated string which should be g_free() by the caller.
439 * This function makes sure to never return %NULL. An empty string
440 * may be returned if the NAIIOProvider is not present at runtime,
441 * or does not implement the needed interface, or returns itself %NULL
442 * or an empty string.
444 gchar *
445 na_io_provider_get_name( const NAIOProvider *provider )
447 static const gchar *thisfn = "na_io_provider_get_name";
448 gchar *name;
450 name = g_strdup( "" );
452 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), name );
454 if( !provider->private->dispose_has_run ){
455 if( na_io_provider_is_available( provider ) &&
456 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->get_name ){
458 g_free( name );
459 name = NULL;
460 name = NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->get_name( provider->private->provider );
461 if( !name ){
462 g_warning( "%s: NAIIOProvider %s get_name() interface returns NULL", thisfn, provider->private->id );
463 name = g_strdup( "" );
466 } else {
467 g_warning( "%s: NAIIOProvider %s doesn't support get_name() interface", thisfn, provider->private->id );
471 return( name );
475 * na_io_provider_is_available:
476 * @provider: the #NAIOProvider object.
478 * Returns: %TRUE if the corresponding #NAIIOProvider module is available
479 * at runtime, %FALSE else.
481 gboolean
482 na_io_provider_is_available( const NAIOProvider *provider )
484 gboolean is_available;
486 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
488 is_available = FALSE;
490 if( !provider->private->dispose_has_run ){
492 is_available = ( provider->private->provider && NA_IS_IIO_PROVIDER( provider->private->provider ));
495 return( is_available );
499 * na_io_provider_is_conf_readable:
500 * @provider: this #NAIOProvider.
501 * @pivot: the #NAPivot application object.
502 * @mandatory: a pointer to a boolean which will be set to %TRUE if the
503 * preference is mandatory; may be %NULL.
505 * Returns: %TRUE is this I/O provider should be read at startup, and so
506 * may participate to the global list of menus and actions, %FALSE else.
508 * This is a configuration property, which defaults to %TRUE.
510 * Whether it is editable by the user or not depends on:
511 * - whether the whole configuration has been locked down by an admin;
512 * - whether this flag has been set as mandatory by an admin.
514 gboolean
515 na_io_provider_is_conf_readable( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory )
517 gboolean readable;
518 gchar *group;
520 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
521 g_return_val_if_fail( NA_IS_PIVOT( pivot ), FALSE );
523 readable = FALSE;
525 if( !provider->private->dispose_has_run ){
527 group = g_strdup_printf( "%s %s", NA_IPREFS_IO_PROVIDER_GROUP, provider->private->id );
528 readable = na_settings_get_boolean_ex(
529 na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_READABLE, NULL, mandatory );
530 g_free( group );
533 return( readable );
537 * na_io_provider_is_able_to_write:
538 * @provider: this #NAIOProvider.
540 * Whether the NAIIOProvider is able to write is a runtime condition.
542 * Returns: %TRUE is this I/O provider is able to write.
544 gboolean
545 na_io_provider_is_able_to_write( const NAIOProvider *provider )
547 gboolean is_able_to;
549 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
551 is_able_to = FALSE;
553 if( !provider->private->dispose_has_run ){
555 if( provider->private->provider ){
557 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), FALSE );
559 if( NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->is_able_to_write ){
561 is_able_to = NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->is_able_to_write( provider->private->provider );
566 return( is_able_to );
570 * na_io_provider_is_conf_writable:
571 * @provider: this #NAIOProvider.
572 * @pivot: the #NAPivot application object.
573 * @mandatory: a pointer to a boolean which will be set to %TRUE if the
574 * preference is mandatory; may be %NULL.
576 * Returns: %TRUE is this I/O provider is candidate to be edited.
578 * This is a configuration property, which defaults to %TRUE.
580 * Whether it is editable by the user or not depends on:
581 * - whether the whole configuration has been locked down by an admin;
582 * - whether this flag has been set as mandatory by an admin.
584 * This property does not say that an item can actually be written by this
585 * NAIIOProvider module. See also is_willing_to() and is_able_to().
587 gboolean
588 na_io_provider_is_conf_writable( const NAIOProvider *provider, const NAPivot *pivot, gboolean *mandatory )
590 gboolean is_writable;
591 gchar *group;
593 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
594 g_return_val_if_fail( NA_IS_PIVOT( pivot ), FALSE );
596 is_writable = FALSE;
598 if( !provider->private->dispose_has_run ){
600 group = g_strdup_printf( "%s %s", NA_IPREFS_IO_PROVIDER_GROUP, provider->private->id );
601 is_writable = na_settings_get_boolean_ex(
602 na_pivot_get_settings( pivot ), group, NA_IPREFS_IO_PROVIDER_WRITABLE, NULL, mandatory );
603 g_free( group );
606 return( is_writable );
610 * na_io_provider_is_willing_to_write:
611 * @provider: this #NAIOProvider.
613 * The 'willing_to_write' property is an intrinsic attribute of the NAIIOProvider
614 * module. It depends on:
615 * - whether it provides a 'willing_to_write' api which returns %TRUE (defaults
616 * to %FALSE)
617 * - whether it has the needed API (is_able_to_write, write_item, delete_item)
619 * Returns: %TRUE is this I/O provider is willing to write.
621 gboolean
622 na_io_provider_is_willing_to_write( const NAIOProvider *provider )
624 gboolean is_willing_to;
626 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
628 is_willing_to = FALSE;
630 if( !provider->private->dispose_has_run &&
631 provider->private->provider ){
633 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), FALSE );
635 if( NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->is_willing_to_write &&
636 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->is_willing_to_write( provider->private->provider )){
638 is_willing_to =
639 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->is_able_to_write &&
640 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->write_item &&
641 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->delete_item;
645 return( is_willing_to );
649 * na_io_provider_load_items:
650 * @pivot: the #NAPivot object which owns the list of registered I/O
651 * storage providers.
652 * @loadable_set: the set of loadable items
653 * (cf. NAPivotLoadableSet enumeration defined in core/na-pivot.h).
654 * @messages: error messages.
656 * Loads the tree from I/O storage subsystems.
658 * Returns: a #GList of newly allocated objects as a hierarchical tree
659 * in display order. This tree contains #NAObjectMenu menus, along with
660 * #NAObjectAction actions and their #NAObjectProfile profiles.
662 * The returned list should be na_object_unref_items() by the caller.
664 GList *
665 na_io_provider_load_items( const NAPivot *pivot, guint loadable_set, GSList **messages )
667 static const gchar *thisfn = "na_io_provider_load_items";
668 GList *flat, *hierarchy, *filtered;
669 GSList *level_zero;
670 guint order_mode;
672 g_return_val_if_fail( NA_IS_PIVOT( pivot ), NULL );
674 g_debug( "%s: pivot=%p, loadable_set=%d, messages=%p",
675 thisfn, ( void * ) pivot, loadable_set, ( void * ) messages );
677 /* get the global flat items list, as a merge of the list provided
678 * each available and readable i/o provider
680 flat = load_items_get_merged_list( pivot, loadable_set, messages );
682 /* build the items hierarchy
684 level_zero = na_settings_get_string_list(
685 na_pivot_get_settings( pivot ), NA_IPREFS_ITEMS_LEVEL_ZERO_ORDER, NULL, NULL );
687 hierarchy = load_items_hierarchy_build( &flat, level_zero, TRUE, NULL );
689 /* items that stay left in the global flat list are simply appended
690 * to the built hierarchy, and level zero is updated accordingly
692 if( flat ){
693 g_debug( "%s: %d items left appended to the hierarchy", thisfn, g_list_length( flat ));
694 hierarchy = g_list_concat( hierarchy, flat );
697 if( flat || !level_zero || !g_slist_length( level_zero )){
698 g_debug( "%s: rewriting level-zero", thisfn );
699 if( !na_iprefs_write_level_zero( pivot, hierarchy, messages )){
700 g_warning( "%s: unable to update level-zero", thisfn );
704 na_core_utils_slist_free( level_zero );
706 /* sort the hierarchy according to preferences
708 order_mode = na_iprefs_get_order_mode( pivot, NULL );
709 switch( order_mode ){
710 case IPREFS_ORDER_ALPHA_ASCENDING:
711 hierarchy = load_items_hierarchy_sort( pivot, hierarchy, ( GCompareFunc ) na_object_id_sort_alpha_asc );
712 break;
714 case IPREFS_ORDER_ALPHA_DESCENDING:
715 hierarchy = load_items_hierarchy_sort( pivot, hierarchy, ( GCompareFunc ) na_object_id_sort_alpha_desc );
716 break;
718 case IPREFS_ORDER_MANUAL:
719 default:
720 break;
723 /* check status here...
725 filtered = load_items_filter_unwanted_items( pivot, hierarchy, loadable_set );
726 g_list_free( hierarchy );
728 g_debug( "%s: tree after filtering and reordering (if any)", thisfn );
729 na_object_dump_tree( filtered );
730 g_debug( "%s: end of tree", thisfn );
732 return( filtered );
735 #if 0
736 static void
737 dump( const NAIOProvider *provider )
739 static const gchar *thisfn = "na_io_provider_dump";
741 g_debug( "%s: id=%s", thisfn, provider->private->id );
742 g_debug( "%s: provider=%p", thisfn, ( void * ) provider->private->provider );
743 g_debug( "%s: item_changed_handler=%lu", thisfn, provider->private->item_changed_handler );
746 static void
747 dump_providers_list( GList *providers )
749 static const gchar *thisfn = "na_io_provider_dump_providers_list";
750 GList *ip;
752 g_debug( "%s: providers=%p (count=%d)", thisfn, ( void * ) providers, g_list_length( providers ));
754 for( ip = providers ; ip ; ip = ip->next ){
755 dump( NA_IO_PROVIDER( ip->data ));
758 #endif
761 * allocate a new NAIOProvider object for the specified module and id
763 * id is mandatory here
764 * module may be NULL
766 static NAIOProvider *
767 io_provider_new( const NAPivot *pivot, NAIIOProvider *module, const gchar *id )
769 NAIOProvider *object;
771 g_return_val_if_fail( id && strlen( id ), NULL );
773 object = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, id, NULL );
775 if( module ){
776 io_providers_list_set_module( pivot, object, module );
779 return( object );
783 * add to the list a NAIOProvider object for each loaded plugin which claim
784 * to implement the NAIIOProvider interface
786 static GList *
787 io_providers_list_add_from_plugins( const NAPivot *pivot, GList *objects_list )
789 static const gchar *thisfn = "na_io_provider_io_providers_list_add_from_plugins";
790 GList *merged;
791 GList *modules_list, *im;
792 gchar *id;
793 NAIIOProvider *provider_module;
795 merged = objects_list;
796 modules_list = na_pivot_get_providers( pivot, NA_IIO_PROVIDER_TYPE );
798 for( im = modules_list ; im ; im = im->next ){
800 id = NULL;
801 provider_module = NA_IIO_PROVIDER( im->data );
803 if( NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->get_id ){
804 id = NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->get_id( provider_module );
805 if( !id || !strlen( id )){
806 g_warning( "%s: NAIIOProvider %p get_id() interface returns null or empty id", thisfn, ( void * ) im->data );
807 g_free( id );
808 id = NULL;
810 } else {
811 g_warning( "%s: NAIIOProvider %p doesn't support get_id() interface", thisfn, ( void * ) im->data );
814 if( id ){
815 merged = io_providers_list_append_object( pivot, merged, provider_module, id );
816 g_free( id );
820 na_pivot_free_providers( modules_list );
822 return( merged );
826 * add to the list NAIOProvider objects for the identifiers we may find
827 * in preferences without having found the plugin itself
829 * preferences may come from the 'write-order' list, or from the io-providers
830 * status.
832 static GList *
833 io_providers_list_add_from_prefs( const NAPivot *pivot, GList *objects_list )
835 GList *merged;
836 const gchar *id;
837 GSList *io_providers, *it;
839 merged = objects_list;
840 io_providers = na_iprefs_get_io_providers( pivot );
842 for( it = io_providers ; it ; it = it->next ){
843 id = ( const gchar * ) it->data;
844 merged = io_providers_list_append_object( pivot, merged, NULL, id );
847 na_core_utils_slist_free( io_providers );
849 return( merged );
853 * adding from write-order means we only create NAIOProvider objects
854 * without having any pointer to the underlying NAIIOProvider (if it exists)
856 static GList *
857 io_providers_list_add_from_write_order( const NAPivot *pivot, GList *objects_list )
859 GList *merged;
860 NASettings *settings;
861 GSList *io_providers, *it;
862 const gchar *id;
864 merged = objects_list;
865 settings = na_pivot_get_settings( pivot );
866 io_providers = na_settings_get_string_list( settings, NA_IPREFS_IO_PROVIDERS_WRITE_ORDER, NULL, NULL );
868 for( it = io_providers ; it ; it = it->next ){
869 id = ( const gchar * ) it->data;
870 merged = io_providers_list_append_object( pivot, merged, NULL, id );
873 na_core_utils_slist_free( io_providers );
875 return( merged );
879 * add to the list a NAIOProvider object for the specified module and id
880 * if it does not have been already registered
882 static GList *
883 io_providers_list_append_object( const NAPivot *pivot, GList *list, NAIIOProvider *module, const gchar *id )
885 GList *merged;
886 NAIOProvider *object;
888 merged = list;
889 object = peek_provider_by_id( list, id );
891 if( !object ){
892 object = io_provider_new( pivot, module, id );
893 merged = g_list_append( merged, object );
895 } else if( module && !object->private->provider ){
896 io_providers_list_set_module( pivot, object, module );
899 return( merged );
903 * when a IIOProvider plugin is associated with the NAIOProvider object,
904 * we connect the NAPivot callback to the 'item-changed' signal
906 static void
907 io_providers_list_set_module( const NAPivot *pivot, NAIOProvider *provider_object, NAIIOProvider *provider_module )
909 provider_object->private->provider = g_object_ref( provider_module );
910 provider_object->private->item_changed_handler =
911 g_signal_connect(
912 provider_module, IO_PROVIDER_SIGNAL_ITEM_CHANGED,
913 ( GCallback ) na_pivot_on_item_changed_handler, ( gpointer ) pivot );
917 * is_really_writable:
918 * @provider: the #NAIOProvider provider.
919 * @pivot: the #NAPivot instance.
921 * Returns: %TRUE if the @provider will be able to write proposed items,
922 * %FALSE else.
924 * Note thay almost all checked conditions are themselves subject to race
925 * conditions. Unless that (!), the caller can be (almost) sure that writings
926 * will be possible when this function returns %TRUE.
928 static gboolean
929 is_really_writable( const NAIOProvider *provider, const NAPivot *pivot )
932 return( na_io_provider_is_willing_to_write( provider ) &&
933 na_io_provider_is_able_to_write( provider ) &&
934 na_io_provider_is_conf_writable( provider, pivot, NULL ) &&
935 !na_pivot_is_configuration_locked_by_admin( pivot ));
938 static GList *
939 load_items_filter_unwanted_items( const NAPivot *pivot, GList *hierarchy, guint loadable_set )
941 GList *it;
942 GList *filtered;
944 for( it = hierarchy ; it ; it = it->next ){
945 na_object_check_status( it->data );
948 filtered = load_items_filter_unwanted_items_rec( hierarchy, loadable_set );
950 return( filtered );
954 * build a dest tree from a source tree, removing filtered items
955 * an item is filtered if it is invalid (and not loading invalid ones)
956 * or disabled (and not loading disabled ones)
958 static GList *
959 load_items_filter_unwanted_items_rec( GList *hierarchy, guint loadable_set )
961 static const gchar *thisfn = "na_io_provider_load_items_filter_unwanted_items_rec";
962 GList *subitems, *subitems_f;
963 GList *it, *itnext;
964 GList *filtered;
965 gboolean selected;
966 gchar *label;
967 gboolean load_invalid, load_disabled;
969 filtered = NULL;
970 load_invalid = loadable_set & PIVOT_LOAD_INVALID;
971 load_disabled = loadable_set & PIVOT_LOAD_DISABLED;
973 for( it = hierarchy ; it ; it = itnext ){
975 itnext = it->next;
976 selected = FALSE;
978 if( NA_IS_OBJECT_PROFILE( it->data )){
979 if( na_object_is_valid( it->data ) || load_invalid ){
980 filtered = g_list_append( filtered, it->data );
981 selected = TRUE;
985 if( NA_IS_OBJECT_ITEM( it->data )){
986 if(( na_object_is_enabled( it->data ) || load_disabled ) &&
987 ( na_object_is_valid( it->data ) || load_invalid )){
989 subitems = na_object_get_items( it->data );
990 subitems_f = load_items_filter_unwanted_items_rec( subitems, loadable_set );
991 na_object_set_items( it->data, subitems_f );
992 filtered = g_list_append( filtered, it->data );
993 selected = TRUE;
997 if( !selected ){
998 label = na_object_get_label( it->data );
999 g_debug( "%s: filtering %p (%s) '%s'", thisfn, ( void * ) it->data, G_OBJECT_TYPE_NAME( it->data ), label );
1000 g_free( label );
1001 na_object_unref( it->data );
1005 return( filtered );
1009 * returns a concatened flat list of read actions / menus
1010 * we take care here of:
1011 * - i/o providers which appear unavailable at runtime
1012 * - i/o providers marked as unreadable
1013 * - items (actions or menus) which do not satisfy the defined loadable set
1015 static GList *
1016 load_items_get_merged_list( const NAPivot *pivot, guint loadable_set, GSList **messages )
1018 const GList *providers;
1019 const GList *ip;
1020 GList *merged, *items, *it;
1021 const NAIOProvider *provider_object;
1022 const NAIIOProvider *provider_module;
1024 merged = NULL;
1025 providers = na_io_provider_get_io_providers_list( pivot );
1027 for( ip = providers ; ip ; ip = ip->next ){
1028 provider_object = NA_IO_PROVIDER( ip->data );
1029 provider_module = provider_object->private->provider;
1031 if( provider_module &&
1032 NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->read_items &&
1033 na_io_provider_is_conf_readable( provider_object, pivot, NULL )){
1035 items = NA_IIO_PROVIDER_GET_INTERFACE( provider_module )->read_items( provider_module, messages );
1037 for( it = items ; it ; it = it->next ){
1038 na_object_set_provider( it->data, provider_object );
1039 na_object_dump( it->data );
1042 merged = g_list_concat( merged, items );
1046 return( merged );
1050 * builds the hierarchy
1052 * this is a recursive function which _moves_ items from input 'tree' to
1053 * output list.
1055 static GList *
1056 load_items_hierarchy_build( GList **tree, GSList *level_zero, gboolean list_if_empty, NAObjectItem *parent )
1058 static const gchar *thisfn = "na_io_provider_load_items_hierarchy_build";
1059 GList *hierarchy, *it;
1060 GSList *ilevel;
1061 GSList *subitems_ids;
1062 GList *subitems;
1064 hierarchy = NULL;
1066 if( g_slist_length( level_zero )){
1067 for( ilevel = level_zero ; ilevel ; ilevel = ilevel->next ){
1068 /*g_debug( "%s: id=%s", thisfn, ( gchar * ) ilevel->data );*/
1069 it = g_list_find_custom( *tree, ilevel->data, ( GCompareFunc ) peek_item_by_id_compare );
1070 if( it ){
1071 hierarchy = g_list_append( hierarchy, it->data );
1072 na_object_set_parent( it->data, parent );
1074 g_debug( "%s: id=%s: %s (%p) appended to hierarchy %p",
1075 thisfn, ( gchar * ) ilevel->data, G_OBJECT_TYPE_NAME( it->data ), ( void * ) it->data, ( void * ) hierarchy );
1077 *tree = g_list_remove_link( *tree, it );
1079 if( NA_IS_OBJECT_MENU( it->data )){
1080 subitems_ids = na_object_get_items_slist( it->data );
1081 subitems = load_items_hierarchy_build( tree, subitems_ids, FALSE, NA_OBJECT_ITEM( it->data ));
1082 na_object_set_items( it->data, subitems );
1083 na_core_utils_slist_free( subitems_ids );
1088 /* if level-zero list is empty,
1089 * we consider that all items are at the same level
1091 else if( list_if_empty ){
1092 for( it = *tree ; it ; it = it->next ){
1093 hierarchy = g_list_append( hierarchy, it->data );
1094 na_object_set_parent( it->data, parent );
1096 g_list_free( *tree );
1097 *tree = NULL;
1100 return( hierarchy );
1103 static GList *
1104 load_items_hierarchy_sort( const NAPivot *pivot, GList *tree, GCompareFunc fn )
1106 GList *sorted;
1107 GList *items, *it;
1109 sorted = g_list_sort( tree, fn );
1111 /* recursively sort each level of the tree
1113 for( it = sorted ; it ; it = it->next ){
1114 if( NA_IS_OBJECT_MENU( it->data )){
1115 items = na_object_get_items( it->data );
1116 items = load_items_hierarchy_sort( pivot, items, fn );
1117 na_object_set_items( it->data, items );
1121 return( sorted );
1125 * returns zero when @obj has the required @id
1127 static gint
1128 peek_item_by_id_compare( const NAObject *obj, const gchar *id )
1130 gchar *obj_id;
1131 gint ret = 1;
1133 if( NA_IS_OBJECT_ITEM( obj )){
1134 obj_id = na_object_get_id( obj );
1135 ret = strcmp( obj_id, id );
1136 g_free( obj_id );
1139 return( ret );
1142 static NAIOProvider *
1143 peek_provider_by_id( const GList *providers, const gchar *id )
1145 NAIOProvider *provider = NULL;
1146 const GList *ip;
1148 for( ip = providers ; ip && !provider ; ip = ip->next ){
1149 if( !strcmp( NA_IO_PROVIDER( ip->data )->private->id, id )){
1150 provider = NA_IO_PROVIDER( ip->data );
1154 return( provider );
1157 #if 0
1159 * @priority: the internal ids of IO providers in descending order of
1160 * priority for writing new elements, as a string list
1162 * build the static list of I/O providers, depending of setup of NAPivot
1163 * doing required initializations
1165 static void
1166 setup_io_providers( const NAPivot *pivot, GSList *priority )
1168 GList *ordered_providers;
1169 GList *merged_providers;
1170 GList *all_providers;
1172 g_return_if_fail( st_io_providers == NULL );
1174 /* allocate the ordered list */
1175 ordered_providers = allocate_ordered_providers( priority );
1177 /* merge with available I/O providers */
1178 merged_providers = merge_available_io_providers( pivot, ordered_providers );
1180 /* add providers found in prefs */
1181 all_providers = add_io_providers_from_prefs( pivot, merged_providers );
1183 st_io_providers = all_providers;
1186 static GList *
1187 allocate_ordered_providers( GSList *priority )
1189 GSList *ip;
1190 NAIOProvider *provider;
1191 GList *providers;
1193 providers = NULL;
1195 for( ip = priority ; ip ; ip = ip->next ){
1197 provider = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, ( const gchar * ) ip->data, NULL );
1198 providers = g_list_prepend( providers, provider );
1201 return( g_list_reverse( providers ));
1205 * merge the ordered list of I/O providers (which have only Id)
1206 * with those found available at runtime
1208 static GList *
1209 merge_available_io_providers( const NAPivot *pivot, GList *ordered )
1211 static const gchar *thisfn = "na_io_provider_merge_available_io_providers";
1212 GList *merged;
1213 GList *module_objects, *im;
1214 gchar *id;
1215 NAIOProvider *provider;
1217 merged = ordered;
1219 module_objects = na_pivot_get_providers( pivot, NA_IIO_PROVIDER_TYPE );
1220 for( im = module_objects ; im ; im = im->next ){
1222 id = NULL;
1223 if( NA_IIO_PROVIDER_GET_INTERFACE( NA_IIO_PROVIDER( im->data ))->get_id ){
1224 id = NA_IIO_PROVIDER_GET_INTERFACE( NA_IIO_PROVIDER( im->data ))->get_id( NA_IIO_PROVIDER( im->data ));
1226 } else {
1227 g_warning( "%s: NAIIOProvider %p doesn't support get_id() interface", thisfn, ( void * ) im->data );
1230 provider = NULL;
1231 if( id ){
1232 provider = na_io_provider_find_provider_by_id( merged, id );
1234 if( !provider ){
1235 g_debug( "%s: no provider already allocated in ordered list for id=%s", thisfn, id );
1236 provider = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, id, NULL );
1237 merged = g_list_append( merged, provider );
1239 } else {
1240 g_debug( "%s: found NAIOProvider=%p (NAIIOProvider=%p) for id=%s",
1241 thisfn, ( void * ) provider, ( void * ) im->data, id );
1244 io_provider_set_provider( provider, NA_IIO_PROVIDER( im->data ), pivot );
1246 g_free( id );
1250 na_pivot_free_providers( module_objects );
1252 return( merged );
1255 static void
1256 io_provider_set_provider( NAIOProvider *provider, NAIIOProvider *instance, const NAPivot *pivot )
1258 static const gchar *thisfn = "na_io_provider_set_provider";
1260 g_return_if_fail( NA_IS_IO_PROVIDER( provider ));
1261 g_return_if_fail( NA_IS_IIO_PROVIDER( instance ));
1263 provider->private->provider = g_object_ref( instance );
1265 if( NA_IIO_PROVIDER_GET_INTERFACE( instance )->get_name ){
1266 provider->private->name = NA_IIO_PROVIDER_GET_INTERFACE( instance )->get_name( instance );
1267 } else {
1268 g_warning( "%s: NAIIOProvider %p doesn't support get_name() interface", thisfn, ( void * ) instance );
1271 provider->private->item_changed_handler =
1272 g_signal_connect(
1273 instance,
1274 IO_PROVIDER_SIGNAL_ITEM_CHANGED,
1275 ( GCallback ) na_pivot_item_changed_handler,
1276 ( gpointer ) pivot );
1279 static GList *
1280 add_io_providers_from_prefs( const NAPivot *pivot, GList *runtime_providers )
1282 gchar *path, *id;
1283 GSList *ids, *iid;
1284 GList *providers;
1285 NAIOProvider *provider;
1287 providers = runtime_providers;
1288 path = gconf_concat_dir_and_key( IPREFS_GCONF_BASEDIR, IO_PROVIDER_KEY_ROOT );
1289 gconf = na_iprefs_get_gconf_client( NA_IPREFS( pivot ));
1291 ids = na_gconf_utils_get_subdirs( gconf, path );
1293 for( iid = ids ; iid ; iid = iid->next ){
1294 id = g_path_get_basename(( const gchar * ) iid->data );
1295 provider = na_io_provider_find_provider_by_id( providers, id );
1297 if( !provider ){
1298 provider = g_object_new( NA_IO_PROVIDER_TYPE, IO_PROVIDER_PROP_ID, id, NULL );
1299 providers = g_list_append( providers, provider );
1302 g_free( id );
1305 na_gconf_utils_free_subdirs( ids );
1306 g_free( path );
1308 return( providers );
1312 * na_io_provider_reorder_providers_list:
1313 * @pivot: the #NAPivot instance of the application.
1315 * Reorder our global list of #NAIOProviders,after the user has reordered
1316 * them in user preferences.
1318 void
1319 na_io_provider_reorder_providers_list( const NAPivot *pivot )
1321 GSList *order, *io;
1322 GList *new_list;
1323 NAIOProvider *provider;
1325 new_list = NULL;
1326 order = na_iprefs_read_string_list( NA_IPREFS( pivot ), IO_PROVIDER_KEY_ORDER, NULL );
1328 for( io = order ; io ; io = io->next ){
1329 provider = na_io_provider_find_provider_by_id( st_io_providers, ( const gchar * ) io->data );
1330 if( provider ){
1331 st_io_providers = g_list_remove( st_io_providers, provider );
1332 new_list = g_list_prepend( new_list, provider );
1336 st_io_providers = g_list_reverse( new_list );
1338 na_core_utils_slist_free( order );
1342 * na_io_provider_is_user_readable_at_startup:
1343 * @provider: this #NAIOProvider.
1344 * @iprefs: an implementor of the #NAIPrefs interface.
1346 * Returns: %TRUE is this I/O provider should be read at startup, and so
1347 * may participate to the global list of menus and actions.
1349 * This is a user preference.
1350 * If the preference is not recorded, then it defaults to %TRUE.
1351 * This means that the user may adjust its personal configuration to
1352 * fully ignore menu/action items from a NAIIOProvider, just by setting
1353 * the corresponding flag to %FALSE.
1355 gboolean
1356 na_io_provider_is_user_readable_at_startup( const NAIOProvider *provider, const NAIPrefs *iprefs )
1358 gboolean to_be_read;
1359 GConfClient *gconf;
1360 gchar *path, *key, *entry;
1362 to_be_read = FALSE;
1363 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
1364 g_return_val_if_fail( NA_IS_IPREFS( iprefs ), FALSE );
1366 if( !provider->private->dispose_has_run ){
1368 gconf = na_iprefs_get_gconf_client( iprefs );
1370 path = gconf_concat_dir_and_key( IPREFS_GCONF_BASEDIR, IO_PROVIDER_KEY_ROOT );
1371 key = gconf_concat_dir_and_key( path, provider->private->id );
1372 entry = gconf_concat_dir_and_key( key, NA_IPREFS_IO_PROVIDER_READABLE );
1374 to_be_read = na_gconf_utils_read_bool( gconf, entry, FALSE, TRUE );
1376 g_free( entry );
1377 g_free( key );
1378 g_free( path );
1381 return( to_be_read );
1385 * na_io_provider_find_provider_by_id:
1386 * @providers: the current list of #NAIOProvider.
1387 * @id: the searched internal id.
1389 * Returns: the searched #NAIOProvider, or %NULL if not found.
1391 * The returned object is owned by #NAIOProvider class, and should not
1392 * be g_object_unref() by the user.
1394 NAIOProvider *
1395 na_io_provider_find_provider_by_id( GList *providers, const gchar *id )
1397 NAIOProvider *provider;
1398 GList *ip;
1400 provider = NULL;
1402 for( ip = providers ; ip && !provider ; ip = ip->next ){
1404 if( !strcmp( NA_IO_PROVIDER( ip->data )->private->id, id )){
1406 provider = NA_IO_PROVIDER( ip->data );
1410 return( provider );
1414 * na_io_provider_is_locked_by_admin:
1415 * @provider: this #NAIOProvider.
1416 * @iprefs: an implementor of the #NAIPrefs interface.
1418 * Returns: %TRUE is this I/O provider has been locked by an admin.
1420 gboolean
1421 na_io_provider_is_locked_by_admin( const NAIOProvider *provider, const NAIPrefs *iprefs )
1423 gboolean locked;
1424 GConfClient *gconf;
1425 gchar *path;
1427 locked = FALSE;
1428 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), FALSE );
1429 g_return_val_if_fail( NA_IS_IPREFS( iprefs ), FALSE );
1431 if( !provider->private->dispose_has_run ){
1433 gconf = na_iprefs_get_gconf_client( iprefs );
1435 path = g_strdup_printf( "%s/mandatory/%s/locked", IPREFS_GCONF_BASEDIR, provider->private->id );
1437 locked = na_gconf_utils_read_bool( gconf, path, FALSE, FALSE );
1439 g_free( path );
1442 return( locked );
1446 * na_io_provider_has_write_api:
1447 * @provider: this #NAIOProvider.
1449 * Returns: %TRUE is the NAIIOProvider implements write and delete api.
1451 gboolean
1452 na_io_provider_has_write_api( const NAIOProvider *provider )
1454 gboolean has_api;
1456 has_api = FALSE;
1457 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), has_api );
1459 if( !provider->private->dispose_has_run ){
1461 if( provider->private->provider ){
1463 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), FALSE );
1465 has_api =
1466 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->write_item &&
1467 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->delete_item;
1471 return( has_api );
1473 #endif
1476 * na_io_provider_write_item:
1477 * @provider: this #NAIOProvider object.
1478 * @item: a #NAObjectItem to be written to the storage subsystem.
1479 * @messages: error messages.
1481 * Writes an @item to the storage subsystem.
1483 * Returns: the NAIIOProvider return code.
1485 * #NAPivot class, which should be the only caller of this function,
1486 * has already check that this item is writable, i.e. that all conditions
1487 * are met to be able to successfully write the item down to the
1488 * storage subsystem.
1490 guint
1491 na_io_provider_write_item( const NAIOProvider *provider, const NAObjectItem *item, GSList **messages )
1493 static const gchar *thisfn = "na_io_provider_write_item";
1494 guint ret;
1496 g_debug( "%s: provider=%p (%s), item=%p (%s), messages=%p", thisfn,
1497 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
1498 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
1499 ( void * ) messages );
1501 ret = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
1503 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), ret );
1504 g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), ret );
1505 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), ret );
1507 ret = NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->write_item( provider->private->provider, item, messages );
1509 return( ret );
1513 * na_io_provider_delete_item:
1514 * @provider: this #NAIOProvider object.
1515 * @item: the #NAObjectItem item to be deleted.
1516 * @messages: error messages.
1518 * Deletes an item (action or menu) from the storage subsystem.
1520 * Returns: the NAIIOProvider return code.
1522 guint
1523 na_io_provider_delete_item( const NAIOProvider *provider, const NAObjectItem *item, GSList **messages )
1525 static const gchar *thisfn = "na_io_provider_delete_item";
1526 guint ret;
1528 g_debug( "%s: provider=%p (%s), item=%p (%s), messages=%p", thisfn,
1529 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
1530 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
1531 ( void * ) messages );
1533 ret = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
1535 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), ret );
1536 g_return_val_if_fail( NA_IS_OBJECT_ITEM( item ), ret );
1537 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), ret );
1539 ret = NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->delete_item( provider->private->provider, item, messages );
1541 return( ret );
1545 * na_io_provider_duplicate_data:
1546 * @provider: this #NAIOProvider object.
1547 * @dest: the target #NAObjectItem item.
1548 * @source: the source #NAObjectItem item.
1549 * @messages: error messages.
1551 * Duplicates provider data (if any) from @source to @dest.
1553 * Returns: the NAIIOProvider return code.
1555 guint
1556 na_io_provider_duplicate_data( const NAIOProvider *provider, NAObjectItem *dest, const NAObjectItem *source, GSList **messages )
1558 static const gchar *thisfn = "na_io_provider_duplicate_data";
1559 guint ret;
1560 void *provider_data;
1562 g_debug( "%s: provider=%p (%s), dest=%p (%s), source=%p (%s), messages=%p", thisfn,
1563 ( void * ) provider, G_OBJECT_TYPE_NAME( provider ),
1564 ( void * ) dest, G_OBJECT_TYPE_NAME( dest ),
1565 ( void * ) source, G_OBJECT_TYPE_NAME( source ),
1566 ( void * ) messages );
1568 ret = NA_IIO_PROVIDER_CODE_PROGRAM_ERROR;
1570 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider ), ret );
1571 g_return_val_if_fail( NA_IS_OBJECT_ITEM( dest ), ret );
1572 g_return_val_if_fail( NA_IS_OBJECT_ITEM( source ), ret );
1573 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider->private->provider ), ret );
1575 na_object_set_provider_data( dest, NULL );
1576 provider_data = na_object_get_provider_data( source );
1578 if( provider_data &&
1579 NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->duplicate_data ){
1580 ret = NA_IIO_PROVIDER_GET_INTERFACE( provider->private->provider )->duplicate_data( provider->private->provider, dest, source, messages );
1583 return( ret );
1587 * na_io_provider_get_readonly_tooltip:
1588 * @reason: the reason for why an item is not writable.
1590 * Returns: the associated tooltip, as a newly allocated string which
1591 * should be g_free() by the caller.
1593 gchar *
1594 na_io_provider_get_readonly_tooltip( guint reason )
1596 gchar *tooltip;
1598 tooltip = NULL;
1600 switch( reason ){
1601 case NA_IIO_PROVIDER_STATUS_ITEM_READONLY:
1602 tooltip = g_strdup( _( "Item is read-only." ));
1603 break;
1605 case NA_IIO_PROVIDER_STATUS_PROVIDER_NOT_WILLING_TO:
1606 tooltip = g_strdup( _( "I/O provider is not willing to write." ));
1607 break;
1609 case NA_IIO_PROVIDER_STATUS_NO_PROVIDER_FOUND:
1610 tooltip = g_strdup( _( "No writable I/O provider found." ));
1611 break;
1613 case NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_ADMIN:
1614 tooltip = g_strdup( _( "I/O provider has been locked down by an administrator." ));
1615 break;
1617 case NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_USER:
1618 tooltip = g_strdup( _( "I/O provider has been locked down by the user." ));
1619 break;
1621 case NA_IIO_PROVIDER_STATUS_NO_API:
1622 tooltip = g_strdup( _( "I/O provider implementation lacks of required API." ));
1623 break;
1625 case NA_IIO_PROVIDER_STATUS_CONFIGURATION_LOCKED_BY_ADMIN:
1626 tooltip = g_strdup( _( "The whole configuration has been locked down by an administrator." ));
1627 break;
1629 /* item is writable, so tooltip is empty */
1630 case 0:
1631 tooltip = g_strdup( "" );
1632 break;
1634 default:
1635 tooltip = g_strdup_printf( _( "Item is not writable for an unknown reason (%d).\n" \
1636 "Please, be kind enough to fill out a bug report on http://bugzilla.gnome.org." ), reason );
1637 break;
1640 return( tooltip );
1644 * na_io_provider_get_return_code_label:
1645 * @code: the return code of an operation.
1647 * Returns: the associated label, as a newly allocated string which
1648 * should be g_free() by the caller.
1650 gchar *
1651 na_io_provider_get_return_code_label( guint code )
1653 gchar *label;
1655 label = NULL;
1657 switch( code ){
1658 case NA_IIO_PROVIDER_CODE_OK:
1659 label = g_strdup( _( "OK." ));
1660 break;
1662 case NA_IIO_PROVIDER_CODE_PROGRAM_ERROR:
1663 label = g_strdup( _( "Program flow error.\n" \
1664 "Please, be kind enough to fill out a bug report on http://bugzilla.gnome.org." ));
1665 break;
1667 case NA_IIO_PROVIDER_CODE_NOT_WILLING_TO_RUN:
1668 label = g_strdup( _( "The I/O provider is not willing to do that." ));
1669 break;
1671 case NA_IIO_PROVIDER_CODE_WRITE_ERROR:
1672 label = g_strdup( _( "Write error in I/O provider." ));
1673 break;
1675 case NA_IIO_PROVIDER_CODE_DELETE_SCHEMAS_ERROR:
1676 label = g_strdup( _( "Unable to delete GConf schemas." ));
1677 break;
1679 case NA_IIO_PROVIDER_CODE_DELETE_CONFIG_ERROR:
1680 label = g_strdup( _( "Unable to delete configuration." ));
1681 break;
1683 default:
1684 label = g_strdup_printf( _( "Unknown return code (%d).\n" \
1685 "Please, be kind enough to fill out a bug report on http://bugzilla.gnome.org." ), code );
1686 break;
1689 return( label );