123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071 |
- #include "main.h"
- #include "Metadata.h"
- #include "../Winamp/wa_ipc.h"
- // ID3v2 stuff
- #include "../id3v2/id3_tag.h"
- #include "FactoryHelper.h"
- #include "id3.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoChar.h"
- #include "AACFrame.h"
- #include "LAMEinfo.h"
- #include <shlwapi.h>
- #include "../nu/ns_wc.h"
- #include "../nu/ListView.h"
- #include "resource.h"
- #include "Stopper.h"
- #include "config.h"
- #include <strsafe.h>
- // TODO: benski> CUT!!!
- char g_stream_title[256] = {0};
- int fixAACCBRbitrate(int br)
- {
- static short brs[] =
- {
- 8, 12, 16, 20, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0
- };
- int x;
- for (x = 0; x < sizeof(brs) / sizeof(brs[0]); x ++)
- {
- int delta = (brs[x] * 8) / 128;
- if (delta < 2) delta = 2;
- if (br < brs[x] - delta) break;
- if (br < brs[x] + delta) return brs[x];
- }
- return br;
- }
- void ConvertTryUTF8(const char *in, wchar_t *out, size_t outlen)
- {
- out[0]=0;
- int x = MultiByteToWideCharSZ(CP_UTF8, MB_ERR_INVALID_CHARS, in, -1, out, (int)outlen);
- if (!x)
- {
- if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
- MultiByteToWideCharSZ(CP_ACP, 0, in, -1, out, (int)outlen);
- else
- MultiByteToWideCharSZ(CP_UTF8, 0, in, -1, out, (int)outlen);
- }
- }
- void getfileinfo(const wchar_t *filename, wchar_t *title, int *length_in_ms)
- {
- const wchar_t *fn;
- if (length_in_ms) *length_in_ms = -1000;
- if (filename && filename[0])
- fn = filename;
- else
- fn = lastfn;
- if (!_wcsnicmp(fn, L"file://", 7)) fn += 7;
- if (PathIsURL(fn))
- {
- if (title)
- {
- if (fn != filename || !_wcsicmp(fn, lastfn))
- {
- EnterCriticalSection(&g_lfnscs);
- if (lastfn_status[0])
- {
- char buf[4096] = {0};
- StringCchPrintfA(buf, 4096, "[%s] %s", lastfn_status, lastfn_data_ready ? g_stream_title : (char *)AutoChar(fn));
- ConvertTryUTF8(buf, title, 256);
- }
- else
- {
- if (!lastfn_data_ready)
- lstrcpynW(title, fn, 256);
- else
- {
- ConvertTryUTF8(g_stream_title, title, 256);
- }
- }
- LeaveCriticalSection(&g_lfnscs);
- if (length_in_ms) *length_in_ms = getlength();
- }
- else
- {
- lstrcpynW(title, fn, 256);
- }
- }
- return ;
- }
- else
- {
- Metadata info;
- if (info.Open(fn) == METADATA_SUCCESS)
- {
- if (title)
- {
- wchar_t mp3artist[256] = L"", mp3title[256] = L"";
- info.GetExtendedData("artist", mp3artist, 256);
- info.GetExtendedData("title", mp3title, 256);
- if (mp3artist[0] && mp3title[0])
- StringCchPrintfW(title, 256, L"%s - %s", mp3artist, mp3title);
- else if (mp3title[0])
- lstrcpynW(title, mp3title, 256);
- else
- {
- lstrcpynW(title, fn, MAX_PATH);
- PathStripPathW(title);
- PathRemoveExtensionW(title);
- }
- }
- if (fn == filename)
- {
- wchar_t ln[128]=L"";
- info.GetExtendedData("length", ln, 128);
- *length_in_ms = _wtoi(ln);
- }
- else
- *length_in_ms = getlength();
- }
- else if (fn != filename)
- *length_in_ms = getlength();
- }
- }
- int id3Dlg(const wchar_t *fn, HWND hwnd)
- {
- return 1;
- }
- extern const wchar_t *id3v1_genres[];
- extern size_t numGenres;
- static int our_change=0;
- #define GetMeta(hwnd) (Metadata *)GetPropW(GetParent(hwnd),L"mp3info")
- #define SetMeta(hwnd,meta) SetPropW(GetParent(hwnd),L"mp3info",(HANDLE)meta)
- static INT_PTR CALLBACK id3v1_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static int my_change_v1=0;
- static const int ctrls[] =
- {
- IDC_ID3V11_TRACK,
- IDC_ID3_TITLE,
- IDC_ID3_ARTIST,
- IDC_ID3_ALBUM,
- IDC_ID3_YEAR,
- IDC_ID3_COMMENT,
- IDC_ID3_GENRE,
- };
- static const int strs_lim[] =
- {
- 3,
- 30,
- 30,
- 30,
- 4,
- 28,
- 1,
- };
- static const char * strs[] =
- {
- "track",
- "title",
- "artist",
- "album",
- "year",
- "comment",
- "genre",
- };
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- meta->AddRef();
- else
- {
- meta = new Metadata();
- meta->Open((wchar_t*)lParam);
- SetMeta(hwndDlg,meta);
- }
- wchar_t genre_buf[32] = {0};
- meta->id3v1.GetString("genre",genre_buf,32);
- our_change=1;
- SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_RESETCONTENT, 0, 0);
- SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_SETCURSEL, -1, 0);
- for (size_t x = 0; x != numGenres; x ++)
- {
- int y = (int)SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_ADDSTRING, 0, (LPARAM)id3v1_genres[x]);
- SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_SETITEMDATA, y, x);
- if (_wcsicmp(genre_buf,id3v1_genres[x])==0)
- SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_SETCURSEL, y, 0);
- }
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- // make sure the edit boxes are limited to id3v1 spec sizes (trickier on number type fields)
- wchar_t buf[32] = {0};
- SendDlgItemMessage(hwndDlg,ctrls[i],EM_SETLIMITTEXT,strs_lim[i],0);
- meta->id3v1.GetString(strs[i],buf,32);
- SetDlgItemTextW(hwndDlg,ctrls[i],buf);
- }
- if (meta->id3v1.HasData())
- {
- CheckDlgButton(hwndDlg,IDC_ID3V1,TRUE);
- if (!config_write_id3v1)
- { // if we have id3v1 writing turned off, disable controls
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),FALSE);
- }
- }
- else
- { // no id3v1 tag present
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),FALSE);
- if (!config_create_id3v1)
- { // don't allow one to be created if the settings disallow
- EnableWindow(GetDlgItem(hwndDlg,IDC_ID3V1),FALSE);
- }
- }
- our_change=0;
- }
- break;
- case WM_USER:
- if (wParam && lParam && !our_change && !my_change_v1)
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- if (!config_write_id3v1)
- break;
- if (!config_create_id3v1 && !meta->id3v1.HasData())
- break;
-
- wchar_t *key = (wchar_t*)wParam;
- wchar_t *value = (wchar_t*)lParam;
- AutoChar keyA(key);
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- if (_stricmp(keyA,strs[i])==0)
- {
- // benski> i don't think this is what we want? meta->SetExtendedData(strs[i],value);
- meta->id3v1.SetString(strs[i], value);
- wchar_t buf[2048]=L"";
- meta->id3v1.GetString(strs[i],buf,2048);
- if (!IsDlgButtonChecked(hwndDlg,IDC_ID3V1))
- {
- // re-enable stuff
- CheckDlgButton(hwndDlg,IDC_ID3V1,TRUE);
- for (int j=0; j<sizeof(ctrls)/sizeof(int); j++)
- {
- EnableWindow(GetDlgItem(hwndDlg,ctrls[j]),TRUE);
- my_change_v1++;
- SetDlgItemTextW(hwndDlg,ctrls[j],L"");
- my_change_v1--;
- }
- }
- my_change_v1++;
- if (ctrls[i] == IDC_ID3_GENRE)
- {
- int n = (int)SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
- SendDlgItemMessage(hwndDlg, IDC_ID3_GENRE, CB_SETCURSEL, n, 0);
- }
- else
- SetDlgItemTextW(hwndDlg,ctrls[i],buf);
- my_change_v1--;
- break;
- }
- }
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDOK:
- {
- // this should be done by one pane ONLY. Doesn't matter which one.
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
-
- Stopper stopper;
- if (!_wcsicmp(lastfn, meta->filename))
- stopper.Stop();
- int ret = meta->Save();
- stopper.Play();
- wchar_t boxtitle[256] = {0};
- switch(ret)
- {
- case SAVE_SUCCESS:
- {
- // cheap way to trigger a metadata reset in a thread-safe manner
- wchar_t d[10] = {0};
- extendedFileInfoStructW reset_info = {0};
- reset_info.filename=L".mp3";
- reset_info.metadata=L"artist";
- reset_info.ret = d;
- reset_info.retlen=10;
- SendMessage(mod.hMainWindow, WM_WA_IPC, (WPARAM)&reset_info, IPC_GET_EXTENDED_FILE_INFOW);
- }
- break;
- case SAVE_ERROR_READONLY:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_READONLY),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- case SAVE_ERROR_OPENING_FILE:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_OPENING_FILE),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- case SAVE_APEV2_WRITE_ERROR:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_APEV2),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- case SAVE_LYRICS3_WRITE_ERROR:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_LYRICS3),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- case SAVE_ID3V1_WRITE_ERROR:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_ID3V1),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- case SAVE_ID3V2_WRITE_ERROR:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_ID3V2),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- default:
- MessageBox(hwndDlg,
- WASABI_API_LNGSTRINGW(IDS_METADATA_ERROR_UNSPECIFIED),
- WASABI_API_LNGSTRINGW_BUF(IDS_ERROR_SAVING_METADATA, boxtitle, 256),
- MB_OK);
- break;
- }
- }
- break;
- case IDC_ID3V1_TO_V2:
- {
- my_change_v1=1;
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- {
- wchar_t buf[2048]=L"";
- GetDlgItemTextW(hwndDlg,ctrls[i],buf,2048);
- meta->id3v2.SetString(strs[i],buf);
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- my_change_v1=0;
- }
- break;
- case IDC_ID3V1:
- {
- our_change=1;
- BOOL checked = IsDlgButtonChecked(hwndDlg,IDC_ID3V1);
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- if (!checked)
- meta->id3v1.Clear();
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- {
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),checked);
- wchar_t buf[2048]=L"";
- if (checked)
- {
- GetDlgItemText(hwndDlg,ctrls[i],buf,2048);
- if (buf[0])
- meta->id3v1.SetString(strs[i],buf);
- }
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- our_change=0;
- }
- break;
- default:
- if (!our_change && !my_change_v1 && (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == CBN_SELCHANGE))
- {
- our_change=1;
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- if (LOWORD(wParam) == ctrls[i])
- {
- wchar_t buf[2048]=L"";
- if (HIWORD(wParam) == EN_CHANGE)
- GetDlgItemTextW(hwndDlg,ctrls[i],buf,2048);
- else
- {
- LRESULT n = SendDlgItemMessage(hwndDlg, ctrls[i], CB_GETCURSEL, 0, 0);
- n = SendDlgItemMessage(hwndDlg, ctrls[i], CB_GETITEMDATA, n, 0);
- if (n>=0 && n<(LRESULT)numGenres)
- lstrcpyn(buf,id3v1_genres[n],2048);
- }
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- meta->id3v1.SetString(strs[i],buf);
- if (!meta->id3v2.HasData())
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- }
- our_change=0;
- }
- }
- break;
- case WM_DESTROY:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta) meta->Release();
- }
- break;
- }
- return 0;
- }
- static INT_PTR CALLBACK id3v2_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static int my_change_v2=0;
- static const int ctrls[] =
- {
- IDC_ID3V2_TRACK,
- IDC_ID3V2_TITLE,
- IDC_ID3V2_ARTIST,
- IDC_ID3V2_ALBUM,
- IDC_ID3V2_YEAR,
- IDC_ID3V2_COMMENT,
- IDC_ID3V2_GENRE,
- IDC_ID3V2_COMPOSER,
- IDC_ID3V2_PUBLISHER,
- IDC_ID3V2_MARTIST,
- IDC_ID3V2_RECORD,
- IDC_ID3V2_URL,
- IDC_ID3V2_ENCODER,
- IDC_ID3V2_ALBUM_ARTIST,
- IDC_ID3V2_DISC,
- IDC_TRACK_GAIN,
- IDC_ALBUM_GAIN,
- IDC_ID3V2_BPM,
- };
- static const char * strs[] =
- {
- "track",
- "title",
- "artist",
- "album",
- "year",
- "comment",
- "genre",
- "composer",
- "publisher",
- "originalartist",
- "copyright",
- "url",
- "tool",
- "albumartist",
- "disc",
- "replaygain_track_gain", // 15
- "replaygain_album_gain", // 16
- "bpm",
- };
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- our_change=1;
- SendDlgItemMessage(hwndDlg, IDC_ID3V2_GENRE, CB_RESETCONTENT, 0, 0);
- for (size_t x = 0; x != numGenres; x ++)
- {
- int y = (int)SendDlgItemMessage(hwndDlg, IDC_ID3V2_GENRE, CB_ADDSTRING, 0, (LPARAM)id3v1_genres[x]);
- SendDlgItemMessage(hwndDlg, IDC_ID3V2_GENRE, CB_SETITEMDATA, y, x);
- }
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- meta->AddRef();
- else
- {
- meta = new Metadata();
- meta->Open((wchar_t*)lParam);
- SetMeta(hwndDlg,meta);
- }
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- wchar_t buf[32768] = {0};
- meta->id3v2.GetString(strs[i],buf,32768);
- if((i == 15 || i == 16) && buf[0])
- {
- SetDlgItemTextW(hwndDlg,ctrls[i],L"buf");
- // this isn't nice but it localises the RG values
- // for display as they're saved in the "C" locale
- double value = _wtof_l(buf,WASABI_API_LNG->Get_C_NumericLocale());
- StringCchPrintfW(buf,64,L"%-+.2f dB", value);
- }
- SetDlgItemTextW(hwndDlg,ctrls[i],buf);
- }
- if (meta->id3v2.HasData())
- CheckDlgButton(hwndDlg,IDC_ID3V2,TRUE);
- else
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),FALSE);
- our_change=0;
- }
- break;
- case WM_USER:
- if (wParam && lParam && !our_change && !my_change_v2)
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- wchar_t *key = (wchar_t*)wParam;
- wchar_t *value = (wchar_t*)lParam;
- AutoChar keyA(key);
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- if (_stricmp(keyA,strs[i])==0)
- {
- // benski> cut? i don't think this is what we want: meta->SetExtendedData(strs[i],value);
- meta->id3v2.SetString(strs[i], value);
- wchar_t buf[32768]=L"";
- meta->id3v2.GetString(strs[i],buf,32768);
- if (!IsDlgButtonChecked(hwndDlg,IDC_ID3V2))
- {
- // re-enable items
- CheckDlgButton(hwndDlg,IDC_ID3V2,TRUE);
- for (int j=0; j<sizeof(ctrls)/sizeof(int); j++)
- {
- EnableWindow(GetDlgItem(hwndDlg,ctrls[j]),TRUE);
- my_change_v2++;
- SetDlgItemTextW(hwndDlg,ctrls[j],L"");
- my_change_v2--;
- }
- }
- my_change_v2++;
- SetDlgItemTextW(hwndDlg,ctrls[i],buf);
- my_change_v2--;
- break;
- }
- }
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDC_ID3V2_TO_V1:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- my_change_v2=1;
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- {
- wchar_t buf[32768]=L"";
- GetDlgItemTextW(hwndDlg,ctrls[i],buf,32768);
- meta->id3v1.SetString(strs[i],buf);
- meta->GetExtendedData(strs[i], buf, 32768);
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- my_change_v2=0;
- }
- break;
- case IDC_ID3V2:
- {
- our_change=1;
- BOOL checked = IsDlgButtonChecked(hwndDlg,IDC_ID3V2);
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- if (!checked)
- meta->id3v2.Clear();
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- {
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),checked);
- wchar_t buf[32768]=L"";
- if (checked)
- {
- GetDlgItemText(hwndDlg,ctrls[i],buf,32768);
- if (buf[0])
- meta->id3v2.SetString(strs[i],buf);
- }
- meta->GetExtendedData(strs[i],buf,32768);
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- our_change=0;
- }
- break;
- case IDOK:
- {
- extern Metadata *m_ext_get_mp3info;
- if (m_ext_get_mp3info)
- m_ext_get_mp3info->Release();
- m_ext_get_mp3info=0;
- }
- break;
- default:
- if (!our_change && !my_change_v2 && (HIWORD(wParam) == EN_CHANGE || HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE || HIWORD(wParam) == CBN_EDITUPDATE))
- {
- our_change=1;
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- if (LOWORD(wParam) == ctrls[i])
- {
- wchar_t buf[32768] = {0};
- if (HIWORD(wParam) == EN_CHANGE)
- GetDlgItemTextW(hwndDlg,ctrls[i],buf,32768);
- else
- {
- LRESULT n = SendMessage(GetDlgItem(hwndDlg, ctrls[i]), CB_GETCURSEL, 0, 0);
- n = SendMessage(GetDlgItem(hwndDlg, ctrls[i]), CB_GETITEMDATA, n, 0);
- if (n>=0 && n<(LRESULT)numGenres)
- lstrcpyn(buf,id3v1_genres[n],32768);
- else{
- GetDlgItemTextW(hwndDlg,ctrls[i],buf,32768);
- }
- }
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- meta->id3v2.SetString(strs[i],buf);
- meta->GetExtendedData(strs[i],buf,32768);
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- }
- }
- our_change=0;
- }
- }
- break;
- case WM_DESTROY:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- meta->Release();
- }
- break;
- }
- return 0;
- }
- static INT_PTR CALLBACK lyrics3_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static const int ctrls[] =
- {
- IDC_LYRICS3_TITLE,
- IDC_LYRICS3_ARTIST,
- IDC_LYRICS3_ALBUM,
- };
- static const char * strs[] =
- {
- "title",
- "artist",
- "album",
- };
- switch (uMsg)
- {
- case WM_INITDIALOG:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- meta->AddRef();
- else
- {
- meta = new Metadata();
- meta->Open((wchar_t*)lParam);
- SetMeta(hwndDlg,meta);
- }
- for (int i=0; i<sizeof(strs)/sizeof(char*); i++)
- {
- wchar_t buf[2048] = {0};
- SendDlgItemMessage(hwndDlg,ctrls[i],EM_SETLIMITTEXT,250,0);
- meta->lyrics3.GetString(strs[i],buf,250);
- SetDlgItemTextW(hwndDlg,ctrls[i],buf);
- }
- if (meta->lyrics3.HasData())
- CheckDlgButton(hwndDlg,IDC_LYRICS3,TRUE);
- }
- break;
- case WM_COMMAND:
- switch (LOWORD(wParam))
- {
- case IDC_LYRICS3:
- {
- BOOL checked = IsDlgButtonChecked(hwndDlg,IDC_LYRICS3);
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- if (!checked)
- meta->lyrics3.Clear();
- else // clear the dirty state if re-enabled so we don't lose the lyrics3 tag
- meta->lyrics3.ResetDirty();
- for (int i=0; i<sizeof(ctrls)/sizeof(int); i++)
- {
- EnableWindow(GetDlgItem(hwndDlg,ctrls[i]),checked);
- wchar_t buf[2048]=L"";
- if (checked)
- {
- GetDlgItemText(hwndDlg,ctrls[i],buf,2048);
- if (buf[0])
- meta->lyrics3.SetString(strs[i],buf);
- }
- meta->GetExtendedData(strs[i],buf,2048);
- // if we don't flag this then we can lose info in the id3v1 and v2 tags which is definitely bad
- our_change++;
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)(wchar_t*)AutoWide(strs[i]),(LPARAM)buf);
- our_change--;
- }
- }
- break;
- }
- break;
- case WM_DESTROY:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta) meta->Release();
- }
- break;
- }
- return 0;
- }
- /* ================
- APEv2 Editor Tab
- ================ */
- static INT_PTR CALLBACK apev2_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
- {
- static W_ListView listview;
- static int my_change_ape=0;
- switch (uMsg)
- {
- case WM_NOTIFYFORMAT:
- return NFR_UNICODE;
- case WM_INITDIALOG:
- {
- our_change++;
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- {
- meta->AddRef();
- }
- else
- {
- meta = new Metadata();
- meta->Open((wchar_t*)lParam);
- SetMeta(hwndDlg,meta);
- }
- if (meta->apev2.HasData())
- CheckDlgButton(hwndDlg,IDC_APEV2,TRUE);
- listview.setwnd(GetDlgItem(hwndDlg, IDC_APE_LIST));
- listview.SetDoubleBuffered(true);
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_NAME), 82);
- listview.AddCol(WASABI_API_LNGSTRINGW(IDS_VALUE), 160);
- listview.SetVirtualCount((int)meta->apev2.GetNumItems());
- listview.AutoSizeColumn(0);
- listview.AutoSizeColumn(1);
- SetDlgItemTextW(hwndDlg,IDC_APE_KEY,L"");
- SetDlgItemTextW(hwndDlg,IDC_APE_VALUE,L"");
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_KEY),FALSE);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_VALUE),FALSE);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_DELETE),FALSE);
- our_change--;
- return 1;
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wParam))
- {
- case IDC_APE_KEY:
- case IDC_APE_VALUE:
- if(HIWORD(wParam) == EN_CHANGE)
- {
- int selected = listview.GetNextSelected();
- if (selected != LB_ERR)
- {
- listview.RefreshItem(selected);
- }
- }
- else if(HIWORD(wParam) == EN_KILLFOCUS)
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- my_change_ape++;
- char key[1024] = {0};
- wchar_t value[32768] = {0};
- GetDlgItemTextA(hwndDlg, IDC_APE_KEY, key, 1024);
- GetDlgItemText(hwndDlg, IDC_APE_VALUE, value, 32768);
- int selected = listview.GetNextSelected();
- if (selected != LB_ERR)
- {
- meta->apev2.SetKeyValueByIndex(selected, key, value);
- }
- const wchar_t *winamp_key = APE::MapApeKeyToWinampKeyW(key);
- if (winamp_key)
- {
- our_change++;
- SendMessage(GetParent(hwndDlg),WM_USER,(WPARAM)winamp_key,(WPARAM)value);
- our_change--;
- }
- my_change_ape--;
- }
- break;
- case IDC_APEV2:
- {
- BOOL checked = IsDlgButtonChecked(hwndDlg,IDC_APEV2);
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- if (!checked)
- meta->apev2.MarkClear();
- else // clear the dirty state if re-enabled so we don't lose the apev2 tag
- meta->apev2.ResetDirty();
- }
- break;
- case IDC_DELETE_ALL:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- my_change_ape++;
- listview.UnselectAll();
- meta->apev2.Clear();
- listview.SetVirtualCount((int)meta->apev2.GetNumItems());
- my_change_ape--;
- }
- break;
- case IDC_APE_ADD:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- int index = listview.GetCount();
- if (meta->apev2.AddItem() == APEv2::APEV2_SUCCESS)
- {
- listview.SetVirtualCount((int)meta->apev2.GetNumItems());
- listview.SetSelected(index);
- listview.ScrollTo(index);
- SetFocus(GetDlgItem(hwndDlg, IDC_APE_KEY));
- }
- }
- break;
- case IDC_APE_DELETE:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (!meta) break;
- int selected = listview.GetNextSelected();
- if (selected != LB_ERR)
- {
- listview.UnselectAll();
- meta->apev2.RemoveItem(selected);
- listview.SetVirtualCount((int)meta->apev2.GetNumItems());
- }
- }
- break;
- }
- break;
- case WM_NOTIFY:
- {
- LPNMHDR l=(LPNMHDR)lParam;
- if (l->idFrom==IDC_APE_LIST) switch (l->code)
- {
- case LVN_GETDISPINFO:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- {
- NMLVDISPINFO *lpdi = (NMLVDISPINFO*) l;
- if (lpdi->item.mask & LVIF_TEXT)
- {
- int selected = listview.GetNextSelected();
- switch (lpdi->item.iSubItem)
- {
- case 0:
- {
- if (lpdi->item.iItem == selected)
- {
- GetDlgItemText(hwndDlg, IDC_APE_KEY, lpdi->item.pszText, lpdi->item.cchTextMax);
- }
- else
- {
- const char *key=0;
- meta->apev2.EnumValue(lpdi->item.iItem, &key, 0, 0);
- MultiByteToWideCharSZ(CP_ACP, 0, key?key:"", -1, lpdi->item.pszText, lpdi->item.cchTextMax);
- }
- }
- return 0;
- case 1:
- {
- if (lpdi->item.iItem == selected)
- {
- GetDlgItemText(hwndDlg, IDC_APE_VALUE, lpdi->item.pszText, lpdi->item.cchTextMax);
- }
- else
- {
- const char *key=0;
- meta->apev2.EnumValue(lpdi->item.iItem, &key, lpdi->item.pszText, lpdi->item.cchTextMax);
- }
- }
- return 0;
- }
- }
- }
- }
- break;
- case LVN_KEYDOWN:
- break;
- case LVN_ITEMCHANGED:
- {
- my_change_ape++;
- LPNMLISTVIEW lv=(LPNMLISTVIEW)lParam;
- if (lv->uNewState & LVIS_SELECTED)
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- {
- const char *key=0;
- wchar_t value[32768] = {0};
- meta->apev2.EnumValue(lv->iItem, &key, value, 32768);
- SetDlgItemTextA(hwndDlg,IDC_APE_KEY,key);
- SetDlgItemText(hwndDlg,IDC_APE_VALUE,value);
- BOOL editable = meta->apev2.IsItemReadOnly(lv->iItem)?FALSE:TRUE;
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_KEY),editable);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_VALUE),editable);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_DELETE),TRUE);
- listview.RefreshItem(lv->iItem);
- }
- }
- if (lv->uOldState & LVIS_SELECTED)
- {
- SetDlgItemTextW(hwndDlg,IDC_APE_KEY,L"");
- SetDlgItemTextW(hwndDlg,IDC_APE_VALUE,L"");
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_KEY),FALSE);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_VALUE),FALSE);
- EnableWindow(GetDlgItem(hwndDlg,IDC_APE_DELETE),FALSE);
- }
- my_change_ape--;
- }
- }
- }
- break;
- case WM_USER:
- if (wParam && lParam && !our_change && !my_change_ape)
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta)
- {
- const wchar_t *keyW = (const wchar_t *)wParam;
- const wchar_t *value = (const wchar_t *)lParam;
- AutoChar key(keyW);
- my_change_ape++;
- meta->apev2.SetString(key, value);
- listview.UnselectAll();
- listview.SetVirtualCount((int)meta->apev2.GetNumItems());
- listview.RefreshAll();
- my_change_ape--;
- }
- }
- break;
- case WM_DESTROY:
- {
- Metadata *meta = GetMeta(hwndDlg);
- if (meta) meta->Release();
- }
- break;
- }
- return 0;
- }
- extern "C"
- {
- // return 1 if you want winamp to show it's own file info dialogue, 0 if you want to show your own (via In_Module.InfoBox)
- // if returning 1, remember to implement winampGetExtendedFileInfo("formatinformation")!
- __declspec(dllexport) int winampUseUnifiedFileInfoDlg(const wchar_t * fn)
- {
- if (!_wcsnicmp(fn, L"file://", 7)) fn += 7;
- if (PathIsURLW(fn)) return 2;
- return 1;
- }
- // should return a child window of 513x271 pixels (341x164 in msvc dlg units), or return NULL for no tab.
- // Fill in name (a buffer of namelen characters), this is the title of the tab (defaults to "Advanced").
- // filename will be valid for the life of your window. n is the tab number. This function will first be
- // called with n == 0, then n == 1 and so on until you return NULL (so you can add as many tabs as you like).
- // The window you return will recieve WM_COMMAND, IDOK/IDCANCEL messages when the user clicks OK or Cancel.
- // when the user edits a field which is duplicated in another pane, do a SendMessage(GetParent(hwnd),WM_USER,(WPARAM)L"fieldname",(LPARAM)L"newvalue");
- // this will be broadcast to all panes (including yours) as a WM_USER.
- __declspec(dllexport) HWND winampAddUnifiedFileInfoPane(int n, const wchar_t * filename, HWND parent, wchar_t *name, size_t namelen)
- {
- if (n == 0)
- {
- SetPropW(parent,L"INBUILT_NOWRITEINFO", (HANDLE)1);
- lstrcpyn(name,L"ID3v1", (int)namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO_ID3V1, parent, id3v1_dlgproc, (LPARAM)filename);
- }
- if (n == 1)
- {
- lstrcpyn(name,L"ID3v2", (int)namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO_ID3V2, parent, id3v2_dlgproc, (LPARAM)filename);
- }
- if (n == 2)
- {
- Metadata *meta = (Metadata *)GetPropW(parent, L"mp3info");
- if (meta->lyrics3.HasData())
- {
- lstrcpyn(name,L"Lyrics3", (int)namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO_LYRICS3, parent, lyrics3_dlgproc, (LPARAM)filename);
- }
- else if (meta->apev2.HasData())
- {
- lstrcpyn(name,L"APEv2", (int)namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO_APEV2, parent, apev2_dlgproc, (LPARAM)filename);
- }
- }
- if (n == 3)
- {
- Metadata *meta = (Metadata *)GetPropW(parent, L"mp3info");
- if (meta->lyrics3.HasData() && meta->apev2.HasData())
- {
- lstrcpyn(name,L"APEv2", (int)namelen);
- return WASABI_API_CREATEDIALOGPARAMW(IDD_INFO_APEV2, parent, apev2_dlgproc, (LPARAM)filename);
- }
- }
- return NULL;
- }
- }
|