~bratsche/vlc/vlc-notify-add-actions-with-server-support

« back to all changes in this revision

Viewing changes to extras/faad2/common/faad/id3v2tag.c

  • Committer: Bazaar Package Importer
  • Date: 2008-11-28 09:29:51 UTC
  • Revision ID: jamesw@ubuntu.com-20081128092951-0y5ojboptscru17f
Tags: upstream-ubuntu-0.8.6.release.e+x264svn20071224+faad2.6.1
ImportĀ upstreamĀ versionĀ 0.8.6.release.e+x264svn20071224+faad2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3
 
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
4
 
**  
5
 
** This program is free software; you can redistribute it and/or modify
6
 
** it under the terms of the GNU General Public License as published by
7
 
** the Free Software Foundation; either version 2 of the License, or
8
 
** (at your option) any later version.
9
 
** 
10
 
** This program is distributed in the hope that it will be useful,
11
 
** but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
** GNU General Public License for more details.
14
 
** 
15
 
** You should have received a copy of the GNU General Public License
16
 
** along with this program; if not, write to the Free Software 
17
 
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
 
**
19
 
** Any non-GPL usage of this software or parts of this software is strictly
20
 
** forbidden.
21
 
**
22
 
** Commercial non-GPL licensing of this software is possible.
23
 
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
24
 
**
25
 
** $Id: id3v2tag.c,v 1.4 2003/07/29 08:20:11 menno Exp $
26
 
**/
27
 
 
28
 
#define WIN32_LEAN_AND_MEAN
29
 
#include <windows.h>
30
 
#include <commctrl.h>
31
 
#include <resource.h>
32
 
 
33
 
#include <id3.h>
34
 
 
35
 
#include <id3v2tag.h>
36
 
 
37
 
HWND m_hwndList;
38
 
 
39
 
LPSTR ID3Frames[] =
40
 
{
41
 
    "No known frame",
42
 
    "Audio encryption",
43
 
    "Attached picture",
44
 
    "Comments",
45
 
    "Commercial frame",
46
 
    "Encryption method registration",
47
 
    "Equalization",
48
 
    "Event timing codes",
49
 
    "General encapsulated object",
50
 
    "Group identification registration",
51
 
    "Involved people list",
52
 
    "Linked information",
53
 
    "Music CD identifier",
54
 
    "MPEG location lookup table",
55
 
    "Ownership frame",
56
 
    "Private frame",
57
 
    "Play counter",
58
 
    "Popularimeter",
59
 
    "Position synchronisation frame",
60
 
    "Recommended buffer size",
61
 
    "Relative volume adjustment",
62
 
    "Reverb",
63
 
    "Synchronized lyric",
64
 
    "Synchronized tempo codes",
65
 
    "Album title",
66
 
    "BPM (beats per minute)",
67
 
    "Composer",
68
 
    "Genre", //"Content type",
69
 
    "Copyright message",
70
 
    "Date",
71
 
    "Playlist delay",
72
 
    "Encoded by",
73
 
    "Lyricist",
74
 
    "File type",
75
 
    "Time",
76
 
    "Content group description",
77
 
    "Title",
78
 
    "Subtitle",
79
 
    "Initial key",
80
 
    "Language(s)",
81
 
    "Length",
82
 
    "Media type",
83
 
    "Original album title",
84
 
    "Original filename",
85
 
    "Original lyricist(s)",
86
 
    "Original artist(s)",
87
 
    "Original release year",
88
 
    "File owner",
89
 
    "Lead performer(s)",
90
 
    "Band/orchestra/accompaniment",
91
 
    "Conductor/performer refinement",
92
 
    "Interpreted, remixed, or otherwise modified by",
93
 
    "Part of a set",
94
 
    "Publisher",
95
 
    "Track number",
96
 
    "Recording dates",
97
 
    "Internet radio station name",
98
 
    "Internet radio station owner",
99
 
    "Size",
100
 
    "ISRC (international standard recording code)",
101
 
    "Software/Hardware and settings used for encoding",
102
 
    "User defined text information",
103
 
    "Year",
104
 
    "Unique file identifier",
105
 
    "Terms of use",
106
 
    "Unsynchronized lyric",
107
 
    "Commercial information",
108
 
    "Copyright/Legal information",
109
 
    "Official audio file webpage",
110
 
    "Official artist webpage",
111
 
    "Official audio source webpage",
112
 
    "Official internet radio station homepage",
113
 
    "Payment",
114
 
    "Official publisher webpage",
115
 
    "User defined URL link",
116
 
    "Encrypted meta frame (id3v2.2.x)",
117
 
    "Compressed meta frame (id3v2.2.1)"
118
 
};
119
 
 
120
 
ID3GENRES ID3Genres[]=
121
 
{
122
 
    123,    "Acapella",
123
 
    34,     "Acid",
124
 
    74,     "Acid Jazz",
125
 
    73,     "Acid Punk",
126
 
    99,     "Acoustic",
127
 
    20,     "Alternative",
128
 
    40,     "AlternRock",
129
 
    26,     "Ambient",
130
 
    90,     "Avantgarde",
131
 
    116,    "Ballad",
132
 
    41,     "Bass",
133
 
    85,     "Bebob",
134
 
    96,     "Big Band",
135
 
    89,     "Bluegrass",
136
 
    0,      "Blues",
137
 
    107,    "Booty Bass",
138
 
    65,     "Cabaret",
139
 
    88,     "Celtic",
140
 
    104,    "Chamber Music",
141
 
    102,    "Chanson",
142
 
    97,     "Chorus",
143
 
    61,     "Christian Rap",
144
 
    1,      "Classic Rock",
145
 
    32,     "Classical",
146
 
    112,    "Club",
147
 
    57,     "Comedy",
148
 
    2,      "Country",
149
 
    58,     "Cult",
150
 
    3,      "Dance",
151
 
    125,    "Dance Hall",
152
 
    50,     "Darkwave",
153
 
    254,    "Data",
154
 
    22,     "Death Metal",
155
 
    4,      "Disco",
156
 
    55,     "Dream",
157
 
    122,    "Drum Solo",
158
 
    120,    "Duet",
159
 
    98,     "Easy Listening",
160
 
    52,     "Electronic",
161
 
    48,     "Ethnic",
162
 
    124,    "Euro-House",
163
 
    25,     "Euro-Techno",
164
 
    54,     "Eurodance",
165
 
    84,     "Fast Fusion",
166
 
    80,     "Folk",
167
 
    81,     "Folk-Rock",
168
 
    115,    "Folklore",
169
 
    119,    "Freestyle",
170
 
    5,      "Funk",
171
 
    30,     "Fusion",
172
 
    36,     "Game",
173
 
    59,     "Gangsta",
174
 
    38,     "Gospel",
175
 
    49,     "Gothic",
176
 
    91,     "Gothic Rock",
177
 
    6,      "Grunge",
178
 
    79,     "Hard Rock",
179
 
    7,      "Hip-Hop",
180
 
    35,     "House",
181
 
    100,    "Humour",
182
 
    19,     "Industrial",
183
 
    33,     "Instrumental",
184
 
    46,     "Instrumental Pop",
185
 
    47,     "Instrumental Rock",
186
 
    8,      "Jazz",
187
 
    29,     "Jazz+Funk",
188
 
    63,     "Jungle",
189
 
    86,     "Latin",
190
 
    71,     "Lo-Fi",
191
 
    45,     "Meditative",
192
 
    9,      "Metal",
193
 
    77,     "Musical",
194
 
    82,     "National Folk",
195
 
    64,     "Native American",
196
 
    10,     "New Age",
197
 
    66,     "New Wave",
198
 
    39,     "Noise",
199
 
    255,    "Not Set",
200
 
    11,     "Oldies",
201
 
    103,    "Opera",
202
 
    12,     "Other",
203
 
    75,     "Polka",
204
 
    13,     "Pop",
205
 
    62,     "Pop/Funk",
206
 
    53,     "Pop-Folk",
207
 
    109,    "Porn Groove",
208
 
    117,    "Power Ballad",
209
 
    23,     "Pranks",
210
 
    108,    "Primus",
211
 
    92,     "Progressive Rock",
212
 
    67,     "Psychadelic",
213
 
    93,     "Psychedelic Rock",
214
 
    43,     "Punk",
215
 
    121,    "Punk Rock",
216
 
    14,     "R&B",
217
 
    15,     "Rap",
218
 
    68,     "Rave",
219
 
    16,     "Reggae",
220
 
    76,     "Retro",
221
 
    87,     "Revival",
222
 
    118,    "Rhythmic Soul",
223
 
    17,     "Rock",
224
 
    78,     "Rock & Roll",
225
 
    114,    "Samba",
226
 
    110,    "Satire",
227
 
    69,     "Showtunes",
228
 
    21,     "Ska",
229
 
    111,    "Slow Jam",
230
 
    95,     "Slow Rock",
231
 
    105,    "Sonata",
232
 
    42,     "Soul",
233
 
    37,     "Sound Clip",
234
 
    24,     "Soundtrack",
235
 
    56,     "Southern Rock",
236
 
    44,     "Space",
237
 
    101,    "Speech",
238
 
    83,     "Swing",
239
 
    94,     "Symphonic Rock",
240
 
    106,    "Symphony",
241
 
    113,    "Tango",
242
 
    18,     "Techno",
243
 
    51,     "Techno-Industrial",
244
 
    60,     "Top 40",
245
 
    70,     "Trailer",
246
 
    31,     "Trance",
247
 
    72,     "Tribal",
248
 
    27,     "Trip-Hop",
249
 
    28,     "Vocal"
250
 
};
251
 
 
252
 
const int NUMFRAMES = sizeof(ID3Frames)/sizeof(ID3Frames[0]);
253
 
const int NUMGENRES = sizeof(ID3Genres)/sizeof(ID3Genres[0]);
254
 
 
255
 
 
256
 
LPSTR DupString(LPSTR lpsz)
257
 
{
258
 
    int cb = lstrlen(lpsz) + 1;
259
 
    LPSTR lpszNew = LocalAlloc(LMEM_FIXED, cb);
260
 
    if (lpszNew != NULL)
261
 
        CopyMemory(lpszNew, lpsz, cb);
262
 
    return lpszNew;
263
 
}
264
 
 
265
 
LPSTR GetFrameDesc(ID3_FrameID id)
266
 
{
267
 
    return DupString(ID3Frames[id]);
268
 
}
269
 
 
270
 
LPSTR GetGenre(LPSTR lpsz)
271
 
{
272
 
    int id = atoi(lpsz + 1);
273
 
    int i;
274
 
 
275
 
    if ((*(lpsz + 1) > '0') && (*(lpsz + 1) < '9'))
276
 
    {
277
 
        for (i = 0; i < NUMGENRES; i++)
278
 
        {
279
 
            if (id == ID3Genres[i].id)
280
 
                return DupString(ID3Genres[i].name);
281
 
        }
282
 
    }
283
 
    return DupString(lpsz);
284
 
}
285
 
 
286
 
void FillID3List(HWND hwndDlg, HWND hwndList, char *filename)
287
 
