1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657 |
- #include "main.h"
- #include "api__ml_downloads.h"
- #include "RFCDate.h"
- #include "Downloaded.h"
- #include "DownloadStatus.h"
- #include "Defaults.h"
- #include "../nu/listview.h"
- #include "..\..\General\gen_ml/ml_ipc.h"
- #include "..\..\General\gen_ml/menu.h"
- #include <vector>
- #include "../nu/menushortcuts.h"
- #include <commctrl.h>
- #include <shlwapi.h>
- #include <shellapi.h>
- #include <strsafe.h>
- #include <algorithm>
- HWND downloads_window = 0;
- extern int downloads_treeItem;
- extern int no_auto_hide;
- int groupBtn = 1, enqueuedef = 0, customAllowed = 0;
- HMENU g_context_menus2 = NULL;
- static viewButtons view;
- #ifndef HDF_SORTUP
- #define HDF_SORTUP 0x0400
- #define HDF_SORTDOWN 0x0200
- #endif // !HDF_SORTUP
- using namespace Nullsoft::Utility;
- enum
- {
- COL_TITLE = 0,
- COL_PROGRESS,
- COL_DATE,
- COL_SOURCE,
- COL_SIZE,
- COL_PATH,
- NUM_COLUMNS,
- };
- int downloadsSourceWidth = DOWNLOADSSOURCEWIDTHDEFAULT;
- int downloadsTitleWidth = DOWNLOADSTITLEWIDTHDEFAULT;
- int downloadsProgressWidth = DOWNLOADSPROGRESSWIDTHDEFAULT;
- int downloadsDateWidth = DOWNLOADSDATEWIDTHDEFAULTS;
- int downloadsSizeWidth = DOWNLOADSSIZEWIDTHDEFAULTS;
- int downloadsPathWidth = DOWNLOADSPATHWIDTHDEFAULTS;
- W_ListView downloadList;
- int downloadsItemSort = 2; // -1 means no sort active
- bool downloadsSortAscending = false;
- enum
- {
- DOWNLOADSDIALOG_TIMER_UPDATESTATUSBAR = 0,
- };
- class DownloadListItem
- {
- public:
- DownloadedFile *f = NULL;
- DownloadToken token = NULL;
- wchar_t *source = 0;
- wchar_t *title = 0;
- wchar_t *path = 0;
- wchar_t status[ 20 ] = { 0 };
- DownloadListItem( DownloadedFile *fi )
- {
- f = new DownloadedFile( *fi );
- ZeroMemory( status, sizeof( status ) );
- }
- DownloadListItem( DownloadToken p_token, const wchar_t *p_source, const wchar_t *p_title, const wchar_t *p_path, size_t p_downloaded, size_t p_maxSize ) : token( p_token )
- {
- if ( p_maxSize )
- StringCchPrintf( status, 20, WASABI_API_LNGSTRINGW( IDS_DOWNLOADING_PERCENT ), (int)( p_downloaded / ( p_maxSize / 100 ) ) );
- else
- {
- if ( WAC_API_DOWNLOADMANAGER->IsPending( p_token ) )
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOAD_PENDING, status, 20 );
- else
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOADING, status, 20 );
- }
- source = p_source ? _wcsdup( p_source ) : NULL;
- title = p_title ? _wcsdup( p_title ) : NULL;
- path = p_path ? _wcsdup( p_path ) : NULL;
- }
- ~DownloadListItem()
- {
- clean();
- if ( f )
- delete f;
- }
- void clean()
- {
- if ( source )
- {
- free( source );
- source = 0;
- }
- if ( title )
- {
- free( title );
- title = 0;
- }
- if ( path )
- {
- free( path );
- path = 0;
- }
- }
- };
- static std::vector<DownloadListItem*> listContents;
- bool GetDownload( int &download )
- {
- download = ListView_GetNextItem( downloadList.getwnd(), download, LVNI_ALL | LVNI_SELECTED );
- if ( download == -1 )
- return false;
- else
- return true;
- }
- void Downloads_Play( bool enqueue = false )
- {
- int download = -1;
- AutoLock lock( downloadedFiles );
- while ( GetDownload( download ) )
- {
- if ( !enqueue )
- {
- if ( listContents[ download ]->f )
- mediaLibrary.PlayFile( listContents[ download ]->f->path );
- else if ( listContents[ download ]->path )
- mediaLibrary.PlayFile( listContents[ download ]->path );
- enqueue = true;
- }
- else
- {
- if ( listContents[ download ]->f )
- mediaLibrary.EnqueueFile( listContents[ download ]->f->path );
- else if ( listContents[ download ]->path )
- mediaLibrary.EnqueueFile( listContents[ download ]->path );
- }
- }
- }
- void DownloadsUpdated( const DownloadStatus::Status &s, DownloadToken token )
- {
- listContents.push_back( new DownloadListItem( token, s.source, s.title, s.path, s.downloaded, s.maxSize ) );
- downloadList.SetVirtualCountAsync( (int)listContents.size() );
- }
- void DownloadsUpdated( DownloadToken token, const DownloadedFile *f )
- {
- for ( DownloadListItem *l_content : listContents )
- {
- if ( l_content->token == token )
- {
- l_content->token = 0;
- if ( f )
- {
- l_content->f = new DownloadedFile( *f );
- l_content->clean();
- }
- else
- lstrcpyn( l_content->status, L"Error", 20 );
- break;
- }
- }
- PostMessage( downloadList.getwnd(), LVM_REDRAWITEMS, 0, listContents.size() );
- }
- void DownloadsUpdated()
- {
- for ( DownloadListItem *l_content : listContents )
- delete l_content;
- listContents.clear();
- for ( DownloadedFile &l_download : downloadedFiles.downloadList )
- listContents.push_back( new DownloadListItem( &l_download ) );
- {
- AutoLock lock( downloadStatus.statusLock );
- for ( DownloadStatus::Downloads::iterator itr = downloadStatus.downloads.begin(); itr != downloadStatus.downloads.end(); itr++ )
- {
- listContents.push_back( new DownloadListItem( itr->first, itr->second.source, itr->second.title, itr->second.path, itr->second.downloaded, itr->second.maxSize ) );
- }
- }
- downloadList.SetVirtualCountAsync( (int)listContents.size() );
- // Navigation_ShowService( SERVICE_DOWNLOADS, SHOWMODE_AUTO );
- }
- static void CleanupDownloads()
- {
- {
- AutoLock lock( downloadedFiles );
- DownloadList::DownloadedFileList &downloads = downloadedFiles.downloadList;
- DownloadList::iterator itr, next;
- for ( itr = downloads.begin(); itr != downloads.end();)
- {
- next = itr;
- ++next;
- if ( !PathFileExists( itr->path ) )
- downloads.erase( itr );
- else
- itr = next;
- }
- }
- // Navigation_ShowService(SERVICE_DOWNLOADS, SHOWMODE_AUTO);
- }
- void Downloads_UpdateStatusBar(HWND hwndDlg)
- {
- wchar_t status[256]=L"";
- downloadStatus.GetStatusString(status, 256);
- SetWindowText(GetDlgItem(hwndDlg, IDC_STATUS), status);
- }
- void Downloads_Paint(HWND hwndDlg)
- {
- int tab[] = { IDC_DOWNLOADLIST | DCW_SUNKENBORDER, };
- dialogSkinner.Draw(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
- }
- static HRGN g_rgnUpdate = NULL;
- static int offsetX = 0, 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_REMOVE, IDC_CLEANUP, IDC_STATUS,
- GROUP_MAIN, IDC_DOWNLOADLIST
- };
- 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};
- WASABI_API_LNGSTRINGW_BUF(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_REMOVE:
- case IDC_CLEANUP:
- 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 };
- GetWindowTextW( pl->hwnd, buffer, ARRAYSIZE( buffer ) );
- LRESULT idealSize = MLSkinnedButton_GetIdealSize( pl->hwnd, buffer );
- LONG width = LOWORD( idealSize ) + WASABI_API_APP->getScaleX( 6 );
- 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_STATUS:
- SETLAYOUTPOS(pl, rg.left, rg.top, rg.right - rg.left, (rg.bottom - rg.top));
- pl->flags |= (pl->cx > 16) ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
- break;
- case IDC_DOWNLOADLIST:
- 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->getScaleY( 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 );
- 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);
- }
- void Downloads_DisplayChange(HWND hwndDlg)
- {
- ListView_SetTextColor(downloadList.getwnd(), dialogSkinner.Color(WADLG_ITEMFG));
- ListView_SetBkColor(downloadList.getwnd(), dialogSkinner.Color(WADLG_ITEMBG));
- ListView_SetTextBkColor(downloadList.getwnd(), dialogSkinner.Color(WADLG_ITEMBG));
- downloadList.SetFont(dialogSkinner.GetFont());
- LayoutWindows(hwndDlg, TRUE);
- }
- static void DownloadsDialog_SkinControls(HWND hwnd, const INT *itemList, INT itemCount, UINT skinType, UINT skinStyle)
- {
- MLSKINWINDOW skinWindow = {0};
- skinWindow.style = skinStyle;
- skinWindow.skinType = skinType;
- for(INT i = 0; i < itemCount; i++)
- {
- skinWindow.hwndToSkin = GetDlgItem(hwnd, itemList[i]);
- if (NULL != skinWindow.hwndToSkin)
- {
- MLSkinWindow(plugin.hwndLibraryParent, &skinWindow);
- }
- }
- }
- static void DownloadDialog_InitializeList(HWND hwnd)
- {
- HWND hControl = GetDlgItem(hwnd, IDC_DOWNLOADLIST);
- if (NULL == hControl) return;
- UINT styleEx = (UINT)GetWindowLongPtr(hControl, GWL_EXSTYLE);
- SetWindowLongPtr(hControl, GWL_EXSTYLE, styleEx & ~WS_EX_NOPARENTNOTIFY);
- styleEx = LVS_EX_DOUBLEBUFFER | LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP;
- SendMessage(hControl, LVM_SETEXTENDEDLISTVIEWSTYLE, styleEx, styleEx);
- SendMessage(hControl, LVM_SETUNICODEFORMAT, (WPARAM)TRUE, 0L);
- MLSKINWINDOW skinWindow;
- skinWindow.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWLVS_ALTERNATEITEMS;
- skinWindow.skinType = SKINNEDWND_TYPE_LISTVIEW;
- skinWindow.hwndToSkin = hControl;
- MLSkinWindow(plugin.hwndLibraryParent, &skinWindow);
- }
- bool COL_SOURCE_Sort(const DownloadListItem* item1, const DownloadListItem* item2)
- {
- if (item1->f && item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->f->source), -1, (item2->f->source), -1));
- else if (!item1->f && !item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->source), -1, (item2->source), -1));
- else if (!item1->f)
- return (FALSE == downloadsSortAscending)?0:1;
- else //if (!item2->f)
- return (FALSE == downloadsSortAscending)?1:0;
- //return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
- // (item1->f?item1->f->source:item1->source), -1,
- // (item2->f?item2->f->source:item2->source), -1));
- }
- bool COL_TITLE_Sort(const DownloadListItem* item1, const DownloadListItem* item2)
- {
- if (item1->f && item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->f->title), -1, (item2->f->title), -1));
- else if (!item1->f && !item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->title), -1, (item2->title), -1));
- else if (!item1->f)
- return (FALSE == downloadsSortAscending)?0:1;
- else //if (!item2->f)
- return (FALSE == downloadsSortAscending)?1:0;
- //return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
- // (item1->f?item1->f->title:item1->title), -1,
- // (item2->f?item2->f->title:item2->title), -1));
- }
- bool COL_PROGRESS_Sort( const DownloadListItem *item1, const DownloadListItem *item2 )
- {
- if ( item1->f && item2->f )
- return ( item1->f->downloadStatus > item2->f->downloadStatus );
- else if ( !item1->f && !item2->f )
- return ( item1->token < item2->token );
- else if ( !item1->f )
- return ( FALSE == downloadsSortAscending ) ? 0 : 1;
- else //if (!item2->f)
- return ( FALSE == downloadsSortAscending ) ? 1 : 0;
- //return ((item1->f?item1->f->downloadStatus:-1) < (item2->f?item2->f->downloadStatus:-1));
- //return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
- // (item1->f?GetDownloadStatus(item1->f->downloadStatus):item1->status), -1,
- // (item2->f?GetDownloadStatus(item2->f->downloadStatus):item2->status), -1));
- }
- bool COL_PATH_Sort(const DownloadListItem* item1, const DownloadListItem* item2)
- {
- if (item1->f && item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->f->path), -1, (item2->f->path), -1));
- else if (!item1->f && !item2->f)
- return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE, (item1->path), -1, (item2->path), -1));
- else if (!item1->f)
- return (FALSE == downloadsSortAscending)?0:1;
- else //if (!item2->f)
- return (FALSE == downloadsSortAscending)?1:0;
- //return (CSTR_LESS_THAN == CompareStringW(LOCALE_USER_DEFAULT, NORM_IGNORECASE,
- // (item1->f?item1->f->path:item1->path), -1,
- // (item2->f?item2->f->path:item2->path), -1));
- }
- bool COL_DATE_Sort(const DownloadListItem* item1, const DownloadListItem* item2)
- {
- if (item1->f && item2->f)
- return item1->f->downloadDate < item2->f->downloadDate;
- else if (!item1->f && !item2->f)
- return item1->token < item2->token;
- else if (!item1->f)
- return (FALSE == downloadsSortAscending)?0:1;
- else //if (!item2->f)
- return (FALSE == downloadsSortAscending)?1:0;
- }
- bool COL_SIZE_Sort(const DownloadListItem* item1, const DownloadListItem* item2)
- {
- if (item1->f && item2->f)
- return item1->f->totalSize < item2->f->totalSize;
- else if (!item1->f && !item2->f)
- return item1->token < item2->token;
- else if (!item1->f)
- return (FALSE == downloadsSortAscending)?0:1;
- else //if (!item2->f)
- return (FALSE == downloadsSortAscending)?1:0;
- }
- static BOOL Downloads_SortItems(int sortColumn)
- {
- AutoLock lock (downloadedFiles);
- switch (sortColumn)
- {
- case COL_TITLE:
- std::sort(listContents.begin(), listContents.end(), COL_TITLE_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- case COL_PROGRESS:
- std::sort(listContents.begin(), listContents.end(), COL_PROGRESS_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- case COL_DATE:
- std::sort(listContents.begin(), listContents.end(), COL_DATE_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- case COL_SOURCE:
- std::sort(listContents.begin(), listContents.end(), COL_SOURCE_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- case COL_SIZE:
- std::sort(listContents.begin(), listContents.end(), COL_SIZE_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- case COL_PATH:
- std::sort(listContents.begin(), listContents.end(), COL_PATH_Sort);
- if (FALSE == downloadsSortAscending) std::reverse(listContents.begin(), listContents.end());
- return TRUE;
- }
- return FALSE;
- }
- static void Downloads_SetListSortColumn(HWND hwnd, INT listId, INT index, BOOL fAscending)
- {
- HWND hItems = GetDlgItem(hwnd, listId);
- if (NULL == hItems) return;
-
- HWND hHeader = (HWND)SNDMSG(hItems, LVM_GETHEADER, 0, 0L);
- if (NULL == hHeader) return;
-
- HDITEM item;
- item.mask = HDI_FORMAT;
- // reset first (ml req)
- INT count = (INT)SNDMSG(hHeader, HDM_GETITEMCOUNT, 0, 0L);
- for (INT i = 0; i < count; i++)
- {
- if (index != i && FALSE != (BOOL)SNDMSG(hHeader, HDM_GETITEM, i, (LPARAM)&item))
- {
- if (0 != ((HDF_SORTUP | HDF_SORTDOWN) & item.fmt))
- {
- item.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
- SNDMSG(hHeader, HDM_SETITEM, i, (LPARAM)&item);
- }
- }
- }
- if (FALSE != (BOOL)SNDMSG(hHeader, HDM_GETITEM, index, (LPARAM)&item))
- {
- INT fmt = item.fmt & ~(HDF_SORTUP | HDF_SORTDOWN);
- fmt |= (FALSE == fAscending) ? HDF_SORTDOWN : HDF_SORTUP;
- if (fmt != item.fmt)
- {
- item.fmt = fmt;
- SNDMSG(hHeader, HDM_SETITEM, index, (LPARAM)&item);
- }
- }
- }
- static BOOL Downloads_Sort(HWND hwnd, INT iColumn, bool fAscending)
- {
- BOOL result = TRUE;
- downloadsSortAscending = fAscending;
- Downloads_SortItems(iColumn);
- Downloads_SetListSortColumn(hwnd, IDC_DOWNLOADLIST, iColumn, fAscending);
- if (FALSE != result)
- {
- HWND hItems = GetDlgItem(hwnd, IDC_DOWNLOADLIST);
- if (NULL != hItems)
- InvalidateRect(hItems, NULL, TRUE);
- }
- return TRUE;
- }
- void Downloads_UpdateButtonText(HWND hwndDlg, int _enqueuedef)
- {
- if (groupBtn)
- {
- switch(_enqueuedef)
- {
- case 1:
- SetDlgItemTextW(hwndDlg, IDC_PLAY, view.enqueue);
- customAllowed = FALSE;
- break;
- default:
- // 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 p = {ML_MSG_VIEW_BUTTON_HOOK_IN_USE, (INT_PTR)_enqueuedef, 0, 0};
- wchar_t *pszTextW = (wchar_t *)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&p);
- 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)
- SetDlgItemTextW(hwndDlg, IDC_PLAY, pszTextW);
- customAllowed = TRUE;
- }
- else
- {
- SetDlgItemTextW(hwndDlg, IDC_PLAY, view.play);
- customAllowed = FALSE;
- }
- break;
- }
- }
- }
- static void Downloads_ManageButtons( HWND hwndDlg )
- {
- int has_selection = downloadList.GetSelectedCount();
- const int buttonids[] = { IDC_PLAY, IDC_ENQUEUE, IDC_CUSTOM, IDC_REMOVE };
- for ( size_t i = 0; i != sizeof( buttonids ) / sizeof( buttonids[ 0 ] ); i++ )
- {
- HWND controlHWND = GetDlgItem( hwndDlg, buttonids[ i ] );
- EnableWindow( controlHWND, has_selection );
- }
- }
- void Downloads_Init(HWND hwndDlg)
- {
- HWND hLibrary = plugin.hwndLibraryParent;
- downloads_window = hwndDlg;
- if (!view.play)
- {
- SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_GET_VIEW_BUTTON_TEXT, (WPARAM)&view);
- }
- HACCEL accel = WASABI_API_LOADACCELERATORSW(IDR_VIEW_DOWNLOAD_ACCELERATORS);
- if (accel)
- WASABI_API_APP->app_addAccelerators(hwndDlg, &accel, 1, TRANSLATE_MODE_CHILD);
- g_context_menus2 = WASABI_API_LOADMENU(IDR_MENU1);
- groupBtn = ML_GROUPBTN_VAL();
- enqueuedef = (ML_ENQDEF_VAL() == 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 p = {ML_MSG_VIEW_BUTTON_HOOK, (INT_PTR)hwndDlg, (INT_PTR)MAKELONG(IDC_CUSTOM, IDC_ENQUEUE), (INT_PTR)L"ml_downloads"};
- wchar_t *pszTextW = (wchar_t *)SENDMLIPC(plugin.hwndLibraryParent, ML_IPC_SEND_PLUGIN_MESSAGE, (WPARAM)&p);
- 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;
- MLSkinWindow2(hLibrary, hwndDlg, SKINNEDWND_TYPE_AUTO, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
- const INT szControls[] = {IDC_PLAY, IDC_ENQUEUE, IDC_CUSTOM};
- DownloadsDialog_SkinControls(hwndDlg, szControls, ARRAYSIZE(szControls), SKINNEDWND_TYPE_AUTO,
- SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | (groupBtn ? SWBS_SPLITBUTTON : 0));
- const INT szControlz[] = {IDC_REMOVE, IDC_CLEANUP, IDC_STATUS};
- DownloadsDialog_SkinControls(hwndDlg, szControlz, ARRAYSIZE(szControlz), SKINNEDWND_TYPE_AUTO,
- SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS);
- DownloadDialog_InitializeList(hwndDlg);
- Downloads_UpdateStatusBar(hwndDlg);
- downloadList.setwnd(GetDlgItem(hwndDlg, IDC_DOWNLOADLIST));
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_TITLE), downloadsTitleWidth);
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_PROGRESS), downloadsProgressWidth);
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_DATE), downloadsDateWidth);
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_SOURCE), downloadsSourceWidth);
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_SIZE), downloadsSizeWidth);
- downloadList.AddCol(WASABI_API_LNGSTRINGW(IDS_PATH), downloadsPathWidth);
- DownloadsUpdated();
- downloadList.SetVirtualCount((int)listContents.size());
- Downloads_UpdateButtonText(hwndDlg, enqueuedef == 1);
- Downloads_ManageButtons(hwndDlg);
- Downloads_DisplayChange(hwndDlg);
- Downloads_Sort(hwndDlg, downloadsItemSort, downloadsSortAscending);
- SetTimer(hwndDlg, DOWNLOADSDIALOG_TIMER_UPDATESTATUSBAR , 1000, 0);
- }
- void Downloads_Timer( HWND hwndDlg, UINT timerId )
- {
- switch ( timerId )
- {
- case DOWNLOADSDIALOG_TIMER_UPDATESTATUSBAR:
- Downloads_UpdateStatusBar( hwndDlg );
- {
- AutoLock lock( downloadStatus.statusLock );
- for ( DownloadListItem *l_content : listContents )
- {
- if ( l_content->token )
- {
- size_t d = downloadStatus.downloads[ l_content->token ].downloaded;
- size_t s = downloadStatus.downloads[ l_content->token ].maxSize;
- if ( s )
- StringCchPrintf( l_content->status, 20, WASABI_API_LNGSTRINGW( IDS_DOWNLOADING_PERCENT ), (int)( d / ( s / 100 ) ) );
- else
- {
- if ( WAC_API_DOWNLOADMANAGER->IsPending( l_content->token ) )
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOAD_PENDING, l_content->status, 20 );
- else
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOADING, l_content->status, 20 );
- }
- PostMessage( downloadList.getwnd(), LVM_REDRAWITEMS, 0, listContents.size() );
- }
- }
- }
- break;
- }
- }
- static INT Downloads_GetListSortColumn(HWND hwnd, INT listId, bool *fAscending)
- {
- HWND hItems = GetDlgItem(hwnd, listId);
- if (NULL != hItems)
- {
- HWND hHeader = (HWND)SNDMSG(hItems, LVM_GETHEADER, 0, 0L);
- if (NULL != hHeader)
- {
- HDITEM item;
- item.mask = HDI_FORMAT;
- INT count = (INT)SNDMSG(hHeader, HDM_GETITEMCOUNT, 0, 0L);
- for (INT i = 0; i < count; i++)
- {
- if (FALSE != (BOOL)SNDMSG(hHeader, HDM_GETITEM, i, (LPARAM)&item) &&
- 0 != ((HDF_SORTUP | HDF_SORTDOWN) & item.fmt))
- {
- if (NULL != fAscending)
- {
- *fAscending = (0 != (HDF_SORTUP & item.fmt));
- }
- return i;
- }
- }
- }
- }
- return -1;
- }
- void Downloads_Destroy( HWND hwndDlg )
- {
- downloads_window = 0;
- downloadsSourceWidth = downloadList.GetColumnWidth( COL_SOURCE );
- downloadsTitleWidth = downloadList.GetColumnWidth( COL_TITLE );
- downloadsProgressWidth = downloadList.GetColumnWidth( COL_PROGRESS );
- downloadsPathWidth = downloadList.GetColumnWidth( COL_PATH );
- downloadsDateWidth = downloadList.GetColumnWidth( COL_DATE );
- downloadsSizeWidth = downloadList.GetColumnWidth( COL_SIZE );
- for ( DownloadListItem *l_content : listContents )
- delete l_content;
- listContents.clear();
- downloadList.setwnd( NULL );
- bool fAscending;
- downloadsItemSort = Downloads_GetListSortColumn( hwndDlg, IDC_DOWNLOADLIST, &fAscending );
- downloadsSortAscending = ( -1 != downloadsItemSort ) ? ( FALSE != fAscending ) : true;
- int activeDownloads = 0;
- int historyDownloads = 0;
- {
- Nullsoft::Utility::AutoLock historylock( downloadedFiles.downloadedLock );
- Nullsoft::Utility::AutoLock statuslock( downloadStatus.statusLock );
- historyDownloads = (int)downloadedFiles.downloadList.size();
- activeDownloads = (int)downloadStatus.downloads.size();
- }
- if ( !activeDownloads && !historyDownloads && !no_auto_hide )
- {
- HNAVITEM hItem = MLNavCtrl_FindItemById( plugin.hwndLibraryParent, downloads_treeItem );
- if ( hItem )
- {
- MLNavCtrl_DeleteItem( plugin.hwndLibraryParent, hItem );
- downloads_treeItem = 0;
- }
- }
- }
- void Downloads_Remove( bool del = false, HWND parent = NULL )
- {
- int d = -1;
- int r = 0;
- while ( GetDownload( d ) )
- {
- int download = d - r;
- DownloadListItem *item = listContents[ download ];
- if ( item->f )
- {
- AutoLock lock( downloadedFiles );
- int j = 0;
- for ( DownloadList::iterator i = downloadedFiles.begin(); i != downloadedFiles.end(); ++i )
- {
- if ( !_wcsicmp( i->path, item->f->path ) )
- {
- if ( del )
- {
- if ( !downloadedFiles.RemoveAndDelete( j ) )
- MessageBox( parent, WASABI_API_LNGSTRINGW( IDS_DELETEFAILED ), downloadedFiles.downloadList[ j ].path, 0 );
- }
- else
- downloadedFiles.Remove( j );
- delete item;
- listContents.erase( listContents.begin() + download );
- r++;
- dirty++;
- break;
- }
- ++j;
- }
- }
- else if ( item->token )
- {
- AutoLock lock( downloadStatus.statusLock );
- downloadStatus.downloads[ item->token ].killswitch = 1;
- delete item;
- listContents.erase( listContents.begin() + download );
- r++;
- }
- else
- {
- delete item;
- listContents.erase( listContents.begin() + download );
- r++;
- }
- }
- downloadList.SetVirtualCountAsync( (int)listContents.size() );
- downloadList.UnselectAll();
- // Navigation_ShowService(SERVICE_DOWNLOADS, SHOWMODE_AUTO);
- }
- void Downloads_Delete( HWND parent )
- {
- wchar_t message[ 256 ] = { 0 };
- int c = downloadList.GetSelectedCount();
-
- if ( !c )
- return;
- else if ( c == 1 )
- WASABI_API_LNGSTRINGW_BUF( IDS_PERM_DELETE_ARE_YOU_SURE, message, 256 );
- else
- StringCchPrintf( message, 256, WASABI_API_LNGSTRINGW( IDS_PERM_DELETE_THESE_ARE_YOU_SURE ), c );
- if ( MessageBox( NULL, message, WASABI_API_LNGSTRINGW( IDS_DELETION ), MB_ICONWARNING | MB_YESNO ) == IDNO )
- return;
- Downloads_Remove( true, parent );
- }
- void Downloads_CleanUp(HWND hwndDlg)
- {
- wchar_t titleStr[64] = {0};
- if ( MessageBox( hwndDlg, WASABI_API_LNGSTRINGW( IDS_CLEAR_ALL_FINISHED_DOWNLOADS ), WASABI_API_LNGSTRINGW_BUF( IDS_CLEAN_UP_LIST, titleStr, 64 ), MB_ICONWARNING | MB_YESNO ) == IDNO )
- return;
- {
- AutoLock lock( downloadedFiles );
- downloadedFiles.downloadList.clear();
- }
- dirty++;
- DownloadsUpdated();
- }
- void Downloads_InfoBox( HWND parent )
- {
- int download = -1;
- if ( GetDownload( download ) )
- {
- const wchar_t *fn;
- if ( listContents[ download ]->f )
- fn = listContents[ download ]->f->path;
- else
- fn = listContents[ download ]->path;
- if ( fn )
- {
- infoBoxParamW p = { parent, fn };
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&p, IPC_INFOBOXW );
- }
- }
- }
- void Downloads_SelectAll()
- {
- int l = downloadList.GetCount();
- for ( int i = 0; i < l; i++ )
- downloadList.SetSelected( i );
- }
- static void exploreItemFolder( HWND hwndDlg )
- {
- if ( downloadList.GetSelectionMark() >= 0 )
- {
- int download = -1;
- while ( GetDownload( download ) )
- {
- wchar_t *file;
- if ( listContents[ download ]->f )
- file = listContents[ download ]->f->path;
- else
- file = listContents[ download ]->path;
- WASABI_API_EXPLORERFINDFILE->AddFile( file );
- }
- WASABI_API_EXPLORERFINDFILE->ShowFiles();
- }
- }
- void Downloads_Cancel()
- {
- int l_selected_count = downloadList.GetSelectedCount();
- for ( int i = -1; i < l_selected_count; ++i )
- {
- if ( GetDownload( i ) )
- {
- dirty++;
- if ( !listContents[ i ]->f )
- WAC_API_DOWNLOADMANAGER->CancelDownload( listContents[ i ]->token );
- break; // Workaround for 5.9.1 to avoid crash if cancel of many downloads in same time
- }
- }
- }
- int we_are_drag_and_dropping = 0;
- static void Downloads_OnColumnClick(HWND hwnd, NMLISTVIEW *plv)
- {
- bool fAscending;
- INT iSort = Downloads_GetListSortColumn(hwnd, IDC_DOWNLOADLIST, &fAscending);
- fAscending = (-1 != iSort && iSort == plv->iSubItem) ? (!fAscending) : true;
- Downloads_Sort(hwnd, plv->iSubItem, fAscending);
- }
- LRESULT DownloadList_Notify( LPNMHDR l, HWND hwndDlg )
- {
- switch ( l->code )
- {
- case LVN_COLUMNCLICK:
- Downloads_OnColumnClick( hwndDlg, (NMLISTVIEW *)l );
- break;
- case NM_DBLCLK:
- Downloads_Play( ( ( !!( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) ) ^ ML_ENQDEF_VAL() ) );
- break;
- case LVN_BEGINDRAG:
- we_are_drag_and_dropping = 1;
- SetCapture( hwndDlg );
- break;
- case LVN_ITEMCHANGED:
- Downloads_ManageButtons( hwndDlg );
- break;
- case LVN_GETDISPINFO:
- NMLVDISPINFO *lpdi = (NMLVDISPINFO *)l;
- size_t item = lpdi->item.iItem;
- if ( item < 0 || item >= listContents.size() )
- return 0;
- //if (FALSE == downloadsSortAscending) item = listContents.size() - item - 1;
- DownloadListItem *l = listContents[ item ];
- if ( lpdi->item.mask & LVIF_TEXT )
- {
- lpdi->item.pszText[ 0 ] = 0;
- switch ( lpdi->item.iSubItem )
- {
- case COL_TITLE:
- if ( !l->token && l->f )
- {
- wchar_t *l_title = L"";
- if ( l->f->title != NULL )
- l_title = l->f->title;
- lstrcpyn( lpdi->item.pszText, l_title, lpdi->item.cchTextMax );
- }
- else
- {
- if ( l->title ) lstrcpyn( lpdi->item.pszText, l->title, lpdi->item.cchTextMax );
- }
- break;
- case COL_PROGRESS:
- if ( !l->token && l->f )
- {
- switch ( l->f->downloadStatus )
- {
- case DownloadedFile::DOWNLOAD_SUCCESS:
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOAD_SUCCESS, lpdi->item.pszText, lpdi->item.cchTextMax );
- break;
- case DownloadedFile::DOWNLOAD_FAILURE:
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOAD_FAILURE, lpdi->item.pszText, lpdi->item.cchTextMax );
- break;
- case DownloadedFile::DOWNLOAD_CANCELED:
- WASABI_API_LNGSTRINGW_BUF( IDS_DOWNLOAD_CANCELED, lpdi->item.pszText, lpdi->item.cchTextMax );
- break;
- }
- }
- else lstrcpyn( lpdi->item.pszText, l->status, lpdi->item.cchTextMax );
- break;
- case COL_DATE:
- {
- if ( !l->token && l->f && l->f->downloadDate )
- {
- wchar_t tmp[ 128 ] = { 0 };
- MakeDateString( l->f->downloadDate, tmp, 128 );
- lstrcpyn( lpdi->item.pszText, tmp, lpdi->item.cchTextMax );
- }
- else
- {
- WASABI_API_LNGSTRINGW_BUF( IDS_N_A, lpdi->item.pszText, lpdi->item.cchTextMax );
- }
- break;
- }
- case COL_SOURCE:
- if ( !l->token && l->f )
- {
- wchar_t *l_source = L"";
- if ( l->f->source != NULL )
- l_source = l->f->source;
- lstrcpyn( lpdi->item.pszText, l_source, lpdi->item.cchTextMax );
- }
- else
- lstrcpyn( lpdi->item.pszText, l->source, lpdi->item.cchTextMax );
- break;
- case COL_SIZE:
- {
- if ( !l->token && l->f && l->f->totalSize > 0 )
- WASABI_API_LNG->FormattedSizeString( lpdi->item.pszText, lpdi->item.cchTextMax, l->f->totalSize );
- else
- WASABI_API_LNGSTRINGW_BUF( IDS_N_A, lpdi->item.pszText, lpdi->item.cchTextMax );
- break;
- }
- case COL_PATH:
- if ( !l->token && l->f )
- {
- wchar_t *l_path = L"";
- if ( l->f->path != NULL )
- l_path = l->f->path;
- lstrcpyn( lpdi->item.pszText, l_path, lpdi->item.cchTextMax );
- }
- else
- {
- if ( l->path )
- lstrcpyn( lpdi->item.pszText, l->path, lpdi->item.cchTextMax );
- }
- break;
- }
- }
- break;
- }
- return 0;
- }
- void listbuild( wchar_t **buf, int &buf_size, int &buf_pos, const wchar_t *tbuf )
- {
- if ( !*buf )
- {
- *buf = (wchar_t *)calloc( 4096, sizeof( wchar_t ) );
- if ( *buf )
- {
- buf_size = 4096;
- buf_pos = 0;
- }
- else
- {
- buf_size = buf_pos = 0;
- }
- }
- int newsize = buf_pos + lstrlenW( tbuf ) + 1;
- if ( newsize < buf_size )
- {
- size_t old_buf_size = buf_size;
- buf_size = newsize + 4096;
- wchar_t *new_buf = (wchar_t *)realloc( *buf, ( buf_size + 1 ) * sizeof( wchar_t ) );
- if ( new_buf )
- {
- *buf = new_buf;
- }
- else
- {
- new_buf = (wchar_t*)calloc( ( buf_size + 1 ), sizeof( wchar_t ) );
- if ( new_buf )
- {
- memcpy( new_buf, *buf, ( old_buf_size * sizeof( wchar_t ) ) );
- free( *buf );
- *buf = new_buf;
- }
- else buf_size = (int)old_buf_size;
- }
- }
- StringCchCopyW( *buf + buf_pos, buf_size, tbuf );
- buf_pos = newsize;
- }
- wchar_t *getSelectedList()
- {
- wchar_t *path = NULL;
- int buf_pos = 0;
- int buf_size = 0;
- int download = -1;
- while ( GetDownload( download ) )
- {
- if ( listContents[ download ]->f )
- listbuild( &path, buf_size, buf_pos, listContents[ download ]->f->path );
- }
- if ( path )
- path[ buf_pos ] = 0;
- return path;
- }
- static void SwapPlayEnqueueInMenu( HMENU listMenu )
- {
- int playPos = -1, enqueuePos = -1;
- MENUITEMINFOW playItem = { sizeof( MENUITEMINFOW ), 0, }, enqueueItem = { sizeof( MENUITEMINFOW ), 0, };
- int numItems = GetMenuItemCount( listMenu );
- for ( int i = 0; i < numItems; i++ )
- {
- UINT id = GetMenuItemID( listMenu, i );
- if ( id == IDC_PLAY )
- {
- playItem.fMask = MIIM_ID;
- playPos = i;
- GetMenuItemInfoW( listMenu, i, TRUE, &playItem );
- }
- else if ( id == IDC_ENQUEUE )
- {
- enqueueItem.fMask = MIIM_ID;
- enqueuePos = i;
- GetMenuItemInfoW( listMenu, i, TRUE, &enqueueItem );
- }
- }
- playItem.wID = IDC_ENQUEUE;
- enqueueItem.wID = IDC_PLAY;
- SetMenuItemInfoW( listMenu, playPos, TRUE, &playItem );
- SetMenuItemInfoW( listMenu, enqueuePos, TRUE, &enqueueItem );
- }
- static void SyncMenuWithAccelerators( HWND hwndDlg, HMENU menu )
- {
- HACCEL szAccel[ 24 ] = { 0 };
- INT c = WASABI_API_APP->app_getAccelerators( hwndDlg, szAccel, sizeof( szAccel ) / sizeof( szAccel[ 0 ] ), FALSE );
- AppendMenuShortcuts( menu, szAccel, c, MSF_REPLACE );
- }
- void UpdateMenuItems( HWND hwndDlg, HMENU menu )
- {
- bool swapPlayEnqueue = false;
- if ( ML_ENQDEF_VAL() )
- {
- SwapPlayEnqueueInMenu( menu );
- swapPlayEnqueue = true;
- }
- SyncMenuWithAccelerators( hwndDlg, menu );
- if ( swapPlayEnqueue )
- SwapPlayEnqueueInMenu( menu );
- }
- static int IPC_LIBRARY_SENDTOMENU = 0;
- static librarySendToMenuStruct s = { 0 };
- static void DownloadList_RightClick(HWND hwndDlg, HWND listHwnd, POINTS pts)
- {
- POINT pt;
- POINTSTOPOINT(pt, pts);
- RECT controlRect, headerRect;
- if (FALSE == GetClientRect(listHwnd, &controlRect))
- SetRectEmpty(&controlRect);
- else
- MapWindowPoints(listHwnd, HWND_DESKTOP, (POINT*)&controlRect, 2);
- if ( -1 == pt.x && -1 == pt.y )
- {
- RECT itemRect;
- int selected = downloadList.GetNextSelected();
- if ( selected != -1 ) // if something is selected we'll drop the menu from there
- {
- downloadList.GetItemRect( selected, &itemRect );
- ClientToScreen( listHwnd, (POINT *)&itemRect );
- }
- else // otherwise we'll drop it from the top-left corner of the listview, adjusting for the header location
- {
- GetWindowRect( listHwnd, &itemRect );
- HWND hHeader = (HWND)SNDMSG( listHwnd, LVM_GETHEADER, 0, 0L );
- RECT headerRect;
- if ( ( WS_VISIBLE & GetWindowLongPtr( hHeader, GWL_STYLE ) ) && GetWindowRect( hHeader, &headerRect ) )
- {
- itemRect.top += ( headerRect.bottom - headerRect.top );
- }
- }
- pt.x = itemRect.left;
- pt.y = itemRect.top;
- }
- HWND hHeader = (HWND)SNDMSG(listHwnd, LVM_GETHEADER, 0, 0L);
- if ( 0 == ( WS_VISIBLE & GetWindowLongPtr( hHeader, GWL_STYLE ) ) || FALSE == GetWindowRect( hHeader, &headerRect ) )
- {
- SetRectEmpty( &headerRect );
- }
- if ( FALSE != PtInRect( &headerRect, pt ) )
- {
- return;
- }
- LVHITTESTINFO hitTest;
- hitTest.pt = pt;
- MapWindowPoints( HWND_DESKTOP, listHwnd, &hitTest.pt, 1 );
- int index = ( downloadList.GetNextSelected() != -1 ? ListView_HitTest( listHwnd, &hitTest ) : -1 );
- HMENU baseMenu = WASABI_API_LOADMENU( IDR_MENU1 );
- if ( baseMenu == NULL )
- return;
- HMENU menu = GetSubMenu( baseMenu, 0 );
- if ( menu != NULL )
- {
- if ( ( index == -1 ) || ( index != -1 ) && listContents[ index ]->f )
- DeleteMenu( menu, ID_DOWNLOADS_CANCELDOWNLOAD, MF_BYCOMMAND );
- UINT enableExtras = MF_ENABLED;
- if ( ( index == -1 ) || ( index != -1 ) && !listContents[ index ]->f
- || ( index != -1 ) && ( listContents[ index ]->f->downloadStatus != 1 ) )
- enableExtras = ( MF_GRAYED | MF_DISABLED );
- UINT enableViewExtras = MF_ENABLED;
- if ( index == -1 )
- enableViewExtras = ( MF_GRAYED | MF_DISABLED );
- EnableMenuItem( menu, IDC_PLAY, MF_BYCOMMAND | enableExtras );
- EnableMenuItem( menu, IDC_ENQUEUE, MF_BYCOMMAND | enableExtras );
- EnableMenuItem( menu, IDC_REMOVE, MF_BYCOMMAND | enableViewExtras );
- EnableMenuItem( menu, IDC_DELETE, MF_BYCOMMAND | enableExtras );
- EnableMenuItem( menu, IDC_INFOBOX, MF_BYCOMMAND | enableExtras );
- EnableMenuItem( menu, ID_DOWNLOADS_EXPLORERITEMFOLDER, MF_BYCOMMAND | enableExtras );
- EnableMenuItem( menu, 2, MF_BYPOSITION | enableExtras );
- { // send-to menu shit...
- ZeroMemory( &s, sizeof( s ) );
- IPC_LIBRARY_SENDTOMENU = (int)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, ( WPARAM ) & "LibrarySendToMenu", IPC_REGISTER_WINAMP_IPCMESSAGE );
- if ( IPC_LIBRARY_SENDTOMENU > 65536 && SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)0, IPC_LIBRARY_SENDTOMENU ) == 0xffffffff )
- {
- s.mode = 1;
- s.hwnd = hwndDlg;
- s.data_type = ML_TYPE_FILENAMESW;
- s.ctx[ 1 ] = 1;
- s.build_hMenu = GetSubMenu( menu, 2 );
- }
- }
- UpdateMenuItems( hwndDlg, menu );
- int r = Menu_TrackPopup( plugin.hwndLibraryParent, menu, TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, pt.x, pt.y, hwndDlg, NULL );
- if ( !SendMessage( hwndDlg, WM_COMMAND, r, 0 ) )
- {
- s.menu_id = r; // more send to menu shit...
- if ( s.mode == 2 && SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU ) == 0xffffffff )
- {
- s.mode = 3;
- wchar_t *path = getSelectedList();
- if ( path )
- {
- s.data = path;
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU );
- free( path );
- }
- }
- }
- if ( s.mode )
- { // yet more send to menu shit...
- s.mode = 4;
- SendMessage( plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU ); // cleanup
- }
- }
- DestroyMenu( baseMenu );
- }
- static void Downloads_ContextMenu( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
- {
- HWND sourceWindow = (HWND)wParam;
- if ( sourceWindow == downloadList.getwnd() )
- DownloadList_RightClick( hwndDlg, sourceWindow, MAKEPOINTS( lParam ) );
- }
- enum
- {
- BPM_ECHO_WM_COMMAND=0x1, // send WM_COMMAND and return value
- BPM_WM_COMMAND = 0x2, // just send WM_COMMAND
- };
- BOOL Downloads_ButtonPopupMenu( HWND hwndDlg, int buttonId, HMENU menu, int flags = 0 )
- {
- RECT r;
- HWND buttonHWND = GetDlgItem( hwndDlg, buttonId );
- GetWindowRect( buttonHWND, &r );
- UpdateMenuItems( hwndDlg, menu );
- MLSkinnedButton_SetDropDownState( buttonHWND, TRUE );
- UINT tpmFlags = TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN;
- if ( !( flags & BPM_WM_COMMAND ) )
- tpmFlags |= TPM_RETURNCMD;
- int x = Menu_TrackPopup( plugin.hwndLibraryParent, menu, tpmFlags, r.left, r.top, hwndDlg, NULL );
- if ( ( flags & BPM_ECHO_WM_COMMAND ) && x )
- SendMessage( hwndDlg, WM_COMMAND, MAKEWPARAM( x, 0 ), 0 );
- MLSkinnedButton_SetDropDownState( buttonHWND, FALSE );
- return x;
- }
- static void Downloads_Play( HWND hwndDlg, HWND from, UINT idFrom )
- {
- HMENU listMenu = GetSubMenu( g_context_menus2, 0 );
- int count = GetMenuItemCount( listMenu );
- if ( count > 2 )
- {
- for ( int i = 2; i < count; i++ )
- {
- DeleteMenu( listMenu, 2, MF_BYPOSITION );
- }
- }
- Downloads_ButtonPopupMenu( hwndDlg, idFrom, listMenu, BPM_WM_COMMAND );
- }
- static BOOL WINAPI DownloadDialog_DlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_INITMENUPOPUP: // yet yet more send to menu shit...
- if (wParam && (HMENU)wParam == s.build_hMenu && s.mode==1)
- {
- if (SendMessage(plugin.hwndWinampParent,WM_WA_IPC,(WPARAM)&s,IPC_LIBRARY_SENDTOMENU)==0xffffffff)
- s.mode=2;
- }
- break;
- case WM_USER+543:
- Navigation_Update();
- break;
- case WM_CONTEXTMENU:
- Downloads_ContextMenu(hwndDlg, wParam, lParam);
- return TRUE;
- case WM_NOTIFYFORMAT:
- return NFR_UNICODE;
- case WM_INITDIALOG:
- Downloads_Init(hwndDlg);
- break;
- case WM_NOTIFY:
- {
- LPNMHDR l = (LPNMHDR)lParam;
- if (l->idFrom == IDC_DOWNLOADLIST)
- return (BOOL)DownloadList_Notify(l,hwndDlg);
- }
- break;
- case WM_DESTROY:
- Downloads_Destroy(hwndDlg);
- return 0;
- case WM_DISPLAYCHANGE:
- Downloads_DisplayChange(hwndDlg);
- return 0;
- case WM_TIMER:
- Downloads_Timer(hwndDlg, (UINT)wParam);
- break;
- case WM_MOUSEMOVE:
- if (we_are_drag_and_dropping && GetCapture() == hwndDlg)
- {
- POINT p = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
- ClientToScreen(hwndDlg, &p);
- mlDropItemStruct m;
- ZeroMemory(&m, sizeof(mlDropItemStruct));
- m.type = ML_TYPE_FILENAMESW;
- m.p = p;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDRAG);
- }
- break;
- case WM_LBUTTONUP:
- if (we_are_drag_and_dropping && GetCapture() == hwndDlg)
- {
- we_are_drag_and_dropping = 0;
- ReleaseCapture();
- POINT p = {GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
- ClientToScreen(hwndDlg, &p);
- mlDropItemStruct m = {0};
- m.type = ML_TYPE_FILENAMESW;
- m.p = p;
- m.flags = ML_HANDLEDRAG_FLAG_NOCURSOR;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDRAG);
- if (m.result > 0)
- {
- m.flags = 0;
- m.result = 0;
- wchar_t* path = getSelectedList();
- if(path)
- {
- m.data = path;
- SendMessage(plugin.hwndLibraryParent,WM_ML_IPC,(WPARAM)&m,ML_IPC_HANDLEDROP);
- free(path);
- }
- }
- }
- break;
- case WM_PAINT:
- {
- int tab[] = { IDC_DOWNLOADLIST|DCW_SUNKENBORDER};
- dialogSkinner.Draw(hwndDlg, tab, sizeof(tab) / sizeof(tab[0]));
- }
- 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_APP + 104:
- {
- Downloads_UpdateButtonText(hwndDlg, (int)wParam);
- LayoutWindows(hwndDlg, TRUE);
- return 0;
- }
- case WM_COMMAND:
- switch ( LOWORD( wParam ) )
- {
- case IDC_PLAY:
- case IDC_ENQUEUE:
- case IDC_CUSTOM:
- if ( HIWORD( wParam ) == MLBN_DROPDOWN )
- {
- Downloads_Play( hwndDlg, (HWND)lParam, LOWORD( wParam ) );
- }
- else
- {
- bool action;
- if ( LOWORD( wParam ) == IDC_PLAY )
- {
- action = ( HIWORD( wParam ) == 1 ) ? ML_ENQDEF_VAL() == 1 : 0;
- }
- else if ( LOWORD( wParam ) == IDC_ENQUEUE )
- {
- action = ( HIWORD( wParam ) == 1 ) ? ML_ENQDEF_VAL() != 1 : 1;
- }
- else
- break;
- Downloads_Play( action );
- }
- break;
- case IDC_REMOVE:
- Downloads_Remove();
- break;
- case IDC_DELETE:
- Downloads_Delete( hwndDlg );
- break;
- case IDC_CLEANUP:
- Downloads_CleanUp( hwndDlg );
- break;
- case IDC_INFOBOX:
- Downloads_InfoBox( hwndDlg );
- break;
- case IDC_SELECTALL:
- Downloads_SelectAll();
- break;
- case ID_DOWNLOADS_EXPLORERITEMFOLDER:
- exploreItemFolder( hwndDlg );
- break;
- case ID_DOWNLOADS_CANCELDOWNLOAD:
- Downloads_Cancel();
- break;
- default:
- return 0;
- }
- return 1;
- }
- return 0;
- }
- HWND CALLBACK DownloadDialog_Create( HWND hParent )
- {
- return WASABI_API_CREATEDIALOGPARAMW( IDD_DOWNLOADS, hParent, DownloadDialog_DlgProc, 0 );
- }
|