prefs.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  1. #include "main.h"
  2. #include "api__ml_local.h"
  3. #include "ml_local.h"
  4. #include <time.h>
  5. #include "..\..\General\gen_ml/config.h"
  6. #include "resource.h"
  7. #include "../nu/listview.h"
  8. #include "..\..\General\gen_ml/gaystring.h"
  9. #include "./scanfolderbrowser.h"
  10. #include "../replicant/nu/AutoChar.h"
  11. #include "../replicant/nu/AutoWide.h"
  12. #include <shlwapi.h>
  13. #include <strsafe.h>
  14. extern HWND subWnd = 0, prefsWnd = 0;
  15. extern int g_bgrescan_int, g_bgrescan_do, g_autochannel_do;
  16. HWND g_bgrescan_status_hwnd;
  17. static W_ListView *m_dir_lv;
  18. static void EnableDisableRecentPlayingControls( HWND hwndDlg, int tracking )
  19. {
  20. if ( tracking == -1 ) tracking = !!g_config->ReadInt( L"trackplays", 1 );
  21. EnableWindow( GetDlgItem( hwndDlg, IDC_CHECK7 ), tracking );
  22. EnableWindow( GetDlgItem( hwndDlg, IDC_CHECK8 ), tracking );
  23. EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT2 ), tracking && !!g_config->ReadInt( L"trackplays_wait_secs", 0 ) );
  24. EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT3 ), tracking && !!g_config->ReadInt( L"trackplays_wait_percent", 0 ) );
  25. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC4 ), tracking );
  26. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC5 ), tracking );
  27. }
  28. // Recently Played
  29. // When 'Recently Played' is enabled, Winamp will keep track of\nwhen and how many times items in the Media Library are played.
  30. static INT_PTR CALLBACK Prefs1Proc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  31. {
  32. switch ( uMsg )
  33. {
  34. case WM_INITDIALOG:
  35. {
  36. CheckDlgButton( hwndDlg, IDC_REMEMBER_SEARCH, !!g_config->ReadInt( L"remembersearch", 0 ) );
  37. CheckDlgButton( hwndDlg, IDC_CHECK3, !!g_config->ReadInt( L"useminiinfo2", 0 ) );
  38. CheckDlgButton( hwndDlg, IDC_CHECK_ATF, !!g_config->ReadInt( L"newtitle", 1 ) );
  39. CheckDlgButton( hwndDlg, IDC_CHECK5, !!g_config->ReadInt( L"audiorefine", 0 ) );
  40. CheckDlgButton( hwndDlg, IDC_CHECK6, !g_config->ReadInt( L"dbloadatstart", 1 ) );
  41. CheckDlgButton( hwndDlg, IDC_ARTIST_AS_ALBUMARTIST, g_config->ReadInt( L"artist_as_albumartist", 1 ) );
  42. SetDlgItemInt( hwndDlg, IDC_EDIT_QUERYDELAY, g_config->ReadInt( L"querydelay", 250 ), 0 );
  43. int tracking = !!g_config->ReadInt( L"trackplays", 1 );
  44. CheckDlgButton( hwndDlg, IDC_CHECK2, tracking );
  45. CheckDlgButton( hwndDlg, IDC_CHECK7, !!g_config->ReadInt( L"trackplays_wait_secs", 0 ) );
  46. CheckDlgButton( hwndDlg, IDC_CHECK8, !!g_config->ReadInt( L"trackplays_wait_percent", 0 ) );
  47. SetDlgItemInt( hwndDlg, IDC_EDIT2, g_config->ReadInt( L"trackplays_wait_secs_lim", 5 ), 0 );
  48. SetDlgItemInt( hwndDlg, IDC_EDIT3, g_config->ReadInt( L"trackplays_wait_percent_lim", 50 ), 0 );
  49. EnableDisableRecentPlayingControls( hwndDlg, tracking );
  50. }
  51. break;
  52. case WM_COMMAND:
  53. switch ( LOWORD( wParam ) )
  54. {
  55. case IDC_CHECK3:
  56. g_config->WriteInt( L"useminiinfo2", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK3 ) );
  57. PostMessage( plugin.hwndLibraryParent, WM_USER + 30, 0, 0 );
  58. break;
  59. case IDC_REMEMBER_SEARCH:
  60. g_config->WriteInt( L"remembersearch", !!IsDlgButtonChecked( hwndDlg, IDC_REMEMBER_SEARCH ) );
  61. break;
  62. case IDC_CHECK_ATF:
  63. g_config->WriteInt( L"newtitle", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK_ATF ) );
  64. break;
  65. case IDC_CHECK5:
  66. g_config->WriteInt( L"audiorefine", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK5 ) );
  67. if ( plugin.hwndLibraryParent ) PostMessage( plugin.hwndLibraryParent, WM_USER + 30, 0, 0 );
  68. break;
  69. case IDC_CHECK6:
  70. g_config->WriteInt( L"dbloadatstart", !IsDlgButtonChecked( hwndDlg, IDC_CHECK6 ) );
  71. break;
  72. case IDC_CHECK2:
  73. {
  74. int tracking = !!IsDlgButtonChecked( hwndDlg, IDC_CHECK2 );
  75. g_config->WriteInt( L"trackplays", tracking );
  76. EnableDisableRecentPlayingControls( hwndDlg, tracking );
  77. }
  78. break;
  79. case IDC_CHECK7:
  80. {
  81. g_config->WriteInt( L"trackplays_wait_secs", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK7 ) );
  82. EnableDisableRecentPlayingControls( hwndDlg, -1 );
  83. }
  84. break;
  85. case IDC_CHECK8:
  86. {
  87. g_config->WriteInt( L"trackplays_wait_percent", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK8 ) );
  88. EnableDisableRecentPlayingControls( hwndDlg, -1 );
  89. }
  90. break;
  91. case IDC_BUTTON2:
  92. {
  93. wchar_t title[ 64 ] = { 0 };
  94. WASABI_API_LNGSTRINGW_BUF( IDS_RECENTLY_PLAYED, title, 64 );
  95. MessageBoxW( hwndDlg, WASABI_API_LNGSTRINGW( IDS_RECENTLY_PLAYED_TEXT ), title, 0 );
  96. }
  97. break;
  98. case IDC_ARTIST_AS_ALBUMARTIST:
  99. {
  100. int oldValue = g_config->ReadInt( L"artist_as_albumartist", 1 );
  101. int newValue = !!IsDlgButtonChecked( hwndDlg, IDC_ARTIST_AS_ALBUMARTIST );
  102. if ( oldValue != newValue )
  103. {
  104. // TODO: prompt to re-read metadata on entire library
  105. }
  106. g_config->WriteInt( L"artist_as_albumartist", newValue );
  107. }
  108. break;
  109. case IDC_EDIT_QUERYDELAY:
  110. {
  111. if ( HIWORD( wParam ) == EN_CHANGE )
  112. {
  113. BOOL t;
  114. int v = GetDlgItemInt( hwndDlg, IDC_EDIT_QUERYDELAY, &t, FALSE );
  115. if ( t )
  116. {
  117. if ( v < 1 )
  118. {
  119. v = 1;
  120. SetDlgItemInt( hwndDlg, IDC_EDIT_QUERYDELAY, v, 0 );
  121. }
  122. else if ( v > 5000 )
  123. {
  124. v = 5000;
  125. SetDlgItemInt( hwndDlg, IDC_EDIT_QUERYDELAY, v, 0 );
  126. }
  127. g_config->WriteInt( L"querydelay", v );
  128. g_querydelay = v;
  129. }
  130. }
  131. }
  132. break;
  133. case IDC_BUTTON1:
  134. nukeLibrary( hwndDlg );
  135. break;
  136. case IDC_EDIT2:
  137. if ( HIWORD( wParam ) == EN_CHANGE )
  138. {
  139. BOOL t;
  140. int v = GetDlgItemInt( hwndDlg, IDC_EDIT2, &t, FALSE );
  141. if ( t )
  142. {
  143. if ( v < 0 )
  144. {
  145. v = 1;
  146. SetDlgItemInt( hwndDlg, IDC_EDIT2, v, 0 );
  147. }
  148. g_config->WriteInt( L"trackplays_wait_secs_lim", v );
  149. }
  150. }
  151. break;
  152. case IDC_EDIT3:
  153. if ( HIWORD( wParam ) == EN_CHANGE )
  154. {
  155. BOOL t;
  156. int v = GetDlgItemInt( hwndDlg, IDC_EDIT3, &t, FALSE );
  157. if ( t )
  158. {
  159. int tweaked = 0;
  160. if ( v > 99 )
  161. {
  162. v = 99;
  163. tweaked = 1;
  164. }
  165. else if ( v < 1 )
  166. {
  167. v = 1;
  168. tweaked = 1;
  169. }
  170. if ( tweaked )
  171. {
  172. SetDlgItemInt( hwndDlg, IDC_EDIT3, v, 0 );
  173. }
  174. g_config->WriteInt( L"trackplays_wait_percent_lim", v );
  175. }
  176. }
  177. break;
  178. }
  179. break;
  180. }
  181. return 0;
  182. }
  183. static void parseMetaStr( wchar_t *buf2, int *guess, int *meta, int *subdir )
  184. {
  185. wchar_t metaPS[ 16 ] = { 0 }, metaMS[ 16 ] = { 0 }, smartPS[ 16 ] = { 0 }, smartMS[ 16 ] = { 0 }, guessS[ 16 ] = { 0 }, recurseS[ 16 ] = { 0 };
  186. StringCchPrintfW( recurseS, 16, L"-%s", WASABI_API_LNGSTRINGW( IDS_RECURSE_STR ) );
  187. StringCchPrintfW( guessS, 16, L"-%s", WASABI_API_LNGSTRINGW( IDS_GUESS_STR ) );
  188. StringCchPrintfW( smartPS, 16, L"+%s", WASABI_API_LNGSTRINGW( IDS_SMART_STR ) );
  189. StringCchPrintfW( smartMS, 16, L"-%s", WASABI_API_LNGSTRINGW( IDS_SMART_STR ) );
  190. StringCchPrintfW( metaPS, 16, L"+%s", WASABI_API_LNGSTRINGW( IDS_META_STR ) );
  191. StringCchPrintfW( metaMS, 16, L"-%s", WASABI_API_LNGSTRINGW( IDS_META_STR ) );
  192. if ( wcsstr( buf2, metaPS ) )
  193. {
  194. *meta = 1;
  195. }
  196. else if ( wcsstr( buf2, metaMS ) )
  197. {
  198. *meta = 0;
  199. }
  200. else
  201. {
  202. *meta = -1;
  203. }
  204. if ( wcsstr( buf2, smartPS ) )
  205. {
  206. *guess = 0;
  207. }
  208. else if ( wcsstr( buf2, smartMS ) )
  209. {
  210. *guess = 1;
  211. }
  212. else if ( wcsstr( buf2, guessS ) )
  213. {
  214. *guess = 2;
  215. }
  216. else
  217. {
  218. *guess = -1;
  219. }
  220. if ( wcsstr( buf2, recurseS ) )
  221. {
  222. *subdir = 0;
  223. }
  224. else
  225. {
  226. *subdir = 1;
  227. }
  228. }
  229. static void makeMetaStr( int guess_mode, int use_metadata, int subdir, wchar_t *buf, int bufLen )
  230. {
  231. wchar_t guessstr[ 32 ] = { 0 }, recurseS[ 16 ] = { 0 };
  232. if ( guess_mode >= 0 )
  233. {
  234. if ( guess_mode == 1 )
  235. StringCchPrintfW( guessstr, 32, L"-%s", WASABI_API_LNGSTRINGW( IDS_SMART_STR ) );
  236. else if ( guess_mode == 2 )
  237. StringCchPrintfW( guessstr, 32, L"-%s", WASABI_API_LNGSTRINGW( IDS_GUESS_STR ) );
  238. else
  239. StringCchPrintfW( guessstr, 32, L"+%s", WASABI_API_LNGSTRINGW( IDS_SMART_STR ) );
  240. }
  241. if ( use_metadata >= 0 && guess_mode >= 0 )
  242. {
  243. wchar_t bufS[ 64 ] = { 0 };
  244. StringCchPrintfW( bufS, 64, L"%%c%s%%s%%s", WASABI_API_LNGSTRINGW( IDS_META_STR ) );
  245. StringCchPrintfW( recurseS, 16, L"%s%s", subdir ? L"" : L"-", subdir ? L"" : WASABI_API_LNGSTRINGW( IDS_RECURSE_STR ) );
  246. StringCchPrintfW( buf, bufLen, bufS, use_metadata ? L'+' : L'-', guessstr, recurseS );
  247. }
  248. else if ( use_metadata >= 0 )
  249. {
  250. wchar_t metaS[ 16 ] = { 0 };
  251. StringCchPrintfW( metaS, 16, L"%s%s", use_metadata ? L"+" : L"-", WASABI_API_LNGSTRINGW( IDS_META_STR ) );
  252. StringCchPrintfW( recurseS, 16, L"%s%s", subdir ? L"" : L"-", subdir ? L"" : WASABI_API_LNGSTRINGW( IDS_RECURSE_STR ) );
  253. StringCchPrintfW( buf, bufLen, L"%s%s", metaS, recurseS );
  254. }
  255. else if ( guess_mode >= 0 )
  256. {
  257. StringCchPrintfW( recurseS, 16, L"%s%s", subdir ? L"" : L"-", subdir ? L"" : WASABI_API_LNGSTRINGW( IDS_RECURSE_STR ) );
  258. StringCchPrintfW( buf, bufLen, L"%s%s", guessstr, recurseS );
  259. }
  260. else if ( !subdir )
  261. {
  262. StringCchPrintfW( buf, bufLen, L"-%s", WASABI_API_LNGSTRINGW( IDS_RECURSE_STR ) );
  263. }
  264. else
  265. {
  266. StringCchCopyW( buf, bufLen, WASABI_API_LNGSTRINGW( IDS_DEFAULT ) );
  267. }
  268. }
  269. static void saveList()
  270. {
  271. GayStringW gs;
  272. int a = 0;
  273. int x, l = m_dir_lv->GetCount();
  274. for ( x = 0; x < l; x++ )
  275. {
  276. wchar_t buf[ 1024 ] = { 0 }, buf2[ 64 ] = { 0 };
  277. m_dir_lv->GetText( x, 0, buf2, 64 );
  278. m_dir_lv->GetText( x, 1, buf, 1024 );
  279. if ( buf[ 0 ] )
  280. {
  281. if ( a )
  282. gs.Append( L"|" );
  283. else
  284. a = 1;
  285. int meta;
  286. int guess;
  287. int subdir;
  288. parseMetaStr( buf2, &guess, &meta, &subdir );
  289. if ( meta >= 0 || guess >= 0 || !subdir )
  290. {
  291. gs.Append( L"<" );
  292. if ( guess >= 0 )
  293. gs.Append( guess == 1 ? L"s" : ( guess == 2 ? L"g" : L"S" ) );
  294. if ( meta >= 0 )
  295. gs.Append( meta ? L"M" : L"m" );
  296. if ( !subdir )
  297. gs.Append( L"r" );
  298. gs.Append( L">" );
  299. }
  300. gs.Append( buf );
  301. }
  302. }
  303. g_config->WriteString( "scandirlist", 0 ); // erase the old ini value
  304. g_config->WriteString( "scandirlist_utf8", AutoChar( gs.Get(), CP_UTF8 ) );
  305. }
  306. int autoscan_add_directory( const wchar_t *path, int *guess, int *meta, int *recurse, int noaddjustcheck )
  307. {
  308. char *_s1 = g_config->ReadString( "scandirlist", "" );
  309. UINT codePage = CP_ACP;
  310. if ( !_s1 || !*_s1 )
  311. {
  312. _s1 = g_config->ReadString( "scandirlist_utf8", "" );
  313. codePage = CP_UTF8;
  314. }
  315. wchar_t *s1 = AutoWideDup( _s1, codePage );
  316. int bufLen = 0;
  317. wchar_t *s = (wchar_t *)calloc( ( bufLen = ( wcslen( s1 ) + 2 ) ), sizeof( wchar_t ) );
  318. if ( s )
  319. {
  320. wcsncpy( s, s1, bufLen );
  321. s[ wcslen( s ) + 1 ] = 0;
  322. wchar_t *p = s;
  323. while ( p && *p == L'|' ) p++;
  324. while ( ( p = wcsstr( p, L"|" ) ) )
  325. {
  326. *p++ = 0;
  327. while ( p && *p == L'|' ) p++;
  328. }
  329. p = s;
  330. while ( p && *p )
  331. {
  332. while ( p && *p == L'|' ) p++;
  333. int use_meta = -1;
  334. int do_guess = -1;
  335. int do_recurse = 1;
  336. if ( *p == L'<' && wcsstr( p, L">" ) )
  337. {
  338. p++;
  339. while ( p && *p != L'>' )
  340. {
  341. // <MmSs>can prefix directory
  342. // M=metadata use override
  343. // m=no metadata
  344. // S=smart guessing
  345. // s=stupid guessing
  346. // g=no guessing
  347. if ( *p == L'M' )
  348. use_meta = 1;
  349. else if ( *p == L'm' )
  350. use_meta = 0;
  351. else if ( *p == L'S' )
  352. do_guess = 0;
  353. else if ( *p == L's' )
  354. do_guess = 1;
  355. else if ( *p == L'g' )
  356. do_guess = 2;
  357. else if ( *p == L'r' )
  358. do_recurse = 0;
  359. p++;
  360. }
  361. p++;
  362. }
  363. if ( !_wcsnicmp( p, path, wcslen( p ) ) && ( path[ wcslen( p ) ] == L'\\' || !path[ wcslen( p ) ] ) )
  364. {
  365. free( s ); // directory already in there
  366. if ( meta )
  367. *meta = use_meta;
  368. if ( guess )
  369. *guess = do_guess;
  370. if ( recurse )
  371. *recurse = do_recurse;
  372. return 1;
  373. }
  374. p += wcslen( p ) + 1;
  375. }
  376. free( s );
  377. }
  378. if ( !noaddjustcheck )
  379. {
  380. WIN32_FIND_DATAW fd = { 0 };
  381. int bufLen = 0;
  382. wchar_t *s = (wchar_t *)calloc( ( bufLen = ( wcslen( path ) + 32 ) ), sizeof( wchar_t ) );
  383. StringCchPrintfW( s, bufLen, L"%s\\*.*", path );
  384. HANDLE h = FindFirstFileW( s, &fd );
  385. free( s );
  386. if ( h != INVALID_HANDLE_VALUE )
  387. {
  388. FindClose( h ); // we are a directory, yay
  389. GayStringW gs;
  390. gs.Set( s1 );
  391. if ( s1[ 0 ] )
  392. gs.Append( L"|" );
  393. gs.Append( path );
  394. g_config->WriteString( "scandirlist", 0 );
  395. g_config->WriteString( "scandirlist_utf8", AutoCharDup( gs.Get(), codePage, 0 ) );
  396. if ( m_dir_lv )
  397. {
  398. int x = m_dir_lv->GetCount();
  399. m_dir_lv->InsertItem( x, WASABI_API_LNGSTRINGW( IDS_DEFAULT ), 0 );
  400. m_dir_lv->SetItemText( x, 1, path );
  401. }
  402. }
  403. }
  404. return 0;
  405. }
  406. static int m_edit_idx;
  407. static INT_PTR CALLBACK editDirProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  408. {
  409. switch ( uMsg )
  410. {
  411. case WM_INITDIALOG:
  412. {
  413. wchar_t buf[ 1024 ] = { 0 };
  414. SHAutoComplete( GetDlgItem( hwndDlg, IDC_EDIT1 ), SHACF_AUTOAPPEND_FORCE_ON | SHACF_AUTOSUGGEST_FORCE_ON | /*SHACF_FILESYS_DIRS*/0x020 | 0x010 | SHACF_USETAB );
  415. m_dir_lv->GetText( m_edit_idx, 1, buf, 1024 );
  416. SetDlgItemTextW( hwndDlg, IDC_EDIT1, buf );
  417. m_dir_lv->GetText( m_edit_idx, 0, buf, 1024 );
  418. int guess, meta, subdir;
  419. parseMetaStr( buf, &guess, &meta, &subdir );
  420. if ( meta )
  421. CheckDlgButton( hwndDlg, IDC_CHECK1, meta > 0 ? BST_CHECKED : BST_INDETERMINATE );
  422. if ( guess < 0 )
  423. CheckDlgButton( hwndDlg, IDC_RADIO6, BST_CHECKED );
  424. else if ( !guess )
  425. CheckDlgButton( hwndDlg, IDC_RADIO1, BST_CHECKED );
  426. else if ( guess == 2 )
  427. CheckDlgButton( hwndDlg, IDC_RADIO8, BST_CHECKED );
  428. else if ( guess > 0 )
  429. CheckDlgButton( hwndDlg, IDC_RADIO2, BST_CHECKED );
  430. if ( subdir ) CheckDlgButton( hwndDlg, IDC_CHECK2, BST_CHECKED );
  431. }
  432. return 0;
  433. case WM_COMMAND:
  434. switch ( LOWORD( wParam ) )
  435. {
  436. case IDOK:
  437. {
  438. //save to m_edit_idx :)
  439. wchar_t buf[ 2048 ] = { 0 };
  440. GetDlgItemTextW( hwndDlg, IDC_EDIT1, buf, 2048 );
  441. m_dir_lv->SetItemText( m_edit_idx, 1, buf );
  442. int meta = IsDlgButtonChecked( hwndDlg, IDC_CHECK1 );
  443. if ( meta == BST_CHECKED )
  444. meta = 1;
  445. else if ( meta == BST_INDETERMINATE )
  446. meta = -1;
  447. else
  448. meta = 0;
  449. int guess = -1;
  450. if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO1 ) )
  451. guess = 0;
  452. else if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO2 ) )
  453. guess = 1;
  454. else if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO8 ) )
  455. guess = 2;
  456. int subdir = 1;
  457. if ( !IsDlgButtonChecked( hwndDlg, IDC_CHECK2 ) )
  458. subdir = 0;
  459. makeMetaStr( guess, meta, subdir, buf, 64 );
  460. m_dir_lv->SetItemText( m_edit_idx, 0, buf );
  461. EndDialog( hwndDlg, 1 );
  462. }
  463. return 0;
  464. case IDCANCEL:
  465. EndDialog( hwndDlg, 0 );
  466. return 0;
  467. case IDC_BUTTON1:
  468. wchar_t path[ MAX_PATH ] = { 0 };
  469. GetDlgItemTextW( hwndDlg, IDC_EDIT1, path, MAX_PATH );
  470. ScanFolderBrowser browse( FALSE );
  471. browse.SetSelection( path );
  472. if ( browse.Browse( hwndDlg ) )
  473. {
  474. wchar_t path[ MAX_PATH ] = { 0 };
  475. SHGetPathFromIDListW( browse.GetPIDL(), path );
  476. SetDlgItemTextW( hwndDlg, IDC_EDIT1, path );
  477. }
  478. return 0;
  479. }
  480. return 0;
  481. }
  482. return 0;
  483. }
  484. void hideShowMetadataRadioboxes( HWND hwndDlg )
  485. {
  486. int enabled = IsDlgButtonChecked( hwndDlg, IDC_CHECK1 );
  487. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC1 ), enabled );
  488. EnableWindow( GetDlgItem( hwndDlg, IDC_STATIC2 ), enabled );
  489. EnableWindow( GetDlgItem( hwndDlg, IDC_COMBO1 ), enabled );
  490. EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO1 ), enabled );
  491. EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO2 ), enabled );
  492. EnableWindow( GetDlgItem( hwndDlg, IDC_RADIO3 ), enabled );
  493. }
  494. static INT_PTR CALLBACK confMetaProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  495. {
  496. switch ( uMsg )
  497. {
  498. case WM_INITDIALOG:
  499. {
  500. if ( g_config->ReadInt( L"usemetadata", 1 ) ) CheckDlgButton( hwndDlg, IDC_CHECK1, BST_CHECKED );
  501. {
  502. int gm = g_config->ReadInt( L"guessmode", 0 );
  503. CheckDlgButton( hwndDlg, gm == 2 ? IDC_RADIO3 : ( gm == 1 ? IDC_RADIO2 : IDC_RADIO1 ), BST_CHECKED );
  504. }
  505. SendDlgItemMessageW( hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW( IDS_ANY ) );
  506. SendDlgItemMessageW( hwndDlg, IDC_COMBO1, CB_ADDSTRING, 0, (LPARAM)WASABI_API_LNGSTRINGW( IDS_ALL ) );
  507. SendDlgItemMessage( hwndDlg, IDC_COMBO1, CB_SETCURSEL, g_guessifany ? 0 : 1, 0 );
  508. hideShowMetadataRadioboxes( hwndDlg );
  509. }
  510. break;
  511. case WM_COMMAND:
  512. switch ( LOWORD( wParam ) )
  513. {
  514. case IDOK:
  515. g_config->WriteInt( L"usemetadata", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK1 ) );
  516. {
  517. int a = SendDlgItemMessage( hwndDlg, IDC_COMBO1, CB_GETCURSEL, 0, 0 );
  518. g_guessifany = ( a == 0 );
  519. g_config->WriteInt( L"guessifany", g_guessifany );
  520. }
  521. if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO1 ) )
  522. g_config->WriteInt( L"guessmode", 0 );
  523. if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO2 ) )
  524. g_config->WriteInt( L"guessmode", 1 );
  525. if ( IsDlgButtonChecked( hwndDlg, IDC_RADIO3 ) )
  526. g_config->WriteInt( L"guessmode", 2 );
  527. case IDCANCEL:
  528. EndDialog( hwndDlg, 0 );
  529. break;
  530. case IDC_CHECK1:
  531. hideShowMetadataRadioboxes( hwndDlg );
  532. break;
  533. }
  534. break;
  535. }
  536. return 0;
  537. }
  538. static INT_PTR CALLBACK Prefs3Proc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  539. {
  540. static int m_last_isscanning, m_set_rescan_int;
  541. switch ( uMsg )
  542. {
  543. case WM_INITDIALOG:
  544. {
  545. m_last_isscanning = -1;
  546. m_set_rescan_int = 0;
  547. SendMessage( hwndDlg, WM_TIMER, 100, 0 );
  548. SetTimer( hwndDlg, 100, 1000, NULL );
  549. g_bgrescan_status_hwnd = GetDlgItem( hwndDlg, IDC_STATUS );
  550. CheckDlgButton( hwndDlg, IDC_CHECK4, g_bgrescan_do ? BST_CHECKED : 0 );
  551. SendMessage( hwndDlg, WM_COMMAND, MAKEWPARAM( IDC_CHECK4, 0 ), 0 );
  552. CheckDlgButton( hwndDlg, IDC_CHECK3, g_config->ReadInt( L"bgrescan_startup", 0 ) ? BST_CHECKED : 0 );
  553. CheckDlgButton( hwndDlg, IDC_CHECK2, g_config->ReadInt( L"bgrescan_compact", 1 ) ? BST_CHECKED : 0 );
  554. CheckDlgButton( hwndDlg, IDC_CHECK5, g_config->ReadInt( L"autoaddplays", 0 ) ? BST_CHECKED : 0 );
  555. SendDlgItemMessage( hwndDlg, IDC_SPIN1, UDM_SETRANGE, 0, MAKELONG( 9999, 1 ) );
  556. SetDlgItemInt( hwndDlg, IDC_EDIT3, g_bgrescan_int, FALSE );
  557. m_set_rescan_int = 1;
  558. delete m_dir_lv;
  559. m_dir_lv = new W_ListView;
  560. m_dir_lv->setwnd( GetDlgItem( hwndDlg, IDC_LIST1 ) );
  561. m_dir_lv->AddCol( WASABI_API_LNGSTRINGW( IDS_OPTIONS ), 120 );
  562. m_dir_lv->AddCol( WASABI_API_LNGSTRINGW( IDS_DIRECTORY ), 500 );
  563. char *_s1 = g_config->ReadString( "scandirlist", "" );
  564. UINT codePage = CP_ACP;
  565. if ( !_s1 || !*_s1 )
  566. {
  567. _s1 = g_config->ReadString( "scandirlist_utf8", "" );
  568. codePage = CP_UTF8;
  569. }
  570. wchar_t *s1 = AutoWideDup( _s1, codePage );
  571. int bufLen = 0;
  572. wchar_t *s = (wchar_t *)calloc( ( bufLen = ( wcslen( s1 ) + 2 ) ), sizeof( wchar_t ) );
  573. if ( s )
  574. {
  575. wcsncpy( s, s1, bufLen );
  576. s[ wcslen( s ) + 1 ] = 0;
  577. wchar_t *p = s;
  578. while ( p && *p == L'|' ) p++;
  579. while ( ( p = wcsstr( p, L"|" ) ) )
  580. {
  581. *p++ = 0;
  582. while ( p && *p == L'|' ) p++;
  583. }
  584. int x = 0;
  585. p = s;
  586. while ( p && *p )
  587. {
  588. while ( p && *p == L'|' ) p++;
  589. int guess_mode = -1;
  590. int use_metadata = -1;
  591. int subdir = 1;
  592. if ( *p == L'<' && wcsstr( p, L">" ) )
  593. {
  594. p++;
  595. while ( p && *p != L'>' )
  596. {
  597. // <MmSs>can prefix directory
  598. // M=metadata use override
  599. // m=no metadata
  600. // S=smart guessing
  601. // s=stupid guessing
  602. if ( *p == L'M' )
  603. use_metadata = 1;
  604. else if ( *p == L'm' )
  605. use_metadata = 0;
  606. else if ( *p == L'S' )
  607. guess_mode = 0;
  608. else if ( *p == L's' )
  609. guess_mode = 1;
  610. else if ( *p == L'r' )
  611. subdir = 0;
  612. else if ( *p == L'g' )
  613. guess_mode = 2;
  614. p++;
  615. }
  616. p++;
  617. }
  618. wchar_t buf[ 64 ] = { 0 };
  619. makeMetaStr( guess_mode, use_metadata, subdir, buf, 64 );
  620. m_dir_lv->InsertItem( x, buf, 0 );
  621. m_dir_lv->SetItemText( x, 1, p );
  622. x++;
  623. p += wcslen( p ) + 1;
  624. }
  625. free( s );
  626. }
  627. if ( NULL != WASABI_API_APP )
  628. WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel( m_dir_lv->getwnd(), TRUE );
  629. }
  630. break;
  631. // process this to update the ui state when a scan is running and we didn't manually run it
  632. case WM_USER + 101:
  633. SendMessage( hwndDlg, WM_TIMER, 100, 0 );
  634. SetTimer( hwndDlg, 100, 1000, NULL );
  635. break;
  636. case WM_TIMER:
  637. if ( wParam == 100 )
  638. {
  639. extern int g_bgscan_scanning;
  640. if ( !!g_bgscan_scanning != !!m_last_isscanning )
  641. {
  642. m_last_isscanning = !!g_bgscan_scanning;
  643. SetDlgItemTextW( hwndDlg, IDC_RESCAN, WASABI_API_LNGSTRINGW( ( m_last_isscanning ? IDS_STOP_SCAN : IDS_RESCAN_NOW ) ) );
  644. }
  645. }
  646. break;
  647. case WM_COMMAND:
  648. switch ( LOWORD( wParam ) )
  649. {
  650. case IDC_CHECK5:
  651. g_config->WriteInt( L"autoaddplays", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK5 ) );
  652. break;
  653. case IDC_CHECK2:
  654. g_config->WriteInt( L"bgrescan_compact", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK2 ) );
  655. break;
  656. case IDC_CHECK3:
  657. g_config->WriteInt( L"bgrescan_startup", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK3 ) );
  658. break;
  659. case IDC_CHECK4:
  660. g_config->WriteInt( L"bgrescan_do", g_bgrescan_do = !!IsDlgButtonChecked( hwndDlg, IDC_CHECK4 ) );
  661. EnableWindow( GetDlgItem( hwndDlg, IDC_EDIT3 ), g_bgrescan_do );
  662. EnableWindow( GetDlgItem( hwndDlg, IDC_SPIN1 ), g_bgrescan_do );
  663. break;
  664. case IDC_EDIT3:
  665. {
  666. if ( HIWORD( wParam ) == EN_CHANGE && m_set_rescan_int )
  667. {
  668. BOOL t;
  669. int x = GetDlgItemInt( hwndDlg, IDC_EDIT3, &t, FALSE );
  670. if ( t )
  671. {
  672. if ( x < 1 ) x = 1;
  673. g_config->WriteInt( L"bgrescan_int", g_bgrescan_int = x );
  674. extern time_t g_bgscan_last_rescan;
  675. g_bgscan_last_rescan = time( NULL );
  676. }
  677. }
  678. }
  679. break;
  680. case IDC_BUTTON1:
  681. {
  682. ScanFolderBrowser browse( FALSE );
  683. if ( browse.Browse( hwndDlg ) )
  684. {
  685. GayStringW n;
  686. wchar_t path[ MAX_PATH ] = { 0 };
  687. SHGetPathFromIDListW( browse.GetPIDL(), path );
  688. char *_s1 = g_config->ReadString( "scandirlist", "" );
  689. UINT codePage = CP_ACP;
  690. if ( !_s1 || !*_s1 )
  691. {
  692. _s1 = g_config->ReadString( "scandirlist_utf8", "" );
  693. codePage = CP_UTF8;
  694. }
  695. wchar_t *scanlist = AutoWide( _s1, codePage );
  696. n.Set( scanlist );
  697. if ( scanlist[ 0 ] )
  698. n.Append( L"|" );
  699. n.Append( path );
  700. g_config->WriteString( "scandirlist", 0 );
  701. g_config->WriteString( "scandirlist_utf8", AutoChar( n.Get(), CP_UTF8 ) );
  702. int x = m_dir_lv->GetCount();
  703. m_dir_lv->InsertItem( x, WASABI_API_LNGSTRINGW( IDS_DEFAULT ), 0 );
  704. m_dir_lv->SetItemText( x, 1, path );
  705. }
  706. }
  707. break;
  708. case IDC_BUTTON4:
  709. {
  710. int x, l = m_dir_lv->GetCount(), s = 0;
  711. for ( x = 0; x < l; x++ )
  712. {
  713. if ( m_dir_lv->GetSelected( x ) )
  714. {
  715. m_edit_idx = x;
  716. if ( WASABI_API_DIALOGBOXW( IDD_EDITDIR, hwndDlg, editDirProc ) )
  717. s = 1;
  718. else
  719. break;
  720. }
  721. }
  722. if ( s )
  723. {
  724. saveList();
  725. }
  726. }
  727. break;
  728. case IDC_BUTTON3:
  729. {
  730. int x, l = m_dir_lv->GetCount();
  731. int s = 0;
  732. for ( x = 0; x < l; x++ )
  733. {
  734. if ( m_dir_lv->GetSelected( x ) )
  735. {
  736. s = 1;
  737. m_dir_lv->DeleteItem( x-- );
  738. l--;
  739. }
  740. }
  741. if ( s )
  742. {
  743. saveList();
  744. }
  745. }
  746. break;
  747. case IDC_RESCAN:
  748. extern int g_bgscan_scanning;
  749. extern time_t g_bgscan_last_rescan;
  750. if ( g_bgscan_scanning )
  751. {
  752. Scan_Cancel();
  753. SetWindowTextW( g_bgrescan_status_hwnd, WASABI_API_LNGSTRINGW( IDS_RESCAN_ABORTED ) );
  754. SendMessage( hwndDlg, WM_TIMER, 100, 0 );
  755. }
  756. else
  757. {
  758. extern int openDb( void );
  759. openDb();
  760. if ( plugin.hwndLibraryParent ) SendMessage( plugin.hwndLibraryParent, WM_USER + 575, 0xffff00dd, 0 );
  761. SendMessage( hwndDlg, WM_TIMER, 100, 0 );
  762. }
  763. break;
  764. case IDC_CONFMETA:
  765. WASABI_API_DIALOGBOXW( IDD_PREFS_METADATA, hwndDlg, confMetaProc );
  766. break;
  767. };
  768. break;
  769. case WM_NOTIFY:
  770. {
  771. LPNMHDR l = (LPNMHDR)lParam;
  772. if ( l->idFrom == IDC_LIST1 && l->code == NM_DBLCLK )
  773. {
  774. SendMessage( hwndDlg, WM_COMMAND, IDC_BUTTON4, 0 );
  775. }
  776. }
  777. break;
  778. case WM_DESTROY:
  779. m_set_rescan_int = 0;
  780. g_bgrescan_status_hwnd = 0;
  781. if ( NULL != WASABI_API_APP )
  782. WASABI_API_APP->DirectMouseWheel_EnableConvertToMouseWheel( m_dir_lv->getwnd(), FALSE );
  783. delete m_dir_lv;
  784. m_dir_lv = 0;
  785. break;
  786. }
  787. return 0;
  788. }
  789. static void _dosetsel( HWND hwndDlg )
  790. {
  791. HWND tabwnd = GetDlgItem( hwndDlg, IDC_TAB1 );
  792. int sel = TabCtrl_GetCurSel( tabwnd );
  793. if ( sel >= 0 && ( sel != g_config->ReadInt( L"lastprefp", 0 ) || !subWnd ) )
  794. {
  795. g_config->WriteInt( L"lastprefp", sel );
  796. if ( subWnd )
  797. DestroyWindow( subWnd );
  798. subWnd = 0;
  799. UINT t = 0;
  800. DLGPROC p = NULL;
  801. switch ( sel )
  802. {
  803. case 0: t = IDD_PREFS1; p = Prefs1Proc; break;
  804. case 1: t = IDD_PREFS3; p = Prefs3Proc; break;
  805. }
  806. if ( t ) subWnd = WASABI_API_CREATEDIALOGW( t, hwndDlg, p );
  807. if ( subWnd )
  808. {
  809. RECT r;
  810. GetClientRect( tabwnd, &r );
  811. TabCtrl_AdjustRect( tabwnd, FALSE, &r );
  812. SetWindowPos( subWnd, HWND_TOP, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE );
  813. ShowWindow( subWnd, SW_SHOWNA );
  814. }
  815. if ( !SendMessage( plugin.hwndWinampParent, WM_WA_IPC, IPC_ISWINTHEMEPRESENT, IPC_USE_UXTHEME_FUNC ) )
  816. {
  817. SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)tabwnd, IPC_USE_UXTHEME_FUNC );
  818. SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)subWnd, IPC_USE_UXTHEME_FUNC );
  819. }
  820. }
  821. }
  822. // frame proc
  823. INT_PTR CALLBACK PrefsProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  824. {
  825. switch ( uMsg )
  826. {
  827. case WM_INITDIALOG:
  828. {
  829. TCITEMW item;
  830. HWND tabwnd = GetDlgItem( hwndDlg, IDC_TAB1 );
  831. item.mask = TCIF_TEXT;
  832. item.pszText = WASABI_API_LNGSTRINGW( IDS_OPTIONS );
  833. SendMessageW( tabwnd, TCM_INSERTITEMW, 0, (LPARAM)&item );
  834. item.pszText = WASABI_API_LNGSTRINGW( IDS_WATCH_FOLDERS );
  835. SendMessageW( tabwnd, TCM_INSERTITEMW, 1, (LPARAM)&item );
  836. TabCtrl_SetCurSel( tabwnd, g_config->ReadInt( L"lastprefp", 0 ) );
  837. _dosetsel( hwndDlg );
  838. prefsWnd = hwndDlg;
  839. }
  840. return 0;
  841. case WM_NOTIFY:
  842. {
  843. LPNMHDR p = (LPNMHDR)lParam;
  844. if ( p->idFrom == IDC_TAB1 && p->code == TCN_SELCHANGE ) _dosetsel( hwndDlg );
  845. }
  846. return 0;
  847. case WM_DESTROY:
  848. subWnd = NULL;
  849. prefsWnd = NULL;
  850. return 0;
  851. }
  852. return 0;
  853. }
  854. void refreshPrefs( int screen )
  855. {
  856. if ( subWnd && g_config->ReadInt( L"lastprefp", -1 ) == screen )
  857. {
  858. if ( screen == 4 ) SendMessage( subWnd, WM_INITDIALOG, 0, 0 );
  859. }
  860. }