{
288
 
    ID3Tag *tag;
289
 
    ID3Frame *frame;
290
 
    ID3Field *field;
291
 
    ID3_FrameID eFrameID;
292
 
    char info[1024];
293
 
    int numFrames;
294
 
    int i;
295
 
    int iItem = 0;
296
 
 
297
 
 
298
 
    if ((tag = ID3Tag_New()) != NULL)
299
 
    {
300
 
        ID3Tag_Link(tag, filename);
301
 
 
302
 
        numFrames = ID3Tag_NumFrames(tag);
303
 
 
304
 
        for (i = 0; i < numFrames; i++)
305
 
        {
306
 
            iItem++;
307
 
 
308
 
            frame = ID3Tag_GetFrameNum(tag, i);
309
 
            eFrameID = ID3Frame_GetID(frame);
310
 
 
311
 
            switch (eFrameID)
312
 
            {
313
 
            case ID3FID_ALBUM:            case ID3FID_BPM:
314
 
            case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
315
 
            case ID3FID_COPYRIGHT:        case ID3FID_DATE:
316
 
            case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
317
 
            case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
318
 
            case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
319
 
            case ID3FID_TITLE:            case ID3FID_SUBTITLE:
320
 
            case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
321
 
            case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
322
 
            case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
323
 
            case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
324
 
            case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
325
 
            case ID3FID_LEADARTIST:       case ID3FID_BAND:
326
 
            case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
327
 
            case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
328
 
            case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
329
 
            case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
330
 
            case ID3FID_SIZE:             case ID3FID_ISRC:
331
 
            case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
332
 
            {
333
 
                LV_ITEM lvi;
334
 
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
335
 
 
336
 
                /* Initialize LV_ITEM members that are common to all items. */
337
 
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
338
 
                lvi.state = 0;
339
 
                lvi.stateMask = 0;
340
 
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
341
 
                lvi.iImage = 0;
342
 
                lvi.iItem = iItem;
343
 
                lvi.iSubItem = 0;
344
 
 
345
 
                pItem->frameId = eFrameID;
346
 
                pItem->aCols[0] = GetFrameDesc(eFrameID);
347
 
 
348
 
                field = ID3Frame_GetField(frame, ID3FN_TEXT);
349
 
                ID3Field_GetASCII(field, info, 1024, 1);
350
 
                if (eFrameID == ID3FID_CONTENTTYPE)
351
 
                    pItem->aCols[1] = GetGenre(info);
352
 
                else
353
 
                    pItem->aCols[1] = DupString(info);
354
 
 
355
 
                lvi.lParam = (LPARAM)pItem;    /* item data */
356
 
 
357
 
                /* Add the item. */
358
 
                ListView_InsertItem(hwndList, &lvi);
359
 
 
360
 
                break;
361
 
            }
362
 
            case ID3FID_USERTEXT:
363
 
            case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
364
 
            case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
365
 
            {
366
 
                LV_ITEM lvi;
367
 
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
368
 
 
369
 
                /* Initialize LV_ITEM members that are common to all items. */
370
 
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
371
 
                lvi.state = 0;
372
 
                lvi.stateMask = 0;
373
 
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
374
 
                lvi.iImage = 0;
375
 
                lvi.iItem = iItem;
376
 
                lvi.iSubItem = 0;
377
 
 
378
 
                pItem->frameId = eFrameID;
379
 
 
380
 
                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
381
 
                ID3Field_GetASCII(field, info, 1024, 1);
382
 
                pItem->aCols[0] = DupString(info);
383
 
 
384
 
                field = ID3Frame_GetField(frame, ID3FN_TEXT);
385
 
                ID3Field_GetASCII(field, info, 1024, 1);
386
 
                pItem->aCols[1] = DupString(info);
387
 
 
388
 
                lvi.lParam = (LPARAM)pItem;    /* item data */
389
 
 
390
 
                /* Add the item. */
391
 
                ListView_InsertItem(hwndList, &lvi);
392
 
 
393
 
                break;
394
 
            }
395
 
            case ID3FID_WWWAUDIOFILE:       case ID3FID_WWWARTIST:
396
 
            case ID3FID_WWWAUDIOSOURCE:     case ID3FID_WWWCOMMERCIALINFO:
397
 
            case ID3FID_WWWCOPYRIGHT:       case ID3FID_WWWPUBLISHER:
398
 
            case ID3FID_WWWPAYMENT:         case ID3FID_WWWRADIOPAGE:
399
 
            {
400
 
                LV_ITEM lvi;
401
 
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
402
 
 
403
 
                /* Initialize LV_ITEM members that are common to all items. */
404
 
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
405
 
                lvi.state = 0;
406
 
                lvi.stateMask = 0;
407
 
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
408
 
                lvi.iImage = 0;
409
 
                lvi.iItem = iItem;
410
 
                lvi.iSubItem = 0;
411
 
 
412
 
                pItem->frameId = eFrameID;
413
 
 
414
 
                pItem->aCols[0] = GetFrameDesc(eFrameID);
415
 
 
416
 
                field = ID3Frame_GetField(frame, ID3FN_URL);
417
 
                ID3Field_GetASCII(field, info, 1024, 1);
418
 
                pItem->aCols[1] = DupString(info);
419
 
 
420
 
                lvi.lParam = (LPARAM)pItem;    /* item data */
421
 
 
422
 
                /* Add the item. */
423
 
                ListView_InsertItem(hwndList, &lvi);
424
 
 
425
 
                break;
426
 
            }
427
 
            case ID3FID_WWWUSER:
428
 
            {
429
 
                LV_ITEM lvi;
430
 
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
431
 
 
432
 
                /* Initialize LV_ITEM members that are common to all items. */
433
 
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
434
 
                lvi.state = 0;
435
 
                lvi.stateMask = 0;
436
 
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
437
 
                lvi.iImage = 0;
438
 
                lvi.iItem = iItem;
439
 
                lvi.iSubItem = 0;
440
 
 
441
 
                pItem->frameId = eFrameID;
442
 
 
443
 
                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
444
 
                ID3Field_GetASCII(field, info, 1024, 1);
445
 
                pItem->aCols[0] = DupString(info);
446
 
 
447
 
                field = ID3Frame_GetField(frame, ID3FN_URL);
448
 
                ID3Field_GetASCII(field, info, 1024, 1);
449
 
                pItem->aCols[1] = DupString(info);
450
 
 
451
 
                lvi.lParam = (LPARAM)pItem;    /* item data */
452
 
 
453
 
                /* Add the item. */
454
 
                ListView_InsertItem(hwndList, &lvi);
455
 
 
456
 
                break;
457
 
            }
458
 
            default:
459
 
                break;
460
 
            }
461
 
        }
462
 
        ID3Tag_Delete(tag);
463
 
    }
464
 
}
465
 
 
466
 
BOOL CALLBACK AddFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
467
 
{
468
 
    int i, cursel;
469
 
 
470
 
    switch (message) {
471
 
    case WM_INITDIALOG:
472
 
        EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
473
 
        EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
474
 
 
475
 
        /* Note: FRAMEID is the index in the combo box + 1 */
476
 
        for (i = 1; i < NUMFRAMES; i++)
477
 
        {
478
 
            SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)ID3Frames[i]);
479
 
        }
480
 
        return TRUE;
481
 
 
482
 
    case WM_COMMAND:
483
 
        switch (LOWORD(wParam)) {
484
 
        case IDC_FRAMETYPE:
485
 
            if (HIWORD(wParam) == CBN_SELCHANGE)
486
 
            {
487
 
                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);
488
 
 
489
 
                switch (cursel + 1)
490
 
                {
491
 
                case ID3FID_ALBUM:             case ID3FID_BPM:
492
 
                case ID3FID_COMPOSER:          case ID3FID_COPYRIGHT:
493
 
                case ID3FID_DATE:              case ID3FID_PLAYLISTDELAY:
494
 
                case ID3FID_ENCODEDBY:         case ID3FID_LYRICIST:
495
 
                case ID3FID_FILETYPE:          case ID3FID_TIME:
496
 
                case ID3FID_CONTENTGROUP:      case ID3FID_TITLE:
497
 
                case ID3FID_SUBTITLE:          case ID3FID_INITIALKEY:
498
 
                case ID3FID_LANGUAGE:          case ID3FID_SONGLEN:
499
 
                case ID3FID_MEDIATYPE:         case ID3FID_ORIGALBUM:
500
 
                case ID3FID_ORIGFILENAME:      case ID3FID_ORIGLYRICIST:
501
 
                case ID3FID_ORIGARTIST:        case ID3FID_ORIGYEAR:
502
 
                case ID3FID_FILEOWNER:         case ID3FID_LEADARTIST:
503
 
                case ID3FID_BAND:              case ID3FID_CONDUCTOR:
504
 
                case ID3FID_MIXARTIST:         case ID3FID_PARTINSET:
505
 
                case ID3FID_PUBLISHER:         case ID3FID_TRACKNUM:
506
 
                case ID3FID_RECORDINGDATES:    case ID3FID_NETRADIOSTATION:
507
 
                case ID3FID_NETRADIOOWNER:     case ID3FID_SIZE:
508
 
                case ID3FID_ISRC:              case ID3FID_ENCODERSETTINGS:
509
 
                case ID3FID_YEAR:              case ID3FID_WWWAUDIOFILE:
510
 
                case ID3FID_WWWARTIST:         case ID3FID_WWWAUDIOSOURCE:
511
 
                case ID3FID_WWWCOMMERCIALINFO: case ID3FID_WWWCOPYRIGHT:
512
 
                case ID3FID_WWWPUBLISHER:      case ID3FID_WWWPAYMENT:
513
 
                case ID3FID_WWWRADIOPAGE:      case ID3FID_CONTENTTYPE:
514
 
                {
515
 
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
516
 
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
517
 
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
518
 
                    break;
519
 
                }
520
 
                case ID3FID_USERTEXT:          case ID3FID_COMMENT:
521
 
                case ID3FID_UNSYNCEDLYRICS:    case ID3FID_WWWUSER:
522
 
                {
523
 
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
524
 
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), TRUE);
525
 
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
526
 
                    break;
527
 
                }
528
 
                default:
529
 
                    MessageBox(hwndDlg, "Sorry, this frame type cannot be added (yet).", "Sorry", MB_OK);
530
 
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
531
 
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
532
 
                    break;
533
 
                }
534
 
            }
535
 
            return TRUE;
536
 
        case IDOK:
537
 
            {
538
 
                LV_ITEM lvi;
539
 
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
540
 
                char *col0 = LocalAlloc(LPTR, 1024);
541
 
                char *col1 = LocalAlloc(LPTR, 1024);
542
 
 
543
 
                /* Initialize LV_ITEM members that are common to all items. */
544
 
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
545
 
                lvi.state = 0;
546
 
                lvi.stateMask = 0;
547
 
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
548
 
                lvi.iImage = 0;
549
 
                lvi.iItem = ListView_GetItemCount(m_hwndList) + 1;
550
 
                lvi.iSubItem = 0;
551
 
 
552
 
                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);
553
 
                pItem->frameId = cursel + 1;
554
 
                GetDlgItemText(hwndDlg, IDC_COL0, col0, 1024);
555
 
                GetDlgItemText(hwndDlg, IDC_COL1, col1, 1024);
556
 
                pItem->aCols[0] = col0;
557
 
                pItem->aCols[1] = col1;
558
 
 
559
 
                lvi.lParam = (LPARAM)pItem;    /* item data */
