diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_local/ReIndexUI.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_local/ReIndexUI.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_local/ReIndexUI.cpp | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_local/ReIndexUI.cpp b/Src/Plugins/Library/ml_local/ReIndexUI.cpp new file mode 100644 index 00000000..83e0c968 --- /dev/null +++ b/Src/Plugins/Library/ml_local/ReIndexUI.cpp @@ -0,0 +1,333 @@ +#include "Main.h" +#include "ml_local.h" +#include "resource.h" + +static INT_PTR CALLBACK CompactWndProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_INITDIALOG: + { + SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam); + SendDlgItemMessage(hwndDlg, IDC_PROGRESS1, PBM_SETRANGE, 0, MAKELPARAM(0, 400)); + SendDlgItemMessage(hwndDlg, IDC_PROGRESS1, PBM_SETPOS, 0, 0); + + int *progress = (int *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (progress[1] == -102) + { + progress[1] = -101; + SetWindowTextW(hwndDlg, WASABI_API_LNGSTRINGW(IDS_REFRESH_FILESIZE_DATEADDED)); + } + + SetTimer(hwndDlg, 666, 500, 0); + break; + } + case WM_TIMER: + if (wParam == 666) + { + int *progress = (int *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); + if (progress[0] == 666) + { + KillTimer(hwndDlg, 666); + EndDialog(hwndDlg, 0); + } + else if (progress[1] != -101) + { + SendDlgItemMessage(hwndDlg, IDC_PROGRESS1, PBM_SETPOS, progress[1] + 300, 0); + } + else + { + SendDlgItemMessage(hwndDlg, IDC_PROGRESS1, PBM_SETPOS, progress[0] + 100, 0); + } + } + break; + } + return 0; +} + +static DWORD CALLBACK CompactThread(LPVOID param) +{ + WASABI_API_DIALOGBOXPARAMW(IDD_REINDEX, NULL, CompactWndProc, (LPARAM)param); + return 0; +} + +static int sortFunc(const void *a, const void *b) +{ + const wchar_t **fn1 = (const wchar_t **)a; + const wchar_t **fn2 = (const wchar_t **)b; + return _wcsicmp(*fn1, *fn2); +} + +void RetypeFilename(nde_table_t table) +{ + int totalRecords = NDE_Table_GetRecordsCount(g_table); + if (totalRecords == 0) // bail out early so we don't flash a dialog + return; + + int progress[2] = {-100, -101}; + DWORD threadId = 0; + HANDLE compactThread = 0; + + nde_scanner_t pruneScanner = NDE_Table_CreateScanner(table); + if (pruneScanner) + { + bool first=true; + int recordNum = 0; + NDE_Scanner_First(pruneScanner); + while (!NDE_Scanner_EOF(pruneScanner)) + { + progress[0] = MulDiv(recordNum, 100, totalRecords)-100; + nde_field_t f = NDE_Scanner_GetFieldByID(pruneScanner, MAINTABLE_ID_FILENAME); + if (f && NDE_Field_GetType(f) == FIELD_STRING) + { + wchar_t *s = NDE_StringField_GetString(f); + ndestring_retain(s); + + NDE_Scanner_DeleteField(pruneScanner, f); + + nde_field_t new_f = NDE_Scanner_NewFieldByID(pruneScanner, MAINTABLE_ID_FILENAME); + NDE_StringField_SetString(new_f, s); + + ndestring_release(s); + NDE_Scanner_Post(pruneScanner); + } + else if (f) + { + first = false; // skips creating the thread + break; + } + + recordNum++; + NDE_Scanner_Next(pruneScanner); + if (first) + { + compactThread = CreateThread(0, 0, CompactThread, progress, 0, &threadId); + DumpArtCache(); // go ahead and dump the album art cache if we had to rebuild this table. ideally we could perform the same logic but this is easier and it's 1 in the morning and i don't feel like doing it :) + } + first=false; + } + + NDE_Table_DestroyScanner(table, pruneScanner); + if (compactThread) + NDE_Table_Sync(table); + } + progress[0] = 666; + if (compactThread) + { + WaitForSingleObject(compactThread, INFINITE); + CloseHandle(compactThread); + } +} + +void RefreshFileSizeAndDateAddedTable(nde_table_t table) +{ + int totalRecords = NDE_Table_GetRecordsCount(g_table); + if (totalRecords == 0) // bail out early so we don't flash a dialog + return; + + int progress[2] = {-100, -102}; + DWORD threadId = 0; + HANDLE compactThread = 0; + + nde_scanner_t scanner = NDE_Table_CreateScanner(table); + if (scanner) + { + bool first=true; + int recordNum = 0; + NDE_Scanner_First(scanner); + while (!NDE_Scanner_EOF(scanner)) + { + progress[0] = MulDiv(recordNum, 400, totalRecords); + + // converts filesize from a int and kb scaled value to the actual filesize as a int64 + nde_field_t f = NDE_Scanner_GetFieldByID(scanner, MAINTABLE_ID_FILESIZE); + if (f && NDE_Field_GetType(f) == FIELD_INTEGER) + { + __int64 size = NDE_IntegerField_GetValue(f); + if (size) size *= 1024; + + NDE_Scanner_DeleteField(scanner, f); + + nde_field_t new_f = NDE_Scanner_NewFieldByType(scanner, FIELD_INT64, MAINTABLE_ID_FILESIZE); + NDE_Int64Field_SetValue(new_f, size); + + NDE_Scanner_Post(scanner); + } + + // takes the lastupd value and applies it to dateadded so we've got something to use + f = NDE_Scanner_GetFieldByID(scanner, MAINTABLE_ID_LASTUPDTIME); + if (f && NDE_Field_GetType(f) == FIELD_DATETIME) + { + int lastupd = NDE_IntegerField_GetValue(f); + nde_field_t new_f = NDE_Scanner_NewFieldByID(scanner, MAINTABLE_ID_DATEADDED); + NDE_IntegerField_SetValue(new_f, lastupd); + + NDE_Scanner_Post(scanner); + } + + NDE_Scanner_Next(scanner); + recordNum++; + if (first) + { + compactThread = CreateThread(0, 0, CompactThread, progress, 0, &threadId); + } + first=false; + } + + NDE_Table_DestroyScanner(table, scanner); + if (compactThread) + NDE_Table_Sync(table); + } + progress[0] = 666; + if (compactThread) + { + WaitForSingleObject(compactThread, INFINITE); + CloseHandle(compactThread); + } +} + +void ReindexTable(nde_table_t table) +{ + int totalRecords = NDE_Table_GetRecordsCount(g_table); + if (totalRecords == 0) // bail out early so we don't flash a dialog + return; + + int progress[2] = {-100, -101}; + DWORD threadId; + HANDLE compactThread = CreateThread(0, 0, CompactThread, progress, 0, &threadId); + + nde_scanner_t pruneScanner = NDE_Table_CreateScanner(table); + if (pruneScanner) + { + int recordNum = 0; + NDE_Scanner_First(pruneScanner); + while (!NDE_Scanner_EOF(pruneScanner)) + { + int total = MulDiv(recordNum, 100, totalRecords); + progress[0] = total - 100; + #ifndef elementsof + #define elementsof(x) (sizeof(x)/sizeof(*x)) + #endif + unsigned char STR_IDS[] = {MAINTABLE_ID_TITLE, MAINTABLE_ID_ARTIST, MAINTABLE_ID_ALBUM, MAINTABLE_ID_GENRE, + MAINTABLE_ID_COMMENT, MAINTABLE_ID_GRACENOTE_ID, MAINTABLE_ID_ALBUMARTIST, + MAINTABLE_ID_TRACKGAIN, MAINTABLE_ID_PUBLISHER, MAINTABLE_ID_COMPOSER, + MAINTABLE_ID_PODCASTCHANNEL, MAINTABLE_ID_GRACENOTEFILEID, MAINTABLE_ID_GRACENOTEEXTDATA, + MAINTABLE_ID_CATEGORY, MAINTABLE_ID_CODEC, MAINTABLE_ID_DIRECTOR, MAINTABLE_ID_PRODUCER + }; + for (size_t i = 0;i != elementsof(STR_IDS);i++) + { + nde_field_t f = NDE_Scanner_GetFieldByID(pruneScanner, STR_IDS[i]); + if (f) + { + const wchar_t *s = NDE_StringField_GetString(f); + if (!s || !*s) + { + NDE_Scanner_DeleteField(pruneScanner, f); + NDE_Scanner_Post(pruneScanner); + } + } + } + + unsigned char INT_IDS_ZEROOK[] = {MAINTABLE_ID_LENGTH, MAINTABLE_ID_PLAYCOUNT, MAINTABLE_ID_FILESIZE, + MAINTABLE_ID_TYPE, MAINTABLE_ID_ISPODCAST, MAINTABLE_ID_LOSSLESS + }; + for (size_t i = 0;i != elementsof(INT_IDS_ZEROOK);i++) + { + nde_field_t f = NDE_Scanner_GetFieldByID(pruneScanner, INT_IDS_ZEROOK[i]); + if (f) + { + int s = NDE_IntegerField_GetValue(f); + if (s < 0) + { + NDE_Scanner_DeleteField(pruneScanner, f); + NDE_Scanner_Post(pruneScanner); + + } + } + } + + unsigned char INT_IDS[] = {MAINTABLE_ID_TRACKNB, MAINTABLE_ID_LASTUPDTIME, MAINTABLE_ID_LASTPLAY, MAINTABLE_ID_RATING, + MAINTABLE_ID_FILETIME, MAINTABLE_ID_BITRATE, MAINTABLE_ID_DISC, MAINTABLE_ID_BPM, MAINTABLE_ID_DISCS, + MAINTABLE_ID_TRACKS, MAINTABLE_ID_PODCASTPUBDATE, MAINTABLE_ID_FILESIZE, MAINTABLE_ID_DATEADDED + }; + for (size_t i = 0;i != elementsof(INT_IDS);i++) + { + nde_field_t f = NDE_Scanner_GetFieldByID(pruneScanner, INT_IDS[i]); + if (f) + { + int s = NDE_IntegerField_GetValue(f); + if (s <= 0) + { + NDE_Scanner_DeleteField(pruneScanner, f); + NDE_Scanner_Post(pruneScanner); + } + } + } + NDE_Scanner_Next(pruneScanner); + recordNum++; + } + + NDE_Table_DestroyScanner(table, pruneScanner); + NDE_Table_Sync(table); + } + + NDE_Table_Compact(table, &progress[0]); + assert(((Table *)table)->CheckIndexing()); + // now remove duplicates + nde_scanner_t dupscanner = NDE_Table_CreateScanner(table); + if (dupscanner) + { + int count = NDE_Scanner_GetRecordsCount(dupscanner); + wchar_t **filenames = new wchar_t *[count]; + int i = 0; + for (NDE_Scanner_First(dupscanner);!NDE_Scanner_EOF(dupscanner);NDE_Scanner_Next(dupscanner)) + { + nde_field_t fileName = NDE_Scanner_GetFieldByID(dupscanner, MAINTABLE_ID_FILENAME); + if (fileName) + { + filenames[i] = NDE_StringField_GetString(fileName); + ndestring_retain(filenames[i]); + i++; + } + } + count = i; + if (count) + { + qsort(filenames, count, sizeof(wchar_t *), sortFunc); + for (int x = 0;x < (count - 1);x++) + { + int total = MulDiv(x, 100, count); + progress[1] = total - 100; + + if (!_wcsicmp(filenames[x], filenames[x+1])) + { + wchar_t query[1024] = {0}; + wnsprintfW(query, 1024, L"filename == \"%s\"", filenames[x]); + + nde_scanner_t scanner = NDE_Table_CreateScanner(table); + NDE_Scanner_Query(scanner, query); + + NDE_Scanner_First(scanner); + NDE_Scanner_Next(scanner); + while (!NDE_Scanner_EOF(scanner)) + { + NDE_Scanner_Delete(scanner); + NDE_Scanner_Post(scanner); + NDE_Scanner_Next(scanner); + } + NDE_Table_DestroyScanner(table, scanner); + } + ndestring_release(filenames[x]); + filenames[x]=0; + } + } + delete[] filenames; + } + NDE_Table_DestroyScanner(table, dupscanner); + NDE_Table_Sync(table); + NDE_Table_Compact(table, &progress[1]); + + progress[0] = 666; + WaitForSingleObject(compactThread, INFINITE); + CloseHandle(compactThread); +}
\ No newline at end of file |