~ubuntu-branches/ubuntu/gutsy/aqualung/gutsy

« back to all changes in this revision

Viewing changes to src/file_info.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Cécile (Le_Vert)
  • Date: 2007-03-10 16:07:32 UTC
  • Revision ID: james.westby@ubuntu.com-20070310160732-6hkwtb2d1h9sx6nr
Tags: upstream-0.9~beta7.1
Import upstream version 0.9~beta7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*                                                     -*- linux-c -*-
 
2
    Copyright (C) 2004 Tom Szilagyi
 
3
 
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
 
 
18
    $Id: file_info.cpp 586 2007-02-18 09:30:01Z tszilagyi $
 
19
*/
 
20
 
 
21
#include <config.h>
 
22
 
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <ctype.h>
 
27
#include <assert.h>
 
28
#include <sys/stat.h>
 
29
#include <gtk/gtk.h>
 
30
#include <gdk/gdkkeysyms.h>
 
31
#include <glib.h>
 
32
#include <glib/gstdio.h>
 
33
 
 
34
#ifdef HAVE_MOD_INFO
 
35
#include <libmodplug/modplug.h>
 
36
#endif /* HAVE_MOD_INFO */
 
37
 
 
38
#ifdef HAVE_MOD
 
39
#include "decoder/dec_mod.h"
 
40
#endif /* HAVE_MOD */
 
41
 
 
42
#ifdef HAVE_TAGLIB
 
43
#include <id3v1tag.h>
 
44
#include <id3v2tag.h>
 
45
#include <apetag.h>
 
46
#include <xiphcomment.h>
 
47
 
 
48
#include <apeitem.h>
 
49
#include <attachedpictureframe.h>
 
50
#include <relativevolumeframe.h>
 
51
#include <textidentificationframe.h>
 
52
 
 
53
#include <mpegfile.h>
 
54
#include <mpcfile.h>
 
55
#include <flacfile.h>
 
56
#include <vorbisfile.h>
 
57
 
 
58
#include <tmap.h>
 
59
#include <tlist.h>
 
60
#include <tbytevector.h>
 
61
#include <tfile.h>
 
62
#include <tstring.h>
 
63
#endif /* HAVE_TAGLIB */
 
64
 
 
65
#include "common.h"
 
66
#include "core.h"
 
67
#include "cover.h"
 
68
#include "decoder/file_decoder.h"
 
69
#include "music_browser.h"
 
70
#include "gui_main.h"
 
71
#include "options.h"
 
72
#include "trashlist.h"
 
73
#include "build_store.h"
 
74
#include "i18n.h"
 
75
#include "meta_decoder.h"
 
76
#include "file_info.h"
 
77
 
 
78
 
 
79
/* import destination codes */
 
80
#define IMPORT_DEST_ARTIST   1
 
81
#define IMPORT_DEST_RECORD   2
 
82
#define IMPORT_DEST_TITLE    3
 
83
#define IMPORT_DEST_NUMBER   4
 
84
#define IMPORT_DEST_COMMENT  5
 
85
#define IMPORT_DEST_RVA      6
 
86
 
 
87
 
 
88
extern options_t options;
 
89
extern GtkWidget* gui_stock_label_button(gchar *label, const gchar *stock);
 
90
 
 
91
GtkWidget * fi_event_box;
 
92
 
 
93
typedef struct {
 
94
        GtkTreeModel * model;
 
95
        GtkTreeIter track_iter;
 
96
        int dest_type; /* one of the above codes */
 
97
        char str[MAXLEN];
 
98
        float fval;
 
99
} import_data_t;
 
100
 
 
101
typedef struct {
 
102
        int is_called_from_browser;
 
103
        GtkTreeModel * model;
 
104
        GtkTreeIter track_iter;
 
105
} fileinfo_mode_t;
 
106
 
 
107
typedef struct {
 
108
        char savefile[MAXLEN];
 
109
        unsigned int image_size;
 
110
        void * image_data;
 
111
} save_pic_t;
 
112
 
 
113
 
 
114
#ifdef HAVE_TAGLIB
 
115
 
 
116
/* edit modes */
 
117
#define EDITABLE_NO    0x00
 
118
#define EDITABLE_YES   0x01
 
119
#define EDITABLE_GENRE 0x02
 
120
 
 
121
 
 
122
/* used in flags below */
 
123
#define CREATE_ID3v2 0x02
 
124
#define CREATE_APE   0x04
 
125
#define REMOVE_ID3v1 0x10
 
126
#define REMOVE_ID3v2 0x20
 
127
#define REMOVE_APE   0x40
 
128
 
 
129
typedef struct {
 
130
        TagLib::FLAC::File * taglib_flac_file;
 
131
        TagLib::Ogg::Vorbis::File * taglib_oggv_file;
 
132
        TagLib::MPEG::File * taglib_mpeg_file;
 
133
        TagLib::MPC::File * taglib_mpc_file;
 
134
 
 
135
        TagLib::ID3v1::Tag * id3v1_tag;
 
136
        TagLib::ID3v2::Tag * id3v2_tag;
 
137
        TagLib::APE::Tag * ape_tag;
 
138
        TagLib::Ogg::XiphComment * oxc;
 
139
 
 
140
        GtkWidget * entry_title;
 
141
        GtkWidget * entry_artist;
 
142
        GtkWidget * entry_album;
 
143
        GtkWidget * entry_track;
 
144
        GtkWidget * entry_year;
 
145
        GtkWidget * entry_genre;
 
146
        GtkWidget * entry_comment;
 
147
 
 
148
        GtkNotebook * nb;
 
149
        GtkWidget * hbox;
 
150
        GtkWidget * hbox_inner;
 
151
        fileinfo_mode_t mode;
 
152
 
 
153
        int flags;
 
154
        int id3v1_page_no;
 
155
        int id3v2_page_no;
 
156
        int ape_page_no;
 
157
        int oxc_page_no;
 
158
} save_basic_t;
 
159
 
 
160
typedef struct {
 
161
        int flags; /* only the exact action associated w/ button */
 
162
        save_basic_t * save_basic;
 
163
} tagbutton_data_t;
 
164
 
 
165
typedef struct {
 
166
        int save_page_no; /* only the exact page to save */
 
167
        save_basic_t * save_basic;
 
168
} savepage_data_t;
 
169
#endif /* HAVE_TAGLIB */
 
170
 
 
171
 
 
172
extern GtkWidget * main_window;
 
173
extern GtkTreeStore * music_store;
 
174
extern GtkTreeSelection * music_select;
 
175
extern GtkWidget * music_tree;
 
176
 
 
177
GtkWidget * info_window = NULL;
 
178
trashlist_t * fileinfo_trash = NULL;
 
179
 
 
180
gint n_pages = 0;       /* number of notebook pages */
 
181
GtkWidget * nb;         /* notebook widget */
 
182
 
 
183
#ifdef HAVE_MOD_INFO
 
184
file_decoder_t * md_fdec = NULL;
 
185
GtkWidget * smp_instr_list;
 
186
GtkListStore * smp_instr_list_store = NULL;
 
187
void fill_module_info_page(mod_info *mdi, GtkWidget *vbox, char *file);
 
188
#endif /* HAVE_MOD_INFO */
 
189
 
 
190
import_data_t *
 
191
import_data_new(void) {
 
192
 
 
193
        import_data_t * data;
 
194
 
 
195
        if ((data = (import_data_t *)calloc(1, sizeof(import_data_t))) == NULL) {
 
196
                fprintf(stderr, "error: import_data_new(): calloc error\n");
 
197
                return NULL;
 
198
        }
 
199
        return data;
 
200
}
 
201
 
 
202
 
 
203
#ifdef HAVE_TAGLIB
 
204
save_basic_t *
 
205
save_basic_new(void) {
 
206
 
 
207
        save_basic_t * save_basic = (save_basic_t *)calloc(1, sizeof(save_basic_t));
 
208
        if (!save_basic) {
 
209
                fprintf(stderr, "error: save_basic_new(): calloc error\n");
 
210
                return NULL;
 
211
        }
 
212
 
 
213
        save_basic->id3v1_page_no = -1;
 
214
        save_basic->id3v2_page_no = -1;
 
215
        save_basic->ape_page_no = -1;
 
216
        save_basic->oxc_page_no = -1;
 
217
 
 
218
        return save_basic;
 
219
}
 
220
 
 
221
 
 
222
tagbutton_data_t *
 
223
tagbutton_data_new(void) {
 
224
 
 
225
        tagbutton_data_t * tdata = (tagbutton_data_t *)calloc(1, sizeof(tagbutton_data_t));
 
226
        if (!tdata) {
 
227
                fprintf(stderr, "error: tagbutton_data_new(): calloc error\n");
 
228
                return NULL;
 
229
        }
 
230
 
 
231
        return tdata;
 
232
}
 
233
 
 
234
 
 
235
savepage_data_t *
 
236
savepage_data_new(void) {
 
237
 
 
238
        savepage_data_t * sdata = (savepage_data_t *)calloc(1, sizeof(savepage_data_t));
 
239
        if (!sdata) {
 
240
                fprintf(stderr, "error: savepage_data_new(): calloc error\n");
 
241
                return NULL;
 
242
        }
 
243
 
 
244
        sdata->save_page_no = -1;
 
245
 
 
246
        return sdata;
 
247
}
 
248
#endif /* HAVE_TAGLIB */
 
249
 
 
250
 
 
251
gint
 
252
dismiss(GtkWidget * widget, gpointer data) {
 
253
 
 
254
        metadata * meta = (metadata *)data;
 
255
        meta_free(meta);
 
256
 
 
257
#ifdef HAVE_MOD_INFO
 
258
        if (md_fdec) {
 
259
                file_decoder_close(md_fdec);
 
260
                file_decoder_delete(md_fdec);
 
261
                md_fdec = NULL;
 
262
        }
 
263
#endif /* HAVE_MOD_INFO */
 
264
 
 
265
        gtk_widget_destroy(info_window);
 
266
        info_window = NULL;
 
267
        trashlist_free(fileinfo_trash);
 
268
        fileinfo_trash = NULL;
 
269
        return TRUE;
 
270
}
 
271
 
 
272
 
 
273
gint
 
274
info_window_close(GtkWidget * widget, GdkEventAny * event, gpointer data) {
 
275
 
 
276
        metadata * meta = (metadata *)data;
 
277
        meta_free(meta);
 
278
 
 
279
        info_window = NULL;
 
280
        trashlist_free(fileinfo_trash);
 
281
        fileinfo_trash = NULL;
 
282
        return FALSE;
 
283
}
 
284
 
 
285
 
 
286
gint
 
287
info_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent, gpointer data) {
 
288
 
 
289
        switch (kevent->keyval) {
 
290
        case GDK_Escape:
 
291
                dismiss(NULL, data);
 
292
                return TRUE;
 
293
                break;
 
294
        case GDK_Return:
 
295
                int page = (gtk_notebook_get_current_page(GTK_NOTEBOOK(nb)) + 1) % n_pages;
 
296
                gtk_notebook_set_current_page(GTK_NOTEBOOK(nb), page);
 
297
                break;
 
298
        }
 
299
        return FALSE;
 
300
}
 
301
 
 
302
 
 
303
char *
 
304
lookup_id3v1_genre(int code) {
 
305
 
 
306
        switch (code) {
 
307
        case 0: return "Blues";
 
308
        case 1: return "Classic Rock";
 
309
        case 2: return "Country";
 
310
        case 3: return "Dance";
 
311
        case 4: return "Disco";
 
312
        case 5: return "Funk";
 
313
        case 6: return "Grunge";
 
314
        case 7: return "Hip-Hop";
 
315
        case 8: return "Jazz";
 
316
        case 9: return "Metal";
 
317
        case 10: return "New Age";
 
318
        case 11: return "Oldies";
 
319
        case 12: return "Other";
 
320
        case 13: return "Pop";
 
321
        case 14: return "R&B";
 
322
        case 15: return "Rap";
 
323
        case 16: return "Reggae";
 
324
        case 17: return "Rock";
 
325
        case 18: return "Techno";
 
326
        case 19: return "Industrial";
 
327
        case 20: return "Alternative";
 
328
        case 21: return "Ska";
 
329
        case 22: return "Death Metal";
 
330
        case 23: return "Pranks";
 
331
        case 24: return "Soundtrack";
 
332
        case 25: return "Euro-Techno";
 
333
        case 26: return "Ambient";
 
334
        case 27: return "Trip-Hop";
 
335
        case 28: return "Vocal";
 
336
        case 29: return "Jazz+Funk";
 
337
        case 30: return "Fusion";
 
338
        case 31: return "Trance";
 
339
        case 32: return "Classical";
 
340
        case 33: return "Instrumental";
 
341
        case 34: return "Acid";
 
342
        case 35: return "House";
 
343
        case 36: return "Game";
 
344
        case 37: return "Sound Clip";
 
345
        case 38: return "Gospel";
 
346
        case 39: return "Noise";
 
347
        case 40: return "AlternRock";
 
348
        case 41: return "Bass";
 
349
        case 42: return "Soul";
 
350
        case 43: return "Punk";
 
351
        case 44: return "Space";
 
352
        case 45: return "Meditative";
 
353
        case 46: return "Instrumental Pop";
 
354
        case 47: return "Instrumental Rock";
 
355
        case 48: return "Ethnic";
 
356
        case 49: return "Gothic";
 
357
        case 50: return "Darkwave";
 
358
        case 51: return "Techno-Industrial";
 
359
        case 52: return "Electronic";
 
360
        case 53: return "Pop-Folk";
 
361
        case 54: return "Eurodance";
 
362
        case 55: return "Dream";
 
363
        case 56: return "Southern Rock";
 
364
        case 57: return "Comedy";
 
365
        case 58: return "Cult";
 
366
        case 59: return "Gangsta";
 
367
        case 60: return "Top 40";
 
368
        case 61: return "Christian Rap";
 
369
        case 62: return "Pop/Funk";
 
370
        case 63: return "Jungle";
 
371
        case 64: return "Native American";
 
372
        case 65: return "Cabaret";
 
373
        case 66: return "New Wave";
 
374
        case 67: return "Psychadelic";
 
375
        case 68: return "Rave";
 
376
        case 69: return "Showtunes";
 
377
        case 70: return "Trailer";
 
378
        case 71: return "Lo-Fi";
 
379
        case 72: return "Tribal";
 
380
        case 73: return "Acid Punk";
 
381
        case 74: return "Acid Jazz";
 
382
        case 75: return "Polka";
 
383
        case 76: return "Retro";
 
384
        case 77: return "Musical";
 
385
        case 78: return "Rock & Roll";
 
386
        case 79: return "Hard Rock";
 
387
        default: return NULL;
 
388
        }
 
389
}
 
390
 
 
391
 
 
392
void
 