560
 
 
561
 
                /* Add the item. */
562
 
                ListView_InsertItem(m_hwndList, &lvi);
563
 
                ListView_Update(m_hwndList, lvi.iItem);
564
 
            }
565
 
        case IDCANCEL:
566
 
            EndDialog(hwndDlg, wParam);
567
 
            return TRUE;
568
 
        }
569
 
    }
570
 
    return FALSE;
571
 
}
572
 
 
573
 
BOOL List_AddFrame(HWND hwndApp, HWND hwndList)
574
 
{
575
 
    int result;
576
 
 
577
 
    m_hwndList = hwndList;
578
 
 
579
 
    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDFRAME),
580
 
        hwndApp, AddFrameProc);
581
 
 
582
 
    if (LOWORD(result) == IDOK)
583
 
        return TRUE;
584
 
    return FALSE;
585
 
}
586
 
 
587
 
 
588
 
void InsertTextFrame(HWND dlg, HWND list, int control, int item, int frame_id)
589
 
{
590
 
    LV_ITEM lvi;
591
 
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
592
 
 
593
 
    /* Initialize LV_ITEM members that are common to all items. */
594
 
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
595
 
    lvi.state = 0;
596
 
    lvi.stateMask = 0;
597
 
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
598
 
    lvi.iImage = 0;
599
 
    lvi.iItem = item;
600
 
    lvi.iSubItem = 0;
601
 
 
602
 
    pItem->frameId = frame_id;
603
 
    pItem->aCols[0] = GetFrameDesc(frame_id);
604
 
 
605
 
    pItem->aCols[1] = LocalAlloc(LPTR, 1024);
606
 
    GetDlgItemText(dlg, control, pItem->aCols[1], 1024);
607
 
 
608
 
    lvi.lParam = (LPARAM)pItem;    /* item data */
609
 
 
610
 
    /* Add the item. */
611
 
    ListView_InsertItem(list, &lvi);
612
 
}
613
 
 
614
 
void AddFrameFromRAWData(HWND hwndList, int frameId, LPSTR data1, LPSTR data2)
615
 
{
616
 
    LV_ITEM lvi;
617
 
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
618
 
    int nextItem;
619
 
 
620
 
    nextItem = ListView_GetItemCount(hwndList);
621
 
 
622
 
    /* Initialize LV_ITEM members that are common to all items. */
623
 
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
624
 
    lvi.state = 0;
625
 
    lvi.stateMask = 0;
626
 
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
627
 
    lvi.iImage = 0;
628
 
    lvi.iItem = nextItem;
629
 
    lvi.iSubItem = 0;
630
 
 
631
 
    pItem->frameId = frameId;
632
 
 
633
 
    pItem->aCols[0] = LocalAlloc(LPTR, 1024);
634
 
    pItem->aCols[1] = LocalAlloc(LPTR, 1024);
635
 
 
636
 
    lstrcpy(pItem->aCols[0], data1);
637
 
    lstrcpy(pItem->aCols[1], data2);
638
 
 
639
 
    lvi.lParam = (LPARAM)pItem;    /* item data */
640
 
 
641
 
    /* Add the item. */
642
 
    ListView_InsertItem(hwndList, &lvi);
643
 
}
644
 
 
645
 
HWND m_hwndDlg;
646
 
int changed;
647
 
 
648
 
BOOL CALLBACK AddStandardProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
649
 
{
650
 
    int added = 0;
651
 
 
652
 
    switch (message) {
653
 
    case WM_INITDIALOG:
654
 
        changed = 0;
655
 
        return TRUE;
656
 
 
657
 
    case WM_COMMAND:
658
 
        switch (LOWORD(wParam)) {
659
 
        case IDOK:
660
 
        {
661
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TRACK)) > 0) {
662
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TRACK, ListView_GetItemCount(m_hwndList)+1, ID3FID_TRACKNUM);
663
 
                added++;
664
 
            }
665
 
 
666
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TITLE)) > 0) {
667
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TITLE, ListView_GetItemCount(m_hwndList)+1, ID3FID_TITLE);
668
 
                added++;
669
 
            }
670
 
 
671
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ARTIST)) > 0) {
672
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_LEADARTIST);
673
 
                added++;
674
 
            }
675
 
 
676
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ALBUM)) > 0) {
677
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ALBUM, ListView_GetItemCount(m_hwndList)+1, ID3FID_ALBUM);
678
 
                added++;
679
 
            }
680
 
 
681
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_YEAR)) > 0) {
682
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_YEAR, ListView_GetItemCount(m_hwndList)+1, ID3FID_YEAR);
683
 
                added++;
684
 
            }
685
 
 
686
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_GENRE)) > 0) {
687
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_GENRE, ListView_GetItemCount(m_hwndList)+1, ID3FID_CONTENTTYPE);
688
 
                added++;
689
 
            }
690
 
 
691
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMMENT)) > 0) {
692
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMMENT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMMENT);
693
 
                added++;
694
 
            }
695
 
 
696
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMPOSER)) > 0) {
697
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMPOSER, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMPOSER);
698
 
                added++;
699
 
            }
700
 
 
701
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ORIGARTIST)) > 0) {
702
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ORIGARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_ORIGARTIST);
703
 
                added++;
704
 
            }
705
 
 
706
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COPYRIGHT)) > 0) {
707
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COPYRIGHT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COPYRIGHT);
708
 
                added++;
709
 
            }
710
 
 
711
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_URL)) > 0) {
712
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_URL, ListView_GetItemCount(m_hwndList)+1, ID3FID_WWWARTIST);
713
 
                added++;
714
 
            }
715
 
 
716
 
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ENCBY)) > 0) {
717
 
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ENCBY, ListView_GetItemCount(m_hwndList)+1, ID3FID_ENCODEDBY);
718
 
                added++;
719
 
            }
720
 
 
721
 
            if (added > 0)
722
 
                changed = 1;
723
 
        }
724
 
        case IDCANCEL:
725
 
            EndDialog(hwndDlg, changed);
726
 
            return TRUE;
727
 
        }
728
 
    }
729
 
    return FALSE;
730
 
}
731
 
 
732
 
 
733
 
BOOL List_AddStandardFrames(HWND hwndApp, HWND hwndList)
734
 
{
735
 
    int result;
736
 
 
737
 
    m_hwndList = hwndList;
738
 
    m_hwndDlg = hwndApp;
739
 
 
740
 
    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDSTANDARD),
741
 
        hwndApp, AddStandardProc);
742
 
 
743
 
    return result?TRUE:FALSE;
744
 
}
745
 
 
746
 
 
747
 
/* List_OnGetDispInfo - processes the LVN_GETDISPINFO  */
748
 
/*     notification message. */
749
 
/* pnmv - value of lParam (points to an LV_DISPINFO structure) */
750
 
void List_OnGetDispInfo(LV_DISPINFO *pnmv)
751
 
{
752
 
    /* Provide the item or subitem's text, if requested. */
753
 
    if (pnmv->item.mask & LVIF_TEXT) {
754
 
        ID3ITEM *pItem = (ID3ITEM *) (pnmv->item.lParam);
755
 
        lstrcpy(pnmv->item.pszText,
756
 
            pItem->aCols[pnmv->item.iSubItem]);
757
 
    }
758
 
}
759
 
 
760
 
ID3ITEM *pItem;
761
 
int editItemIndex;
762
 
 
763
 
BOOL CALLBACK EditTextFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
764
 
{
765
 
    LV_ITEM lvi;
766
 
 
767
 
    switch (message) {
768
 
    case WM_INITDIALOG:
769
 
        SetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0]);
770
 
        SetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1]);
771
 
 
772
 
        switch (pItem->frameId)
773
 
        {
774
 
        case ID3FID_ALBUM:              case ID3FID_BPM:
775
 
        case ID3FID_COMPOSER:           case ID3FID_COPYRIGHT:
776
 
        case ID3FID_DATE:               case ID3FID_PLAYLISTDELAY:
777
 
        case ID3FID_ENCODEDBY:          case ID3FID_LYRICIST:
778
 
        case ID3FID_FILETYPE:           case ID3FID_TIME:
779
 
        case ID3FID_CONTENTGROUP:       case ID3FID_TITLE:
780
 
        case ID3FID_SUBTITLE:           case ID3FID_INITIALKEY:
781
 
        case ID3FID_LANGUAGE:           case ID3FID_SONGLEN:
782
 
        case ID3FID_MEDIATYPE:          case ID3FID_ORIGALBUM:
783
 
        case ID3FID_ORIGFILENAME:       case ID3FID_ORIGLYRICIST:
784
 
        case ID3FID_ORIGARTIST:         case ID3FID_ORIGYEAR:
785
 
        case ID3FID_FILEOWNER:          case ID3FID_LEADARTIST:
786
 
        case ID3FID_BAND:               case ID3FID_CONDUCTOR:
787
 
        case ID3FID_MIXARTIST:          case ID3FID_PARTINSET:
788
 
        case ID3FID_PUBLISHER:          case ID3FID_TRACKNUM:
789
 
        case ID3FID_RECORDINGDATES:     case ID3FID_NETRADIOSTATION:
790
 
        case ID3FID_NETRADIOOWNER:      case ID3FID_SIZE:
791
 
        case ID3FID_ISRC:               case ID3FID_ENCODERSETTINGS:
792
 
        case ID3FID_YEAR:               case ID3FID_WWWAUDIOFILE:
793
 
        case ID3FID_WWWARTIST:          case ID3FID_WWWAUDIOSOURCE:
794
 
        case ID3FID_WWWCOMMERCIALINFO:  case ID3FID_WWWCOPYRIGHT:
795
 
        case ID3FID_WWWPUBLISHER:       case ID3FID_WWWPAYMENT:
796
 
        case ID3FID_WWWRADIOPAGE:       case ID3FID_CONTENTTYPE:
797
 
        {
798
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
799
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
800
 
            break;
801
 
        }
802
 
        case ID3FID_USERTEXT:           case ID3FID_COMMENT:
803
 
        case ID3FID_UNSYNCEDLYRICS:     case ID3FID_WWWUSER:
804
 
        {
805
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), TRUE);
806
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
807
 
            break;
808
 
        }
809
 
        default:
810
 
            EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
811
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
812
 
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), FALSE);
813
 
            break;
814
 
        }
815
 
        return TRUE;
816
 
 
817
 
    case WM_COMMAND:
818
 
        switch (LOWORD(wParam)) {
819
 
        case IDOK:
820
 
        {
821
 
            GetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0], 1024);
822
 
            GetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1], 1024);
823
 
            lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
824
 
            lvi.state = 0;
825
 
            lvi.stateMask = 0;
826
 
            lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
827
 
            lvi.iImage = 0;
828
 
            lvi.iItem = editItemIndex;
829
 
            lvi.iSubItem = 0;
830
 
            lvi.lParam = (LPARAM)pItem;    /* item data */
831
 
 
832
 
            /* Add the item. */
833
 
            ListView_SetItem(m_hwndList, &lvi);
834
 
            ListView_Update(m_hwndList, editItemIndex);
835
 
        } /* Fall through */
836
 
        case IDCANCEL:
837
 
            EndDialog(hwndDlg, wParam);
838
 
            return TRUE;
839
 
        }
840
 
    }
841
 
    return FALSE;
