123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953 |
- #include <windows.h>
- #include <shlwapi.h>
- #include <shlobj.h>
- #include <shellapi.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "main.h"
- #include "nu/listview.h"
- #include "resource.h"
- #include "Playlist.h"
- #include "replicant/nu/AutoChar.h"
- #include "../../General/gen_ml/ml_ipc.h"
- #include "SendTo.h"
- #include "api__ml_playlists.h"
- #include "../../General/gen_ml/ml_ipc_0313.h"
- #include "nu/menushortcuts.h"
- #include "ml_local/api_mldb.h"
- #include "ml_pmp/pmp.h"
- #include "replicant/nswasabi/ReferenceCounted.h"
- #include "replicant/nx/win/nxstring.h"
- void playlist_UpdateButtonText( HWND hwndDlg, int enqueuedef );
- BOOL playlist_ButtonPopupMenu( HWND hwndDlg, int buttonId, HMENU menu, int flags = 0 );
- static std::vector<GUID> playlistGUIDs;
- using namespace Nullsoft::Utility;
- SendToMenu sendTo;
- static W_ListView m_playlistslist;
- int root_is_drag_and_dropping = 0;
- HINSTANCE cloud_hinst = 0;
- static int last_item1 = -1;
- int IPC_GET_CLOUD_HINST = -1;
- int IPC_GET_CLOUD_ACTIVE = -1;
- int cloud_avail = 0;
- int normalimage = 0;
- int cloudImage = 0;
- static void AutoSizePlaylistColumns()
- {
- m_playlistslist.AutoSizeColumn( 2 );
- m_playlistslist.AutoSizeColumn( 3 );
- RECT channelRect;
- GetClientRect( m_playlistslist.getwnd(), &channelRect );
- ListView_SetColumnWidth( m_playlistslist.getwnd(), 0, channelRect.right - m_playlistslist.GetColumnWidth( 1 ) - m_playlistslist.GetColumnWidth( 2 ) - m_playlistslist.GetColumnWidth( 3 ) );
- }
- static bool opened = false, loaded = false;
- void RefreshPlaylistsList()
- {
- if ( opened )
- {
- playlistGUIDs.clear();
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- size_t count = AGAVE_API_PLAYLISTS->GetCount();
- playlistGUIDs.reserve( count );
- for ( size_t i = 0; i < count; i++ )
- playlistGUIDs.push_back( AGAVE_API_PLAYLISTS->GetGUID( i ) );
- ListView_SetItemCount( m_playlistslist.getwnd(), playlistGUIDs.size() );
- ListView_RedrawItems( m_playlistslist.getwnd(), 0, playlistGUIDs.size() - 1 );
- }
- }
- void ImportPlaylist( const wchar_t *srcFilename, bool callback = false )
- {
- wchar_t l_src_filename[ MAX_PATH ] = { 0 };
- lstrcpynW( l_src_filename, srcFilename, MAX_PATH );
- wchar_t filename[ MAX_PATH ] = { 0 };
- wchar_t *filenameptr = ( !g_config->ReadInt( L"external", 0 ) ? createPlayListDBFileName( filename ) : 0 );
- size_t numItems = AGAVE_API_PLAYLISTMANAGER->Copy( filename, l_src_filename );
- // get the filename of the imported playlist
- PathRemoveExtensionW( l_src_filename );
- PathStripPathW( l_src_filename );
- // just incase we've had external playlists added / imported
- // we spin through and abort trying to re-add any that match
- if ( g_config->ReadInt( L"external", 0 ) )
- {
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- size_t count = AGAVE_API_PLAYLISTS->GetCount();
- for ( size_t i = 0; i != count; i++ )
- {
- PlaylistInfo info( i );
- if ( info.Valid() )
- {
- if ( !lstrcmpiW( srcFilename, info.GetFilename() ) )
- {
- wchar_t titleStr[ 96 ] = { 0 };
- MessageBox( currentView, WASABI_API_LNGSTRINGW( IDS_EXTERNAL_ALREADY_ADDED ), WASABI_API_LNGSTRINGW_BUF( IDS_PL_FILE_MNGT, titleStr, 96 ), MB_OK | MB_ICONWARNING );
- return;
- }
- }
- }
- }
- if ( l_src_filename[ 0 ] )
- AddPlaylist( ( !callback ? 1 : 2 ), l_src_filename, ( !g_config->ReadInt( L"external", 0 ) ? filenameptr : srcFilename ), 1, g_config->ReadInt( L"cloud", 1 ), numItems );
- else
- AddPlaylist( ( !callback ? 1 : 2 ), WASABI_API_LNGSTRINGW( IDS_IMPORTED_PLAYLIST ), ( !g_config->ReadInt( L"external", 0 ) ? filenameptr : srcFilename ), 1, g_config->ReadInt( L"cloud", 1 ), numItems );
- }
- void playlists_ImportExternalPrompt( HWND hwndDlg )
- {
- // TODO decide if better to show the message on all changes or only once and
- // then just leave the user to it in the future otherwise leave as it is
- //if (!g_config->ReadInt("external_prompt", 0) && g_config->ReadInt("external", 0))
- if ( !g_config->ReadInt( L"external", 0 ) )
- {
- wchar_t titleStr[ 96 ] = { 0 };
- if ( MessageBox( hwndDlg, WASABI_API_LNGSTRINGW( IDS_EXTERNAL_CHECKED ), WASABI_API_LNGSTRINGW_BUF( IDS_PL_FILE_MNGT, titleStr, 96 ), MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2 ) == IDYES )
- {
- g_config->WriteInt( L"external", ( IsDlgButtonChecked( hwndDlg, IDC_EXTERNAL ) == BST_CHECKED ) );
- }
- else
- {
- CheckDlgButton( hwndDlg, IDC_EXTERNAL, g_config->ReadInt( L"external", 0 ) );
- }
- g_config->WriteInt( L"external_prompt", 1 );
- }
- else
- {
- g_config->WriteInt( L"external", ( IsDlgButtonChecked( hwndDlg, IDC_EXTERNAL ) == BST_CHECKED ) );
- }
- }
- UINT_PTR CALLBACK Playlist_OFNHookProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if ( uMsg == WM_INITDIALOG )
- {
- int cloud = playlists_CloudAvailable();
- HWND cloudWnd = GetDlgItem( hwndDlg, IDC_CLOUD );
- if ( IsWindow( cloudWnd ) )
- {
- ShowWindow( cloudWnd, cloud );
- CheckDlgButton( hwndDlg, IDC_CLOUD, AddToCloud() );
- }
- CheckDlgButton( hwndDlg, IDC_EXTERNAL, g_config->ReadInt( L"external", 0 ) );
- if ( !cloud )
- {
- HWND external = GetDlgItem( hwndDlg, IDC_EXTERNAL );
- if ( IsWindow( external ) && IsWindow( cloudWnd ) )
- {
- RECT r = { 0 }, cl = { 0 };
- GetWindowRect( external, &r );
- GetWindowRect( cloudWnd, &cl );
- ScreenToClient( hwndDlg, (LPPOINT)&r );
- ScreenToClient( hwndDlg, (LPPOINT)&cl );
- SetWindowPos( external, NULL, cl.left, r.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOSENDCHANGING | SWP_SHOWWINDOW );
- }
- }
- }
- else if ( uMsg == WM_COMMAND )
- {
- switch ( LOWORD( wParam ) )
- {
- case IDC_CLOUD:
- playlists_AddToCloudPrompt( hwndDlg );
- return 1;
- case IDC_EXTERNAL:
- playlists_ImportExternalPrompt( hwndDlg );
- return 1;
- }
- }
- return 0;
- }
- void Playlist_importFromFile( HWND dlgparent )
- {
- wchar_t oldCurPath[ MAX_PATH ] = { 0 };
- wchar_t newCurPath[ MAX_PATH ] = { 0 };
- bool skipRes = false;
- GetCurrentDirectoryW( MAX_PATH, oldCurPath );
- retry:
- wchar_t temp[ 1024 ] = { 0 };
- wchar_t filter[ 1024 ] = { 0 };
- AGAVE_API_PLAYLISTMANAGER->GetFilterList( filter, 1024 );
- OPENFILENAMEW l = { sizeof( l ), 0 };
- l.hwndOwner = dlgparent;
- l.lpstrFilter = filter;
- l.lpstrFile = temp;
- l.nMaxFile = 1024;
- l.lpstrTitle = WASABI_API_LNGSTRINGW( IDS_IMPORT_PLAYLIST );
- l.lpstrDefExt = L"m3u";
- l.lpstrInitialDir = WASABI_API_APP->path_getWorkingPath();
- l.lpfnHook = Playlist_OFNHookProc;
- l.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING | OFN_ENABLETEMPLATE;
- l.lpTemplateName = MAKEINTRESOURCE( IDD_IMPORT_PLFLD );
- l.hInstance = ( !skipRes ? WASABI_API_LNG_HINST : WASABI_API_ORIG_HINST );
- if ( GetOpenFileNameW( &l ) )
- {
- GetCurrentDirectoryW( MAX_PATH, newCurPath );
- WASABI_API_APP->path_setWorkingPath( newCurPath );
- ImportPlaylist( temp );
- }
- else
- {
- // deals with the extra child dialog not being present in language packs
- // so we re-spin and try to load the native version before just failing
- DWORD res = CommDlgExtendedError();
- if ( res == CDERR_NOTEMPLATE || res == CDERR_FINDRESFAILURE )
- {
- if ( !skipRes )
- {
- skipRes = true;
- goto retry;
- }
- }
- }
- SetCurrentDirectoryW( oldCurPath );
- }
- void Playlists_ReplaceBadPathChars( LPWSTR pszPath )
- {
- if ( NULL == pszPath )
- return;
- while ( L'\0' != *pszPath )
- {
- switch ( *pszPath )
- {
- case L'?':
- case L'/':
- case L'\\':
- case L':':
- case L'*':
- case L'\"':
- case L'<':
- case L'>':
- case L'|':
- *pszPath = L'_';
- break;
- default:
- if ( *pszPath < 32 )
- *pszPath = L'_';
- break;
- }
- pszPath = CharNextW( pszPath );
- }
- }
- void Playlist_export( HWND dlgparent, const wchar_t *name, const wchar_t *srcm3u )
- {
- wchar_t oldCurPath[ MAX_PATH ] = { 0 };
- GetCurrentDirectoryW( MAX_PATH, oldCurPath );
- wchar_t temp[ MAX_PATH ] = { 0 };
- OPENFILENAMEW l = { sizeof( OPENFILENAMEW ), 0 };
- l.hwndOwner = dlgparent;
- l.hInstance = plugin.hDllInstance;
- lstrcpynW( temp, name, MAX_PATH );
- Playlists_ReplaceBadPathChars( temp );
- l.nFilterIndex = g_config->ReadInt( L"filter", 3 );
- l.lpstrFilter = (LPCWSTR)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 3, IPC_GET_PLAYLIST_EXTLISTW );
- l.lpstrFile = temp;
- l.nMaxFile = MAX_PATH;
- l.lpstrTitle = WASABI_API_LNGSTRINGW( IDS_EXPORT_PLAYLIST );
- l.lpstrDefExt = L"m3u";
- l.lpstrInitialDir = WASABI_API_APP->path_getWorkingPath();
- l.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT;
- if ( GetSaveFileNameW( &l ) )
- {
- wchar_t newCurPath[ MAX_PATH ] = { 0 };
- GetCurrentDirectoryW( MAX_PATH, newCurPath );
- WASABI_API_APP->path_setWorkingPath( newCurPath );
- AGAVE_API_PLAYLISTMANAGER->Copy( temp, srcm3u );
- }
- g_config->WriteInt( L"filter", l.nFilterIndex );
- SetCurrentDirectoryW( oldCurPath );
- }
- void importPlaylistFolder( const wchar_t *path, int dorecurs )
- {
- wchar_t tmppath[ MAX_PATH ] = { 0 };
- PathCombineW( tmppath, path, L"*" );
- WIN32_FIND_DATAW d;
- HANDLE h = FindFirstFileW( tmppath, &d );
- if ( h == INVALID_HANDLE_VALUE )
- return;
- do
- {
- wchar_t l_playlist_folder[ MAX_PATH ] = { 0 };
- PathCombineW( l_playlist_folder, path, d.cFileName );
- if ( d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY && lstrcmpW( d.cFileName, L"." ) && lstrcmpW( d.cFileName, L".." ) && dorecurs )
- {
- importPlaylistFolder( l_playlist_folder, dorecurs );
- continue;
- }
- if ( AGAVE_API_PLAYLISTMANAGER->CanLoad( l_playlist_folder ) )
- {
- ImportPlaylist( l_playlist_folder, true );
- }
- } while ( FindNextFileW( h, &d ) != 0 );
- if ( h != INVALID_HANDLE_VALUE )
- FindClose( h );
- }
- void Shell_Free( void *p )
- {
- IMalloc *m;
- SHGetMalloc( &m );
- m->Free( p );
- }
- static INT_PTR CALLBACK browseCheckBoxProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if ( uMsg == WM_INITDIALOG )
- {
- int cloud = playlists_CloudAvailable();
- HWND cloudWnd = GetDlgItem( hwndDlg, IDC_CLOUD );
- if ( IsWindow( cloudWnd ) )
- {
- ShowWindow( cloudWnd, cloud );
- CheckDlgButton( hwndDlg, IDC_CLOUD, AddToCloud() );
- }
- if ( g_config->ReadInt( L"importplfoldrecurs", 1 ) )
- CheckDlgButton( hwndDlg, IDC_CHECK1, BST_CHECKED );
- CheckDlgButton( hwndDlg, IDC_CLOUD, AddToCloud() );
- CheckDlgButton( hwndDlg, IDC_EXTERNAL, g_config->ReadInt( L"external", 0 ) );
- }
- if ( uMsg == WM_COMMAND )
- {
- if ( LOWORD( wParam ) == IDC_CHECK1 )
- {
- g_config->WriteInt( L"importplfoldrecurs", !!IsDlgButtonChecked( hwndDlg, IDC_CHECK1 ) );
- }
- else if ( LOWORD( wParam ) == IDC_CLOUD )
- {
- playlists_AddToCloudPrompt( hwndDlg );
- }
- else if ( LOWORD( wParam ) == IDC_EXTERNAL )
- {
- playlists_ImportExternalPrompt( hwndDlg );
- }
- }
- return 0;
- }
- BOOL CALLBACK browseEnumProc( HWND hwnd, LPARAM lParam )
- {
- wchar_t cl[ 32 ] = { 0 };
- GetClassNameW( hwnd, cl, ARRAYSIZE( cl ) );
- if ( !lstrcmpiW( cl, WC_TREEVIEW ) )
- {
- PostMessage( hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection( hwnd ) );
- return FALSE;
- }
- return TRUE;
- }
- int CALLBACK WINAPI _bcp( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData )
- {
- switch ( uMsg )
- {
- case BFFM_INITIALIZED:
- {
- SetWindowText( hwnd, WASABI_API_LNGSTRINGW( IDS_IMPORT_PLAYLIST_FROM_FOLDER ) );
- SendMessageW( hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)WASABI_API_APP->path_getWorkingPath() );
- HWND h2 = FindWindowEx( hwnd, NULL, NULL, L"__foo" );
- if ( h2 )
- ShowWindow( h2, SW_HIDE );
- HWND h = WASABI_API_CREATEDIALOGW( IDD_BROWSE_PLFLD, hwnd, browseCheckBoxProc );
- SetWindowPos( h, 0, 4, 4, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
- ShowWindow( h, SW_SHOWNA );
- // this is not nice but it fixes the selection not working correctly on all OSes
- EnumChildWindows( hwnd, browseEnumProc, 0 );
- }
- }
- return 0;
- }
- void Playlist_importFromFolders( HWND dlgparent )
- {
- BROWSEINFOW bi = { 0 };
- wchar_t name[ MAX_PATH ] = { 0 };
- bi.hwndOwner = dlgparent;
- bi.pszDisplayName = name;
- bi.lpszTitle = L"__foo";
- bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
- bi.lpfn = _bcp;
- ITEMIDLIST *idlist = SHBrowseForFolderW( &bi );
- if ( idlist )
- {
- wchar_t path[ MAX_PATH ] = { 0 };
- SHGetPathFromIDListW( idlist, path );
- WASABI_API_APP->path_setWorkingPath( path );
- Shell_Free( idlist );
- MLNavCtrl_BeginUpdate( plugin.hwndLibraryParent, 0 );
- importPlaylistFolder( path, g_config->ReadInt( L"importplfoldrecurs", 1 ) );
- AGAVE_API_PLAYLISTS->Flush(); // REVIEW: save immediately? or only at the end?
- MLNavCtrl_EndUpdate( plugin.hwndLibraryParent );
- }
- }
- static void playlists_Save( HWND parent )
- {
- for ( size_t i = 0; i < playlistGUIDs.size(); i++ )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ i ] );
- wchar_t str[ MAX_PATH ] = { 0 };
- if ( PathIsFileSpecW( info.GetFilename() ) )
- PathCombineW( str, g_path, info.GetFilename() );
- else
- lstrcpynW( str, info.GetFilename(), MAX_PATH );
- Playlist_export( parent, info.GetName(), str );
- }
- }
- void playlists_Import( HWND hwndDlg, LPARAM lParam )
- {
- RECT r;
- HMENU menu = GetSubMenu( g_context_menus, 2 );
- GetWindowRect( (HWND)lParam, &r );
- int x = Menu_TrackPopup( plugin.hwndLibraryParent, menu, TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN | TPM_NONOTIFY | TPM_RETURNCMD, r.left, r.top, hwndDlg, NULL );
- switch ( x )
- {
- case IDC_IMPORT_PLAYLIST_FROM_FILE:
- Playlist_importFromFile( hwndDlg );
- RefreshPlaylistsList();
- break;
- case IDC_IMPORT_WINAMP_PLAYLIST:
- Playlist_importFromWinamp();
- RefreshPlaylistsList();
- break;
- case ID_PLAYLISTSIMPORT_IMPORTPLAYLISTSFROMFOLDER:
- Playlist_importFromFolders( hwndDlg );
- RefreshPlaylistsList();
- break;
- }
- }
- void playlists_Add( HWND parent, bool callback )
- {
- WASABI_API_DIALOGBOXPARAMW( ( playlists_CloudAvailable() ? IDD_ADD_CLOUD_PLAYLIST : IDD_ADD_PLAYLIST ), parent, AddPlaylistDialogProc, callback );
- }
- void DeletePlaylist( GUID _guid, HWND parent, bool confirm )
- {
- wchar_t titleStr[ 32 ] = { 0 };
- if ( confirm && MessageBox( parent, WASABI_API_LNGSTRINGW( IDS_CONFIRM_DELETION ), WASABI_API_LNGSTRINGW_BUF( IDS_CONFIRMATION, titleStr, 32 ), MB_YESNO | MB_ICONQUESTION ) != IDYES )
- {
- SetFocus( parent );
- return;
- }
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( _guid );
- wchar_t gs[ MAX_PATH + 1 ] = { 0 }, gs2[ MAX_PATH ] = { 0 };
- if ( PathIsFileSpecW( info.GetFilename() ) )
- PathCombineW( gs, g_path, info.GetFilename() );
- else
- lstrcpynW( gs, info.GetFilename(), MAX_PATH );
- wchar_t l_node[ MAX_PATH ];
- wchar_t l_dir[ MAX_PATH ];
- wchar_t l_fname[ MAX_PATH ];
- wchar_t l_ext[ MAX_PATH ];
- lstrcpynW( gs2, gs, MAX_PATH );
- _wsplitpath( gs2, l_node, l_dir, l_fname, l_ext );
- _wmakepath( gs2, l_node, l_dir, L"", L"" );
- AGAVE_API_PLAYLISTS->RemovePlaylist( info.GetIndex() );
- // changed in 5.58 to resolve the issue reported at
- // http://forums.winamp.com/showthread.php?l_plugin_message=2652001#post2652001
- // delete the file after the removal and not before which
- // fixes issues if removing the currently viewed playlist
- //DeleteFileW(gs);
- // changed in 5.64 to use SHFileOperation(..) instead of DeleteFile(..)
- // so we're able to recover external playlists incase people messup...
- SHFILEOPSTRUCTW fileOp = { 0 };
- fileOp.hwnd = parent;
- fileOp.wFunc = FO_DELETE;
- fileOp.pFrom = gs;
- fileOp.fFlags = ( lstrcmpi( g_path, gs2 ) ? FOF_ALLOWUNDO : 0 ) | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_SIMPLEPROGRESS | FOF_NORECURSION | FOF_NOERRORUI | FOF_SILENT;
- SHFileOperationW( &fileOp );
- SetFocus( parent );
- }
- static void playlists_Delete( HWND parent )
- {
- if ( !m_playlistslist.GetSelectedCount() || m_playlistslist.GetSelectionMark() == -1 )
- return;
- wchar_t titleStr[ 32 ] = { 0 };
- if ( MessageBox( parent, WASABI_API_LNGSTRINGW( IDS_CONFIRM_DELETION ), WASABI_API_LNGSTRINGW_BUF( IDS_CONFIRMATION, titleStr, 32 ), MB_YESNO | MB_ICONQUESTION ) != IDYES )
- return;
- MLNavCtrl_BeginUpdate( plugin.hwndLibraryParent, 0 );
- for ( int i = playlistGUIDs.size() - 1; i >= 0; i-- )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- DeletePlaylist( playlistGUIDs[ i ], parent, false );
- }
- AGAVE_API_PLAYLISTS->Flush(); // REVIEW: save immediately? or only at the end?
- MLNavCtrl_EndUpdate( plugin.hwndLibraryParent );
- }
- static void playlists_Play( int enqueue )
- {
- int deleted = 0;
- for ( size_t i = 0; i < playlistGUIDs.size(); i++ )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ i ] );
- wchar_t str[ MAX_PATH ] = { 0 };
- const wchar_t *fn;
- if ( PathIsFileSpecW( info.GetFilename() ) )
- {
- PathCombineW( str, g_path, info.GetFilename() );
- fn = str;
- }
- else
- {
- fn = info.GetFilename();
- }
- if ( !enqueue && !deleted )
- {
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_DELETE );
- deleted = 1;
- }
- enqueueFileWithMetaStructW s = { 0 };
- s.filename = fn;
- s.ext = NULL;
- s.length = -1;
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_PLAYFILEW );
- }
- if ( !enqueue )
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_STARTPLAY );
- }
- static void playlists_ManageButtons( HWND hwndDlg )
- {
- int has_selection = m_playlistslist.GetSelectedCount();
- const int buttonids[] = { IDC_PLAY, IDC_ENQUEUE, IDC_CUSTOM, IDC_VIEWLIST, IDC_SAVE };
- for ( size_t i = 0; i != sizeof( buttonids ) / sizeof( buttonids[ 0 ] ); i++ )
- {
- HWND controlHWND = GetDlgItem( hwndDlg, buttonids[ i ] );
- EnableWindow( controlHWND, has_selection );
- }
- }
- static void playlists_ViewList()
- {
- int t = m_playlistslist.GetSelectionMark();
- if ( t >= 0 )
- {
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ t ] );
- //if ( info.treeId == 0 ) // not created yet
- //{
- // // TODO: make a treeid for it
- //}
- mediaLibrary.SelectTreeItem( info.treeId );
- }
- }
- static void playlists_Paint( HWND hwndDlg )
- {
- int tab[] = { IDC_PLAYLIST_LIST | DCW_SUNKENBORDER, };
- dialogSkinner.Draw( hwndDlg, tab, 1 );
- }
- LRESULT playlists_cloud_listview( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- if ( uMsg == WM_NOTIFY )
- {
- LPNMHDR l = (LPNMHDR)lParam;
- switch ( l->code )
- {
- case TTN_SHOW:
- {
- LVHITTESTINFO lvh = { 0 };
- GetCursorPos( &lvh.pt );
- ScreenToClient( hwnd, &lvh.pt );
- ListView_SubItemHitTest( hwnd, &lvh );
- if ( cloud_avail && lvh.iItem != -1 && lvh.iSubItem == 1 )
- {
- LPTOOLTIPTEXTW tt = (LPTOOLTIPTEXTW)lParam;
- RECT r = { 0 };
- if ( lvh.iSubItem )
- ListView_GetSubItemRect( hwnd, lvh.iItem, lvh.iSubItem, LVIR_BOUNDS, &r );
- else
- {
- ListView_GetItemRect( hwnd, lvh.iItem, &r, LVIR_BOUNDS );
- r.right = r.left + ListView_GetColumnWidth( hwnd, 1 );
- }
- MapWindowPoints( hwnd, HWND_DESKTOP, (LPPOINT)&r, 2 );
- SetWindowPos( tt->hdr.hwndFrom, HWND_TOPMOST, r.right, r.top + 2, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE );
- return 1;
- }
- }
- break;
- case TTN_NEEDTEXTW:
- {
- LVHITTESTINFO lvh = { 0 };
- GetCursorPos( &lvh.pt );
- ScreenToClient( hwnd, &lvh.pt );
- ListView_SubItemHitTest( hwnd, &lvh );
- static wchar_t tt_buf1[ 256 ] = { L"" };
- if ( cloud_avail && lvh.iItem != -1 && lvh.iSubItem == 1 )
- {
- LPNMTTDISPINFO lpnmtdi = (LPNMTTDISPINFO)lParam;
- if ( last_item1 == lvh.iItem )
- {
- lpnmtdi->lpszText = tt_buf1;
- return 0;
- }
- if ( lvh.iItem < 0 || lvh.iItem >= (int)playlistGUIDs.size() )
- return 0;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ lvh.iItem ] );
- if ( info.Valid() )
- {
- WASABI_API_LNGSTRINGW_BUF( ( !info.GetCloud() ? IDS_UPLOAD_TO_CLOUD : IDS_AVAILABLE_IN_CLOUD ), tt_buf1, ARRAYSIZE( tt_buf1 ) );
- }
- else
- {
- WASABI_API_LNGSTRINGW_BUF( IDS_UPLOAD_TO_CLOUD, tt_buf1, ARRAYSIZE( tt_buf1 ) );
- }
- last_item1 = lvh.iItem;
- lpnmtdi->lpszText = tt_buf1;
- // bit of a fiddle but it allows for multi-line tooltips
- //SendMessage(l->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 0);
- }
- else
- return CallWindowProcW( (WNDPROC)GetPropW( hwnd, L"cloud_list_proc" ), hwnd, uMsg, wParam, lParam );
- }
- return 0;
- }
- }
- return CallWindowProcW( (WNDPROC)GetPropW( hwnd, L"cloud_list_proc" ), hwnd, uMsg, wParam, lParam );
- }
- static void playlists_InitDialog( HWND hwndDlg )
- {
- HACCEL accel = WASABI_API_LOADACCELERATORSW( IDR_VIEW_PLS_ACCELERATORS );
- if ( accel )
- WASABI_API_APP->app_addAccelerators( hwndDlg, &accel, 1, TRANSLATE_MODE_CHILD );
- if ( !view.play )
- SENDMLIPC( plugin.hwndLibraryParent, ML_IPC_GET_VIEW_BUTTON_TEXT, (WPARAM)&view );
- opened = true;
- loaded = false;
- cloud_avail = playlists_CloudAvailable();
- groupBtn = g_config->ReadInt( L"groupbtn", 1 );
- enqueuedef = ( g_config->ReadInt( L"enqueuedef", 0 ) == 1 );
- // v5.66+ - re-use the old predixis parts so the button can be used functionally via ml_enqplay
- // pass the hwnd, button id and plug-in id so the ml plug-in can check things as needed
- pluginMessage l_plugin_message = { ML_MSG_VIEW_BUTTON_HOOK, (INT_PTR)hwndDlg, (INT_PTR)MAKELONG( IDC_CUSTOM, IDC_ENQUEUE ), (INT_PTR)L"ml_playlists_root" };
- wchar_t *pszTextW = (wchar_t *)SENDMLIPC( plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&l_plugin_message );
- if ( pszTextW && pszTextW[ 0 ] != 0 )
- {
- // set this to be a bit different so we can just use one button and not the
- // mixable one as well (leaving that to prevent messing with the resources)
- customAllowed = TRUE;
- SetDlgItemTextW( hwndDlg, IDC_CUSTOM, pszTextW );
- }
- else
- customAllowed = FALSE;
- /* skin dialog */
- MLSKINWINDOW skinWindow = { 0 };
- skinWindow.skinType = SKINNEDWND_TYPE_DIALOG;
- skinWindow.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT;
- skinWindow.hwndToSkin = hwndDlg;
- MLSkinWindow( plugin.hwndLibraryParent, &skinWindow );
- /* skin listview */
- HWND hwndList = skinWindow.hwndToSkin = GetDlgItem( hwndDlg, IDC_PLAYLIST_LIST );
- skinWindow.skinType = SKINNEDWND_TYPE_LISTVIEW;
- skinWindow.style = SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWLVS_ALTERNATEITEMS | SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
- MLSkinWindow( plugin.hwndLibraryParent, &skinWindow );
- MLSkinnedScrollWnd_ShowHorzBar( hwndList, FALSE );
- /* skin buttons */
- skinWindow.skinType = SKINNEDWND_TYPE_BUTTON;
- skinWindow.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | ( groupBtn ? SWBS_SPLITBUTTON : 0 );
- const int buttonidz[] = { IDC_PLAY, IDC_ENQUEUE, IDC_CUSTOM };
- for ( size_t i = 0; i != sizeof( buttonidz ) / sizeof( buttonidz[ 0 ] ); i++ )
- {
- skinWindow.hwndToSkin = GetDlgItem( hwndDlg, buttonidz[ i ] );
- if ( IsWindow( skinWindow.hwndToSkin ) )
- MLSkinWindow( plugin.hwndLibraryParent, &skinWindow );
- }
- /* skin buttons */
- skinWindow.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS;
- const int buttonids[] = { IDC_VIEWLIST, IDC_CREATENEWPL, IDC_SAVE };
- for ( size_t i = 0; i != sizeof( buttonids ) / sizeof( buttonids[ 0 ] ); i++ )
- {
- skinWindow.hwndToSkin = GetDlgItem( hwndDlg, buttonids[ i ] );
- if ( IsWindow( skinWindow.hwndToSkin ) )
- MLSkinWindow( plugin.hwndLibraryParent, &skinWindow );
- }
- /* skin dropdown buttons */
- skinWindow.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWBS_DROPDOWNBUTTON;
- skinWindow.hwndToSkin = GetDlgItem( hwndDlg, IDC_IMPORT );
- MLSkinWindow( plugin.hwndLibraryParent, &skinWindow );
- HIMAGELIST imageList = ImageList_Create( 15, 15, ILC_COLOR24, 3, 0 );
- if ( imageList != NULL )
- {
- HIMAGELIST prevList = (HIMAGELIST)SNDMSG( hwndList, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)imageList );
- if ( prevList != NULL )
- ImageList_Destroy( prevList );
- }
- m_playlistslist.setwnd( hwndList );
- m_playlistslist.AddCol( WASABI_API_LNGSTRINGW( IDS_PLAYLIST_TITLE ), 400 );
- int width = 27;
- MLCloudColumn_GetWidth( plugin.hwndLibraryParent, &width );
- m_playlistslist.AddCol( L"", ( cloud_avail ? width : 0 ) );
- m_playlistslist.AddCol( WASABI_API_LNGSTRINGW( IDS_ITEMS ), 50 );
- m_playlistslist.AutoColumnWidth( 3 );
- m_playlistslist.JustifyColumn( 3, LVCFMT_RIGHT );
- m_playlistslist.AddCol( WASABI_API_LNGSTRINGW( IDS_TIME ), 75 );
- m_playlistslist.AutoSizeColumn( 4 );
- m_playlistslist.JustifyColumn( 4, LVCFMT_RIGHT );
- MLSkinnedHeader_SetCloudColumn( ListView_GetHeader( hwndList ), ( cloud_avail ? 1 : -1 ) );
- if ( !GetPropW( hwndList, L"cloud_list_proc" ) )
- SetPropW( hwndList, L"cloud_list_proc", (HANDLE)SetWindowLongPtrW( hwndList, GWLP_WNDPROC, (LONG_PTR)playlists_cloud_listview ) );
- playlist_UpdateButtonText( hwndDlg, enqueuedef == 1 );
- playlists_ManageButtons( hwndDlg );
- RefreshPlaylistsList();
- SetWindowRedraw( m_playlistslist.getwnd(), FALSE );
- }
- void playlists_Destroy( HWND hwndDlg )
- {
- opened = false;
- WASABI_API_APP->app_removeAccelerators( hwndDlg );
- m_playlistslist.setwnd( NULL );
- playlistGUIDs.clear();
- }
- BOOL playlists_GetDisplayInfo( NMLVDISPINFO *lpdi )
- {
- size_t item = lpdi->item.iItem;
- if ( item < 0 || item >= playlistGUIDs.size() )
- return 0;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ item ] );
- if ( lpdi->item.mask & LVIF_TEXT && info.Valid() )
- {
- switch ( lpdi->item.iSubItem )
- {
- case 0:
- {
- // TODO: this is going to be slow, we should investigate caching the title
- lstrcpyn( lpdi->item.pszText, info.GetName(), lpdi->item.cchTextMax );
- break;
- }
- case 1:
- {
- StringCchPrintf( lpdi->item.pszText, lpdi->item.cchTextMax, L"%d", info.GetCloud() );
- break;
- }
- case 2:
- {
- StringCchPrintf( lpdi->item.pszText, lpdi->item.cchTextMax, L"%d", info.GetSize() );
- break;
- }
- case 3:
- {
- wchar_t str[ 64 ] = { 0 };
- FormatLength( str, info.GetLength(), 64 );
- lstrcpyn( lpdi->item.pszText, str, lpdi->item.cchTextMax );
- }
- break;
- }
- }
- return 0;
- }
- void Playlists_RenameSelected( HWND hwndDlg )
- {
- // TOOD: loop through selections
- int s = m_playlistslist.GetSelectionMark();
- if ( s != -1 )
- RenamePlaylist( playlistGUIDs[ s ], hwndDlg );
- }
- BOOL playlists_OnCustomDraw( HWND hwndDlg, NMLVCUSTOMDRAW *plvcd, LRESULT *pResult )
- {
- static BOOL bDrawFocus;
- static RECT rcView;
- static CLOUDCOLUMNPAINT cloudColumnPaint;
- *pResult = CDRF_DODEFAULT;
- switch ( plvcd->nmcd.dwDrawStage )
- {
- case CDDS_PREPAINT:
- *pResult |= CDRF_NOTIFYITEMDRAW;
- CopyRect( &rcView, &plvcd->nmcd.rc );
- cloudColumnPaint.hwndList = plvcd->nmcd.hdr.hwndFrom;
- cloudColumnPaint.hdc = plvcd->nmcd.hdc;
- cloudColumnPaint.prcView = &rcView;
- return TRUE;
- case CDDS_ITEMPREPAINT:
- *pResult |= CDRF_NOTIFYSUBITEMDRAW;
- bDrawFocus = ( CDIS_FOCUS & plvcd->nmcd.uItemState );
- if ( bDrawFocus )
- {
- plvcd->nmcd.uItemState &= ~CDIS_FOCUS;
- *pResult |= CDRF_NOTIFYPOSTPAINT;
- }
- return TRUE;
- case CDDS_ITEMPOSTPAINT:
- if ( bDrawFocus )
- {
- RECT rc;
- rc.left = LVIR_BOUNDS;
- SendMessageW( plvcd->nmcd.hdr.hwndFrom, LVM_GETITEMRECT, plvcd->nmcd.dwItemSpec, (LPARAM)&rc );
- rc.left += 3;
- DrawFocusRect( plvcd->nmcd.hdc, &rc );
- plvcd->nmcd.uItemState |= CDIS_FOCUS;
- bDrawFocus = FALSE;
- }
- *pResult = CDRF_SKIPDEFAULT;
- return TRUE;
- case( CDDS_SUBITEM | CDDS_ITEMPREPAINT ):
- // TODO need to have a map between column ids so we do this correctly
- if ( plvcd->iSubItem == 1 )
- {
- if ( 0 == plvcd->iSubItem && 0 == plvcd->nmcd.rc.right || playlistGUIDs.empty() )
- break;
- cloudColumnPaint.iItem = plvcd->nmcd.dwItemSpec;
- cloudColumnPaint.iSubItem = plvcd->iSubItem;
- int cloud_icon = 0;
- size_t item = plvcd->nmcd.dwItemSpec;
- if ( item >= 0 || item < playlistGUIDs.size() )
- {
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ item ] );
- if ( info.Valid() )
- cloud_icon = info.GetCloud();
- }
- // TODO have this show an appropriate cloud icon for the playlist
- // currently all we have is cloud or nothing as we'll only
- // have files locally for this for the moment (need todo!!!)
- cloudColumnPaint.value = cloud_icon;
- cloudColumnPaint.prcItem = &plvcd->nmcd.rc;
- cloudColumnPaint.rgbBk = plvcd->clrTextBk;
- cloudColumnPaint.rgbFg = plvcd->clrText;
- if ( MLCloudColumn_Paint( plugin.hwndLibraryParent, &cloudColumnPaint ) )
- {
- *pResult = CDRF_SKIPDEFAULT;
- return TRUE;
- }
- }
- break;
- }
- return FALSE;
- }
- BOOL playlists_Notify( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
- {
- LPNMHDR l = (LPNMHDR)lParam;
- if ( l->idFrom == IDC_PLAYLIST_LIST )
- {
- switch ( l->code )
- {
- case LVN_ITEMCHANGED:
- playlists_ManageButtons( hwndDlg );
- break;
- case LVN_BEGINDRAG:
- root_is_drag_and_dropping = 1; SetCapture( hwndDlg );
- break;
- case LVN_GETDISPINFO:
- return playlists_GetDisplayInfo( (NMLVDISPINFO *)lParam );
- case NM_DBLCLK:
- playlists_Play( enqueuedef == 1 );
- break;
- case NM_CLICK:
- {
- LPNMITEMACTIVATE pnmitem = (LPNMITEMACTIVATE)lParam;
- if ( cloud_avail && pnmitem->iItem != -1 && pnmitem->iSubItem == 1 )
- {
- RECT itemRect = { 0 };
- if ( pnmitem->iSubItem )
- ListView_GetSubItemRect( pnmitem->hdr.hwndFrom, pnmitem->iItem, pnmitem->iSubItem, LVIR_BOUNDS, &itemRect );
- else
- {
- ListView_GetItemRect( pnmitem->hdr.hwndFrom, pnmitem->iItem, &itemRect, LVIR_BOUNDS );
- itemRect.right = itemRect.left + ListView_GetColumnWidth( pnmitem->hdr.hwndFrom, pnmitem->iSubItem );
- }
- MapWindowPoints( pnmitem->hdr.hwndFrom, HWND_DESKTOP, (POINT *)&itemRect, 2 );
- size_t item = pnmitem->iItem;
- if ( item < 0 || item >= playlistGUIDs.size() )
- return 0;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ item ] );
- HMENU cloud_menu = (HMENU)0x666;
- ReferenceCountedNXString uid;
- NXStringCreateWithFormatting( &uid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- (int)info.playlist_guid.Data1, (int)info.playlist_guid.Data2,
- (int)info.playlist_guid.Data3, (int)info.playlist_guid.Data4[ 0 ],
- (int)info.playlist_guid.Data4[ 1 ], (int)info.playlist_guid.Data4[ 2 ],
- (int)info.playlist_guid.Data4[ 3 ], (int)info.playlist_guid.Data4[ 4 ],
- (int)info.playlist_guid.Data4[ 5 ], (int)info.playlist_guid.Data4[ 6 ],
- (int)info.playlist_guid.Data4[ 7 ] );
- WASABI_API_SYSCB->syscb_issueCallback( api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_GET_CLOUD_STATUS, (intptr_t)uid->string, (intptr_t)&cloud_menu );
- if ( cloud_menu )
- {
- int r = Menu_TrackPopup( plugin.hwndLibraryParent, cloud_menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_NONOTIFY, itemRect.right, itemRect.top, pnmitem->hdr.hwndFrom, NULL );
- if ( r >= CLOUD_SOURCE_MENUS && r < CLOUD_SOURCE_MENUS_PL_UPPER ) // deals with cloud specific menus
- {
- // 0 = no change
- // 1 = adding to cloud
- // 2 = added locally
- // 4 = removed
- int mode = -(int)info.GetIndex();
- WASABI_API_SYSCB->syscb_issueCallback( api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PROCESS_CLOUD_STATUS, (intptr_t)r, (intptr_t)&mode );
- if ( mode > 0 )
- {
- info.SetCloud( ( mode == 1 ? 1 : 0 ) );
- AGAVE_API_PLAYLISTS->Flush();
- UpdatePlaylists();
- last_item1 = -1;
- }
- }
- DestroyMenu( cloud_menu );
- }
- }
- }
- break;
- case LVN_KEYDOWN:
- {
- LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN)lParam;
- switch ( pnkd->wVKey )
- {
- case 0x2E: //Delete
- playlists_Delete( hwndDlg );
- break;
- case VK_F2:
- Playlists_RenameSelected( hwndDlg );
- SendMessage( hwndDlg, WM_NEXTDLGCTL, (WPARAM)l->hwndFrom, (LPARAM)TRUE );
- break;
- case 'A':
- if ( !( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) && ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) )
- m_playlistslist.SelectAll();
- break;
- }
- }
- break;
- case NM_CUSTOMDRAW:
- {
- LRESULT result = 0;
- if ( cloud_avail && playlists_OnCustomDraw( hwndDlg, (NMLVCUSTOMDRAW *)lParam, &result ) )
- {
- SetWindowLongPtrW( hwndDlg, DWLP_MSGRESULT, (LONG_PTR)result );
- return 1;
- }
- break;
- }
- }
- }
- switch ( l->code )
- {
- case HDN_ITEMCHANGING:
- {
- LPNMHEADERW phdr = (LPNMHEADERW)lParam;
- if ( phdr->pitem && ( HDI_WIDTH & phdr->pitem->mask ) && phdr->iItem == 1 )
- {
- if ( !cloud_avail )
- phdr->pitem->cxy = 0;
- else
- {
- INT width = phdr->pitem->cxy;
- if ( MLCloudColumn_GetWidth( plugin.hwndLibraryParent, &width ) )
- phdr->pitem->cxy = width;
- }
- }
- break;
- }
- }
- return 0;
- }
- void playlists_MouseMove( HWND hwndDlg, LPARAM lParam )
- {
- if ( root_is_drag_and_dropping && GetCapture() == hwndDlg )
- {
- POINT p = { GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) };
- ClientToScreen( hwndDlg, &p );
- mlDropItemStruct m = { 0 };
- m.type = ML_TYPE_FILENAMES;
- m.p = p;
- pluginHandleIpcMessage( ML_IPC_HANDLEDRAG, (WPARAM)&m );
- }
- }
- void playlists_LeftButtonUp( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
- {
- if ( root_is_drag_and_dropping && GetCapture() == hwndDlg )
- {
- ReleaseCapture();
- POINT p = { GET_X_LPARAM( lParam ),GET_Y_LPARAM( lParam ) };
- ClientToScreen( hwndDlg, &p );
- mlDropItemStruct m = { 0 };
- m.type = ML_TYPE_FILENAMES;
- m.p = p;
- pluginHandleIpcMessage( ML_IPC_HANDLEDRAG, (WPARAM)&m );
- if ( m.result > 0 )
- {
- //std::vector<char> data;
- std::string data;
- for ( size_t i = 0; i < playlistGUIDs.size(); i++ )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ i ] );
- wchar_t str[ MAX_PATH ] = { 0 };
- if ( PathIsFileSpecW( info.GetFilename() ) )
- PathCombineW( str, g_path, info.GetFilename() );
- else
- lstrcpynW( str, info.GetFilename(), MAX_PATH );
- AutoChar charStr( str );
- // HAKAN: why (len + 1) ?
- //data.append(charStr, lstrlenA( charStr + 1));
- data.append(charStr, lstrlenA(charStr));
- }
- // HAKAN: No need to add trailing zero
- //data.push_back( 0 );
- m.flags = 0;
- m.result = 0;
- m.data = (void *)data.c_str();
- pluginHandleIpcMessage( ML_IPC_HANDLEDROP, (WPARAM)&m );
- RefreshPlaylistsList();
- }
- root_is_drag_and_dropping = 0;
- }
- }
- enum
- {
- BPM_ECHO_WM_COMMAND = 0x1, // send WM_COMMAND and return value
- BPM_WM_COMMAND = 0x2, // just send WM_COMMAND
- };
- static void playlists_PlayEnqueue( HWND hwndDlg, HWND from, UINT idFrom )
- {
- HMENU listMenu = GetSubMenu( g_context_menus3, 0 );
- int count = GetMenuItemCount( listMenu );
- if ( count > 2 )
- {
- for ( int i = 2; i < count; i++ )
- DeleteMenu( listMenu, 2, MF_BYPOSITION );
- }
- UINT menuStatus;
- if ( m_playlistslist.GetNextSelected( -1 ) == -1 )
- menuStatus = MF_BYCOMMAND | MF_GRAYED;
- else
- menuStatus = MF_BYCOMMAND | MF_ENABLED;
- EnableMenuItem( listMenu, IDC_PLAYLIST_INVERT_SELECTION, menuStatus );
- if ( m_playlistslist.GetCount() > 0 )
- menuStatus = MF_BYCOMMAND | MF_ENABLED;
- else
- menuStatus = MF_BYCOMMAND | MF_GRAYED;
- EnableMenuItem( listMenu, IDC_PLAYLIST_SELECT_ALL, menuStatus );
- playlist_ButtonPopupMenu( hwndDlg, idFrom, listMenu, BPM_WM_COMMAND );
- }
- void playlists_Command( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
- {
- switch ( LOWORD( wParam ) )
- {
- case IDC_VIEWLIST:
- playlists_ViewList();
- break;
- case IDC_IMPORT:
- playlists_Import( hwndDlg, lParam );
- break;
- case IDC_CREATENEWPL:
- case IDC_NEWPLAYLIST:
- playlists_Add( hwndDlg );
- break;
- case IDC_PLAY:
- case IDC_ENQUEUE:
- case IDC_CUSTOM:
- {
- if ( HIWORD( wParam ) == MLBN_DROPDOWN )
- {
- playlists_PlayEnqueue( hwndDlg, (HWND)lParam, LOWORD( wParam ) );
- }
- else
- {
- int action;
- if ( LOWORD( wParam ) == IDC_PLAY )
- action = ( HIWORD( wParam ) == 1 ) ? enqueuedef == 1 : 0;
- else if ( LOWORD( wParam ) == IDC_ENQUEUE )
- action = ( HIWORD( wParam ) == 1 ) ? ( enqueuedef != 1 ) : 1;
- else
- // so custom can work with the menu item part
- break;
- playlists_Play( action );
- }
- break;
- }
- case IDC_SAVE:
- playlists_Save( hwndDlg );
- break;
- case IDC_DELETE:
- playlists_Delete( hwndDlg );
- break;
- case IDC_RENAME:
- Playlists_RenameSelected( hwndDlg );
- break;
- }
- }
- void playlists_DropFiles( HDROP hDrop )
- {
- wchar_t l_playlist_filename[ 2048 ] = { 0 };
- int y = DragQueryFileW( hDrop, 0xffffffff, l_playlist_filename, 2048 );
- for ( int x = 0; x < y; x++ )
- {
- Playlist currentPlaylist2;
- DragQueryFileW( hDrop, x, l_playlist_filename, 2048 );
- // make sure that we only add valid playlists and not normal files
- if ( AGAVE_API_PLAYLISTMANAGER->CanLoad( l_playlist_filename ) )
- {
- ImportPlaylist( l_playlist_filename );
- }
- }
- }
- void playlists_Sort( size_t sort_type )
- {
- int cur_sel = mediaLibrary.GetSelectedTreeItem();
- GUID cur_guid = tree_to_guid_map[ cur_sel ];
- // keep the old tree ids before sorting so we can then re-map
- // without having to remove and re-add all of the tree items
- std::vector<int> tree_ids;
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- size_t count = AGAVE_API_PLAYLISTS->GetCount();
- for ( size_t i = 0; i != count; i++ )
- {
- PlaylistInfo info( i );
- if ( info.Valid() )
- tree_ids.push_back( info.treeId );
- }
- if ( AGAVE_API_PLAYLISTS->Sort( sort_type ) )
- {
- for ( size_t i = 0; i != count; i++ )
- {
- PlaylistInfo info( i );
- UpdateTree( info, tree_ids[ i ] );
- }
- for ( size_t i = 0; i != count; i++ )
- {
- PlaylistInfo info( i );
- if ( cur_guid == info.playlist_guid )
- {
- mediaLibrary.SelectTreeItem( info.treeId );
- }
- }
- RefreshPlaylistsList();
- }
- }
- void playlists_ContextMenu( HWND hwndDlg, HWND from, int x, int y )
- {
- if ( from != m_playlistslist.getwnd() )
- return;
- POINT pt = { x,y };
- if ( x == -1 || y == -1 ) // x and y are -1 if the user invoked a shift-f10 popup menu
- {
- RECT channelRect = { 0 };
- int selected = m_playlistslist.GetNextSelected();
- if ( selected != -1 ) // if something is selected we'll drop the menu from there
- {
- m_playlistslist.GetItemRect( selected, &channelRect );
- ClientToScreen( hwndDlg, (POINT *)&channelRect );
- }
- else // otherwise we'll drop it from the top-left corner of the listview, adjusting for the header location
- {
- GetWindowRect( hwndDlg, &channelRect );
- HWND hHeader = (HWND)SNDMSG( from, LVM_GETHEADER, 0, 0L );
- RECT headerRect;
- if ( ( WS_VISIBLE & GetWindowLongPtr( hHeader, GWL_STYLE ) ) && GetWindowRect( hHeader, &headerRect ) )
- {
- channelRect.top += ( headerRect.bottom - headerRect.top );
- }
- }
- x = channelRect.left;
- y = channelRect.top;
- }
- HWND hHeader = (HWND)SNDMSG( from, LVM_GETHEADER, 0, 0L );
- RECT headerRect;
- if ( 0 == ( WS_VISIBLE & GetWindowLongPtr( hHeader, GWL_STYLE ) ) || FALSE == GetWindowRect( hHeader, &headerRect ) )
- SetRectEmpty( &headerRect );
- if ( FALSE != PtInRect( &headerRect, pt ) )
- return;
- HMENU menu = GetSubMenu( g_context_menus, 0 );
- sendTo.AddHere( hwndDlg, GetSubMenu( menu, 2 ), ML_TYPE_FILENAMES, 1, ( ML_TYPE_PLAYLIST + 1 ) );
- HMENU cloud_hmenu = (HMENU)0x666;
- size_t index = 0, i = 0;
- if ( playlists_CloudAvailable() )
- {
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- for ( ; i < playlistGUIDs.size(); i++ )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- PlaylistInfo info( playlistGUIDs[ i ] );
- ReferenceCountedNXString uid;
- NXStringCreateWithFormatting( &uid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
- (int)info.playlist_guid.Data1, (int)info.playlist_guid.Data2,
- (int)info.playlist_guid.Data3, (int)info.playlist_guid.Data4[ 0 ],
- (int)info.playlist_guid.Data4[ 1 ], (int)info.playlist_guid.Data4[ 2 ],
- (int)info.playlist_guid.Data4[ 3 ], (int)info.playlist_guid.Data4[ 4 ],
- (int)info.playlist_guid.Data4[ 5 ], (int)info.playlist_guid.Data4[ 6 ],
- (int)info.playlist_guid.Data4[ 7 ] );
- index = info.GetIndex();
- WASABI_API_SYSCB->syscb_issueCallback( api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_GET_CLOUD_STATUS, (intptr_t)uid->string, (intptr_t)&cloud_hmenu );
- if ( cloud_hmenu && cloud_hmenu != (HMENU)0x666 )
- {
- MENUITEMINFOW m = { sizeof( m ), MIIM_TYPE | MIIM_ID | MIIM_SUBMENU, MFT_SEPARATOR, 0 };
- m.wID = CLOUD_SOURCE_MENUS - 1;
- InsertMenuItemW( menu, 3, TRUE, &m );
- wchar_t a[ 100 ] = { 0 };
- m.fType = MFT_STRING;
- m.dwTypeData = WASABI_API_LNGSTRINGW_BUF( IDS_CLOUD_SOURCES, a, 100 );
- m.wID = CLOUD_SOURCE_MENUS;
- m.hSubMenu = cloud_hmenu;
- InsertMenuItemW( menu, 4, TRUE, &m );
- }
- break;
- }
- }
- UpdateMenuItems( hwndDlg, menu );
- UINT menuStatus;
- if ( m_playlistslist.GetNextSelected( -1 ) == -1 )
- {
- menuStatus = MF_BYCOMMAND | MF_GRAYED;
- EnableMenuItem( menu, 2, MF_BYPOSITION | MF_GRAYED );
- EnableMenuItem( menu, CLOUD_SOURCE_MENUS, MF_BYCOMMAND | MF_GRAYED );
- }
- else
- {
- menuStatus = MF_BYCOMMAND | MF_ENABLED;
- EnableMenuItem( menu, 2, MF_BYPOSITION | MF_ENABLED );
- EnableMenuItem( menu, CLOUD_SOURCE_MENUS, MF_BYCOMMAND | MF_ENABLED );
- }
- EnableMenuItem( menu, IDC_PLAY, menuStatus );
- EnableMenuItem( menu, IDC_ENQUEUE, menuStatus );
- EnableMenuItem( menu, IDC_DELETE, menuStatus );
- EnableMenuItem( menu, ID_QUERYMENU_ADDNEWQUERY, menuStatus );
- EnableMenuItem( menu, IDC_RENAME, menuStatus );
- EnableMenuItem( menu, IDC_ENQUEUE, menuStatus );
- EnableMenuItem( menu, IDC_VIEWLIST, menuStatus );
- int r = Menu_TrackPopup( plugin.hwndLibraryParent, menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, x, y, hwndDlg, NULL );
- switch ( r )
- {
- case IDC_VIEWLIST:
- playlists_ViewList();
- break;
- case IDC_NEWPLAYLIST:
- playlists_Add( hwndDlg );
- break;
- case IDC_PLAY:
- playlists_Play( 0 );
- break;
- case IDC_ENQUEUE:
- playlists_Play( 1 );
- break;
- case IDC_DELETE:
- playlists_Delete( hwndDlg );
- SendMessage( hwndDlg, WM_NEXTDLGCTL, (WPARAM)from, (LPARAM)TRUE );
- break;
- case ID_QUERYMENU_ADDNEWQUERY:
- playlists_Add( hwndDlg );
- SendMessage( hwndDlg, WM_NEXTDLGCTL, (WPARAM)from, (LPARAM)TRUE );
- break;
- case IDC_RENAME:
- Playlists_RenameSelected( hwndDlg );
- SendMessage( hwndDlg, WM_NEXTDLGCTL, (WPARAM)from, (LPARAM)TRUE );
- break;
- default:
- if ( sendTo.WasClicked( r ) )
- {
- bool playlist_type_worked = true;
- int numPlaylists = m_playlistslist.GetSelectedCount();
- if ( !numPlaylists )
- break;
- mlPlaylist **playlists = new mlPlaylist * [ numPlaylists + 1 ];
- playlists[ numPlaylists ] = 0; // null terminate
- // TODO: m_playlistslist.GetNextSelected()
- for ( int i = 0, pl = 0; i < m_playlistslist.GetCount(); i++ )
- {
- if ( !m_playlistslist.GetSelected( i ) )
- continue;
- playlists[ pl ] = new mlPlaylist;
- memset( playlists[ pl ], 0, sizeof( mlPlaylist ) );
- { // scope for lock
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- PlaylistInfo info( playlistGUIDs[ i ] );
- playlists[ pl ]->filename = _wcsdup( info.GetFilename() );
- playlists[ pl ]->length = info.GetLength();
- playlists[ pl ]->numItems = info.GetSize();
- playlists[ pl ]->title = _wcsdup( info.GetName() );
- }
- pl++;
- }
- if ( sendTo.SendPlaylists( playlists ) != 1 )
- {
- for ( int i = 0; i < numPlaylists; i++ )
- {
- if ( sendTo.SendPlaylist( playlists[ i ] ) != 1 )
- {
- playlist_type_worked = false;
- break;
- }
- }
- }
- for ( int i = 0; i < numPlaylists; i++ )
- {
- free( (void *)playlists[ i ]->filename );
- free( (void *)playlists[ i ]->title );
- delete playlists[ i ];
- }
- delete[] playlists;
- if ( !playlist_type_worked )
- {
- //std::vector<wchar_t> data;
- std::wstring data;
- { // scope for lock
- AutoLockT<api_playlists> lock( AGAVE_API_PLAYLISTS );
- for ( size_t ipl = 0; ipl < playlistGUIDs.size(); ipl++ )
- {
- if ( !m_playlistslist.GetSelected( ipl ) )
- continue;
- PlaylistInfo info( playlistGUIDs[ ipl ] );
- wchar_t str[ MAX_PATH ] = { 0 };
- if ( PathIsFileSpecW( info.GetFilename() ) )
- PathCombineW( str, g_path, info.GetFilename() );
- else
- lstrcpynW( str, info.GetFilename(), MAX_PATH );
- // HAKAN: why (len + 1) ?
- //data.append( str, lstrlen(str) + 1);
- data.append(str, lstrlen(str));
- }
- }
- // HAKAN: No need to add trailing zero
- //data.push_back( 0 );
- //
- // build my data.
- sendTo.SendFilenames( data.c_str() );
- }
- }
- else
- {
- if ( r >= CLOUD_SOURCE_MENUS && r < CLOUD_SOURCE_MENUS_PL_UPPER ) // deals with cloud specific menus
- {
- // 0 = no change
- // 1 = adding to cloud
- // 2 = added locally
- // 4 = removed
- int mode = -(int)index;
- WASABI_API_SYSCB->syscb_issueCallback( api_mldb::SYSCALLBACK, api_mldb::MLDB_FILE_PROCESS_CLOUD_STATUS, (intptr_t)r, (intptr_t)&mode );
- if ( mode > 0 )
- {
- PlaylistInfo info( playlistGUIDs[ i ] );
- info.SetCloud( ( mode == 1 ? 1 : 0 ) );
- AGAVE_API_PLAYLISTS->Flush();
- UpdatePlaylists();
- last_item1 = -1;
- }
- }
- }
- break;
- }
- sendTo.Cleanup();
- if ( cloud_hmenu && cloud_hmenu != (HMENU)0x666 )
- {
- DeleteMenu( menu, CLOUD_SOURCE_MENUS - 1, MF_BYCOMMAND );
- DeleteMenu( menu, CLOUD_SOURCE_MENUS, MF_BYCOMMAND );
- DestroyMenu( cloud_hmenu );
- }
- }
- static HRGN g_rgnUpdate = NULL;
- static int offsetX = 0;
- static int offsetY = 0;
- typedef struct _LAYOUT
- {
- INT id;
- HWND hwnd;
- INT x;
- INT y;
- INT cx;
- INT cy;
- DWORD flags;
- HRGN rgn;
- }
- LAYOUT, PLAYOUT;
- #define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
- #define SETLAYOUTFLAGS(_layout, _r) \
- { \
- BOOL fVis; \
- fVis = (WS_VISIBLE & (LONG)GetWindowLongPtr(_layout->hwnd, GWL_STYLE)); \
- if (_layout->x == _r.left && _layout->y == _r.top) _layout->flags |= SWP_NOMOVE; \
- if (_layout->cx == (_r.right - _r.left) && _layout->cy == (_r.bottom - _r.top)) _layout->flags |= SWP_NOSIZE; \
- if ((SWP_HIDEWINDOW & _layout->flags) && !fVis) _layout->flags &= ~SWP_HIDEWINDOW; \
- if ((SWP_SHOWWINDOW & _layout->flags) && fVis) _layout->flags &= ~SWP_SHOWWINDOW; \
- }
- #define LAYOUTNEEEDUPDATE(_layout) ((SWP_NOMOVE | SWP_NOSIZE) != ((SWP_NOMOVE | SWP_NOSIZE | SWP_HIDEWINDOW | SWP_SHOWWINDOW) & _layout->flags))
- #define GROUP_MIN 0x1
- #define GROUP_MAX 0x2
- #define GROUP_STATUSBAR 0x1
- #define GROUP_MAIN 0x2
- static void LayoutWindows( HWND hwnd, BOOL fRedraw, BOOL fUpdateAll = FALSE )
- {
- static INT controls[] =
- {
- GROUP_STATUSBAR, IDC_PLAY, IDC_ENQUEUE, IDC_CUSTOM, IDC_VIEWLIST, IDC_CREATENEWPL, IDC_IMPORT, IDC_SAVE,
- GROUP_MAIN, IDC_PLAYLIST_LIST
- };
- INT index;
- RECT rc, rg, ri;
- LAYOUT layout[ sizeof( controls ) / sizeof( controls[ 0 ] ) ], *pl;
- BOOL skipgroup;
- HRGN rgn = NULL;
- GetClientRect( hwnd, &rc );
- if ( rc.right == rc.left || rc.bottom == rc.top )
- return;
- if ( rc.right > WASABI_API_APP->getScaleX( 4 ) )
- rc.right -= WASABI_API_APP->getScaleX( 4 );
- SetRect( &rg, rc.left, rc.top, rc.right, rc.top );
- pl = layout;
- skipgroup = FALSE;
- InvalidateRect( hwnd, NULL, TRUE );
- for ( index = 0; index < sizeof( controls ) / sizeof( *controls ); index++ )
- {
- if ( controls[ index ] >= GROUP_MIN && controls[ index ] <= GROUP_MAX ) // group id
- {
- skipgroup = FALSE;
- switch ( controls[ index ] )
- {
- case GROUP_STATUSBAR:
- {
- wchar_t buffer[ 128 ] = { 0 };
- GetDlgItemTextW( hwnd, IDC_PLAY, buffer, ARRAYSIZE( buffer ) );
- LRESULT idealSize = MLSkinnedButton_GetIdealSize( GetDlgItem( hwnd, IDC_PLAY ), buffer );
- SetRect( &rg, rc.left + WASABI_API_APP->getScaleX( 1 ),
- rc.bottom - WASABI_API_APP->getScaleY( HIWORD( idealSize ) ),
- rc.right, rc.bottom );
- rc.bottom = rg.top - WASABI_API_APP->getScaleY( 3 );
- break;
- }
- case GROUP_MAIN:
- SetRect( &rg, rc.left + WASABI_API_APP->getScaleX( 1 ), rc.top, rc.right, rc.bottom );
- break;
- }
- continue;
- }
- if ( skipgroup )
- continue;
- pl->id = controls[ index ];
- pl->hwnd = GetDlgItem( hwnd, pl->id );
- if ( !pl->hwnd )
- continue;
- GetWindowRect( pl->hwnd, &ri );
- MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
- pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
- switch ( pl->id )
- {
- case IDC_PLAY:
- case IDC_ENQUEUE:
- case IDC_CUSTOM:
- case IDC_VIEWLIST:
- case IDC_CREATENEWPL:
- case IDC_IMPORT:
- case IDC_SAVE:
- if ( IDC_CUSTOM != pl->id || customAllowed )
- {
- if ( groupBtn && ( pl->id == IDC_PLAY ) && ( enqueuedef == 1 ) )
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- if ( groupBtn && ( pl->id == IDC_ENQUEUE ) && ( enqueuedef != 1 ) )
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- if ( groupBtn && ( pl->id == IDC_PLAY || pl->id == IDC_ENQUEUE ) && customAllowed )
- {
- pl->flags |= SWP_HIDEWINDOW;
- break;
- }
- wchar_t buffer[ 128 ] = { 0 };
- GetWindowText( pl->hwnd, buffer, ARRAYSIZE( buffer ) );
- LRESULT idealSize = MLSkinnedButton_GetIdealSize( pl->hwnd, buffer );
- LONG width = LOWORD( idealSize ) + ( pl->id != IDC_IMPORT ? WASABI_API_APP->getScaleX( 6 ) : 0 );
- SETLAYOUTPOS( pl, rg.left, rg.bottom - WASABI_API_APP->getScaleY( HIWORD( idealSize ) ), width, WASABI_API_APP->getScaleY( HIWORD( idealSize ) ) );
- pl->flags |= ( ( rg.right - rg.left ) > width ) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- if ( SWP_SHOWWINDOW & pl->flags )
- rg.left += ( pl->cx + WASABI_API_APP->getScaleX( 4 ) );
- }
- else
- pl->flags |= SWP_HIDEWINDOW;
- break;
- case IDC_PLAYLIST_LIST:
- pl->flags |= ( rg.top < rg.bottom ) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- SETLAYOUTPOS( pl, rg.left, rg.top + WASABI_API_APP->getScaleY( 1 ), rg.right - rg.left + WASABI_API_APP->getScaleX( 1 ), ( rg.bottom - rg.top ) - WASABI_API_APP->getScaleY( 2 ) );
- break;
- }
- SETLAYOUTFLAGS( pl, ri );
- if ( LAYOUTNEEEDUPDATE( pl ) )
- {
- if ( SWP_NOSIZE == ( ( SWP_HIDEWINDOW | SWP_SHOWWINDOW | SWP_NOSIZE ) & pl->flags ) && ri.left == ( pl->x + offsetX ) && ri.top == ( pl->y + offsetY ) && IsWindowVisible( pl->hwnd ) )
- {
- SetRect( &ri, pl->x, pl->y, pl->cx + pl->x, pl->y + pl->cy );
- ValidateRect( hwnd, &ri );
- }
- pl++;
- }
- else if ( ( fRedraw || ( !offsetX && !offsetY ) ) && IsWindowVisible( pl->hwnd ) )
- {
- ValidateRect( hwnd, &ri );
- if ( GetUpdateRect( pl->hwnd, NULL, FALSE ) )
- {
- if ( !rgn )
- rgn = CreateRectRgn( 0, 0, 0, 0 );
- GetUpdateRgn( pl->hwnd, rgn, FALSE );
- OffsetRgn( rgn, pl->x, pl->y );
- InvalidateRgn( hwnd, rgn, FALSE );
- }
- }
- }
- if ( pl != layout )
- {
- LAYOUT *pc;
- HDWP hdwp = BeginDeferWindowPos( (INT)( pl - layout ) );
- for ( pc = layout; pc < pl && hdwp; pc++ )
- hdwp = DeferWindowPos( hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
- if ( hdwp )
- EndDeferWindowPos( hdwp );
- if ( !rgn )
- rgn = CreateRectRgn( 0, 0, 0, 0 );
- for ( pc = layout; pc < pl && hdwp; pc++ )
- {
- switch ( pc->id )
- {
- case IDC_PLAYLIST_LIST:
- PostMessage( hwnd, WM_APP + 100, 0, 0 );
- break;
- }
- }
- if ( fRedraw )
- {
- GetUpdateRgn( hwnd, rgn, FALSE );
- for ( pc = layout; pc < pl && hdwp; pc++ )
- {
- if ( pc->rgn )
- {
- OffsetRgn( pc->rgn, pc->x, pc->y );
- CombineRgn( rgn, rgn, pc->rgn, RGN_OR );
- }
- }
- RedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN );
- }
- if ( g_rgnUpdate )
- {
- GetUpdateRgn( hwnd, g_rgnUpdate, FALSE );
- for ( pc = layout; pc < pl && hdwp; pc++ )
- {
- if ( pc->rgn )
- {
- OffsetRgn( pc->rgn, pc->x, pc->y );
- CombineRgn( g_rgnUpdate, g_rgnUpdate, pc->rgn, RGN_OR );
- }
- }
- }
- for ( pc = layout; pc < pl && hdwp; pc++ )
- if ( pc->rgn )
- DeleteObject( pc->rgn );
- }
- if ( rgn )
- DeleteObject( rgn );
- ValidateRgn( hwnd, NULL );
- }
- INT_PTR CALLBACK view_playlistsDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- INT_PTR a = dialogSkinner.Handle( hwndDlg, uMsg, wParam, lParam ); if ( a ) return a;
- switch ( uMsg )
- {
- case WM_INITMENUPOPUP:
- sendTo.InitPopupMenu( wParam );
- return 0;
- case WM_INITDIALOG:
- playlists_InitDialog( hwndDlg );
- return TRUE;
- case WM_NOTIFY:
- return playlists_Notify( hwndDlg, wParam, lParam );
- case WM_MOUSEMOVE:
- playlists_MouseMove( hwndDlg, lParam );
- return 0;
- case WM_LBUTTONUP:
- playlists_LeftButtonUp( hwndDlg, wParam, lParam );
- return 0;
- case WM_COMMAND:
- playlists_Command( hwndDlg, wParam, lParam );
- break;
- case WM_PAINT:
- playlists_Paint( hwndDlg );
- return 0;
- case WM_ERASEBKGND:
- return 1; //handled by WADlg_DrawChildWindowBorders in WM_PAINT
- case WM_DESTROY:
- playlists_Destroy( hwndDlg );
- break;
- case WM_DROPFILES:
- playlists_DropFiles( (HDROP)wParam );
- return 0;
- case WM_CONTEXTMENU:
- playlists_ContextMenu( hwndDlg, (HWND)wParam, GET_X_LPARAM( lParam ), GET_Y_LPARAM( lParam ) );
- return 0;
- case WM_DISPLAYCHANGE:
- LayoutWindows( hwndDlg, TRUE );
- return 0;
- case WM_APP + 104:
- {
- playlist_UpdateButtonText( hwndDlg, wParam );
- LayoutWindows( hwndDlg, TRUE );
- return 0;
- }
- case WM_APP + 102:
- {
- if ( cloud_avail )
- {
- int width = 27;
- MLCloudColumn_GetWidth( plugin.hwndLibraryParent, &width );
- m_playlistslist.SetColumnWidth( 1, width );
- MLSkinnedHeader_SetCloudColumn( ListView_GetHeader( m_playlistslist.getwnd() ), 1 );
- }
- }
- case WM_APP + 101:
- m_playlistslist.RefreshAll(); UpdateWindow( m_playlistslist.getwnd() );
- case WM_APP + 100:
- AutoSizePlaylistColumns();
- if ( !loaded )
- {
- loaded = true;
- SetWindowRedraw( m_playlistslist.getwnd(), TRUE );
- }
- return 0;
- case WM_WINDOWPOSCHANGED:
- if ( ( SWP_NOSIZE | SWP_NOMOVE ) != ( ( SWP_NOSIZE | SWP_NOMOVE ) & ( (WINDOWPOS *)lParam )->flags ) ||
- ( SWP_FRAMECHANGED & ( (WINDOWPOS *)lParam )->flags ) )
- {
- LayoutWindows( hwndDlg, !( SWP_NOREDRAW & ( (WINDOWPOS *)lParam )->flags ) );
- }
- return 0;
- case WM_USER + 0x200:
- SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, 1 ); // yes, we support no - redraw resize
- return TRUE;
- case WM_USER + 0x201:
- offsetX = (short)LOWORD( wParam );
- offsetY = (short)HIWORD( wParam );
- g_rgnUpdate = (HRGN)lParam;
- return TRUE;
- case WM_ML_CHILDIPC:
- {
- if ( lParam == ML_CHILDIPC_DROPITEM && wParam )
- {
- mlDropItemStruct *dis = (mlDropItemStruct *)wParam;
- if ( dis )
- {
- switch ( dis->type )
- {
- case ML_TYPE_FILENAMES:
- case ML_TYPE_STREAMNAMES:
- case ML_TYPE_FILENAMESW:
- case ML_TYPE_STREAMNAMESW:
- case ML_TYPE_ITEMRECORDLIST:
- case ML_TYPE_ITEMRECORDLISTW:
- case ML_TYPE_CDTRACKS:
- // check we're not dropping back on ourself - not
- // pretty but it prevents the new playlist prompt
- if ( root_is_drag_and_dropping )
- {
- RECT r;
- GetWindowRect( hwndDlg, &r );
- dis->result = ( !PtInRect( &r, dis->p ) ? 1 : -1 );
- }
- // otherwise allow through as from external
- else
- dis->result = 1;
- break;
- default:
- dis->result = -1;
- break;
- }
- }
- return 0;
- }
- }
- }
- return 0;
- }
|