393
import_button_pressed(GtkWidget * widget, gpointer gptr_data) {
 
394
 
 
395
        import_data_t * data = (import_data_t *)gptr_data;
 
396
        GtkTreeIter record_iter;
 
397
        GtkTreeIter artist_iter;
 
398
        GtkTreePath * path;
 
399
        char tmp[MAXLEN];
 
400
        char * ptmp;
 
401
        float ftmp;
 
402
 
 
403
        switch (data->dest_type) {
 
404
        case IMPORT_DEST_TITLE:
 
405
                gtk_tree_store_set(music_store, &(data->track_iter), 0, data->str, -1);
 
406
                music_store_mark_changed(&(data->track_iter));
 
407
                break;
 
408
        case IMPORT_DEST_RECORD:
 
409
                gtk_tree_model_iter_parent(data->model, &record_iter, &(data->track_iter));
 
410
                gtk_tree_store_set(music_store, &record_iter, 0, data->str, -1);
 
411
                music_store_mark_changed(&(data->track_iter));
 
412
                break;
 
413
        case IMPORT_DEST_ARTIST:
 
414
                gtk_tree_model_iter_parent(data->model, &record_iter, &(data->track_iter));
 
415
                gtk_tree_model_iter_parent(data->model, &artist_iter, &record_iter);
 
416
                gtk_tree_store_set(music_store, &artist_iter, 0, data->str, -1);
 
417
                gtk_tree_store_set(music_store, &artist_iter, 1, data->str, -1);
 
418
                path = gtk_tree_model_get_path(data->model, &(data->track_iter));
 
419
                gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(music_tree), path, NULL, TRUE, 0.5f, 0.0f);
 
420
                music_store_mark_changed(&(data->track_iter));
 
421
                break;
 
422
        case IMPORT_DEST_NUMBER:
 
423
                if (data->str[0] != '0') {
 
424
                        tmp[0] = '0';
 
425
                        tmp[1] = '\0';
 
426
                } else {
 
427
                        tmp[0] = '\0';
 
428
                }
 
429
                strncat(tmp, data->str, MAXLEN-1);
 
430
                gtk_tree_store_set(music_store, &(data->track_iter), 1, tmp, -1);
 
431
                music_store_mark_changed(&(data->track_iter));
 
432
                break;
 
433
        case IMPORT_DEST_COMMENT:
 
434
                gtk_tree_model_get(data->model, &(data->track_iter), 3, &ptmp, -1);
 
435
                tmp[0] = '\0';
 
436
                if (ptmp != NULL) {
 
437
                        strncat(tmp, ptmp, MAXLEN-1);
 
438
                }
 
439
                if ((tmp[strlen(tmp)-1] != '\n') && (tmp[0] != '\0')) {
 
440
                        strncat(tmp, "\n", MAXLEN-1);
 
441
                }
 
442
                strncat(tmp, data->str, MAXLEN-1);
 
443
                gtk_tree_store_set(music_store, &(data->track_iter), 3, tmp, -1);
 
444
                tree_selection_changed_cb(music_select, NULL);
 
445
                music_store_mark_changed(&(data->track_iter));
 
446
                break;
 
447
        case IMPORT_DEST_RVA:
 
448
                ftmp = 1.0f;
 
449
                gtk_tree_store_set(music_store, &(data->track_iter), 6, data->fval, -1);
 
450
                gtk_tree_store_set(music_store, &(data->track_iter), 7, ftmp, -1);
 
451
                music_store_mark_changed(&(data->track_iter));
 
452
                break;
 
453
        }
 
454
}
 
455
 
 
456
 
 
457
/* returns the text entry widget */
 
458
GtkWidget *
 
459
append_table(GtkWidget * table, int * cnt, int edit_mode, char * field, char * value,
 
460
             char * importbtn_text, import_data_t * data) {
 
461
 
 
462
        GtkWidget * hbox;
 
463
        GtkWidget * entry = NULL;
 
464
        GtkWidget * label;
 
465
 
 
466
        GtkWidget * button;
 
467
 
 
468
        gtk_table_resize(GTK_TABLE(table), *cnt + 1, 3);
 
469
 
 
470
        hbox = gtk_hbox_new(FALSE, 0);
 
471
        label = gtk_label_new(field);
 
472
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
473
        gtk_table_attach(GTK_TABLE(table), hbox, 0, 1, *cnt, *cnt+1, GTK_FILL, GTK_FILL, 5, 3);
 
474
 
 
475
#ifdef HAVE_TAGLIB
 
476
        if (edit_mode == EDITABLE_GENRE) {
 
477
                entry = gtk_combo_box_new_text();
 
478
                int selected = 0;
 
479
                int i = 0;
 
480
                gtk_combo_box_append_text(GTK_COMBO_BOX(entry), _("(not set)"));
 
481
                while (lookup_id3v1_genre(i) != NULL) {
 
482
                        gtk_combo_box_append_text(GTK_COMBO_BOX(entry), lookup_id3v1_genre(i));
 
483
                        if (strcmp(lookup_id3v1_genre(i), value) == 0) {
 
484
                                selected = i+1;
 
485
                        }
 
486
                        ++i;
 
487
                }
 
488
                gtk_combo_box_set_active(GTK_COMBO_BOX(entry), selected);
 
489
        } else {
 
490
                entry = gtk_entry_new();
 
491
                gtk_entry_set_text(GTK_ENTRY(entry), value);
 
492
        }
 
493
 
 
494
        if (edit_mode == EDITABLE_NO) {
 
495
                GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
496
                gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
497
        }
 
498
#endif /* HAVE_TAG_LIB */
 
499
 
 
500
        if (importbtn_text == NULL) {
 
501
                gtk_table_attach(GTK_TABLE(table), entry, 1, 3, *cnt, *cnt+1,
 
502
                                 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
503
        } else if (data != NULL) {
 
504
                button = gtk_button_new_with_label(importbtn_text);
 
505
                g_signal_connect(G_OBJECT(button), "clicked",
 
506
                                 G_CALLBACK(import_button_pressed), (gpointer)data);
 
507
                gtk_table_attach(GTK_TABLE(table), entry, 1, 2, *cnt, *cnt+1,
 
508
                                 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
509
                gtk_table_attach(GTK_TABLE(table), button, 2, 3, *cnt, *cnt+1,
 
510
                                 GTK_FILL, GTK_FILL, 5, 3);
 
511
        } else { /* we have no data -> dummy button, no signal attached */
 
512
                button = gtk_button_new_with_label(importbtn_text);
 
513
                gtk_table_attach(GTK_TABLE(table), entry, 1, 2, *cnt, *cnt+1,
 
514
                                 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
515
                gtk_table_attach(GTK_TABLE(table), button, 2, 3, *cnt, *cnt+1,
 
516
                                 GTK_FILL, GTK_FILL, 5, 3);
 
517
        }
 
518
        
 
519
        (*cnt)++;
 
520
        return entry;
 
521
}
 
522
 
 
523
 
 
524
void
 
525
save_pic_button_pressed(GtkWidget * widget, gpointer data) {
 
526
 
 
527
        save_pic_t * save_pic = (save_pic_t *)data;
 
528
        GtkWidget * dialog;
 
529
        gchar * selected_filename;
 
530
        char filename[MAXLEN];
 
531
 
 
532
        dialog = gtk_file_chooser_dialog_new(_("Please specify the file to save the image to."), 
 
533
                                             GTK_WINDOW(info_window), 
 
534
                                             GTK_FILE_CHOOSER_ACTION_SAVE, 
 
535
                                             GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
 
536
                                             GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
 
537
                                             NULL);
 
538
 
 
539
        deflicker();
 
540
        gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), options.currdir);
 
541
        gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), save_pic->savefile);
 
542
 
 
543
        gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
 
544
        gtk_window_set_default_size(GTK_WINDOW(dialog), 580, 390);
 
545
        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 
546
 
 
547
        if (options.show_hidden) {
 
548
                gtk_file_chooser_set_show_hidden(GTK_FILE_CHOOSER(dialog), TRUE);
 
549
        }
 
550
 
 
551
        if (aqualung_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
 
552
                selected_filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
553
                strncpy(filename, selected_filename, MAXLEN-1);
 
554
                g_free(selected_filename);
 
555
 
 
556
                FILE * f = fopen(filename, "wb");
 
557
                if (f == NULL) {
 
558
                        printf("error: fopen() failed\n");
 
559
                        gtk_widget_destroy(dialog);
 
560
                        return;
 
561
                }
 
562
                if (fwrite(save_pic->image_data, 1, save_pic->image_size, f) != save_pic->image_size) {
 
563
                        printf("fwrite() error\n");
 
564
                        gtk_widget_destroy(dialog);
 
565
                        return;
 
566
                }
 
567
                fclose(f);
 
568
 
 
569
                strncpy(options.currdir, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)), MAXLEN-1);
 
570
        }
 
571
        gtk_widget_destroy(dialog);
 
572
}
 
573
 
 
574
 
 
575
void
 
576
append_table_pic(GtkWidget * table, int * cnt, GtkWidget * image,
 
577
                 char * type, char * descr, char * savefilename,
 
578
                 void * image_data, int image_size) {
 
579
 
 
580
        char type_str[MAXLEN];
 
581
        char descr_str[MAXLEN];
 
582
 
 
583
        save_pic_t * save_pic = (save_pic_t *)malloc(sizeof(save_pic_t));
 
584
        if (save_pic == NULL)
 
585
                return;
 
586
 
 
587
        trashlist_add(fileinfo_trash, save_pic);
 
588
        strncpy(save_pic->savefile, savefilename, MAXLEN-1);
 
589
        save_pic->image_size = image_size;
 
590
        save_pic->image_data = image_data;
 
591
 
 
592
        snprintf(type_str, MAXLEN-1, "%s: %s", _("Type"), type);
 
593
        if (descr != NULL) {
 
594
                snprintf(descr_str, MAXLEN-1, "%s: %s", _("Description"), descr);
 
595
        } else {
 
596
                strcpy(descr_str, _("No description"));
 
597
        }
 
598
 
 
599
        GtkWidget * frame = gtk_frame_new(_("Embedded picture"));
 
600
        GtkWidget * hbox = gtk_hbox_new(FALSE, 0);
 
601
        GtkWidget * hbox_i;
 
602
        GtkWidget * vbox = gtk_vbox_new(FALSE, 0);
 
603
        GtkWidget * label;
 
604
        gtk_container_add(GTK_CONTAINER(frame), hbox);
 
605
        gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
606
 
 
607
        hbox_i = gtk_hbox_new(FALSE, 0);
 
608
        label = gtk_label_new(type_str);
 
609
        gtk_box_pack_start(GTK_BOX(hbox_i), label, FALSE, FALSE, 0);
 
610
        gtk_box_pack_start(GTK_BOX(vbox), hbox_i, FALSE, FALSE, 3);
 
611
        hbox_i = gtk_hbox_new(FALSE, 0);
 
612
        label = gtk_label_new(descr_str);
 
613
        gtk_box_pack_start(GTK_BOX(hbox_i), label, FALSE, FALSE, 0);
 
614
        gtk_box_pack_start(GTK_BOX(vbox), hbox_i, FALSE, FALSE, 3);
 
615
 
 
616
        GtkWidget * hbuttonbox = gtk_hbutton_box_new();
 
617
        gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
 
618
        GtkWidget * button = gui_stock_label_button(_("Save to file..."), GTK_STOCK_SAVE);
 
619
        gtk_container_add(GTK_CONTAINER(hbuttonbox), button);   
 
620
        g_signal_connect(G_OBJECT(button), "clicked",
 
621
                         G_CALLBACK(save_pic_button_pressed), (gpointer)save_pic);
 
622
        gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, FALSE, 3);  
 
623
 
 
624
        gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 3);
 
625
        gtk_box_pack_end(GTK_BOX(hbox), image, FALSE, FALSE, 3);
 
626
        gtk_table_attach(GTK_TABLE(table), frame, 0, 3, *cnt, *cnt+1,
 
627
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
628
 
 
629
        (*cnt)++;
 
630
}
 
631
 
 
632
 
 
633
#ifdef HAVE_TAGLIB
 
634
void
 
635
save_basic_fields(GtkWidget * widget, gpointer data) {
 
636
 
 
637
        savepage_data_t * sdata = (savepage_data_t *)data;
 
638
        save_basic_t * save_basic = sdata->save_basic;
 
639
        char buf[MAXLEN];
 
640
        int i;
 
641
        TagLib::String str;
 
642
        TagLib::Tag * tag = NULL;
 
643
 
 
644
        if (sdata->save_page_no == save_basic->id3v1_page_no) {
 
645
                tag = dynamic_cast<TagLib::Tag *>(save_basic->id3v1_tag);
 
646
        } else if (sdata->save_page_no == save_basic->id3v2_page_no) {
 
647
                tag = dynamic_cast<TagLib::Tag *>(save_basic->id3v2_tag);
 
648
        } else if (sdata->save_page_no == save_basic->ape_page_no) {
 
649
                tag = dynamic_cast<TagLib::Tag *>(save_basic->ape_tag);
 
650
        } else if (sdata->save_page_no == save_basic->oxc_page_no) {
 
651
                tag = dynamic_cast<TagLib::Tag *>(save_basic->oxc);
 
652
        } else {
 
653
                fprintf(stderr, "save_basic_fields(): error looking up metadata type\n");
 
654
                return;
 
655
        }
 
656
 
 
657
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_title)), MAXLEN-1);
 
658
        cut_trailing_whitespace(buf);
 
659
        /* hack to work around TagLib not saving the tag if it's empty */
 
660
        if (buf[0] == '\0') {
 
661
                buf[0] = ' ';
 
662
                buf[1] = '\0';
 
663
        }
 
664
        str = TagLib::String(buf, TagLib::String::UTF8);        
 
665
        tag->setTitle(str);
 
666
 
 
667
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_artist)), MAXLEN-1);
 
668
        cut_trailing_whitespace(buf);
 
669
        str = TagLib::String(buf, TagLib::String::UTF8);
 
670
        tag->setArtist(str);
 
671
 
 
672
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_album)), MAXLEN-1);
 
673
        cut_trailing_whitespace(buf);
 
674
        str = TagLib::String(buf, TagLib::String::UTF8);
 
675
        tag->setAlbum(str);
 
676
 
 
677
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_comment)), MAXLEN-1);
 
678
        cut_trailing_whitespace(buf);
 
679
        /* workaround silly TagLib when writing an empty comment to an id3v2 tag */
 
680
        if (save_basic->taglib_mpeg_file != NULL) {
 
681
                if (buf[0] == '\0') {
 
682
                        buf[0] = ' ';
 
683
                        buf[1] = '\0';
 
684
                }
 
685
        }
 
686
        str = TagLib::String(buf, TagLib::String::UTF8);
 
687
        tag->setComment(str);
 
688
 
 
689
        if (GTK_IS_ENTRY(save_basic->entry_genre)) {
 
690
                strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_genre)), MAXLEN-1);
 
691
                cut_trailing_whitespace(buf);
 
692
        } else {
 
693
                int selected = gtk_combo_box_get_active(GTK_COMBO_BOX(save_basic->entry_genre));
 
694
                if (selected > 0) {
 
695
                        strncpy(buf, lookup_id3v1_genre(selected-1), MAXLEN-1);
 
696
                } else {
 
697
                        buf[0] = '\0';
 
698
                }
 
699
        }
 
700
        str = TagLib::String(buf, TagLib::String::UTF8);
 
701
        tag->setGenre(str);
 
702
 
 
703
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_year)), MAXLEN-1);
 
704
        cut_trailing_whitespace(buf);
 
705
        if (sscanf(buf, "%d", &i) < 1) {
 
706
                i = 0;
 
707
        }
 