842
 
}
843
 
 
844
 
 
845
 
/* Double clicking means editing a frame */
846
 
BOOL List_EditData(HWND hwndApp, HWND hwndList)
847
 
{
848
 
    LV_ITEM lvi;
849
 
    BOOL result;
850
 
 
851
 
    /* First get the selected item */
852
 
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
853
 
 
854
 
    m_hwndList = hwndList;
855
 
 
856
 
    if (index != -1)
857
 
    {
858
 
        lvi.mask = LVIF_PARAM;
859
 
        lvi.iItem = index;
860
 
        lvi.iSubItem = 0;
861
 
 
862
 
        if (ListView_GetItem(hwndList, &lvi) == TRUE)
863
 
        {
864
 
            pItem = (ID3ITEM*)lvi.lParam;
865
 
            editItemIndex = lvi.iItem;
866
 
 
867
 
            result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_EDITTEXTFRAME),
868
 
                hwndApp, EditTextFrameProc);
869
 
            if (LOWORD(result) == IDOK)
870
 
                return TRUE;
871
 
        }
872
 
    }
873
 
    return FALSE;
874
 
}
875
 
 
876
 
 
877
 
/* Delete the selected frame */
878
 
BOOL List_DeleteSelected(HWND hwndApp, HWND hwndList)
879
 
{
880
 
    int items;
881
 
 
882
 
    /* First get the selected item */
883
 
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
884
 
 
885
 
    if (index != -1)
886
 
        ListView_DeleteItem(hwndList, index);
887
 
 
888
 
    items = ListView_GetItemCount(hwndList);
889
 
    if (index != -1) return TRUE;
890
 
    else return FALSE;
891
 
}
892
 
 
893
 
 
894
 
/* Save the ID3 to the file */
895
 
void List_SaveID3(HWND hwndApp, HWND hwndList, char *filename)
896
 
{
897
 
    LV_ITEM lvi;
898
 
    ID3ITEM *pItem1;
899
 
    int i, items;
900
 
    ID3Tag *tag;
901
 
    ID3Frame *frame;
902
 
    ID3Field *field;
903
 
    
904
 
    /* Strip the tag first, before completely rewriting it */
905
 
    if ((tag = ID3Tag_New()) != NULL)
906
 
    {
907
 
        ID3Tag_Link(tag, filename);
908
 
        ID3Tag_Strip(tag, ID3TT_ALL);
909
 
        ID3Tag_Clear(tag);
910
 
 
911
 
        if (SendMessage(GetDlgItem(hwndApp, IDC_ID3V2TAG), BM_GETCHECK, 0, 0) == BST_UNCHECKED)
912
 
        {
913
 
            /* No frames saved */
914
 
            ID3Tag_Delete(tag);
915
 
            EnableWindow(GetDlgItem(hwndApp, IDC_ID3V2TAG), FALSE);
916
 
            ListView_DeleteAllItems(hwndList);
917
 
            return;
918
 
        }
919
 
 
920
 
        /* First get the number of items */
921
 
        items = ListView_GetItemCount(hwndList);
922
 
 
923
 
        if (items > 0)
924
 
        {
925
 
            for (i = 0; i < items; i++)
926
 
            {
927
 
                lvi.mask = LVIF_PARAM;
928
 
                lvi.iItem = i;
929
 
                lvi.iSubItem = 0;
930
 
 
931
 
                if (ListView_GetItem(hwndList, &lvi) == TRUE)
932
 
                {
933
 
                    pItem1 = (ID3ITEM*)lvi.lParam;
934
 
 
935
 
                    frame = ID3Frame_NewID(pItem1->frameId);
936
 
 
937
 
                    switch (pItem1->frameId)
938
 
                    {
939
 
                    case ID3FID_ALBUM:            case ID3FID_BPM:
940
 
                    case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
941
 
                    case ID3FID_COPYRIGHT:        case ID3FID_DATE:
942
 
                    case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
943
 
                    case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
944
 
                    case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
945
 
                    case ID3FID_TITLE:            case ID3FID_SUBTITLE:
946
 
                    case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
947
 
                    case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
948
 
                    case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
949
 
                    case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
950
 
                    case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
951
 
                    case ID3FID_LEADARTIST:       case ID3FID_BAND:
952
 
                    case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
953
 
                    case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
954
 
                    case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
955
 
                    case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
956
 
                    case ID3FID_SIZE:             case ID3FID_ISRC:
957
 
                    case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
958
 
                    {
959
 
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
960
 
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
961
 
                        ID3Tag_AddFrame(tag, frame);
962
 
                        break;
963
 
                    }
964
 
                    case ID3FID_USERTEXT:
965
 
                    case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
966
 
                    case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
967
 
                    {
968
 
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
969
 
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
970
 
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
971
 
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
972
 
                        ID3Tag_AddFrame(tag, frame);
973
 
                        break;
974
 
                    }
975
 
                    case ID3FID_WWWAUDIOFILE:     case ID3FID_WWWARTIST:
976
 
                    case ID3FID_WWWAUDIOSOURCE:   case ID3FID_WWWCOMMERCIALINFO:
977
 
                    case ID3FID_WWWCOPYRIGHT:     case ID3FID_WWWPUBLISHER:
978
 
                    case ID3FID_WWWPAYMENT:       case ID3FID_WWWRADIOPAGE:
979
 
                    {
980
 
                        field = ID3Frame_GetField(frame, ID3FN_URL);
981
 
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
982
 
                        ID3Tag_AddFrame(tag, frame);
983
 
                        break;
984
 
                    }
985
 
                    case ID3FID_WWWUSER:
986
 
                    {
987
 
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
988
 
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
989
 
                        field = ID3Frame_GetField(frame, ID3FN_URL);
990
 
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
991
 
                        ID3Tag_AddFrame(tag, frame);
992
 
                        break;
993
 
                    }
994
 
                    default:
995
 
                        break;
996
 
                    }
997
 
                }
998
 
            }
999
 
            ID3Tag_UpdateByTagType(tag, ID3TT_ID3V2);
1000
 
        }
1001
 
 
1002
 
        ID3Tag_Delete(tag);
1003
 
    }
1004
 
}
1005
 
 
1006
 
/* Get the title from the file */
1007
 
void GetID3FileTitle(char *filename, char *title, char *format)
1008
 
{
1009
 
    ID3Tag *tag;
1010
 
    ID3Frame *frame;
1011
 
    ID3Field *field;
1012
 
    char buffer[255];
1013
 
    int some_info = 0;
1014
 
    char *in = format;
1015
 
    char *out = title;
1016
 
    char *bound = out + (MAX_PATH - 10 - 1);
1017
 
 
1018
 
 
1019
 
    if ((tag = ID3Tag_New()) != NULL)
1020
 
    {
1021
 
        ID3Tag_Link(tag, filename);
1022
 
 
1023
 
        while (*in && out < bound)
1024
 
        {
1025
 
            switch (*in) {
1026
 
            case '%':
1027
 
                ++in;
1028
 
                break;
1029
 
 
1030
 
            default:
1031
 
                *out++ = *in++;
1032
 
                continue;
1033
 
            }
1034
 
 
1035
 
            /* handle % escape sequence */
1036
 
            switch (*in++) {
1037
 
            case '0':
1038
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TRACKNUM)) != NULL) {
1039
 
                    int size;
1040
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1041
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1042
 
                    lstrcpy(out, buffer); out += size;
1043
 
                    some_info = 1;
1044
 
                }
1045
 
                break;
1046
 
            case '1':
1047
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_LEADARTIST)) != NULL) {
1048
 
                    int size;
1049
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1050
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1051
 
                    lstrcpy(out, buffer); out += size;
1052
 
                    some_info = 1;
1053
 
                }
1054
 
                break;
1055
 
            case '2':
1056
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TITLE)) != NULL) {
1057
 
                    int size;
1058
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1059
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1060
 
                    lstrcpy(out, buffer); out += size;
1061
 
                    some_info = 1;
1062
 
                }
1063
 
                break;
1064
 
            case '3':
1065
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_ALBUM)) != NULL) {
1066
 
                    int size;
1067
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1068
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1069
 
                    lstrcpy(out, buffer); out += size;
1070
 
                    some_info = 1;
1071
 
                }
1072
 
                break;
1073
 
            case '4':
1074
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_YEAR)) != NULL) {
1075
 
                    int size;
1076
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1077
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1078
 
                    lstrcpy(out, buffer); out += size;
1079
 
                    some_info = 1;
1080
 
                }
1081
 
                break;
1082
 
            case '5':
1083
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_COMMENT)) != NULL) {
1084
 
                    int size;
1085
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1086
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1087
 
                    lstrcpy(out, buffer); out += size;
1088
 
                    some_info = 1;
1089
 
                }
1090
 
                break;
1091
 
            case '6':
1092
 
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_CONTENTTYPE)) != NULL) {
1093
 
                    int size; char *tmp;
1094
 
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
1095
 
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
1096
 
                    tmp = GetGenre(buffer);
1097
 
                    lstrcpy(out, tmp); out += size;
1098
 
                    some_info = 1;
1099
 
                }
1100
 
                break;
1101
 
            case '7':
1102
 
            {
1103
 
                char *p=filename+lstrlen(filename);
1104
 
                int len = 0;
1105
 
                while (*p != '\\' && p >= filename) { p--; len++; }
1106
 
                lstrcpy(out, ++p); out += len;
1107
 
                some_info = 1;
1108
 
                break;
1109
 
            }
1110
 
            }
1111
 
        }
1112
 
 
1113
 
        *out = '\0';
1114
 
        ID3Tag_Delete(tag);
1115
 
    }
1116
 
 
1117
 
    if (!some_info)
1118
 
    {
1119
 
        char *p=filename+lstrlen(filename);
1120
 
        while (*p != '\\' && p >= filename) p--;
1121
 
        lstrcpy(title,++p);
1122
 
    }
1123
 
}
1124
 
 
 
1
/*
 
2
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
 
3
** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
 
4
**  
 
5
** This program is free software; you can redistribute it and/or modify
 
6
** it under the terms of the GNU General Public License as published by
 
7
** the Free Software Foundation; either version 2 of the License, or
 
8
** (at your option) any later version.
 
9
** 
 
10
** This program is distributed in the hope that it will be useful,
 
11
** but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
** GNU General Public License for more details.
 
14
** 
 
15
** You should have received a copy of the GNU General Public License
 
16
** along with this program; if not, write to the Free Software 
 
17
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
18
**
 
19
** Any non-GPL usage of this software or parts of this software is strictly
 
20
** forbidden.
 
21
**
 
22
** Commercial non-GPL licensing of this software is possible.
 
23
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 
24
**
 
25
** $Id: id3v2tag.c,v 1.4 2003/07/29 08:20:11 menno Exp $
 
26
**/
 
27
 
 
28
#define WIN32_LEAN_AND_MEAN
 
29
#include <windows.h>
 
30
#include <commctrl.h>
 
31
#include <resource.h>
 
32
 
 
33
#include <id3.h>
 
34
 
 
35
#include <id3v2tag.h>
 
36
 
 
37
HWND m_hwndList;
 
38
 
 
39
LPSTR ID3Frames[] =
 
