1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
20
|
|
21
|
|
22
|
|
23
|
#include <string.h>
|
24
|
#include <gtk/gtk.h>
|
25
|
|
26
|
#include <libaudcore/audstrings.h>
|
27
|
#include <libaudcore/i18n.h>
|
28
|
#include <libaudcore/plugin.h>
|
29
|
#include <libaudcore/preferences.h>
|
30
|
#include <libaudcore/runtime.h>
|
31
|
|
32
|
#include "filewriter.h"
|
33
|
#include "plugins.h"
|
34
|
#include "convert.h"
|
35
|
|
36
|
class FileWriter : public OutputPlugin
|
37
|
{
|
38
|
public:
|
39
|
static const char about[];
|
40
|
static const char * const defaults[];
|
41
|
static const PreferencesWidget widgets[];
|
42
|
static const PluginPreferences prefs;
|
43
|
|
44
|
static constexpr PluginInfo info = {
|
45
|
N_("FileWriter Plugin"),
|
46
|
PACKAGE,
|
47
|
about,
|
48
|
& prefs
|
49
|
};
|
50
|
|
51
|
constexpr FileWriter () : OutputPlugin (info, 0, true) {}
|
52
|
|
53
|
bool init ();
|
54
|
void cleanup ();
|
55
|
|
56
|
StereoVolume get_volume () { return {0, 0}; }
|
57
|
void set_volume (StereoVolume v) {}
|
58
|
|
59
|
void set_info (const char * filename, const Tuple & tuple);
|
60
|
bool open_audio (int fmt, int rate, int nch);
|
61
|
void close_audio ();
|
62
|
|
63
|
void period_wait () {}
|
64
|
int write_audio (const void * ptr, int length);
|
65
|
void drain () {}
|
66
|
|
67
|
int get_delay ()
|
68
|
{ return 0; }
|
69
|
|
70
|
void pause (bool pause) {}
|
71
|
void flush () {}
|
72
|
};
|
73
|
|
74
|
EXPORT FileWriter aud_plugin_instance;
|
75
|
|
76
|
static String in_filename;
|
77
|
static Tuple in_tuple;
|
78
|
|
79
|
struct format_info input;
|
80
|
|
81
|
static GtkWidget * path_hbox, * path_dirbrowser;
|
82
|
static GtkWidget * fileext_combo, * plugin_button;
|
83
|
|
84
|
enum fileext_t
|
85
|
{
|
86
|
WAV = 0,
|
87
|
#ifdef FILEWRITER_MP3
|
88
|
MP3,
|
89
|
#endif
|
90
|
#ifdef FILEWRITER_VORBIS
|
91
|
VORBIS,
|
92
|
#endif
|
93
|
#ifdef FILEWRITER_FLAC
|
94
|
FLAC,
|
95
|
#endif
|
96
|
FILEEXT_MAX
|
97
|
};
|
98
|
|
99
|
static int fileext;
|
100
|
static const char *fileext_str[FILEEXT_MAX] =
|
101
|
{
|
102
|
"wav",
|
103
|
#ifdef FILEWRITER_MP3
|
104
|
"mp3",
|
105
|
#endif
|
106
|
#ifdef FILEWRITER_VORBIS
|
107
|
"ogg",
|
108
|
#endif
|
109
|
#ifdef FILEWRITER_FLAC
|
110
|
"flac"
|
111
|
#endif
|
112
|
};
|
113
|
|
114
|
static FileWriterImpl *plugin;
|
115
|
|
116
|
static gboolean save_original;
|
117
|
|
118
|
static GtkWidget *filenamefrom_hbox, *filenamefrom_label;
|
119
|
static gboolean filenamefromtags;
|
120
|
|
121
|
static GtkWidget *use_suffix_toggle = nullptr;
|
122
|
static gboolean use_suffix;
|
123
|
|
124
|
static gboolean use_stdout;
|
125
|
|
126
|
static GtkWidget *prependnumber_toggle = nullptr;
|
127
|
static gboolean prependnumber;
|
128
|
|
129
|
static GtkWidget * saveplace1 = nullptr;
|
130
|
static GtkWidget * saveplace2 = nullptr;
|
131
|
static String file_path;
|
132
|
|
133
|
static VFSFile output_file;
|
134
|
|
135
|
FileWriterImpl *plugins[FILEEXT_MAX] = {
|
136
|
&wav_plugin,
|
137
|
#ifdef FILEWRITER_MP3
|
138
|
&mp3_plugin,
|
139
|
#endif
|
140
|
#ifdef FILEWRITER_VORBIS
|
141
|
&vorbis_plugin,
|
142
|
#endif
|
143
|
#ifdef FILEWRITER_FLAC
|
144
|
&flac_plugin,
|
145
|
#endif
|
146
|
};
|
147
|
|
148
|
static void set_plugin(void)
|
149
|
{
|
150
|
if (fileext < 0 || fileext >= FILEEXT_MAX)
|
151
|
fileext = 0;
|
152
|
|
153
|
plugin = plugins[fileext];
|
154
|
}
|
155
|
|
156
|
const char * const FileWriter::defaults[] = {
|
157
|
"fileext", "0",
|
158
|
"filenamefromtags", "TRUE",
|
159
|
"prependnumber", "FALSE",
|
160
|
"save_original", "TRUE",
|
161
|
"use_suffix", "FALSE",
|
162
|
"use_stdout", "FALSE",
|
163
|
nullptr};
|
164
|
|
165
|
bool FileWriter::init ()
|
166
|
{
|
167
|
aud_config_set_defaults ("filewriter", defaults);
|
168
|
|
169
|
fileext = aud_get_int ("filewriter", "fileext");
|
170
|
filenamefromtags = aud_get_bool ("filewriter", "filenamefromtags");
|
171
|
file_path = aud_get_str ("filewriter", "file_path");
|
172
|
prependnumber = aud_get_bool ("filewriter", "prependnumber");
|
173
|
save_original = aud_get_bool ("filewriter", "save_original");
|
174
|
use_suffix = aud_get_bool ("filewriter", "use_suffix");
|
175
|
use_stdout = aud_get_bool ("filewriter", "use_stdout");
|
176
|
|
177
|
if (! file_path[0])
|
178
|
{
|
179
|
file_path = String (filename_to_uri (g_get_home_dir ()));
|
180
|
g_return_val_if_fail (file_path != nullptr, false);
|
181
|
}
|
182
|
|
183
|
set_plugin();
|
184
|
if (plugin->init)
|
185
|
plugin->init();
|
186
|
|
187
|
return true;
|
188
|
}
|
189
|
|
190
|
void FileWriter::cleanup ()
|
191
|
{
|
192
|
file_path = String ();
|
193
|
}
|
194
|
|
195
|
static VFSFile safe_create (const char * filename)
|
196
|
{
|
197
|
if (use_stdout || ! VFSFile::test_file (filename, VFS_EXISTS))
|
198
|
return VFSFile (filename, "w");
|
199
|
|
200
|
const char * extension = strrchr (filename, '.');
|
201
|
|
202
|
for (int count = 1; count < 100; count ++)
|
203
|
{
|
204
|
StringBuf scratch = extension ?
|
205
|
str_printf ("%.*s-%d%s", (int) (extension - filename), filename, count, extension) :
|
206
|
str_printf ("%s-%d", filename, count);
|
207
|
|
208
|
if (! VFSFile::test_file (scratch, VFS_EXISTS))
|
209
|
return VFSFile (scratch, "w");
|
210
|
}
|
211
|
|
212
|
return VFSFile ();
|
213
|
}
|
214
|
|
215
|
void FileWriter::set_info (const char * filename, const Tuple & tuple)
|
216
|
{
|
217
|
in_filename = String (filename);
|
218
|
in_tuple = tuple.ref ();
|
219
|
}
|
220
|
|
221
|
bool FileWriter::open_audio (int fmt, int rate, int nch)
|
222
|
{
|
223
|
String filename, directory;
|
224
|
|
225
|
input.format = fmt;
|
226
|
input.frequency = rate;
|
227
|
input.channels = nch;
|
228
|
|
229
|
if (use_stdout)
|
230
|
{
|
231
|
#ifdef _WINDOWS
|
232
|
filename = String ("file://CON");
|
233
|
#endif
|
234
|
#ifndef _WINDOWS
|
235
|
filename = String ("file:///dev/stdout");
|
236
|
#endif
|
237
|
|
238
|
}
|
239
|
else
|
240
|
{
|
241
|
if (filenamefromtags)
|
242
|
{
|
243
|
String title = in_tuple.get_str (Tuple::FormattedTitle);
|
244
|
StringBuf buf = str_encode_percent (title);
|
245
|
str_replace_char (buf, '/', '-');
|
246
|
filename = String (buf);
|
247
|
}
|
248
|
else
|
249
|
{
|
250
|
const char * original = strrchr (in_filename, '/');
|
251
|
g_return_val_if_fail (original != nullptr, 0);
|
252
|
filename = String (original + 1);
|
253
|
|
254
|
if (! use_suffix)
|
255
|
{
|
256
|
const char * temp;
|
257
|
if ((temp = strrchr (filename, '.')))
|
258
|
filename = String (str_copy (filename, temp - filename));
|
259
|
}
|
260
|
}
|
261
|
|
262
|
if (prependnumber)
|
263
|
{
|
264
|
int number = in_tuple.get_int (Tuple::Track);
|
265
|
if (number >= 0)
|
266
|
filename = String (str_printf ("%d%%20%s", number, (const char *) filename));
|
267
|
}
|
268
|
|
269
|
if (save_original)
|
270
|
{
|
271
|
const char * temp = strrchr (in_filename, '/');
|
272
|
g_return_val_if_fail (temp != nullptr, 0);
|
273
|
directory = String (str_copy (in_filename, temp + 1 - in_filename));
|
274
|
}
|
275
|
else
|
276
|
{
|
277
|
g_return_val_if_fail (file_path[0], 0);
|
278
|
if (file_path[strlen (file_path) - 1] == '/')
|
279
|
directory = String (file_path);
|
280
|
else
|
281
|
directory = String (str_concat ({file_path, "/"}));
|
282
|
}
|
283
|
|
284
|
filename = String (str_printf ("%s%s.%s", (const char *) directory,
|
285
|
(const char *) filename, fileext_str[fileext]));
|
286
|
}
|
287
|
|
288
|
output_file = safe_create (filename);
|
289
|
if (! output_file)
|
290
|
goto err;
|
291
|
|
292
|
convert_init (fmt, plugin->format_required (fmt));
|
293
|
|
294
|
if (plugin->open (output_file, input, in_tuple))
|
295
|
return true;
|
296
|
|
297
|
err:
|
298
|
in_filename = String ();
|
299
|
in_tuple = Tuple ();
|
300
|
return false;
|
301
|
}
|
302
|
|
303
|
int FileWriter::write_audio (const void * ptr, int length)
|
304
|
{
|
305
|
auto & buf = convert_process (ptr, length);
|
306
|
plugin->write (output_file, buf.begin (), buf.len ());
|
307
|
|
308
|
return length;
|
309
|
}
|
310
|
|
311
|
void FileWriter::close_audio ()
|
312
|
{
|
313
|
plugin->close (output_file);
|
314
|
convert_free ();
|
315
|
|
316
|
output_file = VFSFile ();
|
317
|
in_filename = String ();
|
318
|
in_tuple = Tuple ();
|
319
|
}
|
320
|
|
321
|
static void configure_response_cb (void)
|
322
|
{
|
323
|
fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
|
324
|
|
325
|
char * temp = gtk_file_chooser_get_uri ((GtkFileChooser *) path_dirbrowser);
|
326
|
file_path = String (temp);
|
327
|
g_free (temp);
|
328
|
|
329
|
use_suffix =
|
330
|
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(use_suffix_toggle));
|
331
|
|
332
|
prependnumber =
|
333
|
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(prependnumber_toggle));
|
334
|
|
335
|
aud_set_int ("filewriter", "fileext", fileext);
|
336
|
aud_set_bool ("filewriter", "filenamefromtags", filenamefromtags);
|
337
|
aud_set_str ("filewriter", "file_path", file_path);
|
338
|
aud_set_bool ("filewriter", "prependnumber", prependnumber);
|
339
|
aud_set_bool ("filewriter", "save_original", save_original);
|
340
|
aud_set_bool ("filewriter", "use_suffix", use_suffix);
|
341
|
aud_set_bool ("filewriter", "use_stdout", use_stdout);
|
342
|
}
|
343
|
|
344
|
static void fileext_cb(GtkWidget *combo, void * data)
|
345
|
{
|
346
|
fileext = gtk_combo_box_get_active(GTK_COMBO_BOX(fileext_combo));
|
347
|
set_plugin();
|
348
|
if (plugin->init)
|
349
|
plugin->init();
|
350
|
|
351
|
gtk_widget_set_sensitive(plugin_button, plugin->configure != nullptr);
|
352
|
}
|
353
|
|
354
|
static void plugin_configure_cb(GtkWidget *button, void * data)
|
355
|
{
|
356
|
if (plugin->configure)
|
357
|
plugin->configure();
|
358
|
}
|
359
|
|
360
|
|
361
|
static void saveplace_original_cb(GtkWidget *button, void * data)
|
362
|
{
|
363
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
364
|
{
|
365
|
gtk_widget_set_sensitive(path_hbox, FALSE);
|
366
|
save_original = TRUE;
|
367
|
}
|
368
|
}
|
369
|
|
370
|
static void saveplace_custom_cb(GtkWidget *button, void * data)
|
371
|
{
|
372
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
373
|
{
|
374
|
gtk_widget_set_sensitive(path_hbox, TRUE);
|
375
|
save_original = FALSE;
|
376
|
}
|
377
|
}
|
378
|
|
379
|
static void filenamefromtags_cb(GtkWidget *button, void * data)
|
380
|
{
|
381
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
382
|
{
|
383
|
gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
|
384
|
gtk_widget_set_sensitive(saveplace1, TRUE);
|
385
|
gtk_widget_set_sensitive(saveplace2, TRUE);
|
386
|
gtk_widget_set_sensitive(prependnumber_toggle, TRUE);
|
387
|
gtk_widget_set_sensitive(path_hbox, TRUE);
|
388
|
use_suffix = FALSE;
|
389
|
filenamefromtags = TRUE;
|
390
|
use_stdout = FALSE;
|
391
|
}
|
392
|
}
|
393
|
|
394
|
static void filenamefromfilename_cb(GtkWidget *button, void * data)
|
395
|
{
|
396
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
397
|
{
|
398
|
gtk_widget_set_sensitive(use_suffix_toggle, TRUE);
|
399
|
gtk_widget_set_sensitive(saveplace1, TRUE);
|
400
|
gtk_widget_set_sensitive(saveplace2, TRUE);
|
401
|
gtk_widget_set_sensitive(prependnumber_toggle, TRUE);
|
402
|
gtk_widget_set_sensitive(path_hbox, TRUE);
|
403
|
filenamefromtags = FALSE;
|
404
|
use_stdout = FALSE;
|
405
|
}
|
406
|
}
|
407
|
|
408
|
static void filenamefromstdout_cb(GtkWidget *button, void * data)
|
409
|
{
|
410
|
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
|
411
|
{
|
412
|
gtk_widget_set_sensitive(path_hbox, FALSE);
|
413
|
gtk_widget_set_sensitive(saveplace1, FALSE);
|
414
|
gtk_widget_set_sensitive(saveplace2, FALSE);
|
415
|
gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
|
416
|
gtk_widget_set_sensitive(prependnumber_toggle, FALSE);
|
417
|
use_suffix = FALSE;
|
418
|
filenamefromtags = TRUE;
|
419
|
use_stdout = TRUE;
|
420
|
}
|
421
|
}
|
422
|
|
423
|
static void * file_configure (void)
|
424
|
{
|
425
|
GtkWidget * configure_vbox = gtk_vbox_new (FALSE, 6);
|
426
|
|
427
|
GtkWidget * fileext_hbox = gtk_hbox_new (FALSE, 5);
|
428
|
gtk_box_pack_start(GTK_BOX(configure_vbox), fileext_hbox, FALSE, FALSE, 0);
|
429
|
|
430
|
GtkWidget * fileext_label = gtk_label_new (_("Output file format:"));
|
431
|
gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_label, FALSE, FALSE, 0);
|
432
|
|
433
|
fileext_combo = gtk_combo_box_text_new ();
|
434
|
gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "WAV");
|
435
|
#ifdef FILEWRITER_MP3
|
436
|
gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "MP3");
|
437
|
#endif
|
438
|
#ifdef FILEWRITER_VORBIS
|
439
|
gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "Vorbis");
|
440
|
#endif
|
441
|
#ifdef FILEWRITER_FLAC
|
442
|
gtk_combo_box_text_append_text ((GtkComboBoxText *) fileext_combo, "FLAC");
|
443
|
#endif
|
444
|
gtk_box_pack_start(GTK_BOX(fileext_hbox), fileext_combo, FALSE, FALSE, 0);
|
445
|
gtk_combo_box_set_active(GTK_COMBO_BOX(fileext_combo), fileext);
|
446
|
|
447
|
plugin_button = gtk_button_new_with_label(_("Configure"));
|
448
|
gtk_widget_set_sensitive(plugin_button, plugin->configure != nullptr);
|
449
|
gtk_box_pack_end(GTK_BOX(fileext_hbox), plugin_button, FALSE, FALSE, 0);
|
450
|
|
451
|
gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
|
452
|
|
453
|
GtkWidget * saveplace_hbox = gtk_hbox_new (FALSE, 5);
|
454
|
gtk_container_add(GTK_CONTAINER(configure_vbox), saveplace_hbox);
|
455
|
|
456
|
saveplace1 = gtk_radio_button_new_with_label (nullptr,
|
457
|
_("Save into original directory"));
|
458
|
gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace1, FALSE, FALSE, 0);
|
459
|
|
460
|
saveplace2 = gtk_radio_button_new_with_label_from_widget
|
461
|
((GtkRadioButton *) saveplace1, _("Save into custom directory"));
|
462
|
|
463
|
if (!save_original)
|
464
|
gtk_toggle_button_set_active ((GtkToggleButton *) saveplace2, TRUE);
|
465
|
|
466
|
gtk_box_pack_start ((GtkBox *) saveplace_hbox, saveplace2, FALSE, FALSE, 0);
|
467
|
|
468
|
path_hbox = gtk_hbox_new (FALSE, 5);
|
469
|
gtk_box_pack_start(GTK_BOX(configure_vbox), path_hbox, FALSE, FALSE, 0);
|
470
|
|
471
|
GtkWidget * path_label = gtk_label_new (_("Output file folder:"));
|
472
|
gtk_box_pack_start ((GtkBox *) path_hbox, path_label, FALSE, FALSE, 0);
|
473
|
|
474
|
path_dirbrowser =
|
475
|
gtk_file_chooser_button_new (_("Pick a folder"),
|
476
|
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
|
477
|
gtk_file_chooser_set_uri ((GtkFileChooser *) path_dirbrowser, file_path);
|
478
|
gtk_box_pack_start(GTK_BOX(path_hbox), path_dirbrowser, TRUE, TRUE, 0);
|
479
|
|
480
|
if (save_original)
|
481
|
gtk_widget_set_sensitive(path_hbox, FALSE);
|
482
|
|
483
|
gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
|
484
|
|
485
|
filenamefrom_hbox = gtk_hbox_new (FALSE, 5);
|
486
|
gtk_container_add(GTK_CONTAINER(configure_vbox), filenamefrom_hbox);
|
487
|
|
488
|
filenamefrom_label = gtk_label_new(_("Generate file name from:"));
|
489
|
gtk_box_pack_start(GTK_BOX(filenamefrom_hbox), filenamefrom_label, FALSE, FALSE, 0);
|
490
|
|
491
|
GtkWidget * filenamefrom_toggle1 = gtk_radio_button_new_with_label
|
492
|
(nullptr, _("file tag"));
|
493
|
gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle1, FALSE, FALSE, 0);
|
494
|
|
495
|
GtkWidget * filenamefrom_toggle2 =
|
496
|
gtk_radio_button_new_with_label_from_widget
|
497
|
((GtkRadioButton *) filenamefrom_toggle1, _("file name"));
|
498
|
gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle2, FALSE, FALSE, 0);
|
499
|
|
500
|
GtkWidget * filenamefrom_toggle3 =
|
501
|
gtk_radio_button_new_with_label_from_widget
|
502
|
((GtkRadioButton *) filenamefrom_toggle1, _("stdout"));
|
503
|
gtk_box_pack_start ((GtkBox *) filenamefrom_hbox, filenamefrom_toggle3, FALSE, FALSE, 0);
|
504
|
|
505
|
if (use_stdout)
|
506
|
{
|
507
|
gtk_widget_set_sensitive (saveplace1, FALSE);
|
508
|
gtk_widget_set_sensitive (saveplace2, FALSE);
|
509
|
gtk_toggle_button_set_active ((GtkToggleButton *) filenamefrom_toggle3, TRUE);
|
510
|
}
|
511
|
else if (!filenamefromtags)
|
512
|
gtk_toggle_button_set_active ((GtkToggleButton *) filenamefrom_toggle2, TRUE);
|
513
|
|
514
|
use_suffix_toggle = gtk_check_button_new_with_label(_("Include original file name extension"));
|
515
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_suffix_toggle), use_suffix);
|
516
|
gtk_box_pack_start(GTK_BOX(configure_vbox), use_suffix_toggle, FALSE, FALSE, 0);
|
517
|
|
518
|
if (filenamefromtags || use_stdout)
|
519
|
gtk_widget_set_sensitive(use_suffix_toggle, FALSE);
|
520
|
|
521
|
gtk_box_pack_start(GTK_BOX(configure_vbox), gtk_hseparator_new(), FALSE, FALSE, 0);
|
522
|
|
523
|
prependnumber_toggle = gtk_check_button_new_with_label(_("Prepend track number to file name"));
|
524
|
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prependnumber_toggle), prependnumber);
|
525
|
gtk_box_pack_start(GTK_BOX(configure_vbox), prependnumber_toggle, FALSE, FALSE, 0);
|
526
|
|
527
|
if (use_stdout)
|
528
|
{
|
529
|
gtk_widget_set_sensitive(path_hbox, FALSE);
|
530
|
gtk_widget_set_sensitive(prependnumber_toggle, FALSE);
|
531
|
}
|
532
|
|
533
|
g_signal_connect (fileext_combo, "changed", (GCallback) fileext_cb, nullptr);
|
534
|
g_signal_connect (plugin_button, "clicked", (GCallback) plugin_configure_cb, nullptr);
|
535
|
g_signal_connect (saveplace1, "toggled", (GCallback) saveplace_original_cb, nullptr);
|
536
|
g_signal_connect (saveplace2, "toggled", (GCallback) saveplace_custom_cb, nullptr);
|
537
|
g_signal_connect (filenamefrom_toggle1, "toggled", (GCallback) filenamefromtags_cb, nullptr);
|
538
|
g_signal_connect (filenamefrom_toggle2, "toggled", (GCallback) filenamefromfilename_cb, nullptr);
|
539
|
g_signal_connect (filenamefrom_toggle3, "toggled", (GCallback) filenamefromstdout_cb, nullptr);
|
540
|
|
541
|
return configure_vbox;
|
542
|
}
|
543
|
|
544
|
const char FileWriter::about[] =
|
545
|
N_("This program is free software; you can redistribute it and/or modify\n"
|
546
|
"it under the terms of the GNU General Public License as published by\n"
|
547
|
"the Free Software Foundation; either version 2 of the License, or\n"
|
548
|
"(at your option) any later version.\n"
|
549
|
"\n"
|
550
|
"This program is distributed in the hope that it will be useful,\n"
|
551
|
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
552
|
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
553
|
"GNU General Public License for more details.\n"
|
554
|
"\n"
|
555
|
"You should have received a copy of the GNU General Public License\n"
|
556
|
"along with this program; if not, write to the Free Software\n"
|
557
|
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n"
|
558
|
"USA.");
|
559
|
|
560
|
const PreferencesWidget FileWriter::widgets[] = {
|
561
|
WidgetCustomGTK (file_configure)
|
562
|
};
|
563
|
|
564
|
const PluginPreferences FileWriter::prefs = {
|
565
|
{widgets},
|
566
|
nullptr,
|
567
|
configure_response_cb
|
568
|
};
|