1
|
|
2
|
|
3
|
|
4
|
|
5
|
|
6
|
|
7
|
|
8
|
|
9
|
|
10
|
|
11
|
|
12
|
|
13
|
|
14
|
|
15
|
|
16
|
|
17
|
|
18
|
|
19
|
|
20
|
|
21
|
#include <gtk/gtk.h>
|
22
|
#include <stdarg.h>
|
23
|
#include <stdlib.h>
|
24
|
#include <string.h>
|
25
|
|
26
|
#include <libaudcore/audstrings.h>
|
27
|
#include <libaudcore/hook.h>
|
28
|
#include <libaudcore/i18n.h>
|
29
|
#include <libaudcore/interface.h>
|
30
|
#include <libaudcore/mainloop.h>
|
31
|
#include <libaudcore/playlist.h>
|
32
|
#include <libaudcore/probe.h>
|
33
|
#include <libaudcore/runtime.h>
|
34
|
#include <libaudcore/tuple.h>
|
35
|
|
36
|
#include "internal.h"
|
37
|
#include "libaudgui.h"
|
38
|
#include "libaudgui-gtk.h"
|
39
|
|
40
|
#define AUDGUI_STATUS_TIMEOUT 3000
|
41
|
|
42
|
enum {
|
43
|
CODEC_FORMAT,
|
44
|
CODEC_QUALITY,
|
45
|
CODEC_BITRATE,
|
46
|
CODEC_ITEMS
|
47
|
};
|
48
|
|
49
|
static const char * codec_labels[CODEC_ITEMS] = {
|
50
|
N_("Format:"),
|
51
|
N_("Quality:"),
|
52
|
N_("Bitrate:")
|
53
|
};
|
54
|
|
55
|
static struct {
|
56
|
GtkTextView * location;
|
57
|
GtkWidget * location_scrolled;
|
58
|
GtkTextBuffer * textbuffer;
|
59
|
GtkWidget * title;
|
60
|
GtkWidget * artist;
|
61
|
GtkWidget * album;
|
62
|
GtkWidget * album_artist;
|
63
|
GtkWidget * comment;
|
64
|
GtkWidget * year;
|
65
|
GtkWidget * track;
|
66
|
GtkWidget * genre;
|
67
|
GtkWidget * image;
|
68
|
GtkWidget * codec[3];
|
69
|
GtkWidget * apply;
|
70
|
GtkWidget * autofill;
|
71
|
GtkWidget * ministatus;
|
72
|
} widgets;
|
73
|
|
74
|
static GtkWidget * infowin;
|
75
|
static Playlist current_playlist;
|
76
|
static int current_entry;
|
77
|
static String current_file;
|
78
|
static Tuple current_tuple;
|
79
|
static PluginHandle * current_decoder = nullptr;
|
80
|
static bool can_write = false;
|
81
|
static QueuedFunc ministatus_timer;
|
82
|
|
83
|
|
84
|
|
85
|
|
86
|
|
87
|
static const char * genre_table[] = {
|
88
|
N_("Acid Jazz"),
|
89
|
N_("Acid Rock"),
|
90
|
N_("Ambient"),
|
91
|
N_("Bebop"),
|
92
|
N_("Bluegrass"),
|
93
|
N_("Blues"),
|
94
|
N_("Chamber Music"),
|
95
|
N_("Classical"),
|
96
|
N_("Country"),
|
97
|
N_("Death Metal"),
|
98
|
N_("Disco"),
|
99
|
N_("Easy Listening"),
|
100
|
N_("Folk"),
|
101
|
N_("Funk"),
|
102
|
N_("Gangsta Rap"),
|
103
|
N_("Gospel"),
|
104
|
N_("Grunge"),
|
105
|
N_("Hard Rock"),
|
106
|
N_("Heavy Metal"),
|
107
|
N_("Hip-hop"),
|
108
|
N_("House"),
|
109
|
N_("Jazz"),
|
110
|
N_("Jungle"),
|
111
|
N_("Metal"),
|
112
|
N_("New Age"),
|
113
|
N_("New Wave"),
|
114
|
N_("Noise"),
|
115
|
N_("Pop"),
|
116
|
N_("Punk Rock"),
|
117
|
N_("Rap"),
|
118
|
N_("Reggae"),
|
119
|
N_("Rock"),
|
120
|
N_("Rock and Roll"),
|
121
|
N_("Rhythm and Blues"),
|
122
|
N_("Ska"),
|
123
|
N_("Soul"),
|
124
|
N_("Swing"),
|
125
|
N_("Techno"),
|
126
|
N_("Trip-hop")};
|
127
|
|
128
|
static GtkWidget * small_label_new (const char * text)
|
129
|
{
|
130
|
static PangoAttrList * attrs = nullptr;
|
131
|
|
132
|
if (! attrs)
|
133
|
{
|
134
|
attrs = pango_attr_list_new ();
|
135
|
pango_attr_list_insert (attrs, pango_attr_scale_new (PANGO_SCALE_SMALL));
|
136
|
}
|
137
|
|
138
|
GtkWidget * label = gtk_label_new (text);
|
139
|
gtk_label_set_attributes ((GtkLabel *) label, attrs);
|
140
|
gtk_misc_set_alignment ((GtkMisc *) label, 0, 0.5);
|
141
|
|
142
|
return label;
|
143
|
}
|
144
|
|
145
|
static void set_entry_str_from_field (GtkWidget * widget, const Tuple & tuple,
|
146
|
Tuple::Field field, bool editable, bool clear, bool & changed)
|
147
|
{
|
148
|
String text = tuple.get_str (field);
|
149
|
|
150
|
if (! text && ! clear)
|
151
|
{
|
152
|
if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0)
|
153
|
changed = true;
|
154
|
return;
|
155
|
}
|
156
|
|
157
|
gtk_entry_set_text ((GtkEntry *) widget, text ? text : "");
|
158
|
gtk_editable_set_editable ((GtkEditable *) widget, editable);
|
159
|
}
|
160
|
|
161
|
static void set_entry_int_from_field (GtkWidget * widget, const Tuple & tuple,
|
162
|
Tuple::Field field, bool editable, bool clear, bool & changed)
|
163
|
{
|
164
|
int value = tuple.get_int (field);
|
165
|
|
166
|
if (value <= 0 && ! clear)
|
167
|
{
|
168
|
if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0)
|
169
|
changed = true;
|
170
|
return;
|
171
|
}
|
172
|
|
173
|
gtk_entry_set_text ((GtkEntry *) widget, (value > 0) ? (const char *) int_to_str (value) : "");
|
174
|
gtk_editable_set_editable ((GtkEditable *) widget, editable);
|
175
|
}
|
176
|
|
177
|
static void set_field_str_from_entry (Tuple & tuple, Tuple::Field field, GtkWidget * widget)
|
178
|
{
|
179
|
const char * text = gtk_entry_get_text ((GtkEntry *) widget);
|
180
|
|
181
|
if (text[0])
|
182
|
tuple.set_str (field, text);
|
183
|
else
|
184
|
tuple.unset (field);
|
185
|
}
|
186
|
|
187
|
static void set_field_int_from_entry (Tuple & tuple, Tuple::Field field, GtkWidget * widget)
|
188
|
{
|
189
|
const char * text = gtk_entry_get_text ((GtkEntry *) widget);
|
190
|
|
191
|
if (text[0])
|
192
|
tuple.set_int (field, atoi (text));
|
193
|
else
|
194
|
tuple.unset (field);
|
195
|
}
|
196
|
|
197
|
static void entry_changed ()
|
198
|
{
|
199
|
if (can_write)
|
200
|
gtk_widget_set_sensitive (widgets.apply, true);
|
201
|
}
|
202
|
|
203
|
static void ministatus_display_message (const char * text)
|
204
|
{
|
205
|
gtk_label_set_text ((GtkLabel *) widgets.ministatus, text);
|
206
|
gtk_widget_hide (widgets.autofill);
|
207
|
gtk_widget_show (widgets.ministatus);
|
208
|
|
209
|
ministatus_timer.queue (AUDGUI_STATUS_TIMEOUT, [] () {
|
210
|
gtk_widget_hide (widgets.ministatus);
|
211
|
gtk_widget_show (widgets.autofill);
|
212
|
});
|
213
|
}
|
214
|
|
215
|
static void infowin_update_tuple ()
|
216
|
{
|
217
|
set_field_str_from_entry (current_tuple, Tuple::Title, widgets.title);
|
218
|
set_field_str_from_entry (current_tuple, Tuple::Artist, widgets.artist);
|
219
|
set_field_str_from_entry (current_tuple, Tuple::Album, widgets.album);
|
220
|
set_field_str_from_entry (current_tuple, Tuple::AlbumArtist, widgets.album_artist);
|
221
|
set_field_str_from_entry (current_tuple, Tuple::Comment, widgets.comment);
|
222
|
set_field_str_from_entry (current_tuple, Tuple::Genre,
|
223
|
gtk_bin_get_child ((GtkBin *) widgets.genre));
|
224
|
set_field_int_from_entry (current_tuple, Tuple::Year, widgets.year);
|
225
|
set_field_int_from_entry (current_tuple, Tuple::Track, widgets.track);
|
226
|
|
227
|
if (aud_file_write_tuple (current_file, current_decoder, current_tuple))
|
228
|
{
|
229
|
ministatus_display_message (_("Save successful"));
|
230
|
gtk_widget_set_sensitive (widgets.apply, false);
|
231
|
}
|
232
|
else
|
233
|
ministatus_display_message (_("Save error"));
|
234
|
}
|
235
|
|
236
|
static void infowin_select_entry (int entry)
|
237
|
{
|
238
|
if (entry >= 0 && entry < current_playlist.n_entries ())
|
239
|
{
|
240
|
current_playlist.select_all (false);
|
241
|
current_playlist.select_entry (entry, true);
|
242
|
current_playlist.set_focus (entry);
|
243
|
audgui_infowin_show (current_playlist, entry);
|
244
|
}
|
245
|
else
|
246
|
audgui_infowin_hide ();
|
247
|
}
|
248
|
|
249
|
static void infowin_prev ()
|
250
|
{
|
251
|
infowin_select_entry (current_entry - 1);
|
252
|
}
|
253
|
|
254
|
static void infowin_next ()
|
255
|
{
|
256
|
infowin_select_entry (current_entry + 1);
|
257
|
}
|
258
|
|
259
|
static void genre_fill (GtkWidget * combo)
|
260
|
{
|
261
|
Index<const char *> list;
|
262
|
for (auto genre : genre_table)
|
263
|
list.append (_(genre));
|
264
|
|
265
|
list.sort (g_utf8_collate);
|
266
|
|
267
|
for (auto genre : list)
|
268
|
gtk_combo_box_text_append_text ((GtkComboBoxText *) combo, genre);
|
269
|
}
|
270
|
|
271
|
static void autofill_toggled (GtkToggleButton * toggle)
|
272
|
{
|
273
|
aud_set_bool ("audgui", "clear_song_fields", ! gtk_toggle_button_get_active (toggle));
|
274
|
}
|
275
|
|
276
|
static void infowin_display_image (const char * filename)
|
277
|
{
|
278
|
if (! current_file || strcmp (filename, current_file))
|
279
|
return;
|
280
|
|
281
|
AudguiPixbuf pb = audgui_pixbuf_request (filename);
|
282
|
if (! pb)
|
283
|
pb = audgui_pixbuf_fallback ();
|
284
|
|
285
|
if (pb)
|
286
|
audgui_scaled_image_set (widgets.image, pb.get ());
|
287
|
}
|
288
|
|
289
|
static void infowin_destroyed ()
|
290
|
{
|
291
|
hook_dissociate ("art ready", (HookFunction) infowin_display_image);
|
292
|
|
293
|
ministatus_timer.stop ();
|
294
|
|
295
|
memset (& widgets, 0, sizeof widgets);
|
296
|
|
297
|
infowin = nullptr;
|
298
|
current_file = String ();
|
299
|
current_tuple = Tuple ();
|
300
|
current_decoder = nullptr;
|
301
|
}
|
302
|
|
303
|
static void add_entry (GtkWidget * grid, const char * title, GtkWidget * entry,
|
304
|
int x, int y, int span)
|
305
|
{
|
306
|
GtkWidget * label = small_label_new (title);
|
307
|
|
308
|
gtk_table_attach ((GtkTable *) grid, label, x, x + span, y, y + 1,
|
309
|
(GtkAttachOptions)(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0);
|
310
|
gtk_table_attach ((GtkTable *) grid, entry, x, x + span, y + 1, y + 2,
|
311
|
(GtkAttachOptions)(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0);
|
312
|
|
313
|
g_signal_connect (entry, "changed", (GCallback) entry_changed, nullptr);
|
314
|
}
|
315
|
|
316
|
static void create_infowin ()
|
317
|
{
|
318
|
int dpi = audgui_get_dpi ();
|
319
|
|
320
|
infowin = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
321
|
gtk_container_set_border_width ((GtkContainer *) infowin, 6);
|
322
|
gtk_window_set_title ((GtkWindow *) infowin, _("Song Info"));
|
323
|
gtk_window_set_type_hint ((GtkWindow *) infowin,
|
324
|
GDK_WINDOW_TYPE_HINT_DIALOG);
|
325
|
|
326
|
GtkWidget * main_grid = gtk_table_new (0, 0, false);
|
327
|
gtk_table_set_col_spacings ((GtkTable *) main_grid, 6);
|
328
|
gtk_table_set_row_spacings ((GtkTable *) main_grid, 6);
|
329
|
gtk_container_add ((GtkContainer *) infowin, main_grid);
|
330
|
|
331
|
widgets.image = audgui_scaled_image_new (nullptr);
|
332
|
gtk_widget_set_size_request (widgets.image, 2 * dpi, 2 * dpi);
|
333
|
gtk_table_attach ((GtkTable *) main_grid, widgets.image, 0, 1, 0, 1,
|
334
|
GTK_FILL, GTK_FILL, 0, 0);
|
335
|
|
336
|
widgets.location_scrolled = gtk_scrolled_window_new (nullptr, nullptr);
|
337
|
gtk_scrolled_window_set_shadow_type ((GtkScrolledWindow *) widgets.location_scrolled, GTK_SHADOW_IN);
|
338
|
gtk_scrolled_window_set_policy ((GtkScrolledWindow *) widgets.location_scrolled,
|
339
|
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
340
|
|
341
|
widgets.location = (GtkTextView *) gtk_text_view_new ();
|
342
|
gtk_text_view_set_editable (widgets.location, false);
|
343
|
gtk_text_view_set_cursor_visible (widgets.location, true);
|
344
|
gtk_text_view_set_left_margin (widgets.location, 4);
|
345
|
gtk_text_view_set_right_margin (widgets.location, 4);
|
346
|
gtk_text_view_set_wrap_mode (widgets.location, GTK_WRAP_CHAR);
|
347
|
widgets.textbuffer = gtk_text_view_get_buffer (widgets.location);
|
348
|
|
349
|
gtk_container_add ((GtkContainer *) widgets.location_scrolled, (GtkWidget *) widgets.location);
|
350
|
GtkWidget * scrolled_vbox = gtk_vbox_new (false, 6);
|
351
|
gtk_box_pack_start ((GtkBox *) scrolled_vbox, widgets.location_scrolled, true, true, 0);
|
352
|
gtk_widget_show_all (scrolled_vbox);
|
353
|
gtk_table_attach ((GtkTable *) main_grid, scrolled_vbox, 0, 1, 1, 2,
|
354
|
GTK_FILL, (GtkAttachOptions)(GTK_FILL | GTK_EXPAND), 0, 0);
|
355
|
|
356
|
GtkWidget * codec_grid = gtk_table_new (0, 0, false);
|
357
|
gtk_table_set_row_spacings ((GtkTable *) codec_grid, 2);
|
358
|
gtk_table_set_col_spacings ((GtkTable *) codec_grid, 12);
|
359
|
gtk_table_attach ((GtkTable *) main_grid, codec_grid, 0, 1, 2, 3,
|
360
|
GTK_FILL, GTK_FILL, 0, 8);
|
361
|
|
362
|
for (int row = 0; row < CODEC_ITEMS; row ++)
|
363
|
{
|
364
|
GtkWidget * label = small_label_new (_(codec_labels[row]));
|
365
|
gtk_table_attach ((GtkTable *) codec_grid, label, 0, 1, row, row + 1,
|
366
|
GTK_FILL, GTK_FILL, 0, 0);
|
367
|
|
368
|
widgets.codec[row] = small_label_new (nullptr);
|
369
|
gtk_table_attach ((GtkTable *) codec_grid, widgets.codec[row], 1, 2, row, row + 1,
|
370
|
GTK_FILL, GTK_FILL, 0, 0);
|
371
|
}
|
372
|
|
373
|
GtkWidget * grid = gtk_table_new (0, 0, false);
|
374
|
gtk_table_set_row_spacings ((GtkTable *) grid, 2);
|
375
|
gtk_table_set_col_spacings ((GtkTable *) grid, 6);
|
376
|
gtk_table_attach ((GtkTable *) main_grid, grid, 1, 2, 0, 3,
|
377
|
(GtkAttachOptions)(GTK_FILL | GTK_EXPAND), GTK_FILL, 0, 0);
|
378
|
|
379
|
widgets.title = gtk_entry_new ();
|
380
|
gtk_widget_set_size_request (widgets.title, 3 * dpi, -1);
|
381
|
add_entry (grid, _("Title"), widgets.title, 0, 0, 2);
|
382
|
|
383
|
widgets.artist = gtk_entry_new ();
|
384
|
add_entry (grid, _("Artist"), widgets.artist, 0, 2, 2);
|
385
|
|
386
|
widgets.album = gtk_entry_new ();
|
387
|
add_entry (grid, _("Album"), widgets.album, 0, 4, 2);
|
388
|
|
389
|
widgets.album_artist = gtk_entry_new ();
|
390
|
add_entry (grid, _("Album Artist"), widgets.album_artist, 0, 6, 2);
|
391
|
|
392
|
widgets.comment = gtk_entry_new ();
|
393
|
add_entry (grid, _("Comment"), widgets.comment, 0, 8, 2);
|
394
|
|
395
|
widgets.genre = gtk_combo_box_text_new_with_entry ();
|
396
|
genre_fill (widgets.genre);
|
397
|
add_entry (grid, _("Genre"), widgets.genre, 0, 10, 2);
|
398
|
|
399
|
widgets.year = gtk_entry_new ();
|
400
|
add_entry (grid, _("Year"), widgets.year, 0, 12, 1);
|
401
|
|
402
|
widgets.track = gtk_entry_new ();
|
403
|
add_entry (grid, _("Track Number"), widgets.track, 1, 12, 1);
|
404
|
|
405
|
GtkWidget * bottom_hbox = gtk_hbox_new (false, 6);
|
406
|
gtk_table_attach ((GtkTable *) main_grid, bottom_hbox, 0, 2, 3, 4,
|
407
|
GTK_FILL, GTK_FILL, 0, 0);
|
408
|
|
409
|
widgets.autofill = gtk_check_button_new_with_mnemonic (_("_Auto-fill empty fields"));
|
410
|
|
411
|
gtk_toggle_button_set_active ((GtkToggleButton *) widgets.autofill,
|
412
|
! aud_get_bool ("audgui", "clear_song_fields"));
|
413
|
g_signal_connect (widgets.autofill, "toggled", (GCallback) autofill_toggled, nullptr);
|
414
|
|
415
|
gtk_widget_set_no_show_all (widgets.autofill, true);
|
416
|
gtk_widget_show (widgets.autofill);
|
417
|
gtk_box_pack_start ((GtkBox *) bottom_hbox, widgets.autofill, true, true, 0);
|
418
|
|
419
|
widgets.ministatus = small_label_new (nullptr);
|
420
|
gtk_widget_set_no_show_all (widgets.ministatus, true);
|
421
|
gtk_box_pack_start ((GtkBox *) bottom_hbox, widgets.ministatus, true, true, 0);
|
422
|
|
423
|
widgets.apply = audgui_button_new (_("_Save"), "document-save",
|
424
|
(AudguiCallback) infowin_update_tuple, nullptr);
|
425
|
|
426
|
GtkWidget * close_button = audgui_button_new (_("_Close"), "window-close",
|
427
|
(AudguiCallback) audgui_infowin_hide, nullptr);
|
428
|
|
429
|
GtkWidget * prev_button = audgui_button_new (_("_Previous"), "go-previous",
|
430
|
(AudguiCallback) infowin_prev, nullptr);
|
431
|
|
432
|
GtkWidget * next_button = audgui_button_new (_("_Next"), "go-next",
|
433
|
(AudguiCallback) infowin_next, nullptr);
|
434
|
|
435
|
gtk_box_pack_end ((GtkBox *) bottom_hbox, close_button, false, false, 0);
|
436
|
gtk_box_pack_end ((GtkBox *) bottom_hbox, widgets.apply, false, false, 0);
|
437
|
gtk_box_pack_end ((GtkBox *) bottom_hbox, next_button, false, false, 0);
|
438
|
gtk_box_pack_end ((GtkBox *) bottom_hbox, prev_button, false, false, 0);
|
439
|
|
440
|
audgui_destroy_on_escape (infowin);
|
441
|
g_signal_connect (infowin, "destroy", (GCallback) infowin_destroyed, nullptr);
|
442
|
|
443
|
hook_associate ("art ready", (HookFunction) infowin_display_image, nullptr);
|
444
|
}
|
445
|
|
446
|
static void infowin_show (Playlist list, int entry, const String & filename,
|
447
|
const Tuple & tuple, PluginHandle * decoder, bool writable)
|
448
|
{
|
449
|
if (! infowin)
|
450
|
create_infowin ();
|
451
|
|
452
|
current_playlist = list;
|
453
|
current_entry = entry;
|
454
|
current_file = filename;
|
455
|
current_tuple = tuple.ref ();
|
456
|
current_decoder = decoder;
|
457
|
can_write = writable;
|
458
|
|
459
|
bool clear = aud_get_bool ("audgui", "clear_song_fields");
|
460
|
bool changed = false;
|
461
|
|
462
|
set_entry_str_from_field (widgets.title, tuple, Tuple::Title, writable, clear, changed);
|
463
|
set_entry_str_from_field (widgets.artist, tuple, Tuple::Artist, writable, clear, changed);
|
464
|
set_entry_str_from_field (widgets.album, tuple, Tuple::Album, writable, clear, changed);
|
465
|
set_entry_str_from_field (widgets.album_artist, tuple, Tuple::AlbumArtist, writable, clear, changed);
|
466
|
set_entry_str_from_field (widgets.comment, tuple, Tuple::Comment, writable, clear, changed);
|
467
|
set_entry_str_from_field (gtk_bin_get_child ((GtkBin *) widgets.genre),
|
468
|
tuple, Tuple::Genre, writable, clear, changed);
|
469
|
|
470
|
gtk_text_buffer_set_text (widgets.textbuffer, uri_to_display (filename), -1);
|
471
|
|
472
|
set_entry_int_from_field (widgets.year, tuple, Tuple::Year, writable, clear, changed);
|
473
|
set_entry_int_from_field (widgets.track, tuple, Tuple::Track, writable, clear, changed);
|
474
|
|
475
|
String codec_values[CODEC_ITEMS];
|
476
|
|
477
|
codec_values[CODEC_FORMAT] = tuple.get_str (Tuple::Codec);
|
478
|
codec_values[CODEC_QUALITY] = tuple.get_str (Tuple::Quality);
|
479
|
|
480
|
if (tuple.get_value_type (Tuple::Bitrate) == Tuple::Int)
|
481
|
codec_values[CODEC_BITRATE] = String (str_printf (_("%d kbit/s"),
|
482
|
tuple.get_int (Tuple::Bitrate)));
|
483
|
|
484
|
for (int row = 0; row < CODEC_ITEMS; row ++)
|
485
|
{
|
486
|
const char * text = codec_values[row] ? (const char *) codec_values[row] : _("N/A");
|
487
|
gtk_label_set_text ((GtkLabel *) widgets.codec[row], text);
|
488
|
}
|
489
|
|
490
|
infowin_display_image (filename);
|
491
|
|
492
|
gtk_widget_set_sensitive (widgets.apply, changed);
|
493
|
gtk_widget_grab_focus (widgets.title);
|
494
|
|
495
|
if (! audgui_reshow_unique_window (AUDGUI_INFO_WINDOW))
|
496
|
audgui_show_unique_window (AUDGUI_INFO_WINDOW, infowin);
|
497
|
}
|
498
|
|
499
|
EXPORT void audgui_infowin_show (Playlist playlist, int entry)
|
500
|
{
|
501
|
String filename = playlist.entry_filename (entry);
|
502
|
g_return_if_fail (filename != nullptr);
|
503
|
|
504
|
String error;
|
505
|
PluginHandle * decoder = playlist.entry_decoder (entry, Playlist::Wait, & error);
|
506
|
Tuple tuple = decoder ? playlist.entry_tuple (entry, Playlist::Wait, & error) : Tuple ();
|
507
|
|
508
|
if (decoder && tuple.valid () && ! aud_custom_infowin (filename, decoder))
|
509
|
{
|
510
|
|
511
|
bool can_write = aud_file_can_write_tuple (filename, decoder) &&
|
512
|
! tuple.is_set (Tuple::StartTime);
|
513
|
|
514
|
tuple.delete_fallbacks ();
|
515
|
infowin_show (playlist, entry, filename, tuple, decoder, can_write);
|
516
|
}
|
517
|
else
|
518
|
audgui_infowin_hide ();
|
519
|
|
520
|
if (error)
|
521
|
aud_ui_show_error (str_printf (_("Error opening %s:\n%s"),
|
522
|
(const char *) filename, (const char *) error));
|
523
|
}
|
524
|
|
525
|
EXPORT void audgui_infowin_show_current ()
|
526
|
{
|
527
|
auto playlist = Playlist::playing_playlist ();
|
528
|
if (playlist == Playlist ())
|
529
|
playlist = Playlist::active_playlist ();
|
530
|
|
531
|
int position = playlist.get_position ();
|
532
|
if (position < 0)
|
533
|
return;
|
534
|
|
535
|
audgui_infowin_show (playlist, position);
|
536
|
}
|
537
|
|
538
|
EXPORT void audgui_infowin_hide ()
|
539
|
{
|
540
|
audgui_hide_unique_window (AUDGUI_INFO_WINDOW);
|
541
|
}
|