40
{
 
41
    "No known frame",
 
42
    "Audio encryption",
 
43
    "Attached picture",
 
44
    "Comments",
 
45
    "Commercial frame",
 
46
    "Encryption method registration",
 
47
    "Equalization",
 
48
    "Event timing codes",
 
49
    "General encapsulated object",
 
50
    "Group identification registration",
 
51
    "Involved people list",
 
52
    "Linked information",
 
53
    "Music CD identifier",
 
54
    "MPEG location lookup table",
 
55
    "Ownership frame",
 
56
    "Private frame",
 
57
    "Play counter",
 
58
    "Popularimeter",
 
59
    "Position synchronisation frame",
 
60
    "Recommended buffer size",
 
61
    "Relative volume adjustment",
 
62
    "Reverb",
 
63
    "Synchronized lyric",
 
64
    "Synchronized tempo codes",
 
65
    "Album title",
 
66
    "BPM (beats per minute)",
 
67
    "Composer",
 
68
    "Genre", //"Content type",
 
69
    "Copyright message",
 
70
    "Date",
 
71
    "Playlist delay",
 
72
    "Encoded by",
 
73
    "Lyricist",
 
74
    "File type",
 
75
    "Time",
 
76
    "Content group description",
 
77
    "Title",
 
78
    "Subtitle",
 
79
    "Initial key",
 
80
    "Language(s)",
 
81
    "Length",
 
82
    "Media type",
 
83
    "Original album title",
 
84
    "Original filename",
 
85
    "Original lyricist(s)",
 
86
    "Original artist(s)",
 
87
    "Original release year",
 
88
    "File owner",
 
89
    "Lead performer(s)",
 
90
    "Band/orchestra/accompaniment",
 
91
    "Conductor/performer refinement",
 
92
    "Interpreted, remixed, or otherwise modified by",
 
93
    "Part of a set",
 
94
    "Publisher",
 
95
    "Track number",
 
96
    "Recording dates",
 
97
    "Internet radio station name",
 
98
    "Internet radio station owner",
 
99
    "Size",
 
100
    "ISRC (international standard recording code)",
 
101
    "Software/Hardware and settings used for encoding",
 
102
    "User defined text information",
 
103
    "Year",
 
104
    "Unique file identifier",
 
105
    "Terms of use",
 
106
    "Unsynchronized lyric",
 
107
    "Commercial information",
 
108
    "Copyright/Legal information",
 
109
    "Official audio file webpage",
 
110
    "Official artist webpage",
 
111
    "Official audio source webpage",
 
112
    "Official internet radio station homepage",
 
113
    "Payment",
 
114
    "Official publisher webpage",
 
115
    "User defined URL link",
 
116
    "Encrypted meta frame (id3v2.2.x)",
 
117
    "Compressed meta frame (id3v2.2.1)"
 
118
};
 
119
 
 
120
ID3GENRES ID3Genres[]=
 
121
{
 
122
    123,    "Acapella",
 
123
    34,     "Acid",
 
124
    74,     "Acid Jazz",
 
125
    73,     "Acid Punk",
 
126
    99,     "Acoustic",
 
127
    20,     "Alternative",
 
128
    40,     "AlternRock",
 
129
    26,     "Ambient",
 
130
    90,     "Avantgarde",
 
131
    116,    "Ballad",
 
132
    41,     "Bass",
 
133
    85,     "Bebob",
 
134
    96,     "Big Band",
 
135
    89,     "Bluegrass",
 
136
    0,      "Blues",
 
137
    107,    "Booty Bass",
 
138
    65,     "Cabaret",
 
139
    88,     "Celtic",
 
140
    104,    "Chamber Music",
 
141
    102,    "Chanson",
 
142
    97,     "Chorus",
 
143
    61,     "Christian Rap",
 
144
    1,      "Classic Rock",
 
145
    32,     "Classical",
 
146
    112,    "Club",
 
147
    57,     "Comedy",
 
148
    2,      "Country",
 
149
    58,     "Cult",
 
150
    3,      "Dance",
 
151
    125,    "Dance Hall",
 
152
    50,     "Darkwave",
 
153
    254,    "Data",
 
154
    22,     "Death Metal",
 
155
    4,      "Disco",
 
156
    55,     "Dream",
 
157
    122,    "Drum Solo",
 
158
    120,    "Duet",
 
159
    98,     "Easy Listening",
 
160
    52,     "Electronic",
 
161
    48,     "Ethnic",
 
162
    124,    "Euro-House",
 
163
    25,     "Euro-Techno",
 
164
    54,     "Eurodance",
 
165
    84,     "Fast Fusion",
 
166
    80,     "Folk",
 
167
    81,     "Folk-Rock",
 
168
    115,    "Folklore",
 
169
    119,    "Freestyle",
 
170
    5,      "Funk",
 
171
    30,     "Fusion",
 
172
    36,     "Game",
 
173
    59,     "Gangsta",
 
174
    38,     "Gospel",
 
175
    49,     "Gothic",
 
176
    91,     "Gothic Rock",
 
177
    6,      "Grunge",
 
178
    79,     "Hard Rock",
 
179
    7,      "Hip-Hop",
 
180
    35,     "House",
 
181
    100,    "Humour",
 
182
    19,     "Industrial",
 
183
    33,     "Instrumental",
 
184
    46,     "Instrumental Pop",
 
185
    47,     "Instrumental Rock",
 
186
    8,      "Jazz",
 
187
    29,     "Jazz+Funk",
 
188
    63,     "Jungle",
 
189
    86,     "Latin",
 
190
    71,     "Lo-Fi",
 
191
    45,     "Meditative",
 
192
    9,      "Metal",
 
193
    77,     "Musical",
 
194
    82,     "National Folk",
 
195
    64,     "Native American",
 
196
    10,     "New Age",
 
197
    66,     "New Wave",
 
198
    39,     "Noise",
 
199
    255,    "Not Set",
 
200
    11,     "Oldies",
 
201
    103,    "Opera",
 
202
    12,     "Other",
 
203
    75,     "Polka",
 
204
    13,     "Pop",
 
205
    62,     "Pop/Funk",
 
206
    53,     "Pop-Folk",
 
207
    109,    "Porn Groove",
 
208
    117,    "Power Ballad",
 
209
    23,     "Pranks",
 
210
    108,    "Primus",
 
211
    92,     "Progressive Rock",
 
212
    67,     "Psychadelic",
 
213
    93,     "Psychedelic Rock",
 
214
    43,     "Punk",
 
215
    121,    "Punk Rock",
 
216
    14,     "R&B",
 
217
    15,     "Rap",
 
218
    68,     "Rave",
 
219
    16,     "Reggae",
 
220
    76,     "Retro",
 
221
    87,     "Revival",
 
222
    118,    "Rhythmic Soul",
 
223
    17,     "Rock",
 
224
    78,     "Rock & Roll",
 
225
    114,    "Samba",
 
226
    110,    "Satire",
 
227
    69,     "Showtunes",
 
228
    21,     "Ska",
 
229
    111,    "Slow Jam",
 
230
    95,     "Slow Rock",
 
231
    105,    "Sonata",
 
232
    42,     "Soul",
 
233
    37,     "Sound Clip",
 
234
    24,     "Soundtrack",
 
235
    56,     "Southern Rock",
 
236
    44,     "Space",
 
237
    101,    "Speech",
 
238
    83,     "Swing",
 
239
    94,     "Symphonic Rock",
 
240
    106,    "Symphony",
 
241
    113,    "Tango",
 
242
    18,     "Techno",
 
243
    51,     "Techno-Industrial",
 
244
    60,     "Top 40",
 
245
    70,     "Trailer",
 
246
    31,     "Trance",
 
247
    72,     "Tribal",
 
248
    27,     "Trip-Hop",
 
249
    28,     "Vocal"
 
250
};
 
251
 
 
252
const int NUMFRAMES = sizeof(ID3Frames)/sizeof(ID3Frames[0]);
 
253
const int NUMGENRES = sizeof(ID3Genres)/sizeof(ID3Genres[0]);
 
254
 
 
255
 
 
256
LPSTR DupString(LPSTR lpsz)
 
257
{
 
258
    int cb = lstrlen(lpsz) + 1;
 
259
    LPSTR lpszNew = LocalAlloc(LMEM_FIXED, cb);
 
260
    if (lpszNew != NULL)
 
261
        CopyMemory(lpszNew, lpsz, cb);
 
262
    return lpszNew;
 
263
}
 
264
 
 
265
LPSTR GetFrameDesc(ID3_FrameID id)
 
266
{
 
267
    return DupString(ID3Frames[id]);
 
268
}
 
269
 
 
270
LPSTR GetGenre(LPSTR lpsz)
 
271
{
 
272
    int id = atoi(lpsz + 1);
 
273
    int i;
 
274
 
 
275
    if ((*(lpsz + 1) > '0') && (*(lpsz + 1) < '9'))
 
276
    {
 
277
        for (i = 0; i < NUMGENRES; i++)
 
278
        {
 
279
            if (id == ID3Genres[i].id)
 
280
                return DupString(ID3Genres[i].name);
 
281
        }
 
282
    }
 
283
    return DupString(lpsz);
 
284
}
 
285
 
 
286
void FillID3List(HWND hwndDlg, HWND hwndList, char *filename)
 
