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.
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 <glib/gi18n.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"
47 struct _NAIOProviderClassPrivate
{
48 void *empty
; /* so that gcc -pedantic is happy */
51 /* private instance data
53 struct _NAIOProviderPrivate
{
54 gboolean dispose_has_run
;
56 NAIIOProvider
*provider
;
57 gulong item_changed_handler
;
60 /* NAIOProvider properties
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
);
81 static void dump( const NAIOProvider
*provider
);
82 static void dump_providers_list( GList
*providers
);
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
);
100 na_io_provider_get_type( void )
102 static GType object_type
= 0;
105 object_type
= register_type();
108 return( object_type
);
112 register_type( void )
114 static const gchar
*thisfn
= "na_io_provider_register_type";
117 static GTypeInfo info
= {
118 sizeof( NAIOProviderClass
),
119 ( GBaseInitFunc
) NULL
,
120 ( GBaseFinalizeFunc
) NULL
,
121 ( GClassInitFunc
) class_init
,
124 sizeof( NAIOProvider
),
126 ( GInstanceInitFunc
) instance_init
129 g_debug( "%s", thisfn
);
131 type
= g_type_register_static( G_TYPE_OBJECT
, "NAIOProvider", &info
, 0 );
137 class_init( NAIOProviderClass
*klass
)
139 static const gchar
*thisfn
= "na_io_provider_class_init";
140 GObjectClass
*object_class
;
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(
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 );
165 instance_init( GTypeInstance
*instance
, gpointer klass
)
167 static const gchar
*thisfn
= "na_io_provider_instance_init";
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;
186 instance_constructed( GObject
*object
)
188 static const gchar
*thisfn
= "na_io_provider_instance_constructed";
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
);
207 instance_get_property( GObject
*object
, guint property_id
, GValue
*value
, GParamSpec
*spec
)
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
);
222 G_OBJECT_WARN_INVALID_PROPERTY_ID( object
, property_id
, spec
);
229 instance_set_property( GObject
*object
, guint property_id
, const GValue
*value
, GParamSpec
*spec
)
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
);
248 instance_dispose( GObject
*object
)
250 static const gchar
*thisfn
= "na_io_provider_instance_dispose";
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
);
278 instance_finalize( GObject
*object
)
280 static const gchar
*thisfn
= "na_io_provider_instance_finalize";
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.
309 na_io_provider_find_writable_io_provider( const NAPivot
*pivot
)
311 const GList
*providers
;
313 NAIOProvider
*provider
;
315 providers
= na_io_provider_get_io_providers_list( pivot
);
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
);
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.
338 na_io_provider_find_io_provider_by_id( const NAPivot
*pivot
, const gchar
*id
)
340 const GList
*providers
;
342 NAIOProvider
*provider
;
345 providers
= na_io_provider_get_io_providers_list( pivot
);
348 for( ip
= providers
; ip
&& !found
; ip
= ip
->next
){
349 provider
= NA_IO_PROVIDER( ip
->data
);
350 if( !strcmp( provider
->private->id
, id
)){
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.
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
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.
416 na_io_provider_get_id( const NAIOProvider
*provider
)
420 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider
), NULL
);
424 if( !provider
->private->dispose_has_run
){
426 id
= g_strdup( provider
->private->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.
445 na_io_provider_get_name( const NAIOProvider
*provider
)
447 static const gchar
*thisfn
= "na_io_provider_get_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
){
460 name
= NA_IIO_PROVIDER_GET_INTERFACE( provider
->private->provider
)->get_name( provider
->private->provider
);
462 g_warning( "%s: NAIIOProvider %s get_name() interface returns NULL", thisfn
, provider
->private->id
);
463 name
= g_strdup( "" );
467 g_warning( "%s: NAIIOProvider %s doesn't support get_name() interface", thisfn
, provider
->private->id
);
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.
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.
515 na_io_provider_is_conf_readable( const NAIOProvider
*provider
, const NAPivot
*pivot
, gboolean
*mandatory
)
520 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider
), FALSE
);
521 g_return_val_if_fail( NA_IS_PIVOT( pivot
), 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
);
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.
545 na_io_provider_is_able_to_write( const NAIOProvider
*provider
)
549 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider
), 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().
588 na_io_provider_is_conf_writable( const NAIOProvider
*provider
, const NAPivot
*pivot
, gboolean
*mandatory
)
590 gboolean is_writable
;
593 g_return_val_if_fail( NA_IS_IO_PROVIDER( provider
), FALSE
);
594 g_return_val_if_fail( NA_IS_PIVOT( pivot
), 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
);
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
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.
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
)){
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
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.
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
;
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
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
);
714 case IPREFS_ORDER_ALPHA_DESCENDING
:
715 hierarchy
= load_items_hierarchy_sort( pivot
, hierarchy
, ( GCompareFunc
) na_object_id_sort_alpha_desc
);
718 case IPREFS_ORDER_MANUAL
:
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
);
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
);
747 dump_providers_list( GList
*providers
)
749 static const gchar
*thisfn
= "na_io_provider_dump_providers_list";
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
));
761 * allocate a new NAIOProvider object for the specified module and id
763 * id is mandatory here
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
);
776 io_providers_list_set_module( pivot
, object
, module
);
783 * add to the list a NAIOProvider object for each loaded plugin which claim
784 * to implement the NAIIOProvider interface
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";
791 GList
*modules_list
, *im
;
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
){
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
);
811 g_warning( "%s: NAIIOProvider %p doesn't support get_id() interface", thisfn
, ( void * ) im
->data
);
815 merged
= io_providers_list_append_object( pivot
, merged
, provider_module
, id
);
820 na_pivot_free_providers( modules_list
);
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
833 io_providers_list_add_from_prefs( const NAPivot
*pivot
, GList
*objects_list
)
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
);
853 * adding from write-order means we only create NAIOProvider objects
854 * without having any pointer to the underlying NAIIOProvider (if it exists)
857 io_providers_list_add_from_write_order( const NAPivot
*pivot
, GList
*objects_list
)
860 NASettings
*settings
;
861 GSList
*io_providers
, *it
;
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
);
879 * add to the list a NAIOProvider object for the specified module and id
880 * if it does not have been already registered
883 io_providers_list_append_object( const NAPivot
*pivot
, GList
*list
, NAIIOProvider
*module
, const gchar
*id
)
886 NAIOProvider
*object
;
889 object
= peek_provider_by_id( list
, id
);
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
);
903 * when a IIOProvider plugin is associated with the NAIOProvider object,
904 * we connect the NAPivot callback to the 'item-changed' signal
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
=
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,
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.
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
));
939 load_items_filter_unwanted_items( const NAPivot
*pivot
, GList
*hierarchy
, guint loadable_set
)
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
);
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)
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
;
967 gboolean load_invalid
, load_disabled
;
970 load_invalid
= loadable_set
& PIVOT_LOAD_INVALID
;
971 load_disabled
= loadable_set
& PIVOT_LOAD_DISABLED
;
973 for( it
= hierarchy
; it
; it
= itnext
){
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
);
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
);
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
);
1001 na_object_unref( it
->data
);
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
1016 load_items_get_merged_list( const NAPivot
*pivot
, guint loadable_set
, GSList
**messages
)
1018 const GList
*providers
;
1020 GList
*merged
, *items
, *it
;
1021 const NAIOProvider
*provider_object
;
1022 const NAIIOProvider
*provider_module
;
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
);
1050 * builds the hierarchy
1052 * this is a recursive function which _moves_ items from input 'tree' to
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
;
1061 GSList
*subitems_ids
;
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
);
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
);
1100 return( hierarchy
);
1104 load_items_hierarchy_sort( const NAPivot
*pivot
, GList
*tree
, GCompareFunc fn
)
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
);
1125 * returns zero when @obj has the required @id
1128 peek_item_by_id_compare( const NAObject
*obj
, const gchar
*id
)
1133 if( NA_IS_OBJECT_ITEM( obj
)){
1134 obj_id
= na_object_get_id( obj
);
1135 ret
= strcmp( obj_id
, id
);
1142 static NAIOProvider
*
1143 peek_provider_by_id( const GList
*providers
, const gchar
*id
)
1145 NAIOProvider
*provider
= NULL
;
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
);
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
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
;
1187 allocate_ordered_providers( GSList
*priority
)
1190 NAIOProvider
*provider
;
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
1209 merge_available_io_providers( const NAPivot
*pivot
, GList
*ordered
)
1211 static const gchar
*thisfn
= "na_io_provider_merge_available_io_providers";
1213 GList
*module_objects
, *im
;
1215 NAIOProvider
*provider
;
1219 module_objects
= na_pivot_get_providers( pivot
, NA_IIO_PROVIDER_TYPE
);
1220 for( im
= module_objects
; im
; im
= im
->next
){
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
));
1227 g_warning( "%s: NAIIOProvider %p doesn't support get_id() interface", thisfn
, ( void * ) im
->data
);
1232 provider
= na_io_provider_find_provider_by_id( merged
, id
);
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
);
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
);
1250 na_pivot_free_providers( module_objects
);
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
);
1268 g_warning( "%s: NAIIOProvider %p doesn't support get_name() interface", thisfn
, ( void * ) instance
);
1271 provider
->private->item_changed_handler
=
1274 IO_PROVIDER_SIGNAL_ITEM_CHANGED
,
1275 ( GCallback
) na_pivot_item_changed_handler
,
1276 ( gpointer
) pivot
);
1280 add_io_providers_from_prefs( const NAPivot
*pivot
, GList
*runtime_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
);
1298 provider
= g_object_new( NA_IO_PROVIDER_TYPE
, IO_PROVIDER_PROP_ID
, id
, NULL
);
1299 providers
= g_list_append( providers
, provider
);
1305 na_gconf_utils_free_subdirs( ids
);
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.
1319 na_io_provider_reorder_providers_list( const NAPivot
*pivot
)
1323 NAIOProvider
*provider
;
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
);
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.
1356 na_io_provider_is_user_readable_at_startup( const NAIOProvider
*provider
, const NAIPrefs
*iprefs
)
1358 gboolean to_be_read
;
1360 gchar
*path
, *key
, *entry
;
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
);
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.
1395 na_io_provider_find_provider_by_id( GList
*providers
, const gchar
*id
)
1397 NAIOProvider
*provider
;
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
);
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.
1421 na_io_provider_is_locked_by_admin( const NAIOProvider
*provider
, const NAIPrefs
*iprefs
)
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
);
1446 * na_io_provider_has_write_api:
1447 * @provider: this #NAIOProvider.
1449 * Returns: %TRUE is the NAIIOProvider implements write and delete api.
1452 na_io_provider_has_write_api( const NAIOProvider
*provider
)
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
);
1466 NA_IIO_PROVIDER_GET_INTERFACE( provider
->private->provider
)->write_item
&&
1467 NA_IIO_PROVIDER_GET_INTERFACE( provider
->private->provider
)->delete_item
;
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.
1491 na_io_provider_write_item( const NAIOProvider
*provider
, const NAObjectItem
*item
, GSList
**messages
)
1493 static const gchar
*thisfn
= "na_io_provider_write_item";
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
);
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.
1523 na_io_provider_delete_item( const NAIOProvider
*provider
, const NAObjectItem
*item
, GSList
**messages
)
1525 static const gchar
*thisfn
= "na_io_provider_delete_item";
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
);
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.
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";
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
);
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.
1594 na_io_provider_get_readonly_tooltip( guint reason
)
1601 case NA_IIO_PROVIDER_STATUS_ITEM_READONLY
:
1602 tooltip
= g_strdup( _( "Item is read-only." ));
1605 case NA_IIO_PROVIDER_STATUS_PROVIDER_NOT_WILLING_TO
:
1606 tooltip
= g_strdup( _( "I/O provider is not willing to write." ));
1609 case NA_IIO_PROVIDER_STATUS_NO_PROVIDER_FOUND
:
1610 tooltip
= g_strdup( _( "No writable I/O provider found." ));
1613 case NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_ADMIN
:
1614 tooltip
= g_strdup( _( "I/O provider has been locked down by an administrator." ));
1617 case NA_IIO_PROVIDER_STATUS_PROVIDER_LOCKED_BY_USER
:
1618 tooltip
= g_strdup( _( "I/O provider has been locked down by the user." ));
1621 case NA_IIO_PROVIDER_STATUS_NO_API
:
1622 tooltip
= g_strdup( _( "I/O provider implementation lacks of required API." ));
1625 case NA_IIO_PROVIDER_STATUS_CONFIGURATION_LOCKED_BY_ADMIN
:
1626 tooltip
= g_strdup( _( "The whole configuration has been locked down by an administrator." ));
1629 /* item is writable, so tooltip is empty */
1631 tooltip
= g_strdup( "" );
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
);
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.
1651 na_io_provider_get_return_code_label( guint code
)
1658 case NA_IIO_PROVIDER_CODE_OK
:
1659 label
= g_strdup( _( "OK." ));
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." ));
1667 case NA_IIO_PROVIDER_CODE_NOT_WILLING_TO_RUN
:
1668 label
= g_strdup( _( "The I/O provider is not willing to do that." ));
1671 case NA_IIO_PROVIDER_CODE_WRITE_ERROR
:
1672 label
= g_strdup( _( "Write error in I/O provider." ));
1675 case NA_IIO_PROVIDER_CODE_DELETE_SCHEMAS_ERROR
:
1676 label
= g_strdup( _( "Unable to delete GConf schemas." ));
1679 case NA_IIO_PROVIDER_CODE_DELETE_CONFIG_ERROR
:
1680 label
= g_strdup( _( "Unable to delete configuration." ));
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
);