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)
37 #include <api/na-data-def.h>
38 #include <api/na-data-types.h>
39 #include <api/na-ifactory-provider.h>
40 #include <api/na-iio-provider.h>
41 #include <api/na-object-api.h>
42 #include <api/na-core-utils.h>
43 #include <api/na-gconf-utils.h>
45 #include "nagp-gconf-provider.h"
46 #include "nagp-keys.h"
47 #include "nagp-reader.h"
56 static NAObjectItem
*read_item( NagpGConfProvider
*provider
, const gchar
*path
, GSList
**messages
);
58 static void read_start_profile_attach_profile( const NAIFactoryProvider
*provider
, NAObjectProfile
*profile
, ReaderData
*data
, GSList
**messages
);
60 static gboolean
read_done_item_is_writable( const NAIFactoryProvider
*provider
, NAObjectItem
*item
, ReaderData
*data
, GSList
**messages
);
61 static void read_done_action_read_profiles( const NAIFactoryProvider
*provider
, NAObjectAction
*action
, ReaderData
*data
, GSList
**messages
);
62 static void read_done_action_load_profile( const NAIFactoryProvider
*provider
, ReaderData
*data
, const gchar
*path
, GSList
**messages
);
64 static NADataBoxed
*get_boxed_from_path( const NagpGConfProvider
*provider
, const gchar
*path
, ReaderData
*reader_data
, const NADataDef
*def
);
65 static gboolean
is_key_writable( NagpGConfProvider
*gconf
, const gchar
*key
);
68 * nagp_iio_provider_read_items:
70 * Note that whatever be the version of the read action, it will be
71 * stored as a #NAObjectAction and its set of #NAObjectProfile of the same,
72 * latest, version of these classes.
75 nagp_iio_provider_read_items( const NAIIOProvider
*provider
, GSList
**messages
)
77 static const gchar
*thisfn
= "nagp_gconf_provider_iio_provider_read_items";
78 NagpGConfProvider
*self
;
79 GList
*items_list
= NULL
;
80 GSList
*listpath
, *ip
;
83 g_debug( "%s: provider=%p, messages=%p", thisfn
, ( void * ) provider
, ( void * ) messages
);
85 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider
), NULL
);
86 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider
), NULL
);
87 self
= NAGP_GCONF_PROVIDER( provider
);
89 if( !self
->private->dispose_has_run
){
91 listpath
= na_gconf_utils_get_subdirs( self
->private->gconf
, NAGP_CONFIGURATIONS_PATH
);
93 for( ip
= listpath
; ip
; ip
= ip
->next
){
95 item
= read_item( self
, ( const gchar
* ) ip
->data
, messages
);
97 items_list
= g_list_prepend( items_list
, item
);
101 na_gconf_utils_free_subdirs( listpath
);
104 g_debug( "%s: count=%d", thisfn
, g_list_length( items_list
));
105 return( items_list
);
109 * path is here the full path to an item
111 static NAObjectItem
*
112 read_item( NagpGConfProvider
*provider
, const gchar
*path
, GSList
**messages
)
114 static const gchar
*thisfn
= "nagp_gconf_provider_read_item";
121 g_debug( "%s: provider=%p, path=%s", thisfn
, ( void * ) provider
, path
);
122 g_return_val_if_fail( NAGP_IS_GCONF_PROVIDER( provider
), NULL
);
123 g_return_val_if_fail( NA_IS_IIO_PROVIDER( provider
), NULL
);
124 g_return_val_if_fail( !provider
->private->dispose_has_run
, NULL
);
126 full_path
= gconf_concat_dir_and_key( path
, NAGP_ENTRY_TYPE
);
127 type
= na_gconf_utils_read_string( provider
->private->gconf
, full_path
, TRUE
, NAGP_VALUE_TYPE_ACTION
);
131 /* a menu may have 'Action' or 'Menu' type ; defaults to Action
133 if( !type
|| !strlen( type
) || !strcmp( type
, NAGP_VALUE_TYPE_ACTION
)){
134 item
= NA_OBJECT_ITEM( na_object_action_new());
136 } else if( !strcmp( type
, NAGP_VALUE_TYPE_MENU
)){
137 item
= NA_OBJECT_ITEM( na_object_menu_new());
140 g_warning( "%s: unknown type '%s' at %s", thisfn
, type
, path
);
146 id
= g_path_get_basename( path
);
147 na_object_set_id( item
, id
);
150 data
= g_new0( ReaderData
, 1 );
151 data
->path
= ( gchar
* ) path
;
152 data
->entries
= na_gconf_utils_get_entries( provider
->private->gconf
, path
);
153 na_gconf_utils_dump_entries( data
->entries
);
155 na_ifactory_provider_read_item(
156 NA_IFACTORY_PROVIDER( provider
),
158 NA_IFACTORY_OBJECT( item
),
161 na_gconf_utils_free_entries( data
->entries
);
169 nagp_reader_read_start( const NAIFactoryProvider
*provider
, void *reader_data
, const NAIFactoryObject
*object
, GSList
**messages
)
171 static const gchar
*thisfn
= "nagp_reader_read_start";
173 g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider
));
174 g_return_if_fail( NAGP_IS_GCONF_PROVIDER( provider
));
175 g_return_if_fail( NA_IS_IFACTORY_OBJECT( object
));
177 if( !NAGP_GCONF_PROVIDER( provider
)->private->dispose_has_run
){
179 g_debug( "%s: provider=%p (%s), reader_data=%p, object=%p (%s), messages=%p",
181 ( void * ) provider
, G_OBJECT_TYPE_NAME( provider
),
182 ( void * ) reader_data
,
183 ( void * ) object
, G_OBJECT_TYPE_NAME( object
),
184 ( void * ) messages
);
186 if( NA_IS_OBJECT_PROFILE( object
)){
187 read_start_profile_attach_profile( provider
, NA_OBJECT_PROFILE( object
), ( ReaderData
* ) reader_data
, messages
);
193 read_start_profile_attach_profile( const NAIFactoryProvider
*provider
, NAObjectProfile
*profile
, ReaderData
*data
, GSList
**messages
)
195 na_object_attach_profile( data
->parent
, profile
);
199 nagp_reader_read_data( const NAIFactoryProvider
*provider
, void *reader_data
, const NAIFactoryObject
*object
, const NADataDef
*def
, GSList
**messages
)
201 static const gchar
*thisfn
= "nagp_reader_read_data";
204 g_return_val_if_fail( NA_IS_IFACTORY_PROVIDER( provider
), NULL
);
205 g_return_val_if_fail( NA_IS_IFACTORY_OBJECT( object
), NULL
);
207 /*g_debug( "%s: reader_data=%p, object=%p (%s), data=%s",
209 ( void * ) reader_data,
210 ( void * ) object, G_OBJECT_TYPE_NAME( object ),
213 if( !def
->gconf_entry
|| !strlen( def
->gconf_entry
)){
214 g_warning( "%s: GConf entry is not set for NADataDef %s", thisfn
, def
->name
);
218 boxed
= get_boxed_from_path(
219 NAGP_GCONF_PROVIDER( provider
), (( ReaderData
* ) reader_data
)->path
, reader_data
, def
);
225 nagp_reader_read_done( const NAIFactoryProvider
*provider
, void *reader_data
, const NAIFactoryObject
*object
, GSList
**messages
)
227 static const gchar
*thisfn
= "nagp_reader_read_done";
230 g_return_if_fail( NA_IS_IFACTORY_PROVIDER( provider
));
231 g_return_if_fail( NAGP_IS_GCONF_PROVIDER( provider
));
232 g_return_if_fail( NA_IS_IFACTORY_OBJECT( object
));
234 if( !NAGP_GCONF_PROVIDER( provider
)->private->dispose_has_run
){
236 g_debug( "%s: provider=%p (%s), reader_data=%p, object=%p (%s), messages=%p",
238 ( void * ) provider
, G_OBJECT_TYPE_NAME( provider
),
239 ( void * ) reader_data
,
240 ( void * ) object
, G_OBJECT_TYPE_NAME( object
),
241 ( void * ) messages
);
243 if( NA_IS_OBJECT_ITEM( object
)){
244 writable
= read_done_item_is_writable( provider
, NA_OBJECT_ITEM( object
), ( ReaderData
* ) reader_data
, messages
);
245 na_object_set_readonly( object
, !writable
);
248 if( NA_IS_OBJECT_ACTION( object
)){
249 read_done_action_read_profiles( provider
, NA_OBJECT_ACTION( object
), ( ReaderData
* ) reader_data
, messages
);
252 g_debug( "%s: quitting for %s at %p", thisfn
, G_OBJECT_TYPE_NAME( object
), ( void * ) object
);
257 read_done_item_is_writable( const NAIFactoryProvider
*provider
, NAObjectItem
*item
, ReaderData
*data
, GSList
**messages
)
261 GConfEntry
*gconf_entry
;
264 /* check for writability of this item
265 * item is writable if and only if all entries are themselves writable
268 for( ie
= data
->entries
; ie
&& writable
; ie
= ie
->next
){
269 gconf_entry
= ( GConfEntry
* ) ie
->data
;
270 key
= gconf_entry_get_key( gconf_entry
);
271 writable
= is_key_writable( NAGP_GCONF_PROVIDER( provider
), key
);
274 g_debug( "nagp_reader_read_done_item: writable=%s", writable
? "True":"False" );
279 read_done_action_read_profiles( const NAIFactoryProvider
*provider
, NAObjectAction
*action
, ReaderData
*data
, GSList
**messages
)
282 GSList
*list_profiles
;
288 data
->parent
= NA_OBJECT_ITEM( action
);
289 order
= na_object_get_items_slist( action
);
290 list_profiles
= na_gconf_utils_get_subdirs( NAGP_GCONF_PROVIDER( provider
)->private->gconf
, data
->path
);
292 /* read profiles in the specified order
293 * as a protection against bugs in NACT, we check that profile has not
294 * already been loaded
296 for( ip
= order
; ip
; ip
= ip
->next
){
297 profile_id
= ( gchar
* ) ip
->data
;
298 found
= na_object_get_item( action
, profile_id
);
300 g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id
);
301 profile_path
= gconf_concat_dir_and_key( data
->path
, profile_id
);
302 read_done_action_load_profile( provider
, data
, profile_path
, messages
);
303 g_free( profile_path
);
307 /* append other profiles
308 * this is mandatory for pre-2.29 actions which introduced order of profiles
310 for( ip
= list_profiles
; ip
; ip
= ip
->next
){
311 profile_id
= g_path_get_basename(( const gchar
* ) ip
->data
);
312 found
= na_object_get_item( action
, profile_id
);
314 g_debug( "nagp_reader_read_done_action: loading profile=%s", profile_id
);
315 read_done_action_load_profile( provider
, data
, ( const gchar
* ) ip
->data
, messages
);
317 g_free( profile_id
);
322 read_done_action_load_profile( const NAIFactoryProvider
*provider
, ReaderData
*data
, const gchar
*path
, GSList
**messages
)
325 ReaderData
*profile_data
;
327 NAObjectProfile
*profile
= na_object_profile_new();
329 id
= g_path_get_basename( path
);
330 na_object_set_id( profile
, id
);
333 profile_data
= g_new0( ReaderData
, 1 );
334 profile_data
->parent
= data
->parent
;
335 profile_data
->path
= ( gchar
* ) path
;
336 profile_data
->entries
= na_gconf_utils_get_entries( NAGP_GCONF_PROVIDER( provider
)->private->gconf
, path
);
338 na_ifactory_provider_read_item(
339 NA_IFACTORY_PROVIDER( provider
),
341 NA_IFACTORY_OBJECT( profile
),
344 na_gconf_utils_free_entries( profile_data
->entries
);
345 g_free( profile_data
);
349 get_boxed_from_path( const NagpGConfProvider
*provider
, const gchar
*path
, ReaderData
*reader_data
, const NADataDef
*def
)
351 static const gchar
*thisfn
= "nagp_reader_get_boxed_from_path";
360 have_entry
= na_gconf_utils_has_entry( reader_data
->entries
, def
->gconf_entry
);
361 g_debug( "%s: entry=%s, have_entry=%s", thisfn
, def
->gconf_entry
, have_entry
? "True":"False" );
364 boxed
= na_data_boxed_new( def
);
365 gchar
*entry_path
= gconf_concat_dir_and_key( path
, def
->gconf_entry
);
369 case NAFD_TYPE_STRING
:
370 case NAFD_TYPE_LOCALE_STRING
:
371 str_value
= na_gconf_utils_read_string( provider
->private->gconf
, entry_path
, TRUE
, NULL
);
372 g_debug( "%s: entry=%s, value=%s", thisfn
, def
->gconf_entry
, str_value
);
373 na_data_boxed_set_from_string( boxed
, str_value
);
377 case NAFD_TYPE_BOOLEAN
:
378 bool_value
= na_gconf_utils_read_bool( provider
->private->gconf
, entry_path
, TRUE
, FALSE
);
379 na_data_boxed_set_from_void( boxed
, GUINT_TO_POINTER( bool_value
));
382 case NAFD_TYPE_STRING_LIST
:
383 slist_value
= na_gconf_utils_read_string_list( provider
->private->gconf
, entry_path
);
384 na_data_boxed_set_from_void( boxed
, slist_value
);
385 na_core_utils_slist_free( slist_value
);
389 int_value
= na_gconf_utils_read_int( provider
->private->gconf
, entry_path
, TRUE
, 0 );
390 na_data_boxed_set_from_void( boxed
, GUINT_TO_POINTER( int_value
));
394 g_warning( "%s: unknown type=%u for %s", thisfn
, def
->type
, def
->name
);
399 g_free( entry_path
);
406 * key must be an existing entry (not a dir) to get a relevant return
407 * value ; else we get FALSE
410 is_key_writable( NagpGConfProvider
*gconf
, const gchar
*key
)
412 static const gchar
*thisfn
= "nagp_read_is_key_writable";
413 GError
*error
= NULL
;
414 gboolean is_writable
;
416 is_writable
= gconf_client_key_is_writable( gconf
->private->gconf
, key
, &error
);
418 g_warning( "%s: gconf_client_key_is_writable: %s", thisfn
, error
->message
);
419 g_error_free( error
);
424 return( is_writable
);