287
{
 
288
    ID3Tag *tag;
 
289
    ID3Frame *frame;
 
290
    ID3Field *field;
 
291
    ID3_FrameID eFrameID;
 
292
    char info[1024];
 
293
    int numFrames;
 
294
    int i;
 
295
    int iItem = 0;
 
296
 
 
297
 
 
298
    if ((tag = ID3Tag_New()) != NULL)
 
299
    {
 
300
        ID3Tag_Link(tag, filename);
 
301
 
 
302
        numFrames = ID3Tag_NumFrames(tag);
 
303
 
 
304
        for (i = 0; i < numFrames; i++)
 
305
        {
 
306
            iItem++;
 
307
 
 
308
            frame = ID3Tag_GetFrameNum(tag, i);
 
309
            eFrameID = ID3Frame_GetID(frame);
 
310
 
 
311
            switch (eFrameID)
 
312
            {
 
313
            case ID3FID_ALBUM:            case ID3FID_BPM:
 
314
            case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
 
315
            case ID3FID_COPYRIGHT:        case ID3FID_DATE:
 
316
            case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
 
317
            case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
 
318
            case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
 
319
            case ID3FID_TITLE:            case ID3FID_SUBTITLE:
 
320
            case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
 
321
            case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
 
322
            case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
 
323
            case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
 
324
            case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
 
325
            case ID3FID_LEADARTIST:       case ID3FID_BAND:
 
326
            case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
 
327
            case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
 
328
            case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
 
329
            case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
 
330
            case ID3FID_SIZE:             case ID3FID_ISRC:
 
331
            case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
 
332
            {
 
333
                LV_ITEM lvi;
 
334
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
335
 
 
336
                /* Initialize LV_ITEM members that are common to all items. */
 
337
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
338
                lvi.state = 0;
 
339
                lvi.stateMask = 0;
 
340
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
341
                lvi.iImage = 0;
 
342
                lvi.iItem = iItem;
 
343
                lvi.iSubItem = 0;
 
344
 
 
345
                pItem->frameId = eFrameID;
 
346
                pItem->aCols[0] = GetFrameDesc(eFrameID);
 
347
 
 
348
                field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
349
                ID3Field_GetASCII(field, info, 1024, 1);
 
350
                if (eFrameID == ID3FID_CONTENTTYPE)
 
351
                    pItem->aCols[1] = GetGenre(info);
 
352
                else
 
353
                    pItem->aCols[1] = DupString(info);
 
354
 
 
355
                lvi.lParam = (LPARAM)pItem;    /* item data */
 
356
 
 
357
                /* Add the item. */
 
358
                ListView_InsertItem(hwndList, &lvi);
 
359
 
 
360
                break;
 
361
            }
 
362
            case ID3FID_USERTEXT:
 
363
            case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
 
364
            case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
 
365
            {
 
366
                LV_ITEM lvi;
 
367
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
368
 
 
369
                /* Initialize LV_ITEM members that are common to all items. */
 
370
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
371
                lvi.state = 0;
 
372
                lvi.stateMask = 0;
 
373
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
374
                lvi.iImage = 0;
 
375
                lvi.iItem = iItem;
 
376
                lvi.iSubItem = 0;
 
377
 
 
378
                pItem->frameId = eFrameID;
 
379
 
 
380
                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
 
381
                ID3Field_GetASCII(field, info, 1024, 1);
 
382
                pItem->aCols[0] = DupString(info);
 
383
 
 
384
                field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
385
                ID3Field_GetASCII(field, info, 1024, 1);
 
386
                pItem->aCols[1] = DupString(info);
 
387
 
 
388
                lvi.lParam = (LPARAM)pItem;    /* item data */
 
389
 
 
390
                /* Add the item. */
 
391
                ListView_InsertItem(hwndList, &lvi);
 
392
 
 
393
                break;
 
394
            }
 
395
            case ID3FID_WWWAUDIOFILE:       case ID3FID_WWWARTIST:
 
396
            case ID3FID_WWWAUDIOSOURCE:     case ID3FID_WWWCOMMERCIALINFO:
 
397
            case ID3FID_WWWCOPYRIGHT:       case ID3FID_WWWPUBLISHER:
 
398
            case ID3FID_WWWPAYMENT:         case ID3FID_WWWRADIOPAGE:
 
399
            {
 
400
                LV_ITEM lvi;
 
401
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
402
 
 
403
                /* Initialize LV_ITEM members that are common to all items. */
 
404
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
405
                lvi.state = 0;
 
406
                lvi.stateMask = 0;
 
407
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
408
                lvi.iImage = 0;
 
409
                lvi.iItem = iItem;
 
410
                lvi.iSubItem = 0;
 
411
 
 
412
                pItem->frameId = eFrameID;
 
413
 
 
414
                pItem->aCols[0] = GetFrameDesc(eFrameID);
 
415
 
 
416
                field = ID3Frame_GetField(frame, ID3FN_URL);
 
417
                ID3Field_GetASCII(field, info, 1024, 1);
 
418
                pItem->aCols[1] = DupString(info);
 
419
 
 
420
                lvi.lParam = (LPARAM)pItem;    /* item data */
 
421
 
 
422
                /* Add the item. */
 
423
                ListView_InsertItem(hwndList, &lvi);
 
424
 
 
425
                break;
 
426
            }
 
427
            case ID3FID_WWWUSER:
 
428
            {
 
429
                LV_ITEM lvi;
 
430
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
431
 
 
432
                /* Initialize LV_ITEM members that are common to all items. */
 
433
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
434
                lvi.state = 0;
 
435
                lvi.stateMask = 0;
 
436
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
437
                lvi.iImage = 0;
 
438
                lvi.iItem = iItem;
 
439
                lvi.iSubItem = 0;
 
440
 
 
441
                pItem->frameId = eFrameID;
 
442
 
 
443
                field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
 
444
                ID3Field_GetASCII(field, info, 1024, 1);
 
445
                pItem->aCols[0] = DupString(info);
 
446
 
 
447
                field = ID3Frame_GetField(frame, ID3FN_URL);
 
448
                ID3Field_GetASCII(field, info, 1024, 1);
 
449
                pItem->aCols[1] = DupString(info);
 
450
 
 
451
                lvi.lParam = (LPARAM)pItem;    /* item data */
 
452
 
 
453
                /* Add the item. */
 
454
                ListView_InsertItem(hwndList, &lvi);
 
455
 
 
456
                break;
 
457
            }
 
458
            default:
 
459
                break;
 
460
            }
 
461
        }
 
462
        ID3Tag_Delete(tag);
 
463
    }
 
464
}
 
465
 
 
466
BOOL CALLBACK AddFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
467
{
 
468
    int i, cursel;
 
469
 
 
470
    switch (message) {
 
471
    case WM_INITDIALOG:
 
472
        EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
 
473
        EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
 
474
 
 
475
        /* Note: FRAMEID is the index in the combo box + 1 */
 
476
        for (i = 1; i < NUMFRAMES; i++)
 
477
        {
 
478
            SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)ID3Frames[i]);
 
479
        }
 
480
        return TRUE;
 
481
 
 
482
    case WM_COMMAND:
 
483
        switch (LOWORD(wParam)) {
 
484
        case IDC_FRAMETYPE:
 
485
            if (HIWORD(wParam) == CBN_SELCHANGE)
 
486
            {
 
487
                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);
 
488
 
 
489
                switch (cursel + 1)
 
490
                {
 
491
                case ID3FID_ALBUM:             case ID3FID_BPM:
 
492
                case ID3FID_COMPOSER:          case ID3FID_COPYRIGHT:
 
493
                case ID3FID_DATE:              case ID3FID_PLAYLISTDELAY:
 
494
                case ID3FID_ENCODEDBY:         case ID3FID_LYRICIST:
 
495
                case ID3FID_FILETYPE:          case ID3FID_TIME:
 
496
                case ID3FID_CONTENTGROUP:      case ID3FID_TITLE:
 
497
                case ID3FID_SUBTITLE:          case ID3FID_INITIALKEY:
 
498
                case ID3FID_LANGUAGE:          case ID3FID_SONGLEN:
 
499
                case ID3FID_MEDIATYPE:         case ID3FID_ORIGALBUM:
 
500
                case ID3FID_ORIGFILENAME:      case ID3FID_ORIGLYRICIST:
 
501
                case ID3FID_ORIGARTIST:        case ID3FID_ORIGYEAR:
 
502
                case ID3FID_FILEOWNER:         case ID3FID_LEADARTIST:
 
503
                case ID3FID_BAND:              case ID3FID_CONDUCTOR:
 
504
                case ID3FID_MIXARTIST:         case ID3FID_PARTINSET:
 
505
                case ID3FID_PUBLISHER:         case ID3FID_TRACKNUM:
 
506
                case ID3FID_RECORDINGDATES:    case ID3FID_NETRADIOSTATION:
 
507
                case ID3FID_NETRADIOOWNER:     case ID3FID_SIZE:
 
508
                case ID3FID_ISRC:              case ID3FID_ENCODERSETTINGS:
 
509
                case ID3FID_YEAR:              case ID3FID_WWWAUDIOFILE:
 
510
                case ID3FID_WWWARTIST:         case ID3FID_WWWAUDIOSOURCE:
 
511
                case ID3FID_WWWCOMMERCIALINFO: case ID3FID_WWWCOPYRIGHT:
 
512
                case ID3FID_WWWPUBLISHER:      case ID3FID_WWWPAYMENT:
 
513
                case ID3FID_WWWRADIOPAGE:      case ID3FID_CONTENTTYPE:
 
514
                {
 
515
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
 
516
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
 
517
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
 
518
                    break;
 
519
                }
 
520
                case ID3FID_USERTEXT:          case ID3FID_COMMENT:
 
521
                case ID3FID_UNSYNCEDLYRICS:    case ID3FID_WWWUSER:
 
522
                {
 
523
                    SetDlgItemText(hwndDlg, IDC_COL0, ID3Frames[cursel+1]);
 
524
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), TRUE);
 
525
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
 
526
                    break;
 
527
                }
 
528
                default:
 
529
                    MessageBox(hwndDlg, "Sorry, this frame type cannot be added (yet).", "Sorry", MB_OK);
 
530
                    EnableWindow(GetDlgItem(hwndDlg, IDC_COL0), FALSE);
 
531
                    EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
 
532
                    break;
 
533
                }
 
534
            }
 
535
            return TRUE;
 
536
        case IDOK:
 
537
            {
 
538
                LV_ITEM lvi;
 
539
                ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
540
                char *col0 = LocalAlloc(LPTR, 1024);
 
541
                char *col1 = LocalAlloc(LPTR, 1024);
 
542
 
 
543
                /* Initialize LV_ITEM members that are common to all items. */
 
544
                lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
545
                lvi.state = 0;
 
546
                lvi.stateMask = 0;
 
547
                lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
548
                lvi.iImage = 0;
 
549
                lvi.iItem = ListView_GetItemCount(m_hwndList) + 1;
 
550
                lvi.iSubItem = 0;
 
551
 
 
552
                cursel = SendMessage(GetDlgItem(hwndDlg, IDC_FRAMETYPE), CB_GETCURSEL, 0, 0);
 
553
                pItem->frameId = cursel + 1;
 
554
                GetDlgItemText(hwndDlg, IDC_COL0, col0, 1024);
 
555
                GetDlgItemText(hwndDlg, IDC_COL1, col1, 1024);
 
556
                pItem->aCols[0] = col0;
 
557
                pItem->aCols[1] = col1;
 
558
 
 
559
                lvi.lParam = (LPARAM)pItem;    /* item data */
 
560
 
 
561
                /* Add the item. */
 
562
                ListView_InsertItem(m_hwndList, &lvi);
 
563
                ListView_Update(m_hwndList, lvi.iItem);
 
564
            }
 
565
        case IDCANCEL:
 
566
            EndDialog(hwndDlg, wParam);
 
567
            return TRUE;
 
568
        }
 
569
    }
 
570
    return FALSE;
 
571
}
 
572
 
 
573
BOOL List_AddFrame(HWND hwndApp, HWND hwndList)
 
574
{
 
575
    int result;
 
576
 
 
577
    m_hwndList = hwndList;
 
578
 
 
579
    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDFRAME),
 
580
        hwndApp, AddFrameProc);
 
581
 
 
582
    if (LOWORD(result) == IDOK)
 
583
        return TRUE;
 
584
    return FALSE;
 
585
}
 
586
 
 
587
 
 
588
void InsertTextFrame(HWND dlg, HWND list, int control, int item, int frame_id)
 
589
{
 
590
    LV_ITEM lvi;
 
591
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
592
 
 
593
    /* Initialize LV_ITEM members that are common to all items. */
 
594
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
595
    lvi.state = 0;
 
596
    lvi.stateMask = 0;
 
597
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
598
    lvi.iImage = 0;
 
599
    lvi.iItem = item;
 
600
    lvi.iSubItem = 0;
 
601
 
 
602
    pItem->frameId = frame_id;
 
603
    pItem->aCols[0] = GetFrameDesc(frame_id);
 
604
 
 
605
    pItem->aCols[1] = LocalAlloc(LPTR, 1024);
 
606
    GetDlgItemText(dlg, control, pItem->aCols[1], 1024);
 
607
 
 
608
    lvi.lParam = (LPARAM)pItem;    /* item data */
 
609
 
 
610
    /* Add the item. */
 
611
    ListView_InsertItem(list, &lvi);
 
612
}
 
