1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
4 *
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2014 Pierre Wieser and others (see AUTHORS)
8 *
9 * Nautilus-Actions 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.
13 *
14 * Nautilus-Actions 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 GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Nautilus-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
22 *
23 * Authors:
24 * Frederic Ruaudel <grumz@grumz.net>
25 * Rodrigo Moya <rodrigo@gnome-db.org>
26 * Pierre Wieser <pwieser@trychlos.org>
27 * ... and many others (see AUTHORS)
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <glib/gi18n.h>
35 #include <string.h>
36
37 #include <api/na-core-utils.h>
38 #include <api/na-ifactory-provider.h>
39
40 #include "nadp-desktop-provider.h"
41 #include "nadp-formats.h"
42 #include "nadp-keys.h"
43 #include "nadp-monitor.h"
44 #include "nadp-reader.h"
45 #include "nadp-writer.h"
46
47 /* private class data
48 */
49 struct _NadpDesktopProviderClassPrivate {
50 void *empty; /* so that gcc -pedantic is happy */
51 };
52
53 static GType st_module_type = 0;
54 static GObjectClass *st_parent_class = NULL;
55 static guint st_burst_timeout = 100; /* burst timeout in msec */
56
57 static void class_init( NadpDesktopProviderClass *klass );
58 static void instance_init( GTypeInstance *instance, gpointer klass );
59 static void instance_dispose( GObject *object );
60 static void instance_finalize( GObject *object );
61
62 static void iio_provider_iface_init( NAIIOProviderInterface *iface );
63 static gchar *iio_provider_get_id( const NAIIOProvider *provider );
64 static gchar *iio_provider_get_name( const NAIIOProvider *provider );
65 static guint iio_provider_get_version( const NAIIOProvider *provider );
66
67 static void ifactory_provider_iface_init( NAIFactoryProviderInterface *iface );
68 static guint ifactory_provider_get_version( const NAIFactoryProvider *reader );
69
70 static void iimporter_iface_init( NAIImporterInterface *iface );
71 static guint iimporter_get_version( const NAIImporter *importer );
72
73 static void iexporter_iface_init( NAIExporterInterface *iface );
74 static guint iexporter_get_version( const NAIExporter *exporter );
75 static gchar *iexporter_get_name( const NAIExporter *exporter );
76 static void *iexporter_get_formats( const NAIExporter *exporter );
77 static void iexporter_free_formats( const NAIExporter *exporter, GList *format_list );
78
79 static void on_monitor_timeout( NadpDesktopProvider *provider );
80
81 GType
nadp_desktop_provider_get_type(void)82 nadp_desktop_provider_get_type( void )
83 {
84 return( st_module_type );
85 }
86
87 void
nadp_desktop_provider_register_type(GTypeModule * module)88 nadp_desktop_provider_register_type( GTypeModule *module )
89 {
90 static const gchar *thisfn = "nadp_desktop_provider_register_type";
91
92 static GTypeInfo info = {
93 sizeof( NadpDesktopProviderClass ),
94 NULL,
95 NULL,
96 ( GClassInitFunc ) class_init,
97 NULL,
98 NULL,
99 sizeof( NadpDesktopProvider ),
100 0,
101 ( GInstanceInitFunc ) instance_init
102 };
103
104 static const GInterfaceInfo iio_provider_iface_info = {
105 ( GInterfaceInitFunc ) iio_provider_iface_init,
106 NULL,
107 NULL
108 };
109
110 static const GInterfaceInfo ifactory_provider_iface_info = {
111 ( GInterfaceInitFunc ) ifactory_provider_iface_init,
112 NULL,
113 NULL
114 };
115
116 static const GInterfaceInfo iimporter_iface_info = {
117 ( GInterfaceInitFunc ) iimporter_iface_init,
118 NULL,
119 NULL
120 };
121
122 static const GInterfaceInfo iexporter_iface_info = {
123 ( GInterfaceInitFunc ) iexporter_iface_init,
124 NULL,
125 NULL
126 };
127
128 g_debug( "%s", thisfn );
129
130 st_module_type = g_type_module_register_type( module, G_TYPE_OBJECT, "NadpDesktopProvider", &info, 0 );
131
132 g_type_module_add_interface( module, st_module_type, NA_TYPE_IIO_PROVIDER, &iio_provider_iface_info );
133
134 g_type_module_add_interface( module, st_module_type, NA_TYPE_IFACTORY_PROVIDER, &ifactory_provider_iface_info );
135
136 g_type_module_add_interface( module, st_module_type, NA_TYPE_IIMPORTER, &iimporter_iface_info );
137
138 g_type_module_add_interface( module, st_module_type, NA_TYPE_IEXPORTER, &iexporter_iface_info );
139 }
140
141 static void
class_init(NadpDesktopProviderClass * klass)142 class_init( NadpDesktopProviderClass *klass )
143 {
144 static const gchar *thisfn = "nadp_desktop_provider_class_init";
145 GObjectClass *object_class;
146
147 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
148
149 st_parent_class = g_type_class_peek_parent( klass );
150
151 object_class = G_OBJECT_CLASS( klass );
152 object_class->dispose = instance_dispose;
153 object_class->finalize = instance_finalize;
154
155 klass->private = g_new0( NadpDesktopProviderClassPrivate, 1 );
156 }
157
158 static void
instance_init(GTypeInstance * instance,gpointer klass)159 instance_init( GTypeInstance *instance, gpointer klass )
160 {
161 static const gchar *thisfn = "nadp_desktop_provider_instance_init";
162 NadpDesktopProvider *self;
163
164 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( instance ));
165
166 g_debug( "%s: instance=%p (%s), klass=%p",
167 thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );
168
169 self = NADP_DESKTOP_PROVIDER( instance );
170
171 self->private = g_new0( NadpDesktopProviderPrivate, 1 );
172
173 self->private->dispose_has_run = FALSE;
174 self->private->monitors = NULL;
175 self->private->timeout.timeout = st_burst_timeout;
176 self->private->timeout.handler = ( NATimeoutFunc ) on_monitor_timeout;
177 self->private->timeout.user_data = self;
178 self->private->timeout.source_id = 0;
179 }
180
181 static void
instance_dispose(GObject * object)182 instance_dispose( GObject *object )
183 {
184 static const gchar *thisfn = "nadp_desktop_provider_instance_dispose";
185 NadpDesktopProvider *self;
186
187 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( object ));
188
189 self = NADP_DESKTOP_PROVIDER( object );
190
191 if( !self->private->dispose_has_run ){
192
193 g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
194
195 self->private->dispose_has_run = TRUE;
196
197 nadp_desktop_provider_release_monitors( self );
198
199 /* chain up to the parent class */
200 if( G_OBJECT_CLASS( st_parent_class )->dispose ){
201 G_OBJECT_CLASS( st_parent_class )->dispose( object );
202 }
203 }
204 }
205
206 static void
instance_finalize(GObject * object)207 instance_finalize( GObject *object )
208 {
209 static const gchar *thisfn = "nadp_desktop_provider_instance_finalize";
210 NadpDesktopProvider *self;
211
212 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( object ));
213
214 g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));
215
216 self = NADP_DESKTOP_PROVIDER( object );
217
218 g_free( self->private );
219
220 /* chain call to parent class */
221 if( G_OBJECT_CLASS( st_parent_class )->finalize ){
222 G_OBJECT_CLASS( st_parent_class )->finalize( object );
223 }
224 }
225
226 static void
iio_provider_iface_init(NAIIOProviderInterface * iface)227 iio_provider_iface_init( NAIIOProviderInterface *iface )
228 {
229 static const gchar *thisfn = "nadp_desktop_provider_iio_provider_iface_init";
230
231 g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
232
233 iface->get_version = iio_provider_get_version;
234 iface->get_id = iio_provider_get_id;
235 iface->get_name = iio_provider_get_name;
236 iface->read_items = nadp_iio_provider_read_items;
237 iface->is_willing_to_write = nadp_iio_provider_is_willing_to_write;
238 iface->is_able_to_write = nadp_iio_provider_is_able_to_write;
239 iface->write_item = nadp_iio_provider_write_item;
240 iface->delete_item = nadp_iio_provider_delete_item;
241 iface->duplicate_data = nadp_iio_provider_duplicate_data;
242 }
243
244 static guint
iio_provider_get_version(const NAIIOProvider * provider)245 iio_provider_get_version( const NAIIOProvider *provider )
246 {
247 return( 1 );
248 }
249
250 static gchar *
iio_provider_get_id(const NAIIOProvider * provider)251 iio_provider_get_id( const NAIIOProvider *provider )
252 {
253 return( g_strdup( PROVIDER_ID ));
254 }
255
256 static gchar *
iio_provider_get_name(const NAIIOProvider * provider)257 iio_provider_get_name( const NAIIOProvider *provider )
258 {
259 return( g_strdup( _( "Nautilus-Actions Desktop I/O Provider" )));
260 }
261
262 static void
ifactory_provider_iface_init(NAIFactoryProviderInterface * iface)263 ifactory_provider_iface_init( NAIFactoryProviderInterface *iface )
264 {
265 static const gchar *thisfn = "nadp_desktop_provider_ifactory_provider_iface_init";
266
267 g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
268
269 iface->get_version = ifactory_provider_get_version;
270 iface->read_start = nadp_reader_ifactory_provider_read_start;
271 iface->read_data = nadp_reader_ifactory_provider_read_data;
272 iface->read_done = nadp_reader_ifactory_provider_read_done;
273 iface->write_start = nadp_writer_ifactory_provider_write_start;
274 iface->write_data = nadp_writer_ifactory_provider_write_data;
275 iface->write_done = nadp_writer_ifactory_provider_write_done;
276 }
277
278 static guint
ifactory_provider_get_version(const NAIFactoryProvider * reader)279 ifactory_provider_get_version( const NAIFactoryProvider *reader )
280 {
281 return( 1 );
282 }
283
284 static void
iimporter_iface_init(NAIImporterInterface * iface)285 iimporter_iface_init( NAIImporterInterface *iface )
286 {
287 static const gchar *thisfn = "nadp_desktop_provider_iimporter_iface_init";
288
289 g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
290
291 iface->get_version = iimporter_get_version;
292 iface->import_from_uri = nadp_reader_iimporter_import_from_uri;
293 }
294
295 static guint
iimporter_get_version(const NAIImporter * importer)296 iimporter_get_version( const NAIImporter *importer )
297 {
298 return( 2 );
299 }
300
301 static void
iexporter_iface_init(NAIExporterInterface * iface)302 iexporter_iface_init( NAIExporterInterface *iface )
303 {
304 static const gchar *thisfn = "nadp_desktop_iexporter_iface_init";
305
306 g_debug( "%s: iface=%p", thisfn, ( void * ) iface );
307
308 iface->get_version = iexporter_get_version;
309 iface->get_name = iexporter_get_name;
310 iface->get_formats = iexporter_get_formats;
311 iface->free_formats = iexporter_free_formats;
312 iface->to_file = nadp_writer_iexporter_export_to_file;
313 iface->to_buffer = nadp_writer_iexporter_export_to_buffer;
314 }
315
316 static guint
iexporter_get_version(const NAIExporter * exporter)317 iexporter_get_version( const NAIExporter *exporter )
318 {
319 return( 2 );
320 }
321
322 static gchar *
iexporter_get_name(const NAIExporter * exporter)323 iexporter_get_name( const NAIExporter *exporter )
324 {
325 return( g_strdup( "NA Desktop Exporter" ));
326 }
327
328 static void *
iexporter_get_formats(const NAIExporter * exporter)329 iexporter_get_formats( const NAIExporter *exporter )
330 {
331 return(( void * ) nadp_formats_get_formats( exporter ));
332 }
333
334 static void
iexporter_free_formats(const NAIExporter * exporter,GList * format_list)335 iexporter_free_formats( const NAIExporter *exporter, GList *format_list )
336 {
337 nadp_formats_free_formats( format_list );
338 }
339
340 /**
341 * nadp_desktop_provider_add_monitor:
342 * @provider: this #NadpDesktopProvider object.
343 * @dir: the path to the directory to be monitored. May not exist.
344 *
345 * Installs a GIO monitor on the given directory.
346 */
347 void
nadp_desktop_provider_add_monitor(NadpDesktopProvider * provider,const gchar * dir)348 nadp_desktop_provider_add_monitor( NadpDesktopProvider *provider, const gchar *dir )
349 {
350 NadpMonitor *monitor;
351
352 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( provider ));
353
354 if( !provider->private->dispose_has_run ){
355
356 monitor = nadp_monitor_new( provider, dir );
357 provider->private->monitors = g_list_prepend( provider->private->monitors, monitor );
358 }
359 }
360
361 /**
362 * nadp_desktop_provider_on_monitor_event:
363 * @provider: this #NadpDesktopProvider object.
364 *
365 * Factorize events received from GIO when monitoring desktop directories.
366 */
367 void
nadp_desktop_provider_on_monitor_event(NadpDesktopProvider * provider)368 nadp_desktop_provider_on_monitor_event( NadpDesktopProvider *provider )
369 {
370 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( provider ));
371
372 if( !provider->private->dispose_has_run ){
373
374 na_timeout_event( &provider->private->timeout );
375 }
376 }
377
378 /**
379 * nadp_desktop_provider_release_monitors:
380 * @provider: this #NadpDesktopProvider object.
381 *
382 * Release previously set desktop monitors.
383 */
384 void
nadp_desktop_provider_release_monitors(NadpDesktopProvider * provider)385 nadp_desktop_provider_release_monitors( NadpDesktopProvider *provider )
386 {
387 g_return_if_fail( NADP_IS_DESKTOP_PROVIDER( provider ));
388
389 if( provider->private->monitors ){
390
391 g_list_foreach( provider->private->monitors, ( GFunc ) g_object_unref, NULL );
392 g_list_free( provider->private->monitors );
393 provider->private->monitors = NULL;
394 }
395 }
396
397 static void
on_monitor_timeout(NadpDesktopProvider * provider)398 on_monitor_timeout( NadpDesktopProvider *provider )
399 {
400 static const gchar *thisfn = "nadp_desktop_provider_on_monitor_timeout";
401
402 /* last individual notification is older that the st_burst_timeout
403 * so triggers the NAIIOProvider interface and destroys this timeout
404 */
405 g_debug( "%s: triggering NAIIOProvider interface for provider=%p (%s)",
406 thisfn, ( void * ) provider, G_OBJECT_TYPE_NAME( provider ));
407
408 na_iio_provider_item_changed( NA_IIO_PROVIDER( provider ));
409 }
410