diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_downloads/Main.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_downloads/Main.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_downloads/Main.cpp | 387 |
1 files changed, 387 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_downloads/Main.cpp b/Src/Plugins/Library/ml_downloads/Main.cpp new file mode 100644 index 00000000..09a260eb --- /dev/null +++ b/Src/Plugins/Library/ml_downloads/Main.cpp @@ -0,0 +1,387 @@ +#include "main.h" +#include "DownloadsDialog.h" +#include "DownloadsParse.h" +#include "Preferences.h" +#include "XMLWriter.h" +#include "..\..\General\gen_ml/ml.h" +#include "Defaults.h" +#include "..\..\General\gen_ml/ml_ipc_0313.h" + +#include "api__ml_downloads.h" +#include "Downloaded.h" +#include "DownloadStatus.h" +#include <api/service/waServiceFactory.h> + +#include <strsafe.h> + +wchar_t *ml_cfg = 0, + xmlFileName[1024] = {0}; + +ATOM VIEWPROP = 0; + +api_downloadManager *WAC_API_DOWNLOADMANAGER = 0; +DownloadViewCallback *downloadViewCallback = 0; + +static int Init(); +static void Quit(); +static INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3); + +DWORD threadStorage=TLS_OUT_OF_INDEXES; +extern "C" winampMediaLibraryPlugin plugin = + { + MLHDR_VER, + "nullsoft(ml_downloads.dll)", + Init, + Quit, + MessageProc, + 0, + 0, + 0, + }; + +//static prefsDlgRecW preferences; +//static wchar_t preferencesName[64] = {0}; +int downloads_treeItem = 0, + podcast_parent = 0, + no_auto_hide = 0; +HANDLE hMainThread; + +HCURSOR hDragNDropCursor; +int winampVersion = 0, dirty = 0; + +api_application *applicationApi = NULL; +api_explorerfindfile *WASABI_API_EXPLORERFINDFILE = 0; + +// wasabi based services for localisation support +api_language *WASABI_API_LNG = 0; +HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0; + +int icons[4] = {-1, -1, -1, -1}; +int activeIcon = 0; +int totalIcons = 4; +static Nullsoft::Utility::LockGuard navigationLock; + +// used to get the downloads view parented to the podcast view +#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT) +#define NAVITEM_PREFIX L"podcast_svc_" +#define SERVICE_PODCAST 720 + +enum +{ + DOWNLOADS_TIMER_NAVNODE = 35784, +}; + +HNAVITEM Navigation_FindService(UINT serviceId) +{ + HWND hLibrary = plugin.hwndLibraryParent; + INT cchPrefix = ARRAYSIZE(NAVITEM_PREFIX) - 1; + + WCHAR szBuffer[256] = {0}; + NAVITEM itemInfo = {0}; + itemInfo.cbSize = sizeof(itemInfo); + itemInfo.mask = NIMF_TEXTINVARIANT; + itemInfo.cchInvariantMax = ARRAYSIZE(szBuffer); + itemInfo.pszInvariant = szBuffer; + itemInfo.hItem = MLNavCtrl_GetFirst(hLibrary); + + while(NULL != itemInfo.hItem) + { + if (FALSE != MLNavItem_GetInfo(hLibrary, &itemInfo) && + CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, itemInfo.pszInvariant, cchPrefix, + NAVITEM_PREFIX, cchPrefix)) + { + return itemInfo.hItem; + } + itemInfo.hItem = MLNavItem_GetNext(hLibrary, itemInfo.hItem); + } + return NULL; +} + +void Navigation_Update_Icon(void) +{ + Nullsoft::Utility::AutoLock navlock(navigationLock); + + HNAVITEM hItem = NULL; + if(downloads_treeItem) + { + hItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent,downloads_treeItem); + } + + if (hItem) + { + NAVITEM item; + item.cbSize = sizeof(NAVITEM); + item.hItem = hItem; + item.iSelectedImage = item.iImage = icons[activeIcon]; + activeIcon = (activeIcon + 1) % totalIcons; + item.mask = NIMF_IMAGE | NIMF_IMAGESEL; + MLNavItem_SetInfo(plugin.hwndLibraryParent, &item); + } +} + +BOOL Navigation_Update(void) +{ + int activeDownloads = 0; + int historyDownloads = 0; + { + Nullsoft::Utility::AutoLock historylock(downloadedFiles.downloadedLock); + historyDownloads = (int)downloadedFiles.downloadList.size(); + } + + { + Nullsoft::Utility::AutoLock statuslock(downloadStatus.statusLock); + activeDownloads = (int)downloadStatus.downloads.size(); + } + + Nullsoft::Utility::AutoLock navlock(navigationLock); + HNAVITEM hItem = NULL; + if (downloads_treeItem) + { + hItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent,downloads_treeItem); + } + + NAVINSERTSTRUCT nis = {0}; + nis.item.cbSize = sizeof(NAVITEM); + nis.item.pszText = WASABI_API_LNGSTRINGW(IDS_DOWNLOADS); + nis.item.iSelectedImage = nis.item.iImage = icons[0]; + + WCHAR szName[256] = {0}; + if (activeDownloads && SUCCEEDED(StringCchPrintf(szName, ARRAYSIZE(szName), L"%s (%u)", WASABI_API_LNGSTRINGW(IDS_DOWNLOADS), activeDownloads))) + nis.item.pszText = szName; + + if (activeDownloads > 0 || historyDownloads > 0 || no_auto_hide == 2) + { + if (!hItem) + { + nis.item.pszInvariant = NAVITEM_UNIQUESTR; + nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_IMAGE | NIMF_IMAGESEL; + if(podcast_parent) nis.hParent = Navigation_FindService(SERVICE_PODCAST); + NAVITEM nvItem = {sizeof(NAVITEM),0,NIMF_ITEMID,}; + + nvItem.hItem = MLNavCtrl_InsertItem(plugin.hwndLibraryParent, &nis); + + MLNavItem_GetInfo(plugin.hwndLibraryParent, &nvItem); + downloads_treeItem = nvItem.id; + } + else + { + nis.item.hItem = hItem; + nis.item.mask = NIMF_TEXT; + MLNavItem_SetInfo(plugin.hwndLibraryParent, &nis.item); + } + } + else if (hItem) + { + nis.item.hItem = hItem; + nis.item.mask = NIMF_TEXT | NIMF_IMAGE | NIMF_IMAGESEL; + MLNavItem_SetInfo(plugin.hwndLibraryParent, &nis.item); + } + + return TRUE; +} + +void CALLBACK Downloads_Nav_Timer(HWND hwnd, UINT uMsg, UINT_PTR eventId, ULONG elapsed) +{ + switch (eventId) + { + case DOWNLOADS_TIMER_NAVNODE: + if (downloadStatus.CurrentlyDownloading()) + Navigation_Update_Icon(); + break; + } +} + + +int Init() +{ + hMainThread = GetCurrentThread(); + hDragNDropCursor = LoadCursor( GetModuleHandle( L"gen_ml.dll" ), MAKEINTRESOURCE( ML_IDC_DRAGDROP ) ); + threadStorage = TlsAlloc(); + + if ( 0 == VIEWPROP ) + { + VIEWPROP = GlobalAddAtom( L"Nullsoft_DownloadsView" ); + if ( VIEWPROP == 0 ) + return ML_INIT_FAILURE; + } + + winampVersion = (int)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETVERSION ); + + waServiceFactory *sf = plugin.service->service_getServiceByGuid( DownloadManagerGUID ); + if ( !sf ) // no sense in continuing + return ML_INIT_FAILURE; + else + WAC_API_DOWNLOADMANAGER = reinterpret_cast<api_downloadManager *>( sf->getInterface() ); + + // loader so that we can get the localisation service api for use + sf = plugin.service->service_getServiceByGuid( languageApiGUID ); + if ( sf ) + WASABI_API_LNG = reinterpret_cast<api_language*>( sf->getInterface() ); + + sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid ); + if ( sf ) + WASABI_API_APP = reinterpret_cast<api_application*>( sf->getInterface() ); + + sf = plugin.service->service_getServiceByGuid( ExplorerFindFileApiGUID ); + if ( sf ) + WASABI_API_EXPLORERFINDFILE = reinterpret_cast<api_explorerfindfile*>( sf->getInterface() ); + + // need to have this initialised before we try to do anything with localisation features + WASABI_API_START_LANG( plugin.hDllInstance, MlDownloadsLangGUID ); + + static wchar_t szDescription[ 256 ]; + StringCchPrintf( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_PLUGIN_NAME ), PLUGIN_VERSION_MAJOR, PLUGIN_VERSION_MINOR ); + plugin.description = (char*)szDescription; + + mediaLibrary.library = plugin.hwndLibraryParent; + mediaLibrary.winamp = plugin.hwndWinampParent; + mediaLibrary.instance = plugin.hDllInstance; + + BuildDefaults( plugin.hwndWinampParent ); + + mediaLibrary.BuildPath( L"Plugins\\ml\\downloads.xml", xmlFileName, 1024 ); + if ( PathFileExists( xmlFileName ) ) + { + DownloadsParse downloader; + downloader.DownloadFile( xmlFileName ); + } + else + { + wchar_t xmlRssFileName[ 1024 ] = { 0 }; + mediaLibrary.BuildPath( L"Plugins\\ml\\feeds\\rss.xml", xmlRssFileName, 1024 ); + { + DownloadsParse rssDownloader; + rssDownloader.DownloadFile( xmlRssFileName ); + } + } + + icons[ 0 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS ); + icons[ 1 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS1 ); + icons[ 2 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS2 ); + icons[ 3 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS3 ); + + ml_cfg = (wchar_t *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETMLINIFILEW ); + + podcast_parent = ( !!GetPrivateProfileInt( L"gen_ml_config", L"podcast_parent", 0, ml_cfg ) ); + no_auto_hide = GetPrivateProfileInt( L"gen_ml_config", L"no_auto_hide", 0, ml_cfg ); + + Navigation_Update(); + + downloadViewCallback = new DownloadViewCallback(); + WAC_API_DOWNLOADMANAGER->RegisterStatusCallback( downloadViewCallback ); + + SetTimer( plugin.hwndLibraryParent, DOWNLOADS_TIMER_NAVNODE, 1000, Downloads_Nav_Timer ); + + return ML_INIT_SUCCESS; +} + +void Quit() +{ + KillTimer( plugin.hwndLibraryParent, DOWNLOADS_TIMER_NAVNODE ); + + // If there are still files downloading, cancel download to remove incomplete downloaded files + while ( downloadStatus.CurrentlyDownloading() ) + { + Nullsoft::Utility::AutoLock lock(downloadStatus.statusLock); + DownloadToken dltoken = downloadStatus.downloads.begin()->first; + WAC_API_DOWNLOADMANAGER->CancelDownload(dltoken); + } + + if (dirty) + { + SaveDownloads( xmlFileName, downloadedFiles ); + dirty = 0; + } + + WAC_API_DOWNLOADMANAGER->UnregisterStatusCallback( downloadViewCallback ); + downloadViewCallback->Release(); + + waServiceFactory *sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid ); + if ( sf != NULL ) + sf->releaseInterface(WASABI_API_APP); + + sf = plugin.service->service_getServiceByGuid(ExplorerFindFileApiGUID); + if ( sf != NULL ) + sf->releaseInterface(WASABI_API_EXPLORERFINDFILE); + + sf = plugin.service->service_getServiceByGuid(DownloadManagerGUID); + if ( sf != NULL ) + sf->releaseInterface(WAC_API_DOWNLOADMANAGER); + + if ( VIEWPROP != 0 ) + { + GlobalDeleteAtom(VIEWPROP); + VIEWPROP = 0; + } +} + +HWND CALLBACK DownloadDialog_Create( HWND hParent ); + +INT_PTR MessageProc( int msg, INT_PTR param1, INT_PTR param2, INT_PTR param3 ) +{ + switch ( msg ) + { + case ML_MSG_DOWNLOADS_VIEW_LOADED: + return TRUE; + + case ML_MSG_DOWNLOADS_VIEW_POSITION: + { + // toggle the position of the node based on the preferences settings + if ( param2 ) + { + podcast_parent = (int)param1; + if ( downloads_treeItem ) + { + HNAVITEM hItem = MLNavCtrl_FindItemById( plugin.hwndLibraryParent, downloads_treeItem ); + if (hItem) + { + if ( MLNavCtrl_DeleteItem( plugin.hwndLibraryParent, hItem ) ) + { + downloads_treeItem = 0; + } + } + } + } + + Navigation_Update(); + return 0; + } + + case ML_MSG_TREE_ONCREATEVIEW: + return ( param1 == downloads_treeItem ) ? (INT_PTR)DownloadDialog_Create( (HWND)param2 ) : 0; + + case ML_MSG_NO_CONFIG: + return TRUE; + + case ML_MSG_NOTOKTOQUIT: + if (downloadStatus.CurrentlyDownloading()) + { + wchar_t titleStr[32] = {0}; + if ( MessageBox( plugin.hwndLibraryParent, WASABI_API_LNGSTRINGW( IDS_CANCEL_DOWNLOADS_AND_QUIT ), WASABI_API_LNGSTRINGW_BUF( IDS_CONFIRM_QUIT, titleStr, 32 ), MB_YESNO | MB_ICONQUESTION ) == IDNO ) + return TRUE; + } + return FALSE; + + case ML_MSG_WRITE_CONFIG: + if ( dirty ) + { + SaveDownloads( xmlFileName, downloadedFiles ); + dirty = 0; + } + break; + + case ML_MSG_VIEW_PLAY_ENQUEUE_CHANGE: + enqueuedef = (int)param1; + groupBtn = (int)param2; + PostMessage( downloads_window, WM_APP + 104, param1, param2 ); + return 0; + } + + return 0; +} + + +extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin() +{ + return &plugin; +}
\ No newline at end of file |