| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 | #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);}
 |