README: add deprecation notice
[nautilus-actions.git] / src / core / fma-exporter.c
bloba1cb54163b7e9e15af369166f363a0511d3955d7
1 /*
2 * FileManager-Actions
3 * A file-manager extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2015 Pierre Wieser and others (see AUTHORS)
9 * FileManager-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.
14 * FileManager-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.
19 * You should have received a copy of the GNU General Public License
20 * along with FileManager-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
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)
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
34 #include <glib/gi18n.h>
35 #include <gtk/gtk.h>
36 #include <string.h>
38 #include "fma-exporter.h"
39 #include "fma-export-format.h"
40 #include "fma-settings.h"
42 typedef struct {
43 const gchar *format; /* export format saved in user's preferences */
44 const gchar *label; /* short label */
45 const gchar *description; /* full description */
46 const gchar *image; /* associated image */
48 NAExporterFormatStr;
50 static NAExporterFormatStr st_format_ask = {
51 EXPORTER_FORMAT_ASK,
52 N_( "_Ask me" ),
53 N_( "You will be asked for the format to choose each time an item " \
54 "is about to be exported." ),
55 "fma-export-format-ask.png"
58 /* i18n: FMAIExporter is an interface name, do not even try to translate */
59 #define NO_IMPLEMENTATION_MSG N_( "No FMAIExporter implementation found for '%s' format." )
61 static GList *exporter_get_formats( const FMAIExporter *exporter );
62 static void exporter_free_formats( const FMAIExporter *exporter, GList * str_list );
63 static gchar *exporter_get_name( const FMAIExporter *exporter );
64 static void on_pixbuf_finalized( gpointer user_data, GObject *pixbuf );
67 * fma_exporter_get_formats:
68 * @pivot: the #FMAPivot instance.
70 * Returns: a list of #FMAExportFormat objects, each of them addressing an
71 * available export format, i.e. a format provided by a module which
72 * implement the #FMAIExporter interface.
74 * The returned list should later be fma_exporter_free_formats() by the caller.
76 GList *
77 fma_exporter_get_formats( const FMAPivot *pivot )
79 GList *iexporters, *imod;
80 GList *formats;
81 GList *str_list, *is;
82 FMAExportFormat *format;
84 g_return_val_if_fail( FMA_IS_PIVOT( pivot ), NULL );
86 formats = NULL;
87 iexporters = fma_pivot_get_providers( pivot, FMA_TYPE_IEXPORTER );
89 for( imod = iexporters ; imod ; imod = imod->next ){
90 str_list = exporter_get_formats( FMA_IEXPORTER( imod->data ));
92 for( is = str_list ; is ; is = is->next ){
93 format = fma_export_format_new(( FMAIExporterFormatv2 * ) is->data );
94 formats = g_list_prepend( formats, format );
97 exporter_free_formats( FMA_IEXPORTER( imod->data ), str_list );
100 fma_pivot_free_providers( iexporters );
102 return( formats );
106 * Returns a GList of FMAIExporterFormatv2 structures which describes
107 * the export formats provided by the exporter
108 * If the provider only implements the v1 interface, we dynamically
109 * allocate a new structure and convert the v1 to the v2.
111 static GList *
112 exporter_get_formats( const FMAIExporter *exporter )
114 GList *str_list;
115 guint version;
117 str_list = NULL;
119 version = 1;
120 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->get_version ){
121 version = FMA_IEXPORTER_GET_INTERFACE( exporter )->get_version( exporter );
124 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->get_formats ){
125 if( version == 1 ){
126 #ifdef FMA_ENABLE_DEPRECATED
127 const FMAIExporterFormat *strv1;
128 strv1 = FMA_IEXPORTER_GET_INTERFACE( exporter )->get_formats( exporter );
129 while( strv1->format ){
130 FMAIExporterFormatv2 *strv2 = g_new0( FMAIExporterFormatv2, 1 );
131 strv2->version = 2;
132 strv2->provider = ( FMAIExporter * ) exporter;
133 strv2->format = strv1->format;
134 strv2->label = strv1->label;
135 strv2->description = strv1->description;
136 strv2->pixbuf = NULL;
137 str_list = g_list_prepend( str_list, strv2 );
138 strv1++;
140 #else
142 #endif
143 } else {
144 str_list = FMA_IEXPORTER_GET_INTERFACE( exporter )->get_formats( exporter );
148 return( str_list );
152 * Free the list returned by exporter_get_formats() for this provider
154 static void
155 exporter_free_formats( const FMAIExporter *exporter, GList *str_list )
157 guint version;
159 version = 1;
160 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->get_version ){
161 version = FMA_IEXPORTER_GET_INTERFACE( exporter )->get_version( exporter );
164 if( version == 1 ){
165 g_list_foreach( str_list, ( GFunc ) g_free, NULL );
166 g_list_free( str_list );
168 } else {
169 g_return_if_fail( FMA_IEXPORTER_GET_INTERFACE( exporter )->free_formats );
170 FMA_IEXPORTER_GET_INTERFACE( exporter )->free_formats( exporter, str_list );
175 * fma_exporter_free_formats:
176 * @formats: a list of available export formats, as returned by
177 * fma_exporter_get_formats().
179 * Release the @formats #GList.
181 void
182 fma_exporter_free_formats( GList *formats )
184 static const gchar *thisfn = "fma_exporter_free_formats";
186 g_debug( "%s: formats=%p (count=%d)", thisfn, ( void * ) formats, g_list_length( formats ));
188 g_list_foreach( formats, ( GFunc ) g_object_unref, NULL );
189 g_list_free( formats );
193 * fma_exporter_get_ask_option:
195 * Returns the 'Ask me' option.
197 * Since: 3.2
199 FMAIOption *
200 fma_exporter_get_ask_option( void )
202 static const gchar *thisfn = "fma_exporter_get_ask_option";
203 FMAIExporterFormatv2 *str;
204 gint width, height;
205 gchar *fname;
206 FMAExportFormat *format;
208 if( !gtk_icon_size_lookup( GTK_ICON_SIZE_DIALOG, &width, &height )){
209 width = height = 48;
212 str = g_new0( FMAIExporterFormatv2, 1 );
213 str->version = 2;
214 str->provider = NULL;
215 str->format = g_strdup( st_format_ask.format );
216 str->label = g_strdup( gettext( st_format_ask.label ));
217 str->description = g_strdup( gettext( st_format_ask.description ));
218 if( st_format_ask.image ){
219 fname = g_strdup_printf( "%s/%s", PKGEXPORTFORMATDIR, st_format_ask.image );
220 str->pixbuf = gdk_pixbuf_new_from_file_at_size( fname, width, height, NULL );
221 g_free( fname );
222 if( str->pixbuf ){
223 g_debug( "%s: allocating pixbuf at %p", thisfn, str->pixbuf );
224 g_object_weak_ref( G_OBJECT( str->pixbuf ), ( GWeakNotify ) on_pixbuf_finalized, NULL );
228 format = fma_export_format_new( str );
230 if( str->pixbuf ){
231 g_object_unref( str->pixbuf );
233 g_free( str->description );
234 g_free( str->label );
235 g_free( str->format );
236 g_free( str );
238 return( FMA_IOPTION( format ));
241 static void
242 on_pixbuf_finalized( gpointer user_data /* ==NULL */, GObject *pixbuf )
244 g_debug( "fma_exporter_on_pixbuf_finalized: pixbuf=%p", ( void * ) pixbuf );
248 * fma_exporter_to_buffer:
249 * @pivot: the #FMAPivot pivot for the running application.
250 * @item: a #FMAObjectItem-derived object.
251 * @format: the target format identifier.
252 * @messages: a pointer to a #GSList list of strings; the provider
253 * may append messages to this list, but shouldn't reinitialize it.
255 * Exports the specified @item in the required @format.
257 * Returns: the output buffer, as a newly allocated string which should
258 * be g_free() by the caller, or %NULL if an error has been detected.
260 gchar *
261 fma_exporter_to_buffer( const FMAPivot *pivot,
262 const FMAObjectItem *item, const gchar *format, GSList **messages )
264 static const gchar *thisfn = "fma_exporter_to_buffer";
265 gchar *buffer;
266 FMAIExporterBufferParmsv2 parms;
267 FMAIExporter *exporter;
268 gchar *name;
269 gchar *msg;
271 g_return_val_if_fail( FMA_IS_PIVOT( pivot ), NULL );
272 g_return_val_if_fail( FMA_IS_OBJECT_ITEM( item ), NULL );
274 buffer = NULL;
276 g_debug( "%s: pivot=%p, item=%p (%s), format=%s, messages=%p",
277 thisfn,
278 ( void * ) pivot,
279 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
280 format,
281 ( void * ) messages );
283 exporter = fma_exporter_find_for_format( pivot, format );
284 g_debug( "%s: exporter=%p (%s)", thisfn, ( void * ) exporter, G_OBJECT_TYPE_NAME( exporter ));
286 if( exporter ){
287 parms.version = 2;
288 parms.exported = ( FMAObjectItem * ) item;
289 parms.format = g_strdup( format );
290 parms.buffer = NULL;
291 parms.messages = messages ? *messages : NULL;
293 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->to_buffer ){
294 FMA_IEXPORTER_GET_INTERFACE( exporter )->to_buffer( exporter, &parms );
296 if( parms.buffer ){
297 buffer = parms.buffer;
300 } else {
301 name = exporter_get_name( exporter );
302 /* i18n: FMAIExporter is an interface name, do not even try to translate */
303 msg = g_strdup_printf( _( "%s FMAIExporter doesn't implement 'to_buffer' interface." ), name );
304 *messages = g_slist_append( *messages, msg );
305 g_free( name );
308 g_free( parms.format );
310 } else {
311 msg = g_strdup_printf( NO_IMPLEMENTATION_MSG, format );
312 *messages = g_slist_append( *messages, msg );
315 return( buffer );
319 * fma_exporter_to_file:
320 * @pivot: the #FMAPivot pivot for the running application.
321 * @item: a #FMAObjectItem-derived object.
322 * @folder_uri: the URI of the target folder.
323 * @format: the target format identifier.
324 * @messages: a pointer to a #GSList list of strings; the provider
325 * may append messages to this list, but shouldn't reinitialize it.
327 * Exports the specified @item to the target @uri in the required @format.
329 * Returns: the URI of the exported file, as a newly allocated string which
330 * should be g_free() by the caller, or %NULL if an error has been detected.
332 gchar *
333 fma_exporter_to_file( const FMAPivot *pivot,
334 const FMAObjectItem *item, const gchar *folder_uri, const gchar *format, GSList **messages )
336 static const gchar *thisfn = "fma_exporter_to_file";
337 gchar *export_uri;
338 FMAIExporterFileParmsv2 parms;
339 FMAIExporter *exporter;
340 gchar *msg;
341 gchar *name;
343 g_return_val_if_fail( FMA_IS_PIVOT( pivot ), NULL );
344 g_return_val_if_fail( FMA_IS_OBJECT_ITEM( item ), NULL );
346 export_uri = NULL;
348 g_debug( "%s: pivot=%p, item=%p (%s), folder_uri=%s, format=%s, messages=%p",
349 thisfn,
350 ( void * ) pivot,
351 ( void * ) item, G_OBJECT_TYPE_NAME( item ),
352 folder_uri,
353 format,
354 ( void * ) messages );
356 exporter = fma_exporter_find_for_format( pivot, format );
358 if( exporter ){
359 parms.version = 2;
360 parms.exported = ( FMAObjectItem * ) item;
361 parms.folder = ( gchar * ) folder_uri;
362 parms.format = g_strdup( format );
363 parms.basename = NULL;
364 parms.messages = messages ? *messages : NULL;
366 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->to_file ){
367 FMA_IEXPORTER_GET_INTERFACE( exporter )->to_file( exporter, &parms );
369 if( parms.basename ){
370 export_uri = g_strdup_printf( "%s%s%s", folder_uri, G_DIR_SEPARATOR_S, parms.basename );
373 } else {
374 name = exporter_get_name( exporter );
375 /* i18n: FMAIExporter is an interface name, do not even try to translate */
376 msg = g_strdup_printf( _( "%s FMAIExporter doesn't implement 'to_file' interface." ), name );
377 *messages = g_slist_append( *messages, msg );
378 g_free( name );
381 g_free( parms.format );
383 } else {
384 msg = g_strdup_printf( NO_IMPLEMENTATION_MSG, format );
385 *messages = g_slist_append( *messages, msg );
388 return( export_uri );
391 static gchar *
392 exporter_get_name( const FMAIExporter *exporter )
394 gchar *name;
396 name = NULL;
398 if( FMA_IEXPORTER_GET_INTERFACE( exporter )->get_name ){
399 name = FMA_IEXPORTER_GET_INTERFACE( exporter )->get_name( exporter );
402 return( name );
406 * fma_exporter_find_for_format:
407 * @pivot: the #FMAPivot instance.
408 * @format: the string identifier of the searched format.
410 * Returns: the #FMAIExporter instance which provides the @format export
411 * format. The returned instance is owned by @pivot, and should not be
412 * released by the caller.
414 FMAIExporter *
415 fma_exporter_find_for_format( const FMAPivot *pivot, const gchar *format )
417 FMAIExporter *exporter;
418 GList *formats, *ifmt;
419 gchar *id;
420 FMAExportFormat *export_format;
422 g_return_val_if_fail( FMA_IS_PIVOT( pivot ), NULL );
424 exporter = NULL;
425 formats = fma_exporter_get_formats( pivot );
427 for( ifmt = formats ; ifmt && !exporter ; ifmt = ifmt->next ){
429 export_format = FMA_EXPORT_FORMAT( ifmt->data );
430 id = fma_ioption_get_id( FMA_IOPTION( export_format ));
431 if( !strcmp( id, format )){
432 exporter = fma_export_format_get_provider( FMA_EXPORT_FORMAT( ifmt->data ));
434 g_free( id );
437 fma_exporter_free_formats( formats );
439 return( exporter );