708
        if ((i < 0) || (i > 9999)) {
 
709
                i = 0;
 
710
        }
 
711
        tag->setYear(i);
 
712
 
 
713
        strncpy(buf, gtk_entry_get_text(GTK_ENTRY(save_basic->entry_track)), MAXLEN-1);
 
714
        cut_trailing_whitespace(buf);
 
715
        if (sscanf(buf, "%d", &i) < 1) {
 
716
                i = 0;
 
717
        }
 
718
        if ((i < 0) || (i > 9999)) {
 
719
                i = 0;
 
720
        }
 
721
        tag->setTrack(i);
 
722
 
 
723
        /* save the file */
 
724
        if (save_basic->taglib_flac_file != NULL)
 
725
                save_basic->taglib_flac_file->save();
 
726
        if (save_basic->taglib_oggv_file != NULL)
 
727
                save_basic->taglib_oggv_file->save();
 
728
        if (save_basic->taglib_mpeg_file != NULL) {
 
729
                int tags = 0;
 
730
                if (save_basic->id3v1_tag != NULL)
 
731
                        tags |= TagLib::MPEG::File::ID3v1;
 
732
                if (save_basic->id3v2_tag != NULL)
 
733
                        tags |= TagLib::MPEG::File::ID3v2;
 
734
                if (save_basic->ape_tag != NULL)
 
735
                        tags |= TagLib::MPEG::File::APE;
 
736
                save_basic->taglib_mpeg_file->save(tags, false);
 
737
        }
 
738
        if (save_basic->taglib_mpc_file != NULL)
 
739
                save_basic->taglib_mpc_file->save();
 
740
}
 
741
 
 
742
 
 
743
/* simple mode for fields that don't require anything fancy */
 
744
int
 
745
build_simple_page(save_basic_t * save_basic, TagLib::Tag * tag, int * cnt, GtkWidget ** ptable,
 
746
                  int edit_mode, char * nb_label) {
 
747
 
 
748
        GtkWidget * vbox = gtk_vbox_new(FALSE, 4);
 
749
        GtkWidget * table = gtk_table_new(0, 3, FALSE);
 
750
        GtkWidget * label = gtk_label_new(nb_label);
 
751
        GtkWidget * scrwin = gtk_scrolled_window_new(NULL, NULL);
 
752
        GtkWidget * viewp = gtk_viewport_new(NULL, NULL);
 
753
        gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewp), GTK_SHADOW_NONE);
 
754
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
 
755
                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
756
        gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 10);
 
757
        gtk_container_add(GTK_CONTAINER(scrwin), viewp);
 
758
        gtk_container_add(GTK_CONTAINER(viewp), vbox);
 
759
        int page_id = gtk_notebook_append_page(GTK_NOTEBOOK(save_basic->nb), scrwin, label);
 
760
 
 
761
        char str[MAXLEN];
 
762
 
 
763
        if (save_basic->mode.is_called_from_browser) {
 
764
                import_data_t * data;
 
765
 
 
766
                strncpy(str, (char *)tag->title().toCString(true), MAXLEN-1);
 
767
                cut_trailing_whitespace(str);
 
768
                if (is_all_wspace(str)) {
 
769
                        data = NULL;
 
770
                } else {
 
771
                        data = import_data_new();
 
772
                        trashlist_add(fileinfo_trash, data);
 
773
                        data->model = save_basic->mode.model;
 
774
                        data->track_iter = save_basic->mode.track_iter;
 
775
                        data->dest_type = IMPORT_DEST_TITLE;
 
776
                        strncpy(data->str, str, MAXLEN-1);
 
777
                }
 
778
                save_basic->entry_title = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
779
                                                       _("Title:"), str, _("Import as Title"), data);
 
780
 
 
781
                strncpy(str, (char *)tag->artist().toCString(true), MAXLEN-1);
 
782
                cut_trailing_whitespace(str);
 
783
                if (is_all_wspace(str)) {
 
784
                        data = NULL;
 
785
                } else {
 
786
                        data = import_data_new();
 
787
                        trashlist_add(fileinfo_trash, data);
 
788
                        data->model = save_basic->mode.model;
 
789
                        data->track_iter = save_basic->mode.track_iter;
 
790
                        data->dest_type = IMPORT_DEST_ARTIST;
 
791
                        strncpy(data->str, str, MAXLEN-1);
 
792
                }
 
793
                save_basic->entry_artist = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
794
                                                        _("Artist:"), str, _("Import as Artist"), data);
 
795
 
 
796
                strncpy(str, (char *)tag->album().toCString(true), MAXLEN-1);
 
797
                cut_trailing_whitespace(str);
 
798
                if (is_all_wspace(str)) {
 
799
                        data = NULL;
 
800
                } else {
 
801
                        data = import_data_new();
 
802
                        trashlist_add(fileinfo_trash, data);
 
803
                        data->model = save_basic->mode.model;
 
804
                        data->track_iter = save_basic->mode.track_iter;
 
805
                        data->dest_type = IMPORT_DEST_RECORD;
 
806
                        strncpy(data->str, str, MAXLEN-1);
 
807
                }
 
808
                save_basic->entry_album = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
809
                                                       _("Album:"), str, _("Import as Record"), data);
 
810
 
 
811
                if (tag->track() != 0) {
 
812
                        sprintf(str, "%d", tag->track());
 
813
                        data = import_data_new();
 
814
                        trashlist_add(fileinfo_trash, data);
 
815
                        data->model = save_basic->mode.model;
 
816
                        data->track_iter = save_basic->mode.track_iter;
 
817
                        data->dest_type = IMPORT_DEST_NUMBER;
 
818
                        strncpy(data->str, str, MAXLEN-1);
 
819
                } else {
 
820
                        str[0] = '\0';
 
821
                        data = NULL;
 
822
                }
 
823
                save_basic->entry_track = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
824
                                                       _("Track:"), str, _("Import as Track number"), data);
 
825
 
 
826
                if (tag->year() != 0) {
 
827
                        sprintf(str, "%d", tag->year());
 
828
                        data = import_data_new();
 
829
                        trashlist_add(fileinfo_trash, data);
 
830
                        data->model = save_basic->mode.model;
 
831
                        data->track_iter = save_basic->mode.track_iter;
 
832
                        data->dest_type = IMPORT_DEST_COMMENT;
 
833
                        snprintf(data->str, MAXLEN-1, "%s %s", _("Year:"), str);
 
834
                } else {
 
835
                        str[0] = '\0';
 
836
                        data = NULL;
 
837
                }
 
838
                save_basic->entry_year = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
839
                                                      _("Year:"), str, _("Add to Comments"), data);
 
840
 
 
841
                strncpy(str, (char *)tag->genre().toCString(true), MAXLEN-1);
 
842
                cut_trailing_whitespace(str);
 
843
                if (is_all_wspace(str)) {
 
844
                        data = NULL;
 
845
                } else {
 
846
                        data = import_data_new();
 
847
                        trashlist_add(fileinfo_trash, data);
 
848
                        data->model = save_basic->mode.model;
 
849
                        data->track_iter = save_basic->mode.track_iter;
 
850
                        data->dest_type = IMPORT_DEST_COMMENT;
 
851
                        snprintf(data->str, MAXLEN-1, "%s %s", _("Genre:"), str);
 
852
                }
 
853
                save_basic->entry_genre = append_table(table, cnt, edit_mode, _("Genre:"),
 
854
                                                       str, _("Add to Comments"), data);
 
855
 
 
856
                strncpy(str, (char *)tag->comment().toCString(true), MAXLEN-1);
 
857
                cut_trailing_whitespace(str);
 
858
                if (is_all_wspace(str)) {
 
859
                        data = NULL;
 
860
                } else {
 
861
                        data = import_data_new();
 
862
                        trashlist_add(fileinfo_trash, data);
 
863
                        data->model = save_basic->mode.model;
 
864
                        data->track_iter = save_basic->mode.track_iter;
 
865
                        data->dest_type = IMPORT_DEST_COMMENT;
 
866
                        snprintf(data->str, MAXLEN-1, "%s %s", _("Comment:"), str);
 
867
                }
 
868
                save_basic->entry_comment = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
869
                                                         _("Comment:"), str, _("Add to Comments"), data);
 
870
        } else {
 
871
                strncpy(str, (char *)tag->title().toCString(true), MAXLEN-1);
 
872
                cut_trailing_whitespace(str);
 
873
                save_basic->entry_title = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
874
                                                       _("Title:"), str,  NULL, NULL);
 
875
 
 
876
                strncpy(str, (char *)tag->artist().toCString(true), MAXLEN-1);
 
877
                cut_trailing_whitespace(str);
 
878
                save_basic->entry_artist = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
879
                                                        _("Artist:"), str, NULL, NULL);
 
880
 
 
881
                strncpy(str, (char *)tag->album().toCString(true), MAXLEN-1);
 
882
                cut_trailing_whitespace(str);
 
883
                save_basic->entry_album = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
884
                                                       _("Album:"), str,  NULL, NULL);
 
885
 
 
886
                if (tag->track() != 0) {
 
887
                        sprintf(str, "%d", tag->track());
 
888
                } else {
 
889
                        str[0] = '\0';
 
890
                }
 
891
                save_basic->entry_track = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
892
                                                       _("Track:"), str, NULL, NULL);
 
893
 
 
894
                if (tag->year() != 0) {
 
895
                        sprintf(str, "%d", tag->year());
 
896
                } else {
 
897
                        str[0] = '\0';
 
898
                }
 
899
                save_basic->entry_year = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
900
                                                      _("Year:"), str, NULL, NULL);
 
901
 
 
902
                strncpy(str, (char *)tag->genre().toCString(true), MAXLEN-1);
 
903
                cut_trailing_whitespace(str);
 
904
                save_basic->entry_genre = append_table(table, cnt, edit_mode, _("Genre:"), str,   NULL, NULL);
 
905
 
 
906
                strncpy(str, (char *)tag->comment().toCString(true), MAXLEN-1);
 
907
                cut_trailing_whitespace(str);
 
908
                save_basic->entry_comment = append_table(table, cnt, edit_mode ? EDITABLE_YES : EDITABLE_NO,
 
909
                                                         _("Comment:"), str, NULL, NULL);
 
910
        }
 
911
 
 
912
        if (ptable) {
 
913
                *ptable = table;
 
914
        }
 
915
 
 
916
        if (edit_mode) {
 
917
                GtkWidget * hbuttonbox = gtk_hbutton_box_new();
 
918
                gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END);
 
919
                GtkWidget * button = gui_stock_label_button(_("Save basic fields"), GTK_STOCK_SAVE);
 
920
                gtk_container_add(GTK_CONTAINER(hbuttonbox), button);   
 
921
                savepage_data_t * sdata = savepage_data_new();
 
922
                trashlist_add(fileinfo_trash, sdata);
 
923
                sdata->save_page_no = page_id;
 
924
                sdata->save_basic = save_basic;
 
925
                g_signal_connect(G_OBJECT(button), "clicked",
 
926
                                 G_CALLBACK(save_basic_fields), (gpointer)sdata);
 
927
                gtk_table_resize(GTK_TABLE(table), *cnt + 1, 3);
 
928
                gtk_table_attach(GTK_TABLE(table), hbuttonbox, 1, 3, *cnt, *cnt + 1, GTK_FILL, GTK_FILL, 5, 3);
 
929
                (*cnt)++;
 
930
        }
 
931
        return page_id;
 
932
}
 
933
 
 
934
#ifdef HAVE_WAVPACK
 
935
 
 
936
/* This does not support metadata editing or anything besides basic metadata */
 
937
void
 
938
build_wavpack_page(metadata * meta, GtkNotebook * nb, GtkWidget * hbox, char * nb_label) {
 
939
 
 
940
        GtkWidget * vbox = gtk_vbox_new(FALSE, 4);
 
941
        GtkWidget * table = gtk_table_new(0, 3, FALSE);
 
942
        GtkWidget * label = gtk_label_new(nb_label);
 
943
        GtkWidget * scrwin = gtk_scrolled_window_new(NULL, NULL);
 
944
        GtkWidget * viewp = gtk_viewport_new(NULL, NULL);
 
945
        gtk_viewport_set_shadow_type(GTK_VIEWPORT(viewp), GTK_SHADOW_NONE);
 
946
        gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
 
947
                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
 
948
        gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 10);
 
949
        gtk_container_add(GTK_CONTAINER(scrwin), viewp);
 
950
        gtk_container_add(GTK_CONTAINER(viewp), vbox);
 
951
 
 
952
        gtk_notebook_append_page(GTK_NOTEBOOK(nb), scrwin, label);
 
953
 
 
954
        char str[MAXLEN];
 
955
        int cnt = 0;
 
956
 
 
957
        meta_get_title(meta, str);
 
958
        cut_trailing_whitespace(str);
 
959
        append_table(table, &cnt, EDITABLE_NO, _("Title:"), str,  NULL, NULL);
 
960
 
 
961
        meta_get_artist(meta, str);
 
962
        cut_trailing_whitespace(str);
 
963
        append_table(table, &cnt, EDITABLE_NO, _("Artist:"), str, NULL, NULL);
 
964
 
 
965
        meta_get_record(meta, str);
 
966
        cut_trailing_whitespace(str);
 
967
        append_table(table, &cnt, EDITABLE_NO, _("Album:"), str,  NULL, NULL);
 
968
 
 
969
        meta_get_tracknum(meta, str);
 
970
        append_table(table, &cnt, EDITABLE_NO, _("Track:"), str, NULL, NULL);
 
971
 
 
972
        meta_get_year(meta, str);
 
973
        append_table(table, &cnt, EDITABLE_NO, _("Year:"), str, NULL, NULL);
 
974
 
 
975
        meta_get_genre(meta, str);
 
976
        cut_trailing_whitespace(str);
 
977
        append_table(table, &cnt, EDITABLE_NO, _("Genre:"), str,   NULL, NULL);
 
978
 
 
979
        meta_get_comment(meta, str);
 
980
        cut_trailing_whitespace(str);
 
981
        append_table(table, &cnt, EDITABLE_NO, _("Comment:"), str, NULL, NULL);
 
982
}
 
983
 
 
984
#endif /* HAVE_WAVPACK */
 
985
 
 
986
int
 
987
build_id3v1_page(save_basic_t * save_basic, int edit_mode, TagLib::ID3v1::Tag * id3v1_tag) {
 
988
 
 
989
        int cnt = 0;
 
990
        TagLib::Tag * tag = dynamic_cast<TagLib::Tag *>(id3v1_tag);
 
991
        save_basic->id3v1_tag = id3v1_tag;
 
992
        int page_no = build_simple_page(save_basic, tag, &cnt, NULL, edit_mode, _("ID3v1"));
 
993
        gtk_widget_show_all(GTK_WIDGET(save_basic->nb));
 
994
        return page_no;
 
995
}
 
996
 
 
997
 
 
998
void
 