613
 
 
614
void AddFrameFromRAWData(HWND hwndList, int frameId, LPSTR data1, LPSTR data2)
 
615
{
 
616
    LV_ITEM lvi;
 
617
    ID3ITEM *pItem = LocalAlloc(LPTR, sizeof(ID3ITEM));
 
618
    int nextItem;
 
619
 
 
620
    nextItem = ListView_GetItemCount(hwndList);
 
621
 
 
622
    /* Initialize LV_ITEM members that are common to all items. */
 
623
    lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
624
    lvi.state = 0;
 
625
    lvi.stateMask = 0;
 
626
    lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
627
    lvi.iImage = 0;
 
628
    lvi.iItem = nextItem;
 
629
    lvi.iSubItem = 0;
 
630
 
 
631
    pItem->frameId = frameId;
 
632
 
 
633
    pItem->aCols[0] = LocalAlloc(LPTR, 1024);
 
634
    pItem->aCols[1] = LocalAlloc(LPTR, 1024);
 
635
 
 
636
    lstrcpy(pItem->aCols[0], data1);
 
637
    lstrcpy(pItem->aCols[1], data2);
 
638
 
 
639
    lvi.lParam = (LPARAM)pItem;    /* item data */
 
640
 
 
641
    /* Add the item. */
 
642
    ListView_InsertItem(hwndList, &lvi);
 
643
}
 
644
 
 
645
HWND m_hwndDlg;
 
646
int changed;
 
647
 
 
648
BOOL CALLBACK AddStandardProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
649
{
 
650
    int added = 0;
 
651
 
 
652
    switch (message) {
 
653
    case WM_INITDIALOG:
 
654
        changed = 0;
 
655
        return TRUE;
 
656
 
 
657
    case WM_COMMAND:
 
658
        switch (LOWORD(wParam)) {
 
659
        case IDOK:
 
660
        {
 
661
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TRACK)) > 0) {
 
662
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TRACK, ListView_GetItemCount(m_hwndList)+1, ID3FID_TRACKNUM);
 
663
                added++;
 
664
            }
 
665
 
 
666
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_TITLE)) > 0) {
 
667
                InsertTextFrame(hwndDlg, m_hwndList, IDC_TITLE, ListView_GetItemCount(m_hwndList)+1, ID3FID_TITLE);
 
668
                added++;
 
669
            }
 
670
 
 
671
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ARTIST)) > 0) {
 
672
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_LEADARTIST);
 
673
                added++;
 
674
            }
 
675
 
 
676
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ALBUM)) > 0) {
 
677
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ALBUM, ListView_GetItemCount(m_hwndList)+1, ID3FID_ALBUM);
 
678
                added++;
 
679
            }
 
680
 
 
681
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_YEAR)) > 0) {
 
682
                InsertTextFrame(hwndDlg, m_hwndList, IDC_YEAR, ListView_GetItemCount(m_hwndList)+1, ID3FID_YEAR);
 
683
                added++;
 
684
            }
 
685
 
 
686
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_GENRE)) > 0) {
 
687
                InsertTextFrame(hwndDlg, m_hwndList, IDC_GENRE, ListView_GetItemCount(m_hwndList)+1, ID3FID_CONTENTTYPE);
 
688
                added++;
 
689
            }
 
690
 
 
691
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMMENT)) > 0) {
 
692
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMMENT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMMENT);
 
693
                added++;
 
694
            }
 
695
 
 
696
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COMPOSER)) > 0) {
 
697
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COMPOSER, ListView_GetItemCount(m_hwndList)+1, ID3FID_COMPOSER);
 
698
                added++;
 
699
            }
 
700
 
 
701
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ORIGARTIST)) > 0) {
 
702
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ORIGARTIST, ListView_GetItemCount(m_hwndList)+1, ID3FID_ORIGARTIST);
 
703
                added++;
 
704
            }
 
705
 
 
706
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_COPYRIGHT)) > 0) {
 
707
                InsertTextFrame(hwndDlg, m_hwndList, IDC_COPYRIGHT, ListView_GetItemCount(m_hwndList)+1, ID3FID_COPYRIGHT);
 
708
                added++;
 
709
            }
 
710
 
 
711
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_URL)) > 0) {
 
712
                InsertTextFrame(hwndDlg, m_hwndList, IDC_URL, ListView_GetItemCount(m_hwndList)+1, ID3FID_WWWARTIST);
 
713
                added++;
 
714
            }
 
715
 
 
716
            if (GetWindowTextLength(GetDlgItem(hwndDlg, IDC_ENCBY)) > 0) {
 
717
                InsertTextFrame(hwndDlg, m_hwndList, IDC_ENCBY, ListView_GetItemCount(m_hwndList)+1, ID3FID_ENCODEDBY);
 
718
                added++;
 
719
            }
 
720
 
 
721
            if (added > 0)
 
722
                changed = 1;
 
723
        }
 
724
        case IDCANCEL:
 
725
            EndDialog(hwndDlg, changed);
 
726
            return TRUE;
 
727
        }
 
728
    }
 
729
    return FALSE;
 
730
}
 
731
 
 
732
 
 
733
BOOL List_AddStandardFrames(HWND hwndApp, HWND hwndList)
 
734
{
 
735
    int result;
 
736
 
 
737
    m_hwndList = hwndList;
 
738
    m_hwndDlg = hwndApp;
 
739
 
 
740
    result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_ADDSTANDARD),
 
741
        hwndApp, AddStandardProc);
 
742
 
 
743
    return result?TRUE:FALSE;
 
744
}
 
745
 
 
746
 
 
747
/* List_OnGetDispInfo - processes the LVN_GETDISPINFO  */
 
748
/*     notification message. */
 
749
/* pnmv - value of lParam (points to an LV_DISPINFO structure) */
 
750
void List_OnGetDispInfo(LV_DISPINFO *pnmv)
 
751
{
 
752
    /* Provide the item or subitem's text, if requested. */
 
753
    if (pnmv->item.mask & LVIF_TEXT) {
 
754
        ID3ITEM *pItem = (ID3ITEM *) (pnmv->item.lParam);
 
755
        lstrcpy(pnmv->item.pszText,
 
756
            pItem->aCols[pnmv->item.iSubItem]);
 
757
    }
 
758
}
 
759
 
 
760
ID3ITEM *pItem;
 
761
int editItemIndex;
 
762
 
 
763
BOOL CALLBACK EditTextFrameProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
 
764
{
 
765
    LV_ITEM lvi;
 
766
 
 
767
    switch (message) {
 
768
    case WM_INITDIALOG:
 
769
        SetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0]);
 
770
        SetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1]);
 
771
 
 
772
        switch (pItem->frameId)
 
773
        {
 
774
        case ID3FID_ALBUM:              case ID3FID_BPM:
 
775
        case ID3FID_COMPOSER:           case ID3FID_COPYRIGHT:
 
776
        case ID3FID_DATE:               case ID3FID_PLAYLISTDELAY:
 
777
        case ID3FID_ENCODEDBY:          case ID3FID_LYRICIST:
 
778
        case ID3FID_FILETYPE:           case ID3FID_TIME:
 
779
        case ID3FID_CONTENTGROUP:       case ID3FID_TITLE:
 
780
        case ID3FID_SUBTITLE:           case ID3FID_INITIALKEY:
 
781
        case ID3FID_LANGUAGE:           case ID3FID_SONGLEN:
 
782
        case ID3FID_MEDIATYPE:          case ID3FID_ORIGALBUM:
 
783
        case ID3FID_ORIGFILENAME:       case ID3FID_ORIGLYRICIST:
 
784
        case ID3FID_ORIGARTIST:         case ID3FID_ORIGYEAR:
 
785
        case ID3FID_FILEOWNER:          case ID3FID_LEADARTIST:
 
786
        case ID3FID_BAND:               case ID3FID_CONDUCTOR:
 
787
        case ID3FID_MIXARTIST:          case ID3FID_PARTINSET:
 
788
        case ID3FID_PUBLISHER:          case ID3FID_TRACKNUM:
 
789
        case ID3FID_RECORDINGDATES:     case ID3FID_NETRADIOSTATION:
 
790
        case ID3FID_NETRADIOOWNER:      case ID3FID_SIZE:
 
791
        case ID3FID_ISRC:               case ID3FID_ENCODERSETTINGS:
 
792
        case ID3FID_YEAR:               case ID3FID_WWWAUDIOFILE:
 
793
        case ID3FID_WWWARTIST:          case ID3FID_WWWAUDIOSOURCE:
 
794
        case ID3FID_WWWCOMMERCIALINFO:  case ID3FID_WWWCOPYRIGHT:
 
795
        case ID3FID_WWWPUBLISHER:       case ID3FID_WWWPAYMENT:
 
796
        case ID3FID_WWWRADIOPAGE:       case ID3FID_CONTENTTYPE:
 
797
        {
 
798
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
 
799
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
 
800
            break;
 
801
        }
 
802
        case ID3FID_USERTEXT:           case ID3FID_COMMENT:
 
803
        case ID3FID_UNSYNCEDLYRICS:     case ID3FID_WWWUSER:
 
804
        {
 
805
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), TRUE);
 
806
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), TRUE);
 
807
            break;
 
808
        }
 
809
        default:
 
810
            EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
 
811
            EnableWindow(GetDlgItem(hwndDlg, IDC_TEXTFRAMENAME), FALSE);
 
812
            EnableWindow(GetDlgItem(hwndDlg, IDC_EDITTEXTFRAME), FALSE);
 
813
            break;
 
814
        }
 
815
        return TRUE;
 
816
 
 
817
    case WM_COMMAND:
 
818
        switch (LOWORD(wParam)) {
 
819
        case IDOK:
 
820
        {
 
821
            GetDlgItemText(hwndDlg, IDC_TEXTFRAMENAME, pItem->aCols[0], 1024);
 
822
            GetDlgItemText(hwndDlg, IDC_EDITTEXTFRAME, pItem->aCols[1], 1024);
 
823
            lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
 
824
            lvi.state = 0;
 
825
            lvi.stateMask = 0;
 
826
            lvi.pszText = LPSTR_TEXTCALLBACK;   /* app. maintains text */
 
827
            lvi.iImage = 0;
 
828
            lvi.iItem = editItemIndex;
 
829
            lvi.iSubItem = 0;
 
830
            lvi.lParam = (LPARAM)pItem;    /* item data */
 
831
 
 
832
            /* Add the item. */
 
833
            ListView_SetItem(m_hwndList, &lvi);
 
834
            ListView_Update(m_hwndList, editItemIndex);
 
835
        } /* Fall through */
 
836
        case IDCANCEL:
 
837
            EndDialog(hwndDlg, wParam);
 
838
            return TRUE;
 
839
        }
 
840
    }
 
841
    return FALSE;
 
842
}
 
843
 
 
844
 
 
845
/* Double clicking means editing a frame */
 
846
BOOL List_EditData(HWND hwndApp, HWND hwndList)
 
