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)
39 #include <api/na-core-utils.h>
40 #include <api/na-gconf-utils.h>
41 #include <api/na-data-def.h>
42 #include <api/na-data-types.h>
43 #include <api/na-data-boxed.h>
47 struct _NADataBoxedClassPrivate
{
48 void *empty
; /* so that gcc -pedantic is happy */
51 /* additional features of our data types
52 * (see NABoxed class for primary features)
56 GParamSpec
* ( *spec
) ( const NADataDef
* );
57 gboolean ( *is_default
)( const NADataBoxed
* );
58 gboolean ( *is_valid
) ( const NADataBoxed
* );
62 /* private instance data
64 struct _NADataBoxedPrivate
{
65 gboolean dispose_has_run
;
66 const NADataDef
*data_def
;
67 const DataBoxedDef
*boxed_def
;
70 static GObjectClass
*st_parent_class
= NULL
;
72 static GType
register_type( void );
73 static void class_init( NADataBoxedClass
*klass
);
74 static void instance_init( GTypeInstance
*instance
, gpointer klass
);
75 static void instance_dispose( GObject
*object
);
76 static void instance_finalize( GObject
*object
);
78 static const DataBoxedDef
*get_data_boxed_def( guint type
);
80 static GParamSpec
*bool_spec( const NADataDef
*idtype
);
81 static gboolean
bool_is_default( const NADataBoxed
*boxed
);
82 static gboolean
bool_is_valid( const NADataBoxed
*boxed
);
84 static GParamSpec
*pointer_spec( const NADataDef
*idtype
);
85 static gboolean
pointer_is_default( const NADataBoxed
*boxed
);
86 static gboolean
pointer_is_valid( const NADataBoxed
*boxed
);
88 static GParamSpec
*string_spec( const NADataDef
*idtype
);
89 static gboolean
string_is_default( const NADataBoxed
*boxed
);
90 static gboolean
string_is_valid( const NADataBoxed
*boxed
);
92 static GParamSpec
*string_list_spec( const NADataDef
*idtype
);
93 static gboolean
string_list_is_default( const NADataBoxed
*boxed
);
94 static gboolean
string_list_is_valid( const NADataBoxed
*boxed
);
96 static gboolean
locale_is_default( const NADataBoxed
*boxed
);
97 static gboolean
locale_is_valid( const NADataBoxed
*boxed
);
99 static GParamSpec
*uint_spec( const NADataDef
*idtype
);
100 static gboolean
uint_is_default( const NADataBoxed
*boxed
);
101 static gboolean
uint_is_valid( const NADataBoxed
*boxed
);
103 static GParamSpec
*uint_list_spec( const NADataDef
*idtype
);
104 static gboolean
uint_list_is_default( const NADataBoxed
*boxed
);
105 static gboolean
uint_list_is_valid( const NADataBoxed
*boxed
);
107 static DataBoxedDef st_data_boxed_def
[] = {
108 { NA_DATA_TYPE_BOOLEAN
,
113 { NA_DATA_TYPE_POINTER
,
118 { NA_DATA_TYPE_STRING
,
123 { NA_DATA_TYPE_STRING_LIST
,
125 string_list_is_default
,
128 { NA_DATA_TYPE_LOCALE_STRING
,
138 { NA_DATA_TYPE_UINT_LIST
,
140 uint_list_is_default
,
147 na_data_boxed_get_type( void )
149 static GType item_type
= 0;
151 if( item_type
== 0 ){
152 item_type
= register_type();
159 register_type( void )
161 static const gchar
*thisfn
= "na_data_boxed_register_type";
164 static GTypeInfo info
= {
165 sizeof( NADataBoxedClass
),
168 ( GClassInitFunc
) class_init
,
171 sizeof( NADataBoxed
),
173 ( GInstanceInitFunc
) instance_init
176 g_debug( "%s", thisfn
);
178 type
= g_type_register_static( NA_BOXED_TYPE
, "NADataBoxed", &info
, 0 );
184 class_init( NADataBoxedClass
*klass
)
186 static const gchar
*thisfn
= "na_data_boxed_class_init";
187 GObjectClass
*object_class
;
189 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
191 st_parent_class
= g_type_class_peek_parent( klass
);
193 object_class
= G_OBJECT_CLASS( klass
);
194 object_class
->dispose
= instance_dispose
;
195 object_class
->finalize
= instance_finalize
;
197 klass
->private = g_new0( NADataBoxedClassPrivate
, 1 );
201 instance_init( GTypeInstance
*instance
, gpointer klass
)
203 static const gchar
*thisfn
= "na_data_boxed_instance_init";
206 g_return_if_fail( NA_IS_DATA_BOXED( instance
));
208 g_debug( "%s: instance=%p (%s), klass=%p",
209 thisfn
, ( void * ) instance
, G_OBJECT_TYPE_NAME( instance
), ( void * ) klass
);
211 self
= NA_DATA_BOXED( instance
);
213 self
->private = g_new0( NADataBoxedPrivate
, 1 );
215 self
->private->dispose_has_run
= FALSE
;
216 self
->private->data_def
= NULL
;
217 self
->private->boxed_def
= NULL
;
221 instance_dispose( GObject
*object
)
225 g_return_if_fail( NA_IS_DATA_BOXED( object
));
227 self
= NA_DATA_BOXED( object
);
229 if( !self
->private->dispose_has_run
){
231 self
->private->dispose_has_run
= TRUE
;
233 /* chain up to the parent class */
234 if( G_OBJECT_CLASS( st_parent_class
)->dispose
){
235 G_OBJECT_CLASS( st_parent_class
)->dispose( object
);
241 instance_finalize( GObject
*object
)
243 static const gchar
*thisfn
= "na_data_boxed_instance_finalize";
246 g_return_if_fail( NA_IS_DATA_BOXED( object
));
248 g_debug( "%s: object=%p (%s), name=%s",
250 ( void * ) object
, G_OBJECT_TYPE_NAME( object
),
251 NA_DATA_BOXED( object
)->private->data_def
->name
);
253 self
= NA_DATA_BOXED( object
);
255 g_free( self
->private );
257 /* chain call to parent class */
258 if( G_OBJECT_CLASS( st_parent_class
)->finalize
){
259 G_OBJECT_CLASS( st_parent_class
)->finalize( object
);
263 static const DataBoxedDef
*
264 get_data_boxed_def( guint type
)
266 static const gchar
*thisfn
= "na_data_boxed_get_data_boxed_def";
269 for( i
= 0 ; st_data_boxed_def
[i
].type
; ++i
){
270 if( st_data_boxed_def
[i
].type
== type
){
271 return(( const DataBoxedDef
* ) st_data_boxed_def
+i
);
275 g_warning( "%s: unmanaged data type=%d", thisfn
, type
);
281 * @def: the #NADataDef definition structure for this boxed.
283 * Returns: a newly allocated #NADataBoxed.
288 na_data_boxed_new( const NADataDef
*def
)
292 g_return_val_if_fail( def
!= NULL
, NULL
);
294 boxed
= g_object_new( NA_DATA_BOXED_TYPE
, NULL
);
295 na_boxed_set_type( NA_BOXED( boxed
), def
->type
);
296 boxed
->private->data_def
= def
;
297 boxed
->private->boxed_def
= get_data_boxed_def( def
->type
);
303 * na_data_boxed_get_data_def:
304 * @boxed: this #NADataBoxed object.
306 * Returns: a pointer to the #NADataDef structure attached to the object.
307 * Should never be %NULL.
312 na_data_boxed_get_data_def( const NADataBoxed
*boxed
)
314 const NADataDef
*def
;
316 g_return_val_if_fail( NA_IS_DATA_BOXED( boxed
), NULL
);
320 if( !boxed
->private->dispose_has_run
){
322 def
= boxed
->private->data_def
;
329 * na_data_boxed_set_data_def:
330 * @boxed: this #NADataBoxed object.
331 * @def: the new #NADataDef to be set.
333 * Changes the #NADataDef a @boxed points to:
334 * -> the new type must be the same that the previous one.
335 * -> value is unchanged.
340 na_data_boxed_set_data_def( NADataBoxed
*boxed
, const NADataDef
*new_def
)
342 g_return_if_fail( NA_IS_DATA_BOXED( boxed
));
343 g_return_if_fail( boxed
->private->data_def
);
344 g_return_if_fail( new_def
);
345 g_return_if_fail( new_def
->type
== boxed
->private->data_def
->type
);
347 if( !boxed
->private->dispose_has_run
){
349 boxed
->private->data_def
= ( NADataDef
* ) new_def
;
354 * na_data_boxed_get_param_spec:
355 * @def: a #NADataDef definition structure.
357 * Returns: a #GParamSpec structure.
362 na_data_boxed_get_param_spec( const NADataDef
*def
)
365 const DataBoxedDef
*fn
;
367 g_return_val_if_fail( def
!= NULL
, NULL
);
370 fn
= get_data_boxed_def( def
->type
);
374 spec
= ( *fn
->spec
)( def
);
381 #ifndef NA_DISABLE_DEPRECATED
383 * na_data_boxed_are_equal:
384 * @a: the first #NADataBoxed object.
385 * @b: the second #NADataBoxed object.
387 * Returns: %TRUE if the two boxeds are equal, %FALSE else.
390 * Deprecated: 3.1.0: Use na_boxed_are_equal() instead.
393 na_data_boxed_are_equal( const NADataBoxed
*a
, const NADataBoxed
*b
)
395 g_return_val_if_fail( NA_IS_DATA_BOXED( a
), FALSE
);
396 g_return_val_if_fail( NA_IS_DATA_BOXED( b
), FALSE
);
398 return( na_boxed_are_equal( NA_BOXED( a
), NA_BOXED( b
)));
400 #endif /* NA_DISABLE_DEPRECATED */
403 * na_data_boxed_is_default:
404 * @boxed: this #NADataBoxed object.
406 * Returns: %TRUE if the #NADataBoxed holds its default value,
412 na_data_boxed_is_default( const NADataBoxed
*boxed
)
416 g_return_val_if_fail( NA_IS_DATA_BOXED( boxed
), FALSE
);
417 g_return_val_if_fail( boxed
->private->boxed_def
, FALSE
);
418 g_return_val_if_fail( boxed
->private->boxed_def
->is_default
, FALSE
);
422 if( !boxed
->private->dispose_has_run
){
424 is_default
= ( *boxed
->private->boxed_def
->is_default
)( boxed
);
427 return( is_default
);
431 * na_data_boxed_is_valid:
432 * @boxed: the #NADataBoxed object whose validity is to be checked.
434 * Returns: %TRUE if the boxed is valid, %FALSE else.
439 na_data_boxed_is_valid( const NADataBoxed
*boxed
)
443 g_return_val_if_fail( NA_IS_DATA_BOXED( boxed
), FALSE
);
444 g_return_val_if_fail( boxed
->private->boxed_def
, FALSE
);
445 g_return_val_if_fail( boxed
->private->boxed_def
->is_valid
, FALSE
);
449 if( !boxed
->private->dispose_has_run
){
451 is_valid
= ( *boxed
->private->boxed_def
->is_valid
)( boxed
);
457 #ifndef NA_DISABLE_DEPRECATED
459 * na_data_boxed_dump:
460 * @boxed: this #NADataBoxed object.
462 * Dump the content of @boxed.
465 * Deprecated: 3.1.0: Use na_boxed_dump() instead.
468 na_data_boxed_dump( const NADataBoxed
*boxed
)
470 na_boxed_dump( NA_BOXED( boxed
));
474 * na_data_boxed_get_as_string:
475 * @boxed: the #NADataBoxed whose value is to be set.
477 * Returns: the value of the @boxed, as a newly allocated string which
478 * should be g_free() by the caller.
481 * Deprecated: 3.1.0: Use na_boxed_get_string() instead.
484 na_data_boxed_get_as_string( const NADataBoxed
*boxed
)
486 return( na_boxed_get_string( NA_BOXED( boxed
)));
490 * na_data_boxed_get_as_value:
491 * @boxed: the #NADataBoxed whose value is to be set.
492 * @value: the string to be set.
494 * Setup @value with the content of the @boxed.
497 * Deprecated: 3.1.0: Use na_boxed_get_as_value() instead.
500 na_data_boxed_get_as_value( const NADataBoxed
*boxed
, GValue
*value
)
502 na_boxed_get_as_value( NA_BOXED( boxed
), value
);
506 * na_data_boxed_get_as_void:
507 * @boxed: the #NADataBoxed whose value is to be set.
509 * Returns: the content of the @boxed.
511 * If of type NAFD_TYPE_STRING, NAFD_TYPE_LOCALE_STRING OR
512 * NAFD_TYPE_STRING_LIST, then the content is returned in a newly
513 * allocated value, which should be released by the caller.
516 * Deprecated: 3.1.0: Use na_boxed_get_as_void() instead.
519 na_data_boxed_get_as_void( const NADataBoxed
*boxed
)
521 return( na_boxed_get_as_void( NA_BOXED( boxed
)));
525 * na_data_boxed_set_from_boxed:
526 * @boxed: the #NADataBoxed whose value is to be set.
527 * @value: the source #NADataBoxed.
529 * Copy value from @value to @boxed.
532 * Deprecated: 3.1.0: Use na_boxed_set_from_boxed() instead.
535 na_data_boxed_set_from_boxed( NADataBoxed
*boxed
, const NADataBoxed
*value
)
537 na_boxed_set_from_boxed( NA_BOXED( boxed
), NA_BOXED( value
));
541 * na_data_boxed_set_from_string:
542 * @boxed: the #NADataBoxed whose value is to be set.
543 * @value: the string to be set.
545 * Evaluates the @value and set it to the @boxed.
548 * Deprecated: 3.1.0: Use na_boxed_set_from_string() instead.
551 na_data_boxed_set_from_string( NADataBoxed
*boxed
, const gchar
*value
)
553 na_boxed_set_from_string( NA_BOXED( boxed
), value
);
557 * na_data_boxed_set_from_value:
558 * @boxed: the #NADataBoxed whose value is to be set.
559 * @value: the value whose content is to be got.
561 * Evaluates the @value and set it to the @boxed.
564 * Deprecated: 3.1.0: Use na_boxed_set_from_value() instead.
567 na_data_boxed_set_from_value( NADataBoxed
*boxed
, const GValue
*value
)
569 na_boxed_set_from_value( NA_BOXED( boxed
), value
);
573 * na_data_boxed_set_from_void:
574 * @boxed: the #NADataBoxed whose value is to be set.
575 * @value: the value whose content is to be got.
577 * Evaluates the @value and set it to the @boxed.
580 * Deprecated: 3.1.0: Use na_boxed_set_from_void() instead.
583 na_data_boxed_set_from_void( NADataBoxed
*boxed
, const void *value
)
585 na_boxed_set_from_void( NA_BOXED( boxed
), value
);
587 #endif /* NA_DISABLE_DEPRECATED */
590 bool_spec( const NADataDef
*def
)
592 return( g_param_spec_boolean(
594 gettext( def
->short_label
),
595 gettext( def
->long_label
),
596 na_core_utils_boolean_from_string( def
->default_value
),
597 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
601 bool_is_default( const NADataBoxed
*boxed
)
603 gboolean is_default
= FALSE
;
604 gboolean default_value
;
606 if( boxed
->private->data_def
->default_value
&& strlen( boxed
->private->data_def
->default_value
)){
607 default_value
= na_core_utils_boolean_from_string( boxed
->private->data_def
->default_value
);
608 is_default
= ( default_value
== na_boxed_get_boolean( NA_BOXED( boxed
)));
611 return( is_default
);
615 bool_is_valid( const NADataBoxed
*boxed
)
621 pointer_spec( const NADataDef
*def
)
623 return( g_param_spec_pointer(
625 gettext( def
->short_label
),
626 gettext( def
->long_label
),
627 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
631 * say that a pointer never has its default value
632 * (essentially because there cannot be / one cannot set any relevant
633 * default value for a pointer)
636 pointer_is_default( const NADataBoxed
*boxed
)
642 pointer_is_valid( const NADataBoxed
*boxed
)
644 gboolean is_valid
= TRUE
;
645 gconstpointer pointer
;
647 if( boxed
->private->data_def
->mandatory
){
648 pointer
= na_boxed_get_pointer( NA_BOXED( boxed
));
650 g_debug( "na_data_boxed_pointer_is_valid: invalid %s: mandatory but null", boxed
->private->data_def
->name
);
659 string_spec( const NADataDef
*def
)
661 return( g_param_spec_string(
663 gettext( def
->short_label
),
664 gettext( def
->long_label
),
666 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
670 string_is_default( const NADataBoxed
*boxed
)
672 gboolean is_default
= FALSE
;
673 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
675 if( boxed
->private->data_def
->default_value
){
676 if( value
&& strlen( value
)){
677 /* default value is not null and string has something */
678 is_default
= ( strcmp( value
, boxed
->private->data_def
->default_value
) == 0 );
681 /* default value is not null, but string is null */
686 /* default value is null, but string has something */
690 /* default value and string are both null */
695 return( is_default
);
699 string_is_valid( const NADataBoxed
*boxed
)
701 gboolean is_valid
= TRUE
;
703 if( boxed
->private->data_def
->mandatory
){
704 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
705 if( !value
|| !strlen( value
)){
706 g_debug( "na_data_boxed_string_is_valid: invalid %s: mandatory but empty or null", boxed
->private->data_def
->name
);
716 string_list_spec( const NADataDef
*def
)
718 return( g_param_spec_pointer(
720 gettext( def
->short_label
),
721 gettext( def
->long_label
),
722 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
726 string_list_is_default( const NADataBoxed
*boxed
)
728 gboolean is_default
= FALSE
;
729 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
731 if( boxed
->private->data_def
->default_value
){
732 if( value
&& strlen( value
)){
733 is_default
= ( strcmp( value
, boxed
->private->data_def
->default_value
) == 0 );
737 } else if( value
&& strlen( value
)){
745 return( is_default
);
749 string_list_is_valid( const NADataBoxed
*boxed
)
751 gboolean is_valid
= TRUE
;
753 if( boxed
->private->data_def
->mandatory
){
754 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
755 if( !value
|| !strlen( value
)){
756 g_debug( "na_data_boxed_string_list_is_valid: invalid %s: mandatory but empty or null", boxed
->private->data_def
->name
);
765 locale_is_default( const NADataBoxed
*boxed
)
767 gboolean is_default
= FALSE
;
768 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
770 if( boxed
->private->data_def
->default_value
){
771 if( value
&& strlen( value
)){
772 /* default value is not null and string has something */
773 is_default
= ( na_core_utils_str_collate( value
, boxed
->private->data_def
->default_value
) == 0 );
776 /* default value is not null, but string is null */
780 /* default value is null, but string has something */
784 /* default value and string are both null */
789 return( is_default
);
793 locale_is_valid( const NADataBoxed
*boxed
)
795 gboolean is_valid
= TRUE
;
797 if( boxed
->private->data_def
->mandatory
){
798 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
799 if( !value
|| !g_utf8_strlen( value
, -1 )){
800 g_debug( "na_data_boxed_locale_is_valid: invalid %s: mandatory but empty or null", boxed
->private->data_def
->name
);
810 uint_spec( const NADataDef
*def
)
812 return( g_param_spec_uint(
814 gettext( def
->short_label
),
815 gettext( def
->long_label
),
818 atoi( def
->default_value
),
819 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
823 uint_is_default( const NADataBoxed
*boxed
)
825 gboolean is_default
= FALSE
;
828 if( boxed
->private->data_def
->default_value
){
829 default_value
= atoi( boxed
->private->data_def
->default_value
);
830 is_default
= ( na_boxed_get_uint( NA_BOXED( boxed
)) == default_value
);
833 return( is_default
);
837 uint_is_valid( const NADataBoxed
*boxed
)
843 uint_list_spec( const NADataDef
*def
)
845 return( g_param_spec_pointer(
847 gettext( def
->short_label
),
848 gettext( def
->long_label
),
849 G_PARAM_STATIC_STRINGS
| G_PARAM_READWRITE
));
853 * we assume no default for uint list
856 uint_list_is_default( const NADataBoxed
*boxed
)
862 uint_list_is_valid( const NADataBoxed
*boxed
)
864 gboolean is_valid
= TRUE
;
866 if( boxed
->private->data_def
->mandatory
){
867 gchar
*value
= na_boxed_get_string( NA_BOXED( boxed
));
868 if( !value
|| !strlen( value
)){
869 g_debug( "na_data_boxed_uint_list_is_valid: invalid %s: mandatory but empty or null", boxed
->private->data_def
->name
);