999
insert_id3v2_text(GtkNotebook * nb, GtkWidget * table, int * cnt, fileinfo_mode_t mode,
 
1000
                  TagLib::ID3v2::Frame * frame, char * frameID) {
 
1001
 
 
1002
        char descr[MAXLEN];
 
1003
        char str[MAXLEN];
 
1004
 
 
1005
        TagLib::ID3v2::TextIdentificationFrame * tid_frame =
 
1006
                dynamic_cast<TagLib::ID3v2::TextIdentificationFrame *>(frame);
 
1007
 
 
1008
        if (!lookup_id3v2_textframe(frameID, descr))
 
1009
                return;
 
1010
 
 
1011
        int len = strlen(descr);
 
1012
        if (len < MAXLEN-1) {
 
1013
                descr[len++] = ':';
 
1014
                descr[len] = '\0';
 
1015
        }
 
1016
 
 
1017
        if (mode.is_called_from_browser) {
 
1018
                import_data_t * data;
 
1019
 
 
1020
                data = import_data_new();
 
1021
                trashlist_add(fileinfo_trash, data);
 
1022
                data->model = mode.model;
 
1023
                data->track_iter = mode.track_iter;
 
1024
                data->dest_type = IMPORT_DEST_COMMENT;
 
1025
                strncpy(str, (char *)tid_frame->toString().toCString(true), MAXLEN-1);
 
1026
                snprintf(data->str, MAXLEN-1, "%s: %s", descr, str);
 
1027
                append_table(table, cnt, false, descr, str, _("Add to Comments"), data);
 
1028
        } else {
 
1029
                strncpy(str, (char *)tid_frame->toString().toCString(true), MAXLEN-1);
 
1030
                append_table(table, cnt, false, descr, str, NULL, NULL);
 
1031
        }
 
1032
}
 
1033
 
 
1034
 
 
1035
void
 
1036
insert_id3v2_rva2(GtkNotebook * nb, GtkWidget * table, int * cnt, fileinfo_mode_t mode,
 
1037
                  char * id_str, float voladj) {
 
1038
        
 
1039
        char descr[MAXLEN];
 
1040
 
 
1041
        snprintf(descr, MAXLEN-1, "%+.1f dB (Id: %s)", voladj, id_str);
 
1042
 
 
1043
        if (mode.is_called_from_browser) {
 
1044
                import_data_t * data;
 
1045
 
 
1046
                data = import_data_new();
 
1047
                trashlist_add(fileinfo_trash, data);
 
1048
                data->model = mode.model;
 
1049
                data->track_iter = mode.track_iter;
 
1050
                data->dest_type = IMPORT_DEST_RVA;
 
1051
                data->fval = voladj;
 
1052
                append_table(table, cnt, false, _("Relative Volume Adj.:"), descr, _("Import as RVA"), data);
 
1053
        } else {
 
1054
                append_table(table, cnt, false, _("Relative Volume Adj.:"), descr, NULL, NULL);
 
1055
        }
 
1056
}
 
1057
 
 
1058
 
 
1059
char *
 
1060
pic_type_to_string(int type) {
 
1061
 
 
1062
        using namespace TagLib::ID3v2;
 
1063
 
 
1064
        switch (type) {
 
1065
        case AttachedPictureFrame::Other:
 
1066
                return _("Other");
 
1067
        case AttachedPictureFrame::FileIcon:
 
1068
                return _("File icon (32x32 PNG)");
 
1069
        case AttachedPictureFrame::OtherFileIcon:
 
1070
                return _("File icon (other)");
 
1071
        case AttachedPictureFrame::FrontCover:
 
1072
                return _("Front cover");
 
1073
        case AttachedPictureFrame::BackCover:
 
1074
                return _("Back cover");
 
1075
        case AttachedPictureFrame::LeafletPage:
 
1076
                return _("Leaflet page");
 
1077
        case AttachedPictureFrame::Media:
 
1078
                return _("Album image");
 
1079
        case AttachedPictureFrame::LeadArtist:
 
1080
                return _("Lead artist/performer");
 
1081
        case AttachedPictureFrame::Artist:
 
1082
                return _("Artist/performer");
 
1083
        case AttachedPictureFrame::Conductor:
 
1084
                return _("Conductor");
 
1085
        case AttachedPictureFrame::Band:
 
1086
                return _("Band/orchestra");
 
1087
        case AttachedPictureFrame::Composer:
 
1088
                return _("Composer");
 
1089
        case AttachedPictureFrame::Lyricist:
 
1090
                return _("Lyricist/text writer");
 
1091
        case AttachedPictureFrame::RecordingLocation:
 
1092
                return _("Recording location/studio");
 
1093
        case AttachedPictureFrame::DuringRecording:
 
1094
                return _("During recording");
 
1095
        case AttachedPictureFrame::DuringPerformance:
 
1096
                return _("During performance");
 
1097
        case AttachedPictureFrame::MovieScreenCapture:
 
1098
                return _("Movie/video screen capture");
 
1099
        case AttachedPictureFrame::ColouredFish:
 
1100
                return _("A large, coloured fish");
 
1101
        case AttachedPictureFrame::Illustration:
 
1102
                return _("Illustration");
 
1103
        case AttachedPictureFrame::BandLogo:
 
1104
                return _("Band/artist logotype");
 
1105
        case AttachedPictureFrame::PublisherLogo:
 
1106
                return _("Publisher/studio logotype");
 
1107
        default:
 
1108
                return NULL;
 
1109
        }
 
1110
}
 
1111
 
 
1112
 
 
1113
void
 
1114
insert_id3v2_apic(GtkNotebook * nb, GtkWidget * table, int * cnt, fileinfo_mode_t mode,
 
1115
                  TagLib::ID3v2::Frame * frame) {
 
1116
 
 
1117
        TagLib::ID3v2::AttachedPictureFrame * apic_frame =
 
1118
                dynamic_cast<TagLib::ID3v2::AttachedPictureFrame *>(frame);
 
1119
        
 
1120
        char mime_type[20];
 
1121
        char savefilename[256];
 
1122
        char tmpname[256];
 
1123
        void * image_data = NULL;
 
1124
 
 
1125
        mime_type[0] = '\0';
 
1126
        strcpy(savefilename, "picture.");
 
1127
        int r = sscanf(apic_frame->mimeType().toCString(true), "image/%s", mime_type);
 
1128
 
 
1129
        if (r == 0) {
 
1130
                strncpy(mime_type, apic_frame->mimeType().toCString(true), 19);
 
1131
        }
 
1132
        for (int i = 0; mime_type[i] != '\0'; i++) {
 
1133
                mime_type[i] = tolower(mime_type[i]);
 
1134
        }
 
1135
        if (mime_type[0] == '\0') {
 
1136
                strcpy(mime_type, "dat");
 
1137
        }
 
1138
        strncat(savefilename, mime_type, 255);
 
1139
 
 
1140
        TagLib::ByteVector bv = apic_frame->picture();
 
1141
        
 
1142
        if (bv.size() <= 0)
 
1143
                return;
 
1144
 
 
1145
        image_data = malloc(bv.size());
 
1146
        if (!image_data)
 
1147
                return;
 
1148
 
 
1149
        trashlist_add(fileinfo_trash, image_data);
 
1150
        memcpy(image_data, bv.data(), bv.size());
 
1151
 
 
1152
        tmpname[0] = '\0';
 
1153
        strcpy(tmpname, "/tmp/aqualung-picture-XXXXXX");
 
1154
        int fd = g_mkstemp(tmpname);
 
1155
        if (fd < 0) {
 
1156
                printf("error: g_mkstemp() failed\n");
 
1157
                return;
 
1158
        }
 
1159
        if (write(fd, bv.data(), bv.size()) != (int)bv.size()) {
 
1160
                printf("write() error\n");
 
1161
                return;
 
1162
        }
 
1163
        close(fd);
 
1164
 
 
1165
        GtkWidget * image = gtk_image_new_from_file(tmpname);
 
1166
        if (g_unlink(tmpname) < 0) {
 
1167
                printf("error: g_unlink() failed on %s\n", tmpname);
 
1168
                return;
 
1169
        }
 
1170
 
 
1171
        append_table_pic(table, cnt, image,
 
1172
                         pic_type_to_string(apic_frame->type()),
 
1173
                         apic_frame->description().isEmpty() ?
 
1174
                         NULL : (char *)apic_frame->description().toCString(true),
 
1175
                         savefilename, image_data, bv.size());
 
1176
}
 
1177
 
 
1178
 
 
1179
int
 
1180
build_id3v2_page(save_basic_t * save_basic, int edit_mode, TagLib::ID3v2::Tag * id3v2_tag) {
 
1181
 
 
1182
        int cnt = 0;
 
1183
        GtkWidget * table;
 
1184
 
 
1185
        TagLib::ID3v2::FrameList l = id3v2_tag->frameList();
 
1186
        std::list<TagLib::ID3v2::Frame*>::iterator i;
 
1187
        
 
1188
        TagLib::Tag * tag = dynamic_cast<TagLib::Tag *>(id3v2_tag);
 
1189
        save_basic->id3v2_tag = id3v2_tag;
 
1190
        int page_no = build_simple_page(save_basic, tag, &cnt, &table, edit_mode, _("ID3v2"));
 
1191
 
 
1192
        for (i = l.begin(); i != l.end(); ++i) {
 
1193
                TagLib::ID3v2::Frame * frame = *i;
 
1194
                char frameID[5];
 
1195
                
 
1196
                for(int j = 0; j < 4; j++) {
 
1197
                        frameID[j] = frame->frameID().data()[j];
 
1198
                }
 
1199
                frameID[4] = '\0';
 
1200
 
 
1201
                if (strcmp(frameID, "APIC") == 0) {
 
1202
                        insert_id3v2_apic(save_basic->nb, table, &cnt, save_basic->mode, frame);
 
1203
                } else if (strcmp(frameID, "RVA2") == 0) {
 
1204
                        char id_str[MAXLEN];
 
1205
                        float voladj;
 
1206
                        read_rva2(frame->render().data() + 10, frame->size(), id_str, &voladj);
 
1207
                        insert_id3v2_rva2(save_basic->nb, table, &cnt, save_basic->mode, id_str, voladj);
 
1208
                } else if (frameID[0] == 'T') {
 
1209
                        /* skip frames that are handled by the simple mode */
 
1210
                        if ((strcmp(frameID, "TIT2") != 0) && /* title */
 
1211
                            (strcmp(frameID, "TPE1") != 0) && /* artist */
 
1212
                            (strcmp(frameID, "TALB") != 0) && /* album */
 
1213
                            (strcmp(frameID, "TRCK") != 0) && /* track no. */
 
1214
                            (strcmp(frameID, "TCON") != 0) && /* genre */
 
1215
                            (strcmp(frameID, "TDRC") != 0)) { /* year */
 
1216
                                insert_id3v2_text(save_basic->nb, table, &cnt, save_basic->mode, frame, frameID);
 
1217
                        }
 
1218
                } else {
 
1219
                        /* XXX incomplete */
 
1220
                }
 
1221
        }
 
1222
        gtk_widget_show_all(GTK_WIDGET(save_basic->nb));
 
1223
        return page_no;
 
1224
}
 
1225
 
 
1226
 
 
1227
/* ape tags also use this */
 
1228
void
 
1229
insert_oxc(GtkNotebook * nb, GtkWidget * table, int * cnt, fileinfo_mode_t mode,
 
1230
           char * key, char * val) {
 
1231
 
 
1232
        if (mode.is_called_from_browser) {
 
1233
                import_data_t * data;
 
1234
                
 
1235
                data = import_data_new();
 
1236
                trashlist_add(fileinfo_trash, data);
 
1237
                
 
1238
                data->model = mode.model;
 
1239
                data->track_iter = mode.track_iter;
 
1240
                snprintf(data->str, MAXLEN-1, "%s %s", key, val);
 
1241
                
 
1242
                if ((strcmp(key, "Replaygain_track_gain:") == 0) ||
 
1243
                    (strcmp(key, "Replaygain_album_gain:") == 0)) {
 
1244
                        
 
1245
                        data->fval = convf(val);
 
1246
                        data->dest_type = IMPORT_DEST_RVA;
 
1247
                        append_table(table, cnt, false, key, val, _("Import as RVA"), data);
 
1248
                } else {
 
1249
                        data->fval = 0.0f;
 
1250
                        data->dest_type = IMPORT_DEST_COMMENT;
 
1251
                        append_table(table, cnt, false, key, val, _("Add to Comments"), data);
 
1252
                }
 
1253
        } else {
 
1254
                append_table(table, cnt, false, key, val, NULL, NULL);
 
1255
        }
 
1256
}
 
1257
 
 
1258
 
 
1259
int
 