847
{
 
848
    LV_ITEM lvi;
 
849
    BOOL result;
 
850
 
 
851
    /* First get the selected item */
 
852
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
 
853
 
 
854
    m_hwndList = hwndList;
 
855
 
 
856
    if (index != -1)
 
857
    {
 
858
        lvi.mask = LVIF_PARAM;
 
859
        lvi.iItem = index;
 
860
        lvi.iSubItem = 0;
 
861
 
 
862
        if (ListView_GetItem(hwndList, &lvi) == TRUE)
 
863
        {
 
864
            pItem = (ID3ITEM*)lvi.lParam;
 
865
            editItemIndex = lvi.iItem;
 
866
 
 
867
            result = DialogBox(hInstance_for_id3editor, MAKEINTRESOURCE(IDD_EDITTEXTFRAME),
 
868
                hwndApp, EditTextFrameProc);
 
869
            if (LOWORD(result) == IDOK)
 
870
                return TRUE;
 
871
        }
 
872
    }
 
873
    return FALSE;
 
874
}
 
875
 
 
876
 
 
877
/* Delete the selected frame */
 
878
BOOL List_DeleteSelected(HWND hwndApp, HWND hwndList)
 
879
{
 
880
    int items;
 
881
 
 
882
    /* First get the selected item */
 
883
    int index = ListView_GetNextItem(hwndList, -1, LVNI_SELECTED);
 
884
 
 
885
    if (index != -1)
 
886
        ListView_DeleteItem(hwndList, index);
 
887
 
 
888
    items = ListView_GetItemCount(hwndList);
 
889
    if (index != -1) return TRUE;
 
890
    else return FALSE;
 
891
}
 
892
 
 
893
 
 
894
/* Save the ID3 to the file */
 
895
void List_SaveID3(HWND hwndApp, HWND hwndList, char *filename)
 
896
{
 
897
    LV_ITEM lvi;
 
898
    ID3ITEM *pItem1;
 
899
    int i, items;
 
900
    ID3Tag *tag;
 
901
    ID3Frame *frame;
 
902
    ID3Field *field;
 
903
    
 
904
    /* Strip the tag first, before completely rewriting it */
 
905
    if ((tag = ID3Tag_New()) != NULL)
 
906
    {
 
907
        ID3Tag_Link(tag, filename);
 
908
        ID3Tag_Strip(tag, ID3TT_ALL);
 
909
        ID3Tag_Clear(tag);
 
910
 
 
911
        if (SendMessage(GetDlgItem(hwndApp, IDC_ID3V2TAG), BM_GETCHECK, 0, 0) == BST_UNCHECKED)
 
912
        {
 
913
            /* No frames saved */
 
914
            ID3Tag_Delete(tag);
 
915
            EnableWindow(GetDlgItem(hwndApp, IDC_ID3V2TAG), FALSE);
 
916
            ListView_DeleteAllItems(hwndList);
 
917
            return;
 
918
        }
 
919
 
 
920
        /* First get the number of items */
 
921
        items = ListView_GetItemCount(hwndList);
 
922
 
 
923
        if (items > 0)
 
924
        {
 
925
            for (i = 0; i < items; i++)
 
926
            {
 
927
                lvi.mask = LVIF_PARAM;
 
928
                lvi.iItem = i;
 
929
                lvi.iSubItem = 0;
 
930
 
 
931
                if (ListView_GetItem(hwndList, &lvi) == TRUE)
 
932
                {
 
933
                    pItem1 = (ID3ITEM*)lvi.lParam;
 
934
 
 
935
                    frame = ID3Frame_NewID(pItem1->frameId);
 
936
 
 
937
                    switch (pItem1->frameId)
 
938
                    {
 
939
                    case ID3FID_ALBUM:            case ID3FID_BPM:
 
940
                    case ID3FID_COMPOSER:         case ID3FID_CONTENTTYPE:
 
941
                    case ID3FID_COPYRIGHT:        case ID3FID_DATE:
 
942
                    case ID3FID_PLAYLISTDELAY:    case ID3FID_ENCODEDBY:
 
943
                    case ID3FID_LYRICIST:         case ID3FID_FILETYPE:
 
944
                    case ID3FID_TIME:             case ID3FID_CONTENTGROUP:
 
945
                    case ID3FID_TITLE:            case ID3FID_SUBTITLE:
 
946
                    case ID3FID_INITIALKEY:       case ID3FID_LANGUAGE:
 
947
                    case ID3FID_SONGLEN:          case ID3FID_MEDIATYPE:
 
948
                    case ID3FID_ORIGALBUM:        case ID3FID_ORIGFILENAME:
 
949
                    case ID3FID_ORIGLYRICIST:     case ID3FID_ORIGARTIST:
 
950
                    case ID3FID_ORIGYEAR:         case ID3FID_FILEOWNER:
 
951
                    case ID3FID_LEADARTIST:       case ID3FID_BAND:
 
952
                    case ID3FID_CONDUCTOR:        case ID3FID_MIXARTIST:
 
953
                    case ID3FID_PARTINSET:        case ID3FID_PUBLISHER:
 
954
                    case ID3FID_TRACKNUM:         case ID3FID_RECORDINGDATES:
 
955
                    case ID3FID_NETRADIOSTATION:  case ID3FID_NETRADIOOWNER:
 
956
                    case ID3FID_SIZE:             case ID3FID_ISRC:
 
957
                    case ID3FID_ENCODERSETTINGS:  case ID3FID_YEAR:
 
958
                    {
 
959
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
960
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
 
961
                        ID3Tag_AddFrame(tag, frame);
 
962
                        break;
 
963
                    }
 
964
                    case ID3FID_USERTEXT:
 
965
                    case ID3FID_COMMENT: /* Can also contain an extra language field (but not used now) */
 
966
                    case ID3FID_UNSYNCEDLYRICS: /* Can also contain an extra language field (but not used now) */
 
967
                    {
 
968
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
 
969
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
 
970
                        field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
971
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
 
972
                        ID3Tag_AddFrame(tag, frame);
 
973
                        break;
 
974
                    }
 
975
                    case ID3FID_WWWAUDIOFILE:     case ID3FID_WWWARTIST:
 
976
                    case ID3FID_WWWAUDIOSOURCE:   case ID3FID_WWWCOMMERCIALINFO:
 
977
                    case ID3FID_WWWCOPYRIGHT:     case ID3FID_WWWPUBLISHER:
 
978
                    case ID3FID_WWWPAYMENT:       case ID3FID_WWWRADIOPAGE:
 
979
                    {
 
980
                        field = ID3Frame_GetField(frame, ID3FN_URL);
 
981
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
 
982
                        ID3Tag_AddFrame(tag, frame);
 
983
                        break;
 
984
                    }
 
985
                    case ID3FID_WWWUSER:
 
986
                    {
 
987
                        field = ID3Frame_GetField(frame, ID3FN_DESCRIPTION);
 
988
                        ID3Field_SetASCII(field, pItem1->aCols[0]);
 
989
                        field = ID3Frame_GetField(frame, ID3FN_URL);
 
990
                        ID3Field_SetASCII(field, pItem1->aCols[1]);
 
991
                        ID3Tag_AddFrame(tag, frame);
 
992
                        break;
 
993
                    }
 
994
                    default:
 
995
                        break;
 
996
                    }
 
997
                }
 
998
            }
 
999
            ID3Tag_UpdateByTagType(tag, ID3TT_ID3V2);
 
1000
        }
 
1001
 
 
1002
        ID3Tag_Delete(tag);
 
1003
    }
 
1004
}
 
1005
 
 
1006
/* Get the title from the file */
 
1007
void GetID3FileTitle(char *filename, char *title, char *format)
 
1008
{
 
1009
    ID3Tag *tag;
 
1010
    ID3Frame *frame;
 
1011
    ID3Field *field;
 
1012
    char buffer[255];
 
1013
    int some_info = 0;
 
1014
    char *in = format;
 
1015
    char *out = title;
 
1016
    char *bound = out + (MAX_PATH - 10 - 1);
 
1017
 
 
1018
 
 
1019
    if ((tag = ID3Tag_New()) != NULL)
 
1020
    {
 
1021
        ID3Tag_Link(tag, filename);
 
1022
 
 
1023
        while (*in && out < bound)
 
1024
        {
 
1025
            switch (*in) {
 
1026
            case '%':
 
1027
                ++in;
 
1028
                break;
 
1029
 
 
1030
            default:
 
1031
                *out++ = *in++;
 
1032
                continue;
 
1033
            }
 
1034
 
 
1035
            /* handle % escape sequence */
 
1036
            switch (*in++) {
 
1037
            case '0':
 
1038
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TRACKNUM)) != NULL) {
 
1039
                    int size;
 
1040
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1041
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1042
                    lstrcpy(out, buffer); out += size;
 
1043
                    some_info = 1;
 
1044
                }
 
1045
                break;
 
1046
            case '1':
 
1047
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_LEADARTIST)) != NULL) {
 
1048
                    int size;
 
1049
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1050
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1051
                    lstrcpy(out, buffer); out += size;
 
1052
                    some_info = 1;
 
1053
                }
 
1054
                break;
 
1055
            case '2':
 
1056
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_TITLE)) != NULL) {
 
1057
                    int size;
 
1058
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1059
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1060
                    lstrcpy(out, buffer); out += size;
 
1061
                    some_info = 1;
 
1062
                }
 
1063
                break;
 
1064
            case '3':
 
1065
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_ALBUM)) != NULL) {
 
1066
                    int size;
 
1067
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1068
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1069
                    lstrcpy(out, buffer); out += size;
 
1070
                    some_info = 1;
 
1071
                }
 
1072
                break;
 
1073
            case '4':
 
1074
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_YEAR)) != NULL) {
 
1075
                    int size;
 
1076
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1077
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1078
                    lstrcpy(out, buffer); out += size;
 
1079
                    some_info = 1;
 
1080
                }
 
1081
                break;
 
1082
            case '5':
 
1083
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_COMMENT)) != NULL) {
 
1084
                    int size;
 
1085
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1086
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1087
                    lstrcpy(out, buffer); out += size;
 
1088
                    some_info = 1;
 
1089
                }
 
1090
                break;
 
1091
            case '6':
 
1092
                if ((frame = ID3Tag_FindFrameWithID(tag, ID3FID_CONTENTTYPE)) != NULL) {
 
1093
                    int size; char *tmp;
 
1094
                    field = ID3Frame_GetField(frame, ID3FN_TEXT);
 
1095
                    size = ID3Field_GetASCII(field, buffer, 255, 1);
 
1096
                    tmp = GetGenre(buffer);
 
1097
                    lstrcpy(out, tmp); out += size;
 
1098
                    some_info = 1;
 
1099
                }
 
1100
                break;
 
1101
            case '7':
 
1102
            {
 
1103
                char *p=filename+lstrlen(filename);
 
1104
                int len = 0;
 
1105
                while (*p != '\\' && p >= filename) { p--; len++; }
 
1106
                lstrcpy(out, ++p); out += len;
 
1107
                some_info = 1;
 
1108
                break;
 
1109
            }
 
1110
            }
 
1111
        }
 
1112
 
 
1113
        *out = '\0';
 
1114
        ID3Tag_Delete(tag);
 
1115
    }
 
1116
 
 
1117
    if (!some_info)
 
1118
    {
 
1119
        char *p=filename+lstrlen(filename);
 
1120
        while (*p != '\\' && p >= filename) p--;
 
1121
        lstrcpy(title,++p);
 
1122
    }
 
1123
}
 
1124