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/>.
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)
34 #include <glib/gi18n.h>
38 #include "fma-exporter.h"
39 #include "fma-export-format.h"
40 #include "fma-settings.h"
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 */
50 static NAExporterFormatStr st_format_ask
= {
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.
77 fma_exporter_get_formats( const FMAPivot
*pivot
)
79 GList
*iexporters
, *imod
;
82 FMAExportFormat
*format
;
84 g_return_val_if_fail( FMA_IS_PIVOT( pivot
), 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
);
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.
112 exporter_get_formats( const FMAIExporter
*exporter
)
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
){
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 );
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
);
144 str_list
= FMA_IEXPORTER_GET_INTERFACE( exporter
)->get_formats( exporter
);
152 * Free the list returned by exporter_get_formats() for this provider
155 exporter_free_formats( const FMAIExporter
*exporter
, GList
*str_list
)
160 if( FMA_IEXPORTER_GET_INTERFACE( exporter
)->get_version
){
161 version
= FMA_IEXPORTER_GET_INTERFACE( exporter
)->get_version( exporter
);
165 g_list_foreach( str_list
, ( GFunc
) g_free
, NULL
);
166 g_list_free( str_list
);
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.
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.
200 fma_exporter_get_ask_option( void )
202 static const gchar
*thisfn
= "fma_exporter_get_ask_option";
203 FMAIExporterFormatv2
*str
;
206 FMAExportFormat
*format
;
208 if( !gtk_icon_size_lookup( GTK_ICON_SIZE_DIALOG
, &width
, &height
)){
212 str
= g_new0( FMAIExporterFormatv2
, 1 );
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
);
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
);
231 g_object_unref( str
->pixbuf
);
233 g_free( str
->description
);
234 g_free( str
->label
);
235 g_free( str
->format
);
238 return( FMA_IOPTION( format
));
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.
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";
266 FMAIExporterBufferParmsv2 parms
;
267 FMAIExporter
*exporter
;
271 g_return_val_if_fail( FMA_IS_PIVOT( pivot
), NULL
);
272 g_return_val_if_fail( FMA_IS_OBJECT_ITEM( item
), NULL
);
276 g_debug( "%s: pivot=%p, item=%p (%s), format=%s, messages=%p",
279 ( void * ) item
, G_OBJECT_TYPE_NAME( item
),
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
));
288 parms
.exported
= ( FMAObjectItem
* ) item
;
289 parms
.format
= g_strdup( format
);
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
);
297 buffer
= parms
.buffer
;
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
);
308 g_free( parms
.format
);
311 msg
= g_strdup_printf( NO_IMPLEMENTATION_MSG
, format
);
312 *messages
= g_slist_append( *messages
, msg
);
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.
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";
338 FMAIExporterFileParmsv2 parms
;
339 FMAIExporter
*exporter
;
343 g_return_val_if_fail( FMA_IS_PIVOT( pivot
), NULL
);
344 g_return_val_if_fail( FMA_IS_OBJECT_ITEM( item
), NULL
);
348 g_debug( "%s: pivot=%p, item=%p (%s), folder_uri=%s, format=%s, messages=%p",
351 ( void * ) item
, G_OBJECT_TYPE_NAME( item
),
354 ( void * ) messages
);
356 exporter
= fma_exporter_find_for_format( pivot
, format
);
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
);
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
);
381 g_free( parms
.format
);
384 msg
= g_strdup_printf( NO_IMPLEMENTATION_MSG
, format
);
385 *messages
= g_slist_append( *messages
, msg
);
388 return( export_uri
);
392 exporter_get_name( const FMAIExporter
*exporter
)
398 if( FMA_IEXPORTER_GET_INTERFACE( exporter
)->get_name
){
399 name
= FMA_IEXPORTER_GET_INTERFACE( exporter
)->get_name( exporter
);
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.
415 fma_exporter_find_for_format( const FMAPivot
*pivot
, const gchar
*format
)
417 FMAIExporter
*exporter
;
418 GList
*formats
, *ifmt
;
420 FMAExportFormat
*export_format
;
422 g_return_val_if_fail( FMA_IS_PIVOT( pivot
), 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
));
437 fma_exporter_free_formats( formats
);