1260
build_ape_page(save_basic_t * save_basic, int edit_mode, TagLib::APE::Tag * ape_tag) {
 
1261
 
 
1262
        int cnt = 0;
 
1263
        GtkWidget * table;
 
1264
        
 
1265
        TagLib::Tag * tag = dynamic_cast<TagLib::Tag *>(ape_tag);
 
1266
        save_basic->ape_tag = ape_tag;
 
1267
        int page_no = build_simple_page(save_basic, tag, &cnt, &table, edit_mode, _("APE"));
 
1268
 
 
1269
        TagLib::APE::ItemListMap m = ape_tag->itemListMap();
 
1270
        for (TagLib::APE::ItemListMap::Iterator i = m.begin(); i != m.end(); ++i) {
 
1271
 
 
1272
                TagLib::StringList::Iterator j;
 
1273
                TagLib::StringList l = (*i).second.toStringList();
 
1274
                for (j = l.begin(); j != l.end(); j++) {
 
1275
                        
 
1276
                        char key[MAXLEN];
 
1277
                        char val[MAXLEN];
 
1278
                        char c;
 
1279
                        int k;
 
1280
                        
 
1281
                        /* skip comments that are handled by the simple mode */
 
1282
                        if ((strcmp("TITLE", (*i).first.toCString(true)) == 0) ||
 
1283
                            (strcmp("ARTIST", (*i).first.toCString(true)) == 0) ||
 
1284
                            (strcmp("ALBUM", (*i).first.toCString(true)) == 0) ||
 
1285
                            (strcmp("YEAR", (*i).first.toCString(true)) == 0) ||
 
1286
                            (strcmp("COMMENT", (*i).first.toCString(true)) == 0) ||
 
1287
                            (strcmp("TRACK", (*i).first.toCString(true)) == 0) ||
 
1288
                            (strcmp("GENRE", (*i).first.toCString(true)) == 0)) {
 
1289
                                
 
1290
                                continue;
 
1291
                        }
 
1292
                        
 
1293
                        for (k = 0; ((c = (*i).first.toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) {
 
1294
                                key[k] = (k == 0) ? toupper(c) : tolower(c);
 
1295
                        }
 
1296
                        key[k++] = ':';
 
1297
                        key[k] = '\0';
 
1298
                        
 
1299
                        for (k = 0; ((c = (*j).toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) {
 
1300
                                val[k] = c;
 
1301
                        }
 
1302
                        val[k] = '\0';
 
1303
                        
 
1304
                        insert_oxc(save_basic->nb, table, &cnt, save_basic->mode, key, val);
 
1305
                }
 
1306
        }
 
1307
        gtk_widget_show_all(GTK_WIDGET(save_basic->nb));
 
1308
        return page_no;
 
1309
}
 
1310
 
 
1311
 
 
1312
int
 
1313
build_oxc_page(save_basic_t * save_basic, int edit_mode, TagLib::Ogg::XiphComment * oxc) {
 
1314
 
 
1315
        int cnt = 0;
 
1316
        GtkWidget * table;
 
1317
 
 
1318
        TagLib::Tag * tag = dynamic_cast<TagLib::Tag *>(oxc);
 
1319
        save_basic->oxc = oxc;
 
1320
        int page_no = build_simple_page(save_basic, tag, &cnt, &table, edit_mode, _("Ogg comments"));
 
1321
 
 
1322
        TagLib::Ogg::FieldListMap m = oxc->fieldListMap();
 
1323
        for (TagLib::Ogg::FieldListMap::Iterator i = m.begin(); i != m.end(); ++i) {
 
1324
                for (TagLib::StringList::Iterator j = (*i).second.begin(); j != (*i).second.end(); ++j) {
 
1325
                        char key[MAXLEN];
 
1326
                        char val[MAXLEN];
 
1327
                        char c;
 
1328
                        int k;
 
1329
 
 
1330
                        /* skip comments that are handled by the simple mode */
 
1331
                        if ((strcmp("TITLE", (*i).first.toCString(true)) == 0) ||
 
1332
                            (strcmp("ARTIST", (*i).first.toCString(true)) == 0) ||
 
1333
                            (strcmp("ALBUM", (*i).first.toCString(true)) == 0) ||
 
1334
                            (strcmp("DATE", (*i).first.toCString(true)) == 0) ||
 
1335
                            (strcmp("COMMENT", (*i).first.toCString(true)) == 0) ||
 
1336
                            (strcmp("TRACKNUMBER", (*i).first.toCString(true)) == 0) ||
 
1337
                            (strcmp("GENRE", (*i).first.toCString(true)) == 0)) {
 
1338
 
 
1339
                                continue;
 
1340
                        }
 
1341
 
 
1342
                        for (k = 0; ((c = (*i).first.toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) {
 
1343
                                key[k] = (k == 0) ? toupper(c) : tolower(c);
 
1344
                        }
 
1345
                        key[k++] = ':';
 
1346
                        key[k] = '\0';
 
1347
 
 
1348
                        for (k = 0; ((c = (*j).toCString(true)[k]) != '\0') && (k < MAXLEN-1); k++) {
 
1349
                                val[k] = c;
 
1350
                        }
 
1351
                        val[k] = '\0';
 
1352
 
 
1353
                        insert_oxc(save_basic->nb, table, &cnt, save_basic->mode, key, val);
 
1354
                }
 
1355
        }
 
1356
        insert_oxc(save_basic->nb, table, &cnt, save_basic->mode, _("Vendor:"),
 
1357
                   (char *)oxc->vendorID().toCString(true));
 
1358
 
 
1359
        gtk_widget_show_all(GTK_WIDGET(save_basic->nb));
 
1360
        return page_no;
 
1361
}
 
1362
 
 
1363
 
 
1364
void build_tag_buttons(save_basic_t * save_basic);
 
1365
 
 
1366
void
 
1367
create_remove_handler(GtkWidget * widget, gpointer data) {
 
1368
 
 
1369
        tagbutton_data_t * tdata = (tagbutton_data_t *)data;
 
1370
        save_basic_t * save_basic = tdata->save_basic;
 
1371
        int tags;
 
1372
 
 
1373
        switch (tdata->flags) {
 
1374
        case CREATE_ID3v2:
 
1375
                if (save_basic->taglib_mpeg_file != NULL) {
 
1376
 
 
1377
                        save_basic->id3v2_tag = save_basic->taglib_mpeg_file->ID3v2Tag(true);
 
1378
                        save_basic->id3v2_tag->setTitle(" ");
 
1379
 
 
1380
                        tags = TagLib::MPEG::File::ID3v2;
 
1381
                        if (save_basic->id3v1_tag != NULL)
 
1382
                                tags |= TagLib::MPEG::File::ID3v1;
 
1383
                        if (save_basic->ape_tag != NULL)
 
1384
                                tags |= TagLib::MPEG::File::APE;
 
1385
                        save_basic->taglib_mpeg_file->save(tags, false);
 
1386
 
 
1387
                        /* close & reopen file to workaround buggy TagLib */
 
1388
                        {
 
1389
                                char buf[MAXLEN];
 
1390
                                strncpy(buf, save_basic->taglib_mpeg_file->name(), MAXLEN-1);
 
1391
                                save_basic->taglib_mpeg_file->~File();
 
1392
                                save_basic->taglib_mpeg_file = new TagLib::MPEG::File(buf, false);
 
1393
                        }
 
1394
 
 
1395
                        /* if we have an ID3v1 page, re-create it in read-only mode */
 
1396
                        if (save_basic->id3v1_page_no != -1) {
 
1397
                                gtk_notebook_remove_page(save_basic->nb, save_basic->id3v1_page_no);
 
1398
                                save_basic->id3v1_page_no = -1;
 
1399
                                save_basic->id3v1_page_no =
 
1400
                                        build_id3v1_page(save_basic, false, save_basic->taglib_mpeg_file->ID3v1Tag());
 
1401
                        }
 
1402
 
 
1403
                        save_basic->id3v2_page_no =
 
1404
                                build_id3v2_page(save_basic, true, save_basic->taglib_mpeg_file->ID3v2Tag());
 
1405
 
 
1406
                        save_basic->flags &= ~CREATE_ID3v2;
 
1407
                        save_basic->flags |= REMOVE_ID3v2;
 
1408
                        build_tag_buttons(save_basic);
 
1409
                }
 
1410
                break;
 
1411
        case CREATE_APE:
 
1412
                if (save_basic->taglib_mpc_file != NULL) {
 
1413
 
 
1414
                        save_basic->ape_tag = save_basic->taglib_mpc_file->APETag(true);
 
1415
                        save_basic->ape_tag->setTitle(" ");
 
1416
                        save_basic->taglib_mpc_file->save();
 
1417
 
 
1418
                        /* close & reopen file to workaround buggy TagLib */
 
1419
                        {
 
1420
                                char buf[MAXLEN];
 
1421
                                strncpy(buf, save_basic->taglib_mpc_file->name(), MAXLEN-1);
 
1422
                                save_basic->taglib_mpc_file->~File();
 
1423
                                save_basic->taglib_mpc_file = new TagLib::MPC::File(buf, false);
 
1424
                        }
 
1425
 
 
1426
                        save_basic->ape_page_no =
 
1427
                                build_ape_page(save_basic, true, save_basic->taglib_mpc_file->APETag());
 
1428
 
 
1429
                        save_basic->flags &= ~CREATE_APE;
 
1430
                        save_basic->flags |= REMOVE_APE;
 
1431
                        build_tag_buttons(save_basic);
 
1432
                }
 
1433
                break;
 
1434
        case REMOVE_ID3v1:
 
1435
                if (save_basic->taglib_mpeg_file != NULL) {
 
1436
                        save_basic->taglib_mpeg_file->strip(TagLib::MPEG::File::ID3v1);
 
1437
                        save_basic->id3v1_tag = NULL;
 
1438
 
 
1439
                        tags = 0;
 
1440
                        if (save_basic->id3v2_tag != NULL)
 
1441
                                tags |= TagLib::MPEG::File::ID3v2;
 
1442
                        if (save_basic->ape_tag != NULL)
 
1443
                                tags |= TagLib::MPEG::File::APE;
 
1444
                        save_basic->taglib_mpeg_file->save(tags, true);
 
1445
                }
 
1446
                if (save_basic->taglib_mpc_file != NULL) {
 
1447
                        save_basic->taglib_mpc_file->remove(TagLib::MPC::File::ID3v1);
 
1448
                        save_basic->taglib_mpc_file->save();
 
1449
                }
 
1450
 
 
1451
                if (save_basic->id3v2_page_no > save_basic->id3v1_page_no)
 
1452
                        save_basic->id3v2_page_no -= 1;
 
1453
                if (save_basic->ape_page_no > save_basic->id3v1_page_no)
 
1454
                        save_basic->ape_page_no -= 1;
 
1455
                if (save_basic->oxc_page_no > save_basic->id3v1_page_no)
 
1456
                        save_basic->oxc_page_no -= 1;
 
1457
 
 
1458
                gtk_notebook_remove_page(save_basic->nb, save_basic->id3v1_page_no);
 
1459
                save_basic->id3v1_page_no = -1;
 
1460
                save_basic->flags &= ~REMOVE_ID3v1;
 
1461
                build_tag_buttons(save_basic);
 
1462
                break;
 
1463
        case REMOVE_ID3v2:
 
1464
                if (save_basic->taglib_mpeg_file == NULL)
 
1465
                        break;
 
1466
 
 
1467
                save_basic->taglib_mpeg_file->strip(TagLib::MPEG::File::ID3v2);
 
1468
                save_basic->id3v2_tag = NULL;
 
1469
 
 
1470
                tags = 0;
 
1471
                if (save_basic->id3v1_tag != NULL)
 
1472
                        tags |= TagLib::MPEG::File::ID3v1;
 
1473
                if (save_basic->ape_tag != NULL)
 
1474
                        tags |= TagLib::MPEG::File::APE;
 
1475
                save_basic->taglib_mpeg_file->save(tags, true);
 
1476
 
 
1477
                if (save_basic->id3v1_page_no > save_basic->id3v2_page_no)
 
1478
                        save_basic->id3v1_page_no -= 1;
 
1479
                if (save_basic->ape_page_no > save_basic->id3v2_page_no)
 
1480
                        save_basic->ape_page_no -= 1;
 
1481
                if (save_basic->oxc_page_no > save_basic->id3v2_page_no)
 
1482
                        save_basic->oxc_page_no -= 1;
 
1483
                
 
1484
                gtk_notebook_remove_page(save_basic->nb, save_basic->id3v2_page_no);
 
1485
                save_basic->id3v2_page_no = -1;
 
1486
                save_basic->flags &= ~REMOVE_ID3v2;
 
1487
                save_basic->flags |= CREATE_ID3v2;
 
1488
                build_tag_buttons(save_basic);
 
1489
                break;
 
1490
        case REMOVE_APE:
 
1491
                if (save_basic->taglib_mpeg_file != NULL) {
 
1492
                        save_basic->taglib_mpeg_file->strip(TagLib::MPEG::File::APE);
 
1493
 
 
1494
                        tags = 0;
 
1495
                        if (save_basic->id3v1_tag != NULL)
 
1496
                                tags |= TagLib::MPEG::File::ID3v1;
 
1497
                        if (save_basic->id3v2_tag != NULL)
 
1498
                                tags |= TagLib::MPEG::File::ID3v2;
 
1499
                        save_basic->taglib_mpeg_file->save(tags, true);
 
1500
                }
 
1501
                if (save_basic->taglib_mpc_file != NULL) {
 
1502
                        save_basic->taglib_mpc_file->remove(TagLib::MPC::File::APE);
 
1503
                        save_basic->taglib_mpc_file->save();
 
1504
                }
 
1505
                save_basic->ape_tag = NULL;
 
1506
 
 
1507
                if (save_basic->id3v1_page_no > save_basic->ape_page_no)
 
1508
                        save_basic->id3v1_page_no -= 1;
 
1509
                if (save_basic->id3v2_page_no > save_basic->ape_page_no)
 
1510
                        save_basic->id3v2_page_no -= 1;
 
1511
                if (save_basic->oxc_page_no > save_basic->ape_page_no)
 
1512
                        save_basic->oxc_page_no -= 1;
 
1513
 
 
1514
                gtk_notebook_remove_page(save_basic->nb, save_basic->ape_page_no);
 
1515
                save_basic->ape_page_no = -1;
 
1516
                save_basic->flags &= ~REMOVE_APE;
 
1517
                if (save_basic->taglib_mpc_file != NULL) {
 
1518
                        save_basic->flags |= CREATE_APE;
 
1519
                }
 
1520
                build_tag_buttons(save_basic);
 
1521
                break;
 
1522
        }
 
1523
}
 
1524
 
 
1525
 
 
1526
void
 
1527
build_tag_buttons(save_basic_t * save_basic) {
 
1528
 
 
1529
        tagbutton_data_t * tdata = NULL;
 
1530
        GtkWidget * button;
 
1531
        GtkWidget * hbox;
 
1532
 
 
1533
        if (save_basic->hbox_inner != NULL) {
 
1534
                gtk_widget_destroy(save_basic->hbox_inner);
 
1535
        }
 
1536
        save_basic->hbox_inner = gtk_hbox_new(FALSE, 0);
 
1537
        gtk_widget_show(save_basic->hbox_inner);
 
1538
        gtk_container_add(GTK_CONTAINER(save_basic->hbox), save_basic->hbox_inner);
 
1539
 
 
1540
        hbox = save_basic->hbox_inner;
 
1541
 
 
1542
        if (save_basic->flags & REMOVE_ID3v1) {
 
1543
                button = gui_stock_label_button(_("Remove ID3v1"), GTK_STOCK_REMOVE);
 
1544
 
 
1545
                gtk_widget_show(button);
 
1546
                tdata = tagbutton_data_new();
 
1547
                trashlist_add(fileinfo_trash, tdata);
 
1548
                tdata->flags |= REMOVE_ID3v1;
 
1549
                tdata->save_basic = save_basic;
 
1550
                g_signal_connect(G_OBJECT(button), "clicked",
 
1551
                                 G_CALLBACK(create_remove_handler), (gpointer)tdata);
 
1552
                gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
 
1553
        }
 
1554
        if (save_basic->flags & CREATE_ID3v2) {
 
1555
                button = gui_stock_label_button(_("Create ID3v2"), GTK_STOCK_ADD);
 
1556
                gtk_widget_show(button);
 
1557
                tdata = tagbutton_data_new();
 
1558
                trashlist_add(fileinfo_trash, tdata);
 
1559
                tdata->flags |= CREATE_ID3v2;
 
1560
                tdata->save_basic = save_basic;
 
1561
                g_signal_connect(G_OBJECT(button), "clicked",
 
1562
                                 G_CALLBACK(create_remove_handler), (gpointer)tdata);
 
1563
                gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
 
1564
        }
 
1565
        if (save_basic->flags & REMOVE_ID3v2) {
 
1566
                button = gui_stock_label_button(_("Remove ID3v2"), GTK_STOCK_REMOVE);
 
1567
                gtk_widget_show(button);
 
1568
                tdata = tagbutton_data_new();
 
1569
                trashlist_add(fileinfo_trash, tdata);
 
1570
                tdata->flags |= REMOVE_ID3v2;
 
1571
                tdata->save_basic = save_basic;
 
1572
                g_signal_connect(G_OBJECT(button), "clicked",
 
1573
                                 G_CALLBACK(create_remove_handler), (gpointer)tdata);
 
1574
                gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
 
1575
        }
 
1576
        if (save_basic->flags & CREATE_APE) {
 
1577
                button = gui_stock_label_button(_("Create APE"), GTK_STOCK_ADD);
 
1578
                gtk_widget_show(button);
 
1579
                tdata = tagbutton_data_new();
 
1580
                trashlist_add(fileinfo_trash, tdata);
 
1581
                tdata->flags |= CREATE_APE;
 
1582
                tdata->save_basic = save_basic;
 
1583
                g_signal_connect(G_OBJECT(button), "clicked",
 
1584
                                 G_CALLBACK(create_remove_handler), (gpointer)tdata);
 
1585
                gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
 
1586
        }
 
1587
        if (save_basic->flags & REMOVE_APE) {
 
1588
                button = gui_stock_label_button(_("Remove APE"), GTK_STOCK_REMOVE);
 
1589
                gtk_widget_show(button);
 
1590
                tdata = tagbutton_data_new();
 
1591
                trashlist_add(fileinfo_trash, tdata);
 
1592
                tdata->flags |= REMOVE_APE;
 
1593
                tdata->save_basic = save_basic;
 
1594
                g_signal_connect(G_OBJECT(button), "clicked",
 
1595
                                 G_CALLBACK(create_remove_handler), (gpointer)tdata);
 
1596
                gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 3);
 
1597
        }
 
1598
}
 
1599
 
 
1600
 
 
1601
#ifdef HAVE_FLAC
 
1602
void
 
1603
build_nb_pages_flac(metadata * meta, GtkNotebook * nb, GtkWidget * hbox, fileinfo_mode_t mode) {
 
1604
 
 
1605
        TagLib::FLAC::File * taglib_flac_file =
 
1606
                reinterpret_cast<TagLib::FLAC::File *>(meta->taglib_file);
 
1607
 
 
1608
#ifdef HAVE_METAEDIT
 
1609
        TagLib::File * taglib_file =
 
1610
                dynamic_cast<TagLib::File *>(taglib_flac_file);
 
1611
 
 
1612
        int edit_mode = taglib_file->readOnly() ? EDITABLE_NO : EDITABLE_YES;
 
1613
#else
 
1614
        int edit_mode = EDITABLE_NO;
 
1615
#endif /* HAVE_METAEDIT */
 
1616
 
 
1617
        save_basic_t * save_basic = save_basic_new();
 
1618
        trashlist_add(fileinfo_trash, save_basic);
 
1619
        save_basic->taglib_flac_file = taglib_flac_file;
 
1620
        save_basic->nb = nb;
 
1621
        save_basic->hbox = hbox;
 
1622
        save_basic->mode = mode;
 
1623
 
 
1624
        if (taglib_flac_file->ID3v1Tag() && !taglib_flac_file->ID3v1Tag()->isEmpty()) {
 
1625
                save_basic->id3v1_page_no =
 
1626
                    build_id3v1_page(save_basic, EDITABLE_NO, taglib_flac_file->ID3v1Tag());
 
1627
        }
 
1628
        if (taglib_flac_file->ID3v2Tag() && !taglib_flac_file->ID3v2Tag()->isEmpty()) {
 
1629
                save_basic->id3v2_page_no =
 
1630
                    build_id3v2_page(save_basic, EDITABLE_NO, taglib_flac_file->ID3v2Tag());
 
1631
        }
 
1632
        if (taglib_flac_file->xiphComment()) {
 
1633
                save_basic->oxc_page_no =
 
1634
                    build_oxc_page(save_basic, edit_mode, taglib_flac_file->xiphComment());
 
1635
        }
 
1636
 
 
1637
        if (edit_mode) {
 
1638
                build_tag_buttons(save_basic);
 
1639
        }
 
1640
}
 
1641
#endif /* HAVE_FLAC */
 
1642
 
 
1643
 
 
1644
#ifdef HAVE_OGG_VORBIS
 
1645
void
 
1646
build_nb_pages_oggv(metadata * meta, GtkNotebook * nb, GtkWidget * hbox, fileinfo_mode_t mode) {
 
1647
 
 
1648
        TagLib::Ogg::Vorbis::File * taglib_oggv_file =
 
1649
                reinterpret_cast<TagLib::Ogg::Vorbis::File *>(meta->taglib_file);
 
1650
 
 
1651
#ifdef HAVE_METAEDIT
 
1652
        TagLib::File * taglib_file =
 
1653
                dynamic_cast<TagLib::File *>(taglib_oggv_file);
 
1654
 
 
1655
        int edit_mode = taglib_file->readOnly() ? EDITABLE_NO : EDITABLE_YES;
 
1656
#else
 
1657
        int edit_mode = EDITABLE_NO;
 
1658
#endif /* HAVE_METAEDIT */
 
1659
 
 
1660
        save_basic_t * save_basic = save_basic_new();
 
1661
        trashlist_add(fileinfo_trash, save_basic);
 
1662
        save_basic->taglib_oggv_file = taglib_oggv_file;
 
1663
        save_basic->nb = nb;
 
1664
        save_basic->hbox = hbox;
 
1665
        save_basic->mode = mode;
 
1666
 
 
1667
        if (taglib_oggv_file->tag()) {
 
1668
                save_basic->oxc_page_no =
 
1669
                    build_oxc_page(save_basic, edit_mode, taglib_oggv_file->tag());
 
1670
        }
 
1671
 
 
1672
        if (edit_mode) {
 
1673
                build_tag_buttons(save_basic);
 
1674
        }
 
1675
}
 
1676
#endif /* HAVE_OGG_VORBIS */
 
1677
 
 
1678
 
 
1679
#ifdef HAVE_MPEG
 
1680
void
 
1681
build_nb_pages_mpeg(metadata * meta, GtkNotebook * nb, GtkWidget * hbox, fileinfo_mode_t mode) {
 
1682
 
 
1683
        TagLib::MPEG::File * taglib_mpeg_file =
 
1684
                reinterpret_cast<TagLib::MPEG::File *>(meta->taglib_file);
 
1685
 
 
1686
#ifdef HAVE_METAEDIT
 
1687
        TagLib::File * taglib_file =
 
1688
                dynamic_cast<TagLib::File *>(taglib_mpeg_file);
 
1689
 
 
1690
        int edit_mode = taglib_file->readOnly() ? EDITABLE_NO : EDITABLE_YES;
 
1691
#else
 
1692
        int edit_mode = EDITABLE_NO;
 
1693
#endif /* HAVE_METAEDIT */
 
1694
 
 
1695
        save_basic_t * save_basic = save_basic_new();
 
1696
        trashlist_add(fileinfo_trash, save_basic);
 
1697
        save_basic->taglib_mpeg_file = taglib_mpeg_file;
 
1698
        save_basic->nb = nb;
 
1699
        save_basic->hbox = hbox;
 
1700
        save_basic->mode = mode;
 
1701
 
 
1702
        if (taglib_mpeg_file->ID3v1Tag() && !taglib_mpeg_file->ID3v1Tag()->isEmpty()) {
 
1703
                /* allow editing only if there is no id3v2 tag */
 
1704
                int id3v1_edit_mode = edit_mode;
 
1705
                if ((id3v1_edit_mode == EDITABLE_YES) && taglib_mpeg_file->ID3v2Tag()) {
 
1706
                        id3v1_edit_mode = taglib_mpeg_file->ID3v2Tag()->isEmpty() ? EDITABLE_YES : EDITABLE_NO;
 
1707
                }
 
1708
                if (id3v1_edit_mode == EDITABLE_YES) {
 
1709
                        id3v1_edit_mode = EDITABLE_GENRE;
 
1710
                }
 
1711
                save_basic->id3v1_page_no =
 
1712
                    build_id3v1_page(save_basic, id3v1_edit_mode, taglib_mpeg_file->ID3v1Tag());
 
1713
                save_basic->flags |= REMOVE_ID3v1;
 
1714
        }
 
1715
 
 
1716
        if (taglib_mpeg_file->ID3v2Tag() && !taglib_mpeg_file->ID3v2Tag()->isEmpty()) {
 
1717
                save_basic->id3v2_page_no =
 
1718
                    build_id3v2_page(save_basic, edit_mode, taglib_mpeg_file->ID3v2Tag());
 
1719
                save_basic->flags |= REMOVE_ID3v2;
 
1720
        } else {
 
1721
                save_basic->flags |= CREATE_ID3v2;
 
1722
        }
 
1723
        if (taglib_mpeg_file->APETag()) {
 
1724
                save_basic->ape_page_no =
 
1725
                    build_ape_page(save_basic, EDITABLE_NO, taglib_mpeg_file->APETag());
 
1726
                save_basic->flags |= REMOVE_APE;
 
1727
        }
 
1728
 
 
1729
        if (edit_mode) {
 
1730
                build_tag_buttons(save_basic);
 
1731
        }
 
1732
}
 
1733
#endif /* HAVE_MPEG */
 
1734
 
 
1735
 
 
1736
#ifdef HAVE_MPC
 
1737
void
 
1738
build_nb_pages_mpc(metadata * meta, GtkNotebook * nb, GtkWidget * hbox, fileinfo_mode_t mode) {
 
1739
 
 
1740
        TagLib::MPC::File * taglib_mpc_file =
 
1741
                reinterpret_cast<TagLib::MPC::File *>(meta->taglib_file);
 
1742
 
 
1743
#ifdef HAVE_METAEDIT
 
1744
        TagLib::File * taglib_file =
 
1745
                dynamic_cast<TagLib::File *>(taglib_mpc_file);
 
1746
 
 
1747
        int edit_mode = taglib_file->readOnly() ? EDITABLE_NO : EDITABLE_YES;
 
1748
#else
 
1749
        int edit_mode = EDITABLE_NO;
 
1750
#endif /* HAVE_METAEDIT */
 
1751
 
 
1752
        save_basic_t * save_basic = save_basic_new();
 
1753
        trashlist_add(fileinfo_trash, save_basic);
 
1754
        save_basic->taglib_mpc_file = taglib_mpc_file;
 
1755
        save_basic->nb = nb;
 
1756
        save_basic->hbox = hbox;
 
1757
        save_basic->mode = mode;
 
1758
 
 
1759
        if (taglib_mpc_file->ID3v1Tag() && !taglib_mpc_file->ID3v1Tag()->isEmpty()) {
 
1760
                save_basic->id3v1_page_no =
 
1761
                    build_id3v1_page(save_basic, EDITABLE_NO, taglib_mpc_file->ID3v1Tag());
 
1762
                save_basic->flags |= REMOVE_ID3v1;
 
1763
        }
 
1764
        if (taglib_mpc_file->APETag() && !taglib_mpc_file->APETag()->isEmpty()) {
 
1765
                save_basic->ape_page_no =
 
1766
                    build_ape_page(save_basic, edit_mode, taglib_mpc_file->APETag());
 
1767
                save_basic->flags |= REMOVE_APE;
 
1768
        } else {
 
1769
                save_basic->flags |= CREATE_APE;
 
1770
        }
 
1771
 
 
1772
        if (edit_mode) {
 
1773
                build_tag_buttons(save_basic);
 
1774
        }
 
1775
}
 
1776
#endif /* HAVE_MPC */
 
1777
#endif /* HAVE_TAGLIB */
 
1778
 
 
1779
gboolean    
 
1780
fi_cover_press_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data) {
 
1781
 
 
1782
        if (event->type == GDK_BUTTON_PRESS && event->button == 1) { /* LMB ? */
 
1783
                display_zoomed_cover(info_window, fi_event_box, (gchar *) user_data);
 
1784
        }
 
1785
        return TRUE;
 
1786
}    
 
1787
 
 
1788
void
 
1789
show_file_info(char * name, char * file, int is_called_from_browser,
 
1790
               GtkTreeModel * model, GtkTreeIter track_iter) {
 
1791
 
 
1792
        char str[MAXLEN];
 
1793
        gchar *file_display;
 
1794
 
 
1795
        GtkWidget * vbox;
 
1796
        GtkWidget * hbox_tagbuttons;
 
1797
        GtkWidget * hbox_t;
 
1798
        GtkWidget * table;
 
1799
        GtkWidget * hbox_name;
 
1800
        GtkWidget * label_name;
 
1801
        GtkWidget * entry_name;
 
1802
        GtkWidget * hbox_path;
 
1803
        GtkWidget * label_path;
 
1804
        GtkWidget * entry_path;
 
1805
        GtkWidget * dismiss_btn;
 
1806
        GtkWidget * fi_cover_image_area;
 
1807
        GtkWidget * fi_cover_align;
 
1808
 
 
1809
        GtkWidget * vbox_file;
 
1810
        GtkWidget * label_file;
 
1811
        GtkWidget * table_file;
 
1812
        GtkWidget * hbox;
 
1813
        GtkWidget * label;
 
1814
        GtkWidget * entry;
 
1815
 
 
1816
#ifdef HAVE_MOD_INFO
 
1817
        mod_info * mdi;
 
1818
        GtkWidget * vbox_mod;
 
1819
        GtkWidget * label_mod;
 
1820
#endif /* HAVE_MOD_INFO */
 
1821
 
 
1822
        metadata * meta = meta_new();
 
1823
 
 
1824
        fileinfo_mode_t mode;
 
1825
        mode.is_called_from_browser = is_called_from_browser;
 
1826
        mode.model = model;
 
1827
        mode.track_iter = track_iter;
 
1828
 
 
1829
        if (info_window != NULL) {
 
1830
                gtk_widget_destroy(info_window);
 
1831
                info_window = NULL;
 
1832
        }
 
1833
 
 
1834
        if (fileinfo_trash != NULL) {
 
1835
                trashlist_free(fileinfo_trash);
 
1836
                fileinfo_trash = NULL;
 
1837
        }
 
1838
        fileinfo_trash = trashlist_new();
 
1839
 
 
1840
        if (!meta_read(meta, file)) {
 
1841
                meta_free(meta);
 
1842
                return;
 
1843
        }
 
1844
 
 
1845
        info_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
1846
        gtk_window_set_title(GTK_WINDOW(info_window), _("File info"));
 
1847
        gtk_window_set_transient_for(GTK_WINDOW(info_window), GTK_WINDOW(main_window));
 
1848
        gtk_window_set_position(GTK_WINDOW(info_window), GTK_WIN_POS_CENTER_ON_PARENT);
 
1849
        gtk_window_set_default_size(GTK_WINDOW(info_window), 600, 500);
 
1850
        gtk_window_set_resizable(GTK_WINDOW(info_window), TRUE);
 
1851
        g_signal_connect(G_OBJECT(info_window), "delete_event",
 
1852
                         G_CALLBACK(info_window_close), (gpointer)meta);
 
1853
        g_signal_connect(G_OBJECT(info_window), "key_press_event",
 
1854
                         G_CALLBACK(info_window_key_pressed), (gpointer)meta);
 
1855
        gtk_container_set_border_width(GTK_CONTAINER(info_window), 5);
 
1856
 
 
1857
        vbox = gtk_vbox_new(FALSE, 0);
 
1858
        gtk_container_add(GTK_CONTAINER(info_window), vbox);
 
1859
 
 
1860
        hbox_t = gtk_hbox_new(FALSE, 0);
 
1861
        gtk_box_pack_start(GTK_BOX(vbox), hbox_t, FALSE, FALSE, 5);
 
1862
 
 
1863
        table = gtk_table_new(2, 2, FALSE);
 
1864
        gtk_box_pack_start(GTK_BOX(hbox_t), table, TRUE, TRUE, 4);
 
1865
 
 
1866
        hbox_name = gtk_hbox_new(FALSE, 0);
 
1867
        label_name = gtk_label_new(_("Track:"));
 
1868
        gtk_box_pack_start(GTK_BOX(hbox_name), label_name, FALSE, FALSE, 0);
 
1869
        gtk_table_attach(GTK_TABLE(table), hbox_name, 0, 1, 0, 1,
 
1870
                         GTK_FILL, GTK_FILL, 5, 2);
 
1871
 
 
1872
        entry_name = gtk_entry_new();
 
1873
        GTK_WIDGET_UNSET_FLAGS(entry_name, GTK_CAN_FOCUS);
 
1874
        gtk_entry_set_text(GTK_ENTRY(entry_name), name);
 
1875
        gtk_editable_set_editable(GTK_EDITABLE(entry_name), FALSE);
 
1876
        gtk_table_attach(GTK_TABLE(table), entry_name, 1, 2, 0, 1,
 
1877
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 2);
 
1878
 
 
1879
        hbox_path = gtk_hbox_new(FALSE, 0);
 
1880
        label_path = gtk_label_new(_("File:"));
 
1881
        gtk_box_pack_start(GTK_BOX(hbox_path), label_path, FALSE, FALSE, 0);
 
1882
        gtk_table_attach(GTK_TABLE(table), hbox_path, 0, 1, 1, 2,
 
1883
                         GTK_FILL, GTK_FILL, 5, 2);
 
1884
 
 
1885
        file_display=g_filename_display_name(file);
 
1886
        entry_path = gtk_entry_new();
 
1887
        GTK_WIDGET_UNSET_FLAGS(entry_path, GTK_CAN_FOCUS);
 
1888
        gtk_entry_set_text(GTK_ENTRY(entry_path), file_display);
 
1889
        g_free(file_display);
 
1890
        gtk_editable_set_editable(GTK_EDITABLE(entry_path), FALSE);
 
1891
        gtk_table_attach(GTK_TABLE(table), entry_path, 1, 2, 1, 2,
 
1892
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 2);
 
1893
 
 
1894
        fi_cover_align = gtk_alignment_new(0.5f, 0.5f, 0.0f, 0.0f);
 
1895
        gtk_box_pack_start(GTK_BOX(hbox_t), fi_cover_align, FALSE, FALSE, 0);
 
1896
        fi_cover_image_area = gtk_image_new();
 
1897
        fi_event_box = gtk_event_box_new ();
 
1898
        gtk_container_add(GTK_CONTAINER(fi_cover_align), fi_event_box);
 
1899
        gtk_container_add (GTK_CONTAINER (fi_event_box), fi_cover_image_area);
 
1900
        g_signal_connect(G_OBJECT(fi_event_box), "button_press_event",
 
1901
                         G_CALLBACK(fi_cover_press_button_cb), file);
 
1902
 
 
1903
        display_cover(fi_cover_image_area, fi_event_box, fi_cover_align,
 
1904
                      48, 48, file, FALSE, TRUE);
 
1905
 
 
1906
        hbox_tagbuttons = gtk_hbox_new(FALSE, 0);
 
1907
        gtk_box_pack_end(GTK_BOX(vbox), hbox_tagbuttons, FALSE, FALSE, 5);
 
1908
 
 
1909
        nb = gtk_notebook_new();
 
1910
        gtk_box_pack_start(GTK_BOX(vbox), nb, TRUE, TRUE, 5);
 
1911
 
 
1912
        /* Audio data notebook page */
 
1913
 
 
1914
        vbox_file = gtk_vbox_new(FALSE, 4);
 
1915
        table_file = gtk_table_new(6, 2, FALSE);
 
1916
        gtk_box_pack_start(GTK_BOX(vbox_file), table_file, TRUE, TRUE, 10);
 
1917
        label_file = gtk_label_new(_("Audio data"));
 
1918
        gtk_notebook_append_page(GTK_NOTEBOOK(nb), vbox_file, label_file);
 
1919
 
 
1920
        hbox = gtk_hbox_new(FALSE, 0);
 
1921
        label = gtk_label_new(_("Format:"));
 
1922
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1923
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 3);
 
1924
        entry = gtk_entry_new();
 
1925
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1926
        gtk_entry_set_text(GTK_ENTRY(entry), meta->format_str);
 
1927
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
1928
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 0, 1,
 
1929
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
1930
 
 
1931
        hbox = gtk_hbox_new(FALSE, 0);
 
1932
        label = gtk_label_new(_("Length:"));
 
1933
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1934
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 3);
 
1935
        entry = gtk_entry_new();
 
1936
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1937
        if (meta->total_samples == 0) {
 
1938
                strcpy(str, "N/A");
 
1939
        } else {
 
1940
                sample2time(meta->sample_rate, meta->total_samples, str, 0);
 
1941
        }
 
1942
        gtk_entry_set_text(GTK_ENTRY(entry), str);
 
1943
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
1944
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 1, 2,
 
1945
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
1946
 
 
1947
        hbox = gtk_hbox_new(FALSE, 0);
 
1948
        label = gtk_label_new(_("Samplerate:"));
 
1949
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1950
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 3);
 
1951
        entry = gtk_entry_new();
 
1952
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1953
        sprintf(str, _("%ld Hz"), meta->sample_rate);
 
1954
        gtk_entry_set_text(GTK_ENTRY(entry), str);
 
1955
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
1956
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 2, 3,
 
1957
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
1958
 
 
1959
        hbox = gtk_hbox_new(FALSE, 0);
 
1960
        label = gtk_label_new(_("Channel count:"));
 
1961
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1962
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 3);
 
1963
        entry = gtk_entry_new();
 
1964
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1965
        if (meta->is_mono)
 
1966
                strcpy(str, _("MONO"));
 
1967
        else
 
1968
                strcpy(str, _("STEREO"));
 
1969
        gtk_entry_set_text(GTK_ENTRY(entry), str);
 
1970
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
1971
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 3, 4,
 
1972
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
1973
 
 
1974
        hbox = gtk_hbox_new(FALSE, 0);
 
1975
        label = gtk_label_new(_("Bandwidth:"));
 
1976
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1977
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 3);
 
1978
        entry = gtk_entry_new();
 
1979
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1980
        if (meta->bps == 0) {
 
1981
                strcpy(str, "N/A kbit/s");
 
1982
        } else {
 
1983
                format_bps_label(meta->bps, meta->format_flags, str);
 
1984
        }
 
1985
        gtk_entry_set_text(GTK_ENTRY(entry), str);
 
1986
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
1987
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 4, 5,
 
1988
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
1989
 
 
1990
        hbox = gtk_hbox_new(FALSE, 0);
 
1991
        label = gtk_label_new(_("Total samples:"));
 
1992
        gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
1993
        gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 3);
 
1994
        entry = gtk_entry_new();
 
1995
        GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
1996
        if (meta->total_samples == 0) {
 
1997
                strcpy(str, "N/A");
 
1998
        } else {
 
1999
                sprintf(str, "%lld", meta->total_samples);
 
2000
        }
 
2001
        gtk_entry_set_text(GTK_ENTRY(entry), str);
 
2002
        gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
2003
        gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 5, 6,
 
2004
                         (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
2005
 
 
2006
#ifdef HAVE_WAVPACK
 
2007
        if (meta->file_lib == WAVPACK_LIB) {
 
2008
                hbox = gtk_hbox_new(FALSE, 0);
 
2009
                label = gtk_label_new(_("Mode:"));
 
2010
                gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
2011
                gtk_table_attach(GTK_TABLE(table_file), hbox, 0, 1, 7, 8, GTK_FILL, GTK_FILL, 5, 3);
 
2012
                entry = gtk_entry_new();
 
2013
                GTK_WIDGET_UNSET_FLAGS(entry, GTK_CAN_FOCUS);
 
2014
                int mode = WavpackGetMode(meta->wpc);
 
2015
                if ((mode & MODE_LOSSLESS) && (mode & MODE_WVC)) {
 
2016
                        strncpy(str, "Hybrid Lossless", MAXLEN-1);
 
2017
                } else if (mode & MODE_LOSSLESS) {
 
2018
                        strncpy(str, "Lossless", MAXLEN-1);
 
2019
                } else {
 
2020
                        strncpy(str, "Hybrid Lossy", MAXLEN-1);
 
2021
                }
 
2022
                cut_trailing_whitespace(str);
 
2023
                gtk_entry_set_text(GTK_ENTRY(entry), str);
 
2024
                gtk_editable_set_editable(GTK_EDITABLE(entry), FALSE);
 
2025
                gtk_table_attach(GTK_TABLE(table_file), entry, 1, 2, 7, 8,
 
2026
                                (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), GTK_FILL, 5, 3);
 
2027
        }
 
2028
#endif /* HAVE_WAVPACK */
 
2029
 
 
2030
 
 
2031
#ifdef HAVE_TAGLIB
 
2032
        switch (meta->file_lib) {
 
2033
#ifdef HAVE_FLAC
 
2034
        case FLAC_LIB:
 
2035
                build_nb_pages_flac(meta, GTK_NOTEBOOK(nb), hbox_tagbuttons, mode);
 
2036
                break;
 
2037
#endif /* HAVE_FLAC */
 
2038
#ifdef HAVE_OGG_VORBIS
 
2039
        case VORBIS_LIB:
 
2040
                build_nb_pages_oggv(meta, GTK_NOTEBOOK(nb), hbox_tagbuttons, mode);
 
2041
                break;
 
2042
#endif /* HAVE_OGG_VORBIS */
 
2043
#ifdef HAVE_MPEG
 
2044
        case MAD_LIB:
 
2045
                build_nb_pages_mpeg(meta, GTK_NOTEBOOK(nb), hbox_tagbuttons, mode);
 
2046
                break;
 
2047
#endif /* HAVE_MPEG */
 
2048
#ifdef HAVE_MPC
 
2049
        case MPC_LIB:
 
2050
                build_nb_pages_mpc(meta, GTK_NOTEBOOK(nb), hbox_tagbuttons, mode);
 
2051
                break;
 
2052
#endif /* HAVE_MPC */
 
2053
        }
 
2054
#endif /* HAVE_TAGLIB */
 
2055
 
 
2056
#ifdef HAVE_WAVPACK
 
2057
        if (meta->file_lib == WAVPACK_LIB) {
 
2058
                build_wavpack_page(meta, GTK_NOTEBOOK(nb), hbox_tagbuttons, _("WavPack Metadata"));
 
2059
        }
 
2060
#endif /* HAVE_WAVPACK */
 
2061
 
 
2062
#ifdef HAVE_MOD_INFO
 
2063
        mdi = meta->mod_root;
 
2064
        if (mdi->active) {
 
2065
                if ((md_fdec = file_decoder_new()) == NULL) {
 
2066
                        fprintf(stderr, "show_file_info(): error: file_decoder_new() returned NULL\n");
 
2067
                }
 
2068
 
 
2069
                if (file_decoder_open(md_fdec, file)) {
 
2070
                        fprintf(stderr, "file_decoder_open() failed on %s\n", file);
 
2071
                }
 
2072
 
 
2073
                if (md_fdec->file_lib == MOD_LIB) {
 
2074
 
 
2075
                        vbox_mod = gtk_vbox_new(FALSE, 4);
 
2076
                        label_mod = gtk_label_new(_("Module info"));
 
2077
                        gtk_notebook_append_page(GTK_NOTEBOOK(nb), vbox_mod, label_mod);
 
2078
                        fill_module_info_page(mdi, vbox_mod, file);
 
2079
                } else {
 
2080
 
 
2081
                        file_decoder_close(md_fdec);
 
2082
                        file_decoder_delete(md_fdec);
 
2083
                }
 
2084
        }
 
2085
#endif /* HAVE_MOD_INFO */
 
2086
 
 
2087
        /* end of notebook stuff */
 
2088
 
 
2089
        gtk_widget_grab_focus(nb);
 
2090
 
 
2091
        dismiss_btn = gtk_button_new_from_stock (GTK_STOCK_CLOSE); 
 
2092
        g_signal_connect(dismiss_btn, "clicked", G_CALLBACK(dismiss), (gpointer)meta);
 
2093
        gtk_widget_set_size_request(dismiss_btn, 80, -1);
 
2094
        gtk_box_pack_end(GTK_BOX(hbox_tagbuttons), dismiss_btn, FALSE, FALSE, 3);
 
2095
 
 
2096
        gtk_widget_show_all(info_window);
 
2097
 
 
2098
        n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(nb));
 
2099
 
 
2100
        if (n_pages > 1) {
 
2101
                gtk_notebook_set_current_page(GTK_NOTEBOOK(nb), options.tags_tab_first ? 1 : 0);
 
2102
        }
 
2103
 
 
2104
        /* metadata object is freed in info_window destroy handlers */
 
2105
}
 
2106
 
 
2107
 
 
2108
#ifdef HAVE_MOD_INFO
 
2109
/*
 
2110
 * type = 0 for sample list
 
2111
 * type != 0 for instrument list
 
2112
 */
 
2113
void
 
2114
show_list (gint type) {
 
2115
 
 
2116
        GtkTreeIter iter;
 
2117
        gint i, len;
 
2118
        gchar temp[MAXLEN], number[MAXLEN];
 
2119
        decoder_t * md_dec;
 
2120
        mod_pdata_t * md_pd;
 
2121
        
 
2122
        md_dec = (decoder_t *)(md_fdec->pdec);
 
2123
        md_pd = (mod_pdata_t *)md_dec->pdata;
 
2124
 
 
2125
        if (type) {
 
2126
                len = ModPlug_NumInstruments(md_pd->mpf);
 
2127
        } else {
 
2128
                len = ModPlug_NumSamples(md_pd->mpf);
 
2129
        }
 
2130
 
 
2131
        if (len) {
 
2132
                gtk_list_store_clear(smp_instr_list_store);
 
2133
                for(i = 0; i < len; i++) {
 
2134
                        memset(temp, 0, MAXLEN-1);
 
2135
 
 
2136
                        if (type) {
 
2137
                                ModPlug_InstrumentName(md_pd->mpf, i, temp);
 
2138
                        } else {
 
2139
                                ModPlug_SampleName(md_pd->mpf, i, temp);
 
2140
                        }
 
2141
 
 
2142
                        sprintf(number, "%2d", i);
 
2143
                        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(smp_instr_list_store), &iter, NULL, i);
 
2144
                        gtk_list_store_append(smp_instr_list_store, &iter);
 
2145
                        gtk_list_store_set(smp_instr_list_store, &iter, 0, number, 1, temp, -1);
 
2146
                }
 
2147
        }
 
2148
}
 
2149
 
 
2150
void
 
2151
set_first_row (void) {
 
2152
 
 
2153
        GtkTreeIter iter;
 
2154
        GtkTreePath * visible_path;
 
2155
 
 
2156
        gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(smp_instr_list_store), &iter, NULL, 0);
 
2157
        visible_path = gtk_tree_model_get_path (GTK_TREE_MODEL(smp_instr_list_store), &iter);
 
2158
        gtk_tree_view_set_cursor (GTK_TREE_VIEW (smp_instr_list), visible_path, NULL, TRUE);
 
2159
        gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (smp_instr_list), visible_path,
 
2160
                                      NULL, TRUE, 1.0, 0.0);
 
2161
        gtk_widget_grab_focus(GTK_WIDGET(smp_instr_list));
 
2162
}
 
2163
 
 
2164
void 
 
2165
radio_buttons_cb (GtkToggleButton *toggle_button, gboolean state) {
 
2166
 
 
2167
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle_button))) {
 
2168
                show_list (0);
 
2169
        } else {
 
2170
                show_list (1);
 
2171
        }
 
2172
        set_first_row();
 
2173
}
 
2174
 
 
2175
void
 
2176
fill_module_info_page(mod_info *mdi, GtkWidget *vbox, char *file) {
 
2177
 
 
2178
        gchar *a_type[] = {
 
2179
                "None", "MOD", "S3M", "XM", "MED", "MTM", "IT", "669",
 
2180
                "ULT", "STM", "FAR", "WAV", "AMF", "AMS", "DSM", "MDL",
 
2181
                "OKT", "MID", "DMF", "PTM", "DBM", "MT2", "AMF0", "PSM",
 
2182
                "J2B", "UMX"
 
2183
        };
 
2184
        
 
2185
        gint i, n;
 
2186
        gchar temp[MAXLEN];
 
2187
        GtkWidget *table;
 
2188
        GtkWidget *label;
 
2189
        GtkWidget *mod_type_label;
 
2190
        GtkWidget *mod_channels_label;
 
2191
        GtkWidget *mod_patterns_label;
 
2192
        GtkWidget *mod_samples_label;
 
2193
        GtkWidget *mod_instruments_label;
 
2194
        GtkWidget *vseparator;
 
2195
        GtkWidget *hbox2;
 
2196
        GtkWidget *vbox2;
 
2197
        GtkWidget *vbox3;
 
2198
        GtkWidget *samples_radiobutton = NULL;
 
2199
        GtkWidget *instruments_radiobutton = NULL;
 
2200
        GSList *samples_radiobutton_group = NULL;
 
2201
        GtkWidget *scrolledwindow;
 
2202
        
 
2203
        GtkCellRenderer *renderer;
 
2204
        GtkTreeViewColumn *column;
 
2205
 
 
2206
 
 
2207
        hbox2 = gtk_hbox_new (FALSE, 0);
 
2208
        gtk_widget_show (hbox2);
 
2209
        gtk_box_pack_start (GTK_BOX (vbox), hbox2, TRUE, TRUE, 0);
 
2210
 
 
2211
        vbox2 = gtk_vbox_new (FALSE, 0);
 
2212
        gtk_widget_show (vbox2);
 
2213
        gtk_box_pack_start (GTK_BOX (hbox2), vbox2, FALSE, FALSE, 0);
 
2214
 
 
2215
        if (mdi->instruments) {
 
2216
 
 
2217
                table = gtk_table_new (5, 2, FALSE);
 
2218
                gtk_widget_show (table);
 
2219
                gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
 
2220
                gtk_container_set_border_width (GTK_CONTAINER (table), 8);
 
2221
                gtk_table_set_row_spacings (GTK_TABLE (table), 6);
 
2222
                gtk_table_set_col_spacings (GTK_TABLE (table), 4);
 
2223
 
 
2224
                label = gtk_label_new (_("Type:"));
 
2225
                gtk_widget_show (label);
 
2226
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
 
2227
                                  (GtkAttachOptions) (GTK_FILL),
 
2228
                                  (GtkAttachOptions) (0), 0, 0);
 
2229
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2230
 
 
2231
                mod_type_label = gtk_label_new ("");
 
2232
                gtk_widget_show (mod_type_label);
 
2233
                gtk_table_attach (GTK_TABLE (table), mod_type_label, 1, 2, 0, 1,
 
2234
                                  (GtkAttachOptions) (GTK_FILL),
 
2235
                                  (GtkAttachOptions) (0), 0, 0);
 
2236
 
 
2237
                label = gtk_label_new (_("Channels:"));
 
2238
                gtk_widget_show (label);
 
2239
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
 
2240
                                  (GtkAttachOptions) (GTK_FILL),
 
2241
                                  (GtkAttachOptions) (0), 0, 0);
 
2242
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2243
 
 
2244
                mod_channels_label = gtk_label_new ("");
 
2245
                gtk_widget_show (mod_channels_label);
 
2246
                gtk_table_attach (GTK_TABLE (table), mod_channels_label, 1, 2, 1, 2,
 
2247
                                  (GtkAttachOptions) (GTK_FILL),
 
2248
                                  (GtkAttachOptions) (0), 0, 0);
 
2249
 
 
2250
                label = gtk_label_new (_("Patterns:"));
 
2251
                gtk_widget_show (label);
 
2252
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
 
2253
                                  (GtkAttachOptions) (GTK_FILL),
 
2254
                                  (GtkAttachOptions) (0), 0, 0);
 
2255
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2256
 
 
2257
                mod_patterns_label = gtk_label_new ("");
 
2258
                gtk_widget_show (mod_patterns_label);
 
2259
                gtk_table_attach (GTK_TABLE (table), mod_patterns_label, 1, 2, 2, 3,
 
2260
                                  (GtkAttachOptions) (GTK_FILL),
 
2261
                                  (GtkAttachOptions) (0), 0, 0);
 
2262
 
 
2263
                label = gtk_label_new (_("Samples:"));
 
2264
                gtk_widget_show (label);
 
2265
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
 
2266
                                  (GtkAttachOptions) (GTK_FILL),
 
2267
                                  (GtkAttachOptions) (0), 0, 0);
 
2268
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2269
 
 
2270
                mod_samples_label = gtk_label_new ("");
 
2271
                gtk_widget_show (mod_samples_label);
 
2272
                gtk_table_attach (GTK_TABLE (table), mod_samples_label, 1, 2, 3, 4,
 
2273
                                  (GtkAttachOptions) (GTK_FILL),
 
2274
                                  (GtkAttachOptions) (0), 0, 0);
 
2275
 
 
2276
                label = gtk_label_new (_("Instruments:"));
 
2277
                gtk_widget_show (label);
 
2278
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
 
2279
                                  (GtkAttachOptions) (GTK_FILL),
 
2280
                                  (GtkAttachOptions) (0), 0, 0);
 
2281
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2282
 
 
2283
                mod_instruments_label = gtk_label_new ("");
 
2284
                gtk_widget_show (mod_instruments_label);
 
2285
                gtk_table_attach (GTK_TABLE (table), mod_instruments_label, 1, 2, 4, 5,
 
2286
                                  (GtkAttachOptions) (GTK_FILL),
 
2287
                                  (GtkAttachOptions) (0), 0, 0);
 
2288
 
 
2289
                sprintf(temp, "%d", mdi->instruments);
 
2290
                gtk_label_set_text (GTK_LABEL(mod_instruments_label), temp);
 
2291
 
 
2292
 
 
2293
                table = gtk_table_new (2, 1, FALSE);
 
2294
                gtk_widget_show (table);
 
2295
                gtk_box_pack_end (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
 
2296
                gtk_container_set_border_width (GTK_CONTAINER (table), 8);
 
2297
                gtk_table_set_row_spacings (GTK_TABLE (table), 4);
 
2298
 
 
2299
                samples_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Samples"));
 
2300
                gtk_widget_show (samples_radiobutton);
 
2301
                gtk_table_attach (GTK_TABLE (table), samples_radiobutton, 0, 1, 0, 1,
 
2302
                                  (GtkAttachOptions) (GTK_FILL | GTK_EXPAND),
 
2303
                                  (GtkAttachOptions) (0), 0, 0);
 
2304
                gtk_radio_button_set_group (GTK_RADIO_BUTTON (samples_radiobutton), samples_radiobutton_group);
 
2305
                samples_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (samples_radiobutton));
 
2306
                g_signal_connect(G_OBJECT(samples_radiobutton), "toggled",
 
2307
                                 G_CALLBACK(radio_buttons_cb), NULL);
 
2308
 
 
2309
                instruments_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Instruments"));
 
2310
                gtk_widget_show (instruments_radiobutton);
 
2311
                gtk_table_attach (GTK_TABLE (table), instruments_radiobutton, 0, 1, 1, 2,
 
2312
                                  (GtkAttachOptions) (GTK_FILL),
 
2313
                                  (GtkAttachOptions) (0), 0, 0);
 
2314
                gtk_radio_button_set_group (GTK_RADIO_BUTTON (instruments_radiobutton), samples_radiobutton_group);
 
2315
                samples_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (instruments_radiobutton));
 
2316
 
 
2317
 
 
2318
        } else {
 
2319
 
 
2320
                table = gtk_table_new (4, 2, FALSE);
 
2321
                gtk_widget_show (table);
 
2322
                gtk_box_pack_start (GTK_BOX (vbox2), table, FALSE, FALSE, 0);
 
2323
                gtk_container_set_border_width (GTK_CONTAINER (table), 8);
 
2324
                gtk_table_set_row_spacings (GTK_TABLE (table), 4);
 
2325
                gtk_table_set_col_spacings (GTK_TABLE (table), 4);
 
2326
 
 
2327
                label = gtk_label_new (_("Type:"));
 
2328
                gtk_widget_show (label);
 
2329
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
 
2330
                                  (GtkAttachOptions) (GTK_FILL),
 
2331
                                  (GtkAttachOptions) (0), 0, 0);
 
2332
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2333
 
 
2334
                mod_type_label = gtk_label_new ("");
 
2335
                gtk_widget_show (mod_type_label);
 
2336
                gtk_table_attach (GTK_TABLE (table), mod_type_label, 1, 2, 0, 1,
 
2337
                                  (GtkAttachOptions) (GTK_FILL),
 
2338
                                  (GtkAttachOptions) (0), 0, 0);
 
2339
 
 
2340
                label = gtk_label_new (_("Channels:"));
 
2341
                gtk_widget_show (label);
 
2342
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
 
2343
                                  (GtkAttachOptions) (GTK_FILL),
 
2344
                                  (GtkAttachOptions) (0), 0, 0);
 
2345
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2346
 
 
2347
                mod_channels_label = gtk_label_new ("");
 
2348
                gtk_widget_show (mod_channels_label);
 
2349
                gtk_table_attach (GTK_TABLE (table), mod_channels_label, 1, 2, 1, 2,
 
2350
                                  (GtkAttachOptions) (GTK_FILL),
 
2351
                                  (GtkAttachOptions) (0), 0, 0);
 
2352
 
 
2353
                label = gtk_label_new (_("Patterns:"));
 
2354
                gtk_widget_show (label);
 
2355
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
 
2356
                                  (GtkAttachOptions) (GTK_FILL),
 
2357
                                  (GtkAttachOptions) (0), 0, 0);
 
2358
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2359
 
 
2360
                mod_patterns_label = gtk_label_new ("");
 
2361
                gtk_widget_show (mod_patterns_label);
 
2362
                gtk_table_attach (GTK_TABLE (table), mod_patterns_label, 1, 2, 2, 3,
 
2363
                                  (GtkAttachOptions) (GTK_FILL),
 
2364
                                  (GtkAttachOptions) (0), 0, 0);
 
2365
 
 
2366
                label = gtk_label_new (_("Samples:"));
 
2367
                gtk_widget_show (label);
 
2368
                gtk_table_attach (GTK_TABLE (table), label, 0, 1, 3, 4,
 
2369
                                  (GtkAttachOptions) (GTK_FILL),
 
2370
                                  (GtkAttachOptions) (0), 0, 0);
 
2371
                gtk_misc_set_alignment (GTK_MISC (label), 1, 0.5);
 
2372
 
 
2373
                mod_samples_label = gtk_label_new ("");
 
2374
                gtk_widget_show (mod_samples_label);
 
2375
                gtk_table_attach (GTK_TABLE (table), mod_samples_label, 1, 2, 3, 4,
 
2376
                                  (GtkAttachOptions) (GTK_FILL),
 
2377
                                  (GtkAttachOptions) (0), 0, 0);
 
2378
        }
 
2379
 
 
2380
        n = mdi->type;
 
2381
        i = 0;
 
2382
        
 
2383
        while (n > 0) {         /* calculate module type index */
 
2384
                n >>= 1;
 
2385
                i++;
 
2386
        }
 
2387
 
 
2388
        gtk_label_set_text (GTK_LABEL(mod_type_label), a_type[i]);
 
2389
        sprintf(temp, "%d", mdi->channels);
 
2390
        gtk_label_set_text (GTK_LABEL(mod_channels_label), temp);
 
2391
        sprintf(temp, "%d", mdi->patterns);
 
2392
        gtk_label_set_text (GTK_LABEL(mod_patterns_label), temp);
 
2393
        sprintf(temp, "%d", mdi->samples);
 
2394
        gtk_label_set_text (GTK_LABEL(mod_samples_label), temp);
 
2395
 
 
2396
        vseparator = gtk_vseparator_new ();
 
2397
        gtk_widget_show (vseparator);
 
2398
        gtk_box_pack_start (GTK_BOX (hbox2), vseparator, FALSE, FALSE, 4);
 
2399
 
 
2400
        vbox3 = gtk_vbox_new (FALSE, 0);
 
2401
        gtk_widget_show (vbox3);
 
2402
        gtk_box_pack_start (GTK_BOX (hbox2), vbox3, TRUE, TRUE, 0);
 
2403
 
 
2404
        scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
 
2405
        gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow), 4);
 
2406
        gtk_widget_show (scrolledwindow);
 
2407
        gtk_widget_set_size_request (scrolledwindow, -1, 220);
 
2408
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow), 
 
2409
                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
2410
        gtk_box_pack_end (GTK_BOX (vbox3), scrolledwindow, TRUE, TRUE, 0);
 
2411
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow), GTK_SHADOW_IN);
 
2412
 
 
2413
        smp_instr_list_store = gtk_list_store_new(2, 
 
2414
                                        G_TYPE_STRING,
 
2415
                                        G_TYPE_STRING);
 
2416
        smp_instr_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(smp_instr_list_store));
 
2417
        gtk_widget_set_name(smp_instr_list, "samples_instruments_list");
 
2418
        gtk_widget_show (smp_instr_list);
 
2419
        renderer = gtk_cell_renderer_text_new();
 
2420
        column = gtk_tree_view_column_new_with_attributes(_("No."), renderer, "text", 0, NULL);
 
2421
        gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
 
2422
                                        GTK_TREE_VIEW_COLUMN_FIXED);
 
2423
        gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(column), 3);
 
2424
        gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), FALSE);
 
2425
        gtk_tree_view_column_set_fixed_width(GTK_TREE_VIEW_COLUMN(column), 40);
 
2426
        gtk_tree_view_append_column(GTK_TREE_VIEW(smp_instr_list), column);
 
2427
        column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", 1, NULL);
 
2428
        gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(column),
 
2429
                                        GTK_TREE_VIEW_COLUMN_FIXED);
 
2430
        gtk_tree_view_append_column(GTK_TREE_VIEW(smp_instr_list), column);
 
2431
        gtk_tree_view_column_set_spacing(GTK_TREE_VIEW_COLUMN(column), 3);
 
2432
        gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(column), FALSE);
 
2433
        gtk_container_add (GTK_CONTAINER (scrolledwindow), smp_instr_list);
 
2434
 
 
2435
        if (mdi->instruments && mdi->type == 0x4) { /* if XM module go to instrument page */
 
2436
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (instruments_radiobutton), TRUE);
 
2437
        } else {
 
2438
                show_list (0);
 
2439
                set_first_row();
 
2440
        }
 
2441
}
 
2442
#endif /* HAVE_MOD_INFO */
 
2443
 
 
2444
 
 
2445
// vim: shiftwidth=8:tabstop=8:softtabstop=8 :  
 
2446