diff options
Diffstat (limited to 'Src/Plugins/Library/ml_bookmarks')
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/api__ml_bookmarks.h | 15 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/bookmark.cpp | 32 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/bookmark.h | 18 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/listview.cpp | 128 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/listview.h | 144 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/main.cpp | 122 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/main.h | 28 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/ml_bookmarks.rc | 186 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/ml_bookmarks.sln | 30 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj | 317 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj.filters | 100 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/resource.h | 46 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/resources/ti_bookmarks_16x16x16.bmp | bin | 0 -> 568 bytes | |||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/version.rc2 | 39 | ||||
-rw-r--r-- | Src/Plugins/Library/ml_bookmarks/view.cpp | 1512 |
15 files changed, 2717 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_bookmarks/api__ml_bookmarks.h b/Src/Plugins/Library/ml_bookmarks/api__ml_bookmarks.h new file mode 100644 index 00000000..2f9ee071 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/api__ml_bookmarks.h @@ -0,0 +1,15 @@ +#ifndef NULLSOFT_API_ML_BOOKMARKS_H +#define NULLSOFT_API_ML_BOOKMARKS_H + +#include "api/service/waServiceFactory.h" + +#include "../Agave/Language/api_language.h" + +#include "../Winamp/api_stats.h" +extern api_stats *statsApi; +#define AGAVE_API_STATS statsApi + +#include "api/application/api_application.h" +#define WASABI_API_APP applicationApi + +#endif // !NULLSOFT_API_ML_BOOKMARKS_H
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/bookmark.cpp b/Src/Plugins/Library/ml_bookmarks/bookmark.cpp new file mode 100644 index 00000000..c7ad05e1 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/bookmark.cpp @@ -0,0 +1,32 @@ +/** (c) Nullsoft, Inc. C O N F I D E N T I A L + ** Filename: + ** Project: + ** Description: + ** Author: + ** Created: + **/ +#include "bookmark.h" + +BookmarkWriter::BookmarkWriter():fp(0) +{ +} + +void BookmarkWriter::Open(const wchar_t *filename) +{ + fp=_wfopen(filename, L"a+t"); +} + +void BookmarkWriter::New(const wchar_t *filename) +{ + fp=_wfopen(filename, L"wt"); +} + +void BookmarkWriter::Write(const char *filename, const char *title) +{ + fprintf(fp,"%s\n%s\n",filename,title); +} + +void BookmarkWriter::Close() +{ + if (fp) fclose(fp); +}
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/bookmark.h b/Src/Plugins/Library/ml_bookmarks/bookmark.h new file mode 100644 index 00000000..5921e82e --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/bookmark.h @@ -0,0 +1,18 @@ +#ifndef NULLSOFT_BOOKMARKH +#define NULLSOFT_BOOKMARKH + +#include <stdio.h> + +class BookmarkWriter +{ +public: + BookmarkWriter(); + void New(const wchar_t *filename); + void Open(const wchar_t *filename); + void Write(const char *filename, const char *title); + void Close(); +private: + FILE *fp; +}; + +#endif
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/listview.cpp b/Src/Plugins/Library/ml_bookmarks/listview.cpp new file mode 100644 index 00000000..a3ceb22c --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/listview.cpp @@ -0,0 +1,128 @@ +/* +** Copyright (C) 2003 Nullsoft, Inc. +** +** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held +** liable for any damages arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to +** alter it and redistribute it freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +** +** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +** +** 3. This notice may not be removed or altered from any source distribution. +** +*/ + +#include <windows.h> +#include <commctrl.h> +#include "listview.h" + +#ifdef GEN_ML_EXPORTS +#include "main.h" // for getting the font +#include "config.h" +#endif +// bp Comment: all the calls beginning "ListView_" are +// MACROs defined in commctrl.h + +void W_ListView :: AddCol (char *text, int w) +{ + LVCOLUMN lvc={0,}; + lvc.mask = LVCF_TEXT|LVCF_WIDTH; + lvc.pszText = text; + if (w) lvc.cx=w; + ListView_InsertColumn (m_hwnd, m_col, &lvc); + m_col++; +} + +int W_ListView::GetColumnWidth (int col) +{ + if (col < 0 || col >= m_col) return 0; + return ListView_GetColumnWidth (m_hwnd, col); +} + + +int W_ListView::GetParam (int p) +{ + LVITEM lvi={0,}; + lvi.mask = LVIF_PARAM; + lvi.iItem = p; + ListView_GetItem (m_hwnd, &lvi); + return lvi.lParam; +} + +int W_ListView::InsertItem (int p, char *text, int param) +{ + LVITEM lvi={0,}; + lvi.mask = LVIF_TEXT | LVIF_PARAM; + lvi.iItem = p; + lvi.pszText = text; + lvi.cchTextMax=strlen (text); + lvi.lParam = param; + return ListView_InsertItem (m_hwnd, &lvi); +} + + +void W_ListView::SetItemText (int p, int si, char *text) +{ + LVITEM lvi={0,}; + lvi.iItem = p; + lvi.iSubItem = si; + lvi.mask = LVIF_TEXT; + lvi.pszText = text; + lvi.cchTextMax = strlen (text); + ListView_SetItem (m_hwnd, &lvi); +} + +void W_ListView::SetItemParam (int p, int param) +{ + LVITEM lvi={0,}; + lvi.iItem = p; + lvi.mask=LVIF_PARAM; + lvi.lParam=param; + ListView_SetItem (m_hwnd, &lvi); +} + +void W_ListView::refreshFont () +{ + if (m_font) + { + DeleteFont (m_font); + SetWindowFont (m_hwnd, NULL, FALSE); + } + m_font = NULL; + + HWND h; +#ifdef GEN_ML_EXPORTS + h=g_hwnd; +#else + h=m_libraryparent; +#endif + if (h && m_allowfonts) + { + int a=SendMessage (h, WM_USER+0x1000 /*WM_ML_IPC*/,66, 0x0600 /*ML_IPC_SKIN_WADLG_GETFUNC*/); + if (a) + { + m_font= (HFONT)a; + SetWindowFont (m_hwnd, m_font, FALSE); + } + } + InvalidateRect (m_hwnd, NULL, TRUE); +} + +void W_ListView::setallowfonts (int allow) +{ + m_allowfonts=allow; +} + +void W_ListView::setwnd (HWND hwnd) +{ + m_hwnd = hwnd; + if (hwnd) + { + ListView_SetExtendedListViewStyle (hwnd, LVS_EX_FULLROWSELECT|LVS_EX_UNDERLINEHOT ); + refreshFont (); + } +} diff --git a/Src/Plugins/Library/ml_bookmarks/listview.h b/Src/Plugins/Library/ml_bookmarks/listview.h new file mode 100644 index 00000000..5938a4dc --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/listview.h @@ -0,0 +1,144 @@ +/* +** Copyright (C) 2003 Nullsoft, Inc. +** +** This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held +** liable for any damages arising from the use of this software. +** +** Permission is granted to anyone to use this software for any purpose, including commercial applications, and to +** alter it and redistribute it freely, subject to the following restrictions: +** +** 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. +** If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. +** +** 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. +** +** 3. This notice may not be removed or altered from any source distribution. +** +*/ +#if 0 +#ifndef _LISTVIEW_H_ +#define _LISTVIEW_H_ + +#include <windows.h> +#include <windowsx.h> +#include <commctrl.h> + +class W_ListView +{ +public: + W_ListView() + { + m_hwnd=NULL; + m_col=0; + m_allowfonts=1; + m_font=NULL; +#ifndef GEN_ML_EXPORTS + m_libraryparent=NULL; +#endif + } + W_ListView(HWND hwnd) + { + m_hwnd=NULL; + m_col=0; + m_allowfonts=1; + m_font=NULL; +#ifndef GEN_ML_EXPORTS + m_libraryparent=NULL; +#endif + setwnd(hwnd); + } + ~W_ListView() + { + if (m_font) DeleteFont(m_font); + m_font=0; + } + + void refreshFont(); + +#ifndef GEN_ML_EXPORTS + void setLibraryParentWnd(HWND hwndParent) + { + m_libraryparent=hwndParent; + }// for Winamp Font getting stuff +#endif + void setallowfonts(int allow=1); + void setwnd(HWND hwnd); + void AddCol(char *text, int w); + int GetCount(void) + { + return ListView_GetItemCount(m_hwnd); + } + int GetParam(int p); + void DeleteItem(int n) + { + ListView_DeleteItem(m_hwnd,n); + } + void Clear(void) + { + ListView_DeleteAllItems(m_hwnd); + } + int GetSelected(int x) + { + return(ListView_GetItemState(m_hwnd, x, LVIS_SELECTED) & LVIS_SELECTED)?1:0; + } + + int GetSelectedCount() + { + return ListView_GetSelectedCount(m_hwnd); + } + + int GetSelectionMark() + { + return ListView_GetSelectionMark(m_hwnd); + } + void SetSelected(int x) + { + ListView_SetItemState(m_hwnd,x,LVIS_SELECTED,LVIS_SELECTED); + } + int InsertItem(int p, char *text, int param); + void GetItemRect(int i, RECT *r) + { + ListView_GetItemRect(m_hwnd, i, r, LVIR_BOUNDS); + } + void SetItemText(int p, int si, char *text); + void SetItemParam(int p, int param); + + void GetText(int p, int si, char *text, int maxlen) + { + ListView_GetItemText(m_hwnd, p, si, text, maxlen); + } + int FindItemByParam(int param) + { + LVFINDINFO fi={LVFI_PARAM,0,param}; + return ListView_FindItem(m_hwnd,-1,&fi); + } + int FindItemByPoint(int x, int y) + { + int l=GetCount(); + for (int i=0;i<l;i++) + { + RECT r; + GetItemRect(i, &r); + if (r.left<=x && r.right>=x && r.top<=y && r.bottom>=y) return i; + } + return -1; + } + int GetColumnWidth(int col); + HWND getwnd(void) + { + return m_hwnd; + } + +protected: + HWND m_hwnd; + HFONT m_font; + int m_col; + int m_allowfonts; +#ifndef GEN_ML_EXPORTS + HWND m_libraryparent; +#endif +}; + +#endif//_LISTVIEW_H_ + +#endif
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/main.cpp b/Src/Plugins/Library/ml_bookmarks/main.cpp new file mode 100644 index 00000000..c85674ba --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/main.cpp @@ -0,0 +1,122 @@ +//#define PLUGIN_NAME "Nullsoft Bookmarks" +#define PLUGIN_VERSION L"1.27" + +#include "Main.h" +#include "../nu/AutoWide.h" +#include <strsafe.h> +#include "../../General/gen_ml/menu.h" +#include "../../General/gen_ml/ml_ipc_0313.h" + +static int Init(); +static void Quit(); + +extern "C" winampMediaLibraryPlugin plugin = +{ + MLHDR_VER, + "nullsoft(ml_bookmarks.dll)", + Init, + Quit, + bm_pluginMessageProc, + 0, + 0, + 0, +}; + +int bookmark_treeItem = 0; +HMENU g_context_menus, g_context_menus2; +HCURSOR hDragNDropCursor; +C_Config *g_config; +WNDPROC waProc=0; + +// wasabi based services for localisation support +api_language *WASABI_API_LNG = 0; +HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0; +api_stats *AGAVE_API_STATS = 0; +api_application *WASABI_API_APP = 0; + +static DWORD WINAPI wa_newWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_WA_IPC && lParam == IPC_ADDBOOKMARK && wParam && wParam != 666) + { + bookmark_notifyAdd(AutoWide((char*)wParam)); + } + else if (msg == WM_WA_IPC && lParam == IPC_ADDBOOKMARKW && wParam && wParam != 666) + { + bookmark_notifyAdd((wchar_t*)wParam); + } + else if ((msg == WM_COMMAND || msg == WM_SYSCOMMAND) && LOWORD(wParam) == WINAMP_EDIT_BOOKMARKS) + { + mediaLibrary.ShowMediaLibrary(); + mediaLibrary.SwitchToPluginView(bookmark_treeItem); + return 0; + } + + if (waProc) + return (DWORD)CallWindowProcW(waProc, hwnd, msg, wParam, lParam); + else + return (DWORD)DefWindowProc(hwnd, msg, wParam, lParam); +} + +int Init() +{ + waProc = (WNDPROC)SetWindowLongPtrW( plugin.hwndWinampParent, GWLP_WNDPROC, (LONG_PTR)wa_newWndProc ); + + mediaLibrary.library = plugin.hwndLibraryParent; + mediaLibrary.winamp = plugin.hwndWinampParent; + mediaLibrary.instance = plugin.hDllInstance; + + waServiceFactory *sf = plugin.service->service_getServiceByGuid( languageApiGUID ); + if ( sf ) + WASABI_API_LNG = reinterpret_cast<api_language *>( sf->getInterface() ); + + sf = plugin.service->service_getServiceByGuid( AnonymousStatsGUID ); + if ( sf ) + AGAVE_API_STATS = reinterpret_cast<api_stats *>( sf->getInterface() ); + + sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid ); + if ( sf ) + WASABI_API_APP = reinterpret_cast<api_application *>( sf->getInterface() ); + + // need to have this initialised before we try to do anything with localisation features + WASABI_API_START_LANG( plugin.hDllInstance, MlBookmarkLangGUID ); + + static wchar_t szDescription[ 256 ]; + StringCchPrintfW( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_NULLSOFT_BOOKMARKS ), PLUGIN_VERSION ); + plugin.description = (char *)szDescription; + + wchar_t inifile[ MAX_PATH ] = { 0 }; + mediaLibrary.BuildPath( L"Plugins", inifile, MAX_PATH ); + CreateDirectoryW( inifile, NULL ); + + mediaLibrary.BuildPath( L"Plugins\\gen_ml.ini", inifile, MAX_PATH ); + g_config = new C_Config( inifile ); + + g_context_menus = WASABI_API_LOADMENU( IDR_MENU1 ); + g_context_menus2 = WASABI_API_LOADMENU( IDR_MENU1 ); + hDragNDropCursor = LoadCursor( GetModuleHandle( L"gen_ml.dll" ), MAKEINTRESOURCE( ML_IDC_DRAGDROP ) ); + + NAVINSERTSTRUCT nis = { 0 }; + nis.item.cbSize = sizeof( NAVITEM ); + nis.item.pszText = WASABI_API_LNGSTRINGW( IDS_BOOKMARKS ); + nis.item.pszInvariant = L"Bookmarks"; + nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_IMAGE | NIMF_IMAGESEL; + nis.item.iSelectedImage = nis.item.iImage = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_BOOKMARKS ); + + // map to item id (will probably have to change but is a quick port to support invariant item naming) + NAVITEM nvItem = { sizeof( NAVITEM ),0,NIMF_ITEMID, }; + nvItem.hItem = MLNavCtrl_InsertItem( plugin.hwndLibraryParent, &nis ); + MLNavItem_GetInfo( plugin.hwndLibraryParent, &nvItem ); + bookmark_treeItem = nvItem.id; + + return 0; +} + +void Quit() +{ + delete g_config; +} + +extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin() +{ + return &plugin; +}
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/main.h b/Src/Plugins/Library/ml_bookmarks/main.h new file mode 100644 index 00000000..d8c2f355 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/main.h @@ -0,0 +1,28 @@ +#ifndef NULLSOFT_BOOKMARKS_MAIN_H +#define NULLSOFT_BOOKMARKS_MAIN_H + +#include <windows.h> +#include <windowsx.h> + +#include "api__ml_bookmarks.h" + +#include "../Plugins/General/gen_ml/ml.h" +#include "../nu/MediaLibraryInterface.h" + +#include "resource.h" + +#include "../winamp/wa_ipc.h" +//#include "../Plugins/General/gen_ml/ml.h" +#include "../Plugins/General/gen_ml/config.h" + + +#define WINAMP_EDIT_BOOKMARKS 40320 + +INT_PTR bm_pluginMessageProc( int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3 ); + +extern winampMediaLibraryPlugin plugin; +extern int bookmark_treeItem; + +void bookmark_notifyAdd( wchar_t *filenametitle ); + +#endif // !NULLSOFT_BOOKMARKS_MAIN_H diff --git a/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.rc b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.rc new file mode 100644 index 00000000..f36fe7f8 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.rc @@ -0,0 +1,186 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#include ""version.rc2""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Menu +// + +IDR_MENU1 MENU +BEGIN + POPUP "BMWnd" + BEGIN + MENUITEM "Play selection\tEnter", ID_BMWND_PLAYSELECTEDFILES + MENUITEM "Enqueue selection\tShift+Enter", ID_BMWND_ENQUEUESELECTEDFILES + MENUITEM "Send to:", ID_BMWND_SENDTO + MENUITEM SEPARATOR + MENUITEM "Select all\tCtrl+A", ID_BMWND_SELECTALL + MENUITEM SEPARATOR + MENUITEM "Remove selected bookmarks\tDel", ID_BMWND_REMOVESELECTEDBOOKMARKS + MENUITEM "Edit selected bookmarks\tCtrl+E", ID_BMWND_EDITSELECTEDBOOKMARKS + END + POPUP "BMWndIcon" + BEGIN + MENUITEM "Play all bookmarks\tEnter", ID_BMWND_PLAYSELECTEDFILES + MENUITEM "Enqueue all bookmarks\tShift+Enter", ID_BMWND_ENQUEUESELECTEDFILES + MENUITEM SEPARATOR + MENUITEM "Help", ID_BMWND_HELP + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_VIEW_BM DIALOGEX 0, 0, 186, 92 +STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN +EXSTYLE WS_EX_ACCEPTFILES | WS_EX_CONTROLPARENT +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + CONTROL "",IDC_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_TABSTOP,0,0,184,79 + CONTROL "Play",IDC_BUTTON_PLAY,"Button",BS_OWNERDRAW | WS_TABSTOP,0,81,35,11 + CONTROL "Enqueue",IDC_BUTTON_ENQUEUE,"Button",BS_OWNERDRAW | WS_TABSTOP,38,81,35,11 + CONTROL "Edit",IDC_EDITBOOK,"Button",BS_OWNERDRAW | WS_TABSTOP,76,81,36,11 + CONTROL "Delete",IDC_REMOVEBOOK,"Button",BS_OWNERDRAW | WS_TABSTOP,114,81,36,11 +END + +IDD_EDITBOOKMARK DIALOGEX 0, 0, 241, 65 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Edit Bookmark" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Title",IDC_STATIC,8,10,14,8,SS_CENTERIMAGE + EDITTEXT IDC_TITLE,28,7,206,14,ES_AUTOHSCROLL + LTEXT "File",IDC_STATIC,8,29,12,8,SS_CENTERIMAGE + EDITTEXT IDC_FILE,28,26,187,14,ES_AUTOHSCROLL + PUSHBUTTON "&...",IDC_EDIT_FN,218,25,16,15 + DEFPUSHBUTTON "&OK",IDOK,6,44,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,60,44,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_EDITBOOKMARK, DIALOG + BEGIN + LEFTMARGIN, 6 + RIGHTMARGIN, 234 + TOPMARGIN, 7 + BOTTOMMARGIN, 58 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Bitmap +// + +IDB_TREEITEM_BOOKMARKS BITMAP "resources\\ti_bookmarks_16x16x16.bmp" + +///////////////////////////////////////////////////////////////////////////// +// +// Accelerator +// + +IDR_VIEW_BM_ACCELERATORS ACCELERATORS +BEGIN + "A", ID_BMWND_SELECTALL, VIRTKEY, CONTROL, NOINVERT + "E", ID_BMWND_EDITSELECTEDBOOKMARKS, VIRTKEY, CONTROL, NOINVERT + VK_DELETE, ID_BMWND_REMOVESELECTEDBOOKMARKS, VIRTKEY, NOINVERT + VK_RETURN, ID_BMWND_PLAYSELECTEDFILES, VIRTKEY, NOINVERT + VK_RETURN, ID_BMWND_ENQUEUESELECTEDFILES, VIRTKEY, SHIFT, NOINVERT + VK_RETURN, IDC_BUTTON_CUSTOM, VIRTKEY, SHIFT, CONTROL, NOINVERT +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_NULLSOFT_BOOKMARKS "Nullsoft Bookmarks v%s" + 65535 "{A3A1E7C0-761B-4391-A08A-F0D7AF38931C}" +END + +STRINGTABLE +BEGIN + IDS_BOOKMARKS "Bookmarks" + IDS_ADD_TO_BOOKMARKS "Add to bookmarks" + IDS_BOOKMARK_TITLE "Bookmark Title" + IDS_BOOKMARK_FN_URL "Bookmark Filename/URL" + IDS_BROWSE_FOR_BM_ENTRY "Browse for bookmark entry..." +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "version.rc2" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.sln b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.sln new file mode 100644 index 00000000..746468be --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.sln @@ -0,0 +1,30 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29509.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_bookmarks", "ml_bookmarks.vcxproj", "{24335E73-2704-466A-8265-4314DD99886A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {24335E73-2704-466A-8265-4314DD99886A}.Debug|Win32.ActiveCfg = Debug|Win32 + {24335E73-2704-466A-8265-4314DD99886A}.Debug|Win32.Build.0 = Debug|Win32 + {24335E73-2704-466A-8265-4314DD99886A}.Debug|x64.ActiveCfg = Debug|x64 + {24335E73-2704-466A-8265-4314DD99886A}.Debug|x64.Build.0 = Debug|x64 + {24335E73-2704-466A-8265-4314DD99886A}.Release|Win32.ActiveCfg = Release|Win32 + {24335E73-2704-466A-8265-4314DD99886A}.Release|Win32.Build.0 = Release|Win32 + {24335E73-2704-466A-8265-4314DD99886A}.Release|x64.ActiveCfg = Release|x64 + {24335E73-2704-466A-8265-4314DD99886A}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {91C2E933-BA43-4ADA-A8B4-B3A2E571BA11} + EndGlobalSection +EndGlobal diff --git a/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj new file mode 100644 index 00000000..669a0893 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj @@ -0,0 +1,317 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{24335E73-2704-466A-8265-4314DD99886A}</ProjectGuid> + <RootNamespace>ml_bookmarks</RootNamespace> + <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <PlatformToolset>v142</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + <EmbedManifest>true</EmbedManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <EmbedManifest>true</EmbedManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <IncludePath>$(IncludePath)</IncludePath> + <LibraryPath>$(LibraryPath)</LibraryPath> + <EmbedManifest>true</EmbedManifest> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <LinkIncremental>false</LinkIncremental> + <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir> + <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir> + <EmbedManifest>true</EmbedManifest> + </PropertyGroup> + <PropertyGroup Label="Vcpkg"> + <VcpkgEnableManifest>false</VcpkgEnableManifest> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + <VcpkgConfiguration>Debug</VcpkgConfiguration> + </PropertyGroup> + <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <VcpkgInstalledDir> + </VcpkgInstalledDir> + <VcpkgUseStatic>false</VcpkgUseStatic> + <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_BOOKMARKS_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <BufferSecurityCheck>true</BufferSecurityCheck> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile> + </Manifest> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <Optimization>Disabled</Optimization> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_DEBUG;_WINDOWS;_USRDLL;ML_BOOKMARKS_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <MinimalRebuild>false</MinimalRebuild> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> + <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> + <DisableSpecificWarnings>4302;4311;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <BufferSecurityCheck>true</BufferSecurityCheck> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ +xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile> + </Manifest> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_BOOKMARKS_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <TargetMachine>MachineX86</TargetMachine> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile> + </Manifest> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <Optimization>MinSpace</Optimization> + <FavorSizeOrSpeed>Size</FavorSizeOrSpeed> + <AdditionalIncludeDirectories>.;..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;NDEBUG;_WINDOWS;_USRDLL;ML_BOOKMARKS_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <StringPooling>true</StringPooling> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> + <BufferSecurityCheck>true</BufferSecurityCheck> + <WarningLevel>Level3</WarningLevel> + <DebugInformationFormat>None</DebugInformationFormat> + <DisableSpecificWarnings>4302;4311;%(DisableSpecificWarnings)</DisableSpecificWarnings> + <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName> + </ClCompile> + <Link> + <AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile> + <GenerateDebugInformation>false</GenerateDebugInformation> + <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <OptimizeReferences>true</OptimizeReferences> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <RandomizedBaseAddress>false</RandomizedBaseAddress> + <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary> + <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers> + <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <ModuleDefinitionFile> + </ModuleDefinitionFile> + </Link> + <PostBuildEvent> + <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command> + <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message> + </PostBuildEvent> + <ResourceCompile> + <PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ResourceCompile> + <Manifest> + <OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile> + </Manifest> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\General\gen_ml\config.cpp" /> + <ClCompile Include="..\..\General\gen_ml\menu.cpp" /> + <ClCompile Include="..\..\..\nu\DialogSkinner.cpp" /> + <ClCompile Include="..\..\..\nu\listview.cpp" /> + <ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp" /> + <ClCompile Include="..\..\..\nu\menushortcuts.cpp" /> + <ClCompile Include="bookmark.cpp" /> + <ClCompile Include="main.cpp" /> + <ClCompile Include="view.cpp" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\General\gen_ml\config.h" /> + <ClInclude Include="..\..\General\gen_ml\menu.h" /> + <ClInclude Include="..\..\..\nu\DialogSkinner.h" /> + <ClInclude Include="..\..\..\nu\listview.h" /> + <ClInclude Include="..\..\..\nu\MediaLibraryInterface.h" /> + <ClInclude Include="..\..\..\nu\menushortcuts.h" /> + <ClInclude Include="api__ml_bookmarks.h" /> + <ClInclude Include="bookmark.h" /> + <ClInclude Include="main.h" /> + <ClInclude Include="resource.h" /> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="ml_bookmarks.rc" /> + </ItemGroup> + <ItemGroup> + <Image Include="resources\ti_bookmarks_16x16x16.bmp" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj"> + <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj.filters b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj.filters new file mode 100644 index 00000000..7207ea75 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/ml_bookmarks.vcxproj.filters @@ -0,0 +1,100 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="view.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="bookmark.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\General\gen_ml\config.cpp"> + <Filter>Source Files\gen_ml</Filter> + </ClCompile> + <ClCompile Include="..\..\..\nu\DialogSkinner.cpp"> + <Filter>Source Files\nu</Filter> + </ClCompile> + <ClCompile Include="..\..\..\nu\listview.cpp"> + <Filter>Source Files\nu</Filter> + </ClCompile> + <ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp"> + <Filter>Source Files\nu</Filter> + </ClCompile> + <ClCompile Include="..\..\General\gen_ml\menu.cpp"> + <Filter>Source Files\gen_ml</Filter> + </ClCompile> + <ClCompile Include="..\..\..\nu\menushortcuts.cpp"> + <Filter>Source Files\nu</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="api__ml_bookmarks.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="bookmark.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="main.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="resource.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="..\..\General\gen_ml\config.h"> + <Filter>Header Files\gen_ml</Filter> + </ClInclude> + <ClInclude Include="..\..\..\nu\DialogSkinner.h"> + <Filter>Header Files\nu</Filter> + </ClInclude> + <ClInclude Include="..\..\..\nu\listview.h"> + <Filter>Header Files\nu</Filter> + </ClInclude> + <ClInclude Include="..\..\..\nu\MediaLibraryInterface.h"> + <Filter>Header Files\nu</Filter> + </ClInclude> + <ClInclude Include="..\..\General\gen_ml\menu.h"> + <Filter>Header Files\gen_ml</Filter> + </ClInclude> + <ClInclude Include="..\..\..\nu\menushortcuts.h"> + <Filter>Header Files\nu</Filter> + </ClInclude> + </ItemGroup> + <ItemGroup> + <Filter Include="Header Files"> + <UniqueIdentifier>{b4c6c983-ad68-4d2d-a542-7f1bf6b1c155}</UniqueIdentifier> + </Filter> + <Filter Include="Ressource Files"> + <UniqueIdentifier>{f072eba6-51ff-4c40-b136-bf3c79f3e120}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files"> + <UniqueIdentifier>{b04fff17-1af4-4d74-b609-169c1a32b097}</UniqueIdentifier> + </Filter> + <Filter Include="Image Files"> + <UniqueIdentifier>{56f5b459-ac0f-423d-b448-563135bf4bd8}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\gen_ml"> + <UniqueIdentifier>{f4c07660-d9f0-42b1-8745-0d6446aef60f}</UniqueIdentifier> + </Filter> + <Filter Include="Source Files\nu"> + <UniqueIdentifier>{d31d9efd-4434-46c5-8d2d-8a894aa24055}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\gen_ml"> + <UniqueIdentifier>{00b097a1-1383-414f-8c19-82f97c6d06a5}</UniqueIdentifier> + </Filter> + <Filter Include="Header Files\nu"> + <UniqueIdentifier>{8eaf67d8-c524-468a-a78b-334c69d1cf9e}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ResourceCompile Include="ml_bookmarks.rc"> + <Filter>Ressource Files</Filter> + </ResourceCompile> + </ItemGroup> + <ItemGroup> + <Image Include="resources\ti_bookmarks_16x16x16.bmp"> + <Filter>Image Files</Filter> + </Image> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Src/Plugins/Library/ml_bookmarks/resource.h b/Src/Plugins/Library/ml_bookmarks/resource.h new file mode 100644 index 00000000..037b9841 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/resource.h @@ -0,0 +1,46 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ml_bookmarks.rc +// +#define IDS_BOOKMARKS 1 +#define IDS_ADD_TO_BOOKMARKS 2 +#define IDS_BOOKMARK_TITLE 3 +#define IDS_BOOKMARK_FN_URL 4 +#define IDS_BROWSE_FOR_BM_ENTRY 5 +#define IDR_MENU1 101 +#define IDD_VIEW_BM 102 +#define IDD_EDITBOOKMARK 103 +#define IDC_CURSOR1 105 +#define IDB_BITMAP1 106 +#define IDR_VIEW_BM_ACCELERATORS 111 +#define IDC_BUTTON_CUSTOM 1000 +#define IDC_LIST 1001 +#define IDC_BUTTON_PLAY 1002 +#define IDC_BUTTON_ENQUEUE 1003 +#define IDB_TREEITEM_BOOKMARKS 1003 +#define IDC_EDITBOOK 1004 +#define IDC_REMOVEBOOK 1005 +#define IDC_TITLE 1006 +#define IDC_FILE 1008 +#define IDC_EDIT_FN 1009 +#define ID_BMWND_PLAYSELECTEDFILES 40001 +#define ID_BMWND_ENQUEUESELECTEDFILES 40002 +#define ID_BMWND_REMOVESELECTEDBOOKMARKS 40003 +#define ID_BMWND_EDITSELECTEDBOOKMARKS 40004 +#define ID_BMWND_SELECTALL 40005 +#define ID_Menu 40006 +#define ID_BMWNDICON_HELP 40007 +#define ID_BMWND_HELP 40008 +#define ID_BMWND_SENDTO 40012 +#define IDS_NULLSOFT_BOOKMARKS 65534 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 114 +#define _APS_NEXT_COMMAND_VALUE 40013 +#define _APS_NEXT_CONTROL_VALUE 1010 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/Src/Plugins/Library/ml_bookmarks/resources/ti_bookmarks_16x16x16.bmp b/Src/Plugins/Library/ml_bookmarks/resources/ti_bookmarks_16x16x16.bmp Binary files differnew file mode 100644 index 00000000..92f58e77 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/resources/ti_bookmarks_16x16x16.bmp diff --git a/Src/Plugins/Library/ml_bookmarks/version.rc2 b/Src/Plugins/Library/ml_bookmarks/version.rc2 new file mode 100644 index 00000000..b5ce38cb --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/version.rc2 @@ -0,0 +1,39 @@ + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// +#include "../../../Winamp/buildType.h" +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,27,0,0 + PRODUCTVERSION WINAMP_PRODUCTVER + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Winamp SA" + VALUE "FileDescription", "Winamp Media Library Plug-in" + VALUE "FileVersion", "1,27,0,0" + VALUE "InternalName", "Nullsoft Bookmarks" + VALUE "LegalCopyright", "Copyright © 2003-2023 Winamp SA" + VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA" + VALUE "OriginalFilename", "ml_bookmark.dll" + VALUE "ProductName", "Winamp" + VALUE "ProductVersion", STR_WINAMP_PRODUCTVER + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END diff --git a/Src/Plugins/Library/ml_bookmarks/view.cpp b/Src/Plugins/Library/ml_bookmarks/view.cpp new file mode 100644 index 00000000..f89196a0 --- /dev/null +++ b/Src/Plugins/Library/ml_bookmarks/view.cpp @@ -0,0 +1,1512 @@ +#include "main.h" +#include "../nu/AutoCharFn.h" +#include "../nu/DialogSkinner.h" +#include "Bookmark.h" +#include "../../General/gen_ml/ml_ipc.h" +#include <string> +#include "../nu/ListView.h" +#include "../nu/AutoChar.h" +#include "../nu/AutoWide.h" +#include "../nu/menushortcuts.h" +#include <strsafe.h> +#include "../../General/gen_ml/menu.h" + +INT_PTR CALLBACK view_bmDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam); +static W_ListView m_bmlist; +static HWND m_headerhwnd, m_hwnd; +extern C_Config *g_config; +static int customAllowed, groupBtn = 1, enqueuedef; +static viewButtons view; + +// used for the send-to menu bits +static INT_PTR IPC_LIBRARY_SENDTOMENU; +static librarySendToMenuStruct s; +BOOL myMenu = FALSE; + +extern HMENU g_context_menus, g_context_menus2; +extern HCURSOR hDragNDropCursor; + +static int bookmark_contextMenu( INT_PTR param1, HWND parent, POINTS pts ); +static void bookmarks_contextMenu( HWND hwndDlg, HWND from, int x, int y ); +static void bookmark_onTreeEnterDblClk(); + +static int pluginHandleIpcMessage(int msg, int param) +{ + return (int)SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, param, msg); +} + +void bookmark_notifyAdd(wchar_t *filenametitle) +{ + if (!m_hwnd || !filenametitle) return; + int cnt=m_bmlist.GetCount(); + m_bmlist.InsertItem(cnt,filenametitle+lstrlenW(filenametitle)+1,0); + m_bmlist.SetItemText(cnt,1,filenametitle); +} + +INT_PTR bm_pluginMessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3) +{ + if (message_type == ML_MSG_NO_CONFIG) + { + return TRUE; + } + else if (message_type == ML_MSG_TREE_ONCLICK) + { + switch(param2) + { + case ML_ACTION_ENTER: + case ML_ACTION_DBLCLICK: + if (param1 == bookmark_treeItem) + bookmark_onTreeEnterDblClk(); + break; + } + } + else if (message_type == ML_MSG_TREE_ONCREATEVIEW && param1 == bookmark_treeItem) + { + return (INT_PTR)WASABI_API_CREATEDIALOGW(IDD_VIEW_BM, (HWND)param2, view_bmDialogProc); + } + else if (message_type == ML_MSG_NAVIGATION_CONTEXTMENU) + { + return bookmark_contextMenu(param1, (HWND)param2, MAKEPOINTS(param3)); + } + else if (message_type == ML_MSG_ONSENDTOBUILD) + { + if (!myMenu && + (param1 == ML_TYPE_ITEMRECORDLISTW || param1 == ML_TYPE_ITEMRECORDLIST || + param1 == ML_TYPE_FILENAMES || param1 == ML_TYPE_STREAMNAMES || + param1 == ML_TYPE_FILENAMESW || param1 == ML_TYPE_STREAMNAMESW || + param1 == ML_TYPE_CDTRACKS)) + mediaLibrary.AddToSendTo(WASABI_API_LNGSTRINGW(IDS_ADD_TO_BOOKMARKS), + param2, (INT_PTR)bm_pluginMessageProc); + } + else if (message_type == ML_MSG_ONSENDTOSELECT || message_type == ML_MSG_TREE_ONDROPTARGET) + { + // set with droptarget defaults =) + UINT_PTR type = 0,data = 0; + + if (message_type == ML_MSG_ONSENDTOSELECT) + { + if (param3 != (INT_PTR)bm_pluginMessageProc) return 0; + + type=(int)param1; + data = (int)param2; + } + else + { + if (param1 != bookmark_treeItem) return 0; + + type=(int)param2; + data=(int)param3; + + if (!data) + { + return (type == ML_TYPE_ITEMRECORDLISTW || type == ML_TYPE_ITEMRECORDLIST || + type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES || + type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW || + type == ML_TYPE_CDTRACKS || + type == ML_TYPE_PLAYLIST || type == ML_TYPE_PLAYLISTS) ? 1 : -1; + } + } + + if (data) + { + if (type == ML_TYPE_ITEMRECORDLIST || type == ML_TYPE_CDTRACKS) + { + itemRecordList *p=(itemRecordList*)data; + for (int x = 0; x < p->Size; x ++) + mediaLibrary.AddBookmarkW(AutoWide(p->Items[x].filename)); + + return 1; + } + else if (type == ML_TYPE_ITEMRECORDLISTW) + { + itemRecordListW *p=(itemRecordListW *)data; + for (int x = 0; x < p->Size; x ++) + mediaLibrary.AddBookmarkW(p->Items[x].filename); + + return 1; + } + else if (type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES) + { + char *p=(char*)data; + while (p && *p) + { + mediaLibrary.AddBookmark(p); + p+=lstrlenA(p)+1; + } + return 1; + } + else if (type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW) + { + wchar_t *p=(wchar_t*)data; + while (p && *p) + { + mediaLibrary.AddBookmarkW(p); + p+=wcslen(p)+1; + } + return 1; + } + else if(type == ML_TYPE_PLAYLIST) + { + mediaLibrary.AddBookmarkW((wchar_t*)((mlPlaylist*)data)->filename); + return 1; + } + else if(type == ML_TYPE_PLAYLISTS) + { + mlPlaylist **playlists = (mlPlaylist **)data; + while (playlists && *playlists) + { + mlPlaylist *pl = *playlists; + mediaLibrary.AddBookmarkW((wchar_t*)pl->filename); + playlists++; + } + return 1; + } + } + } + else if (message_type == ML_MSG_VIEW_PLAY_ENQUEUE_CHANGE) + { + enqueuedef = (int)param1; + groupBtn = (int)param2; + PostMessage(m_hwnd, WM_APP + 104, param1, param2); + return 0; + } + return 0; +} + +static void playFiles(int enqueue, int all) +{ + int cnt=0; + int l=m_bmlist.GetCount(); + for(int i=0;i<l;i++) + { + if(all || m_bmlist.GetSelected(i)) + { + if (!cnt) + { + if(!enqueue) SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_DELETE); + cnt++; + } + //send the file to winamp + COPYDATASTRUCT cds = {0}; + cds.dwData = IPC_ENQUEUEFILEW; + wchar_t buf[1024] = {0}; + m_bmlist.GetText(i,1,buf,sizeof(buf)-1); + buf[1023]=0; + cds.lpData = (void *) buf; + cds.cbData = (lstrlenW((wchar_t*)cds.lpData)+1)*sizeof(wchar_t); // include space for null char + SendMessage(plugin.hwndWinampParent,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds); + } + } + if (cnt) + { + if(!enqueue) SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_STARTPLAY); + } +} + +static wchar_t *g_bmedit_fn, *g_bmedit_ft; + +static BOOL CALLBACK BookMarkEditProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + SetDlgItemTextW(hwndDlg,IDC_TITLE,g_bmedit_ft); + SetDlgItemTextW(hwndDlg,IDC_FILE,g_bmedit_fn); + return 0; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + GetDlgItemTextW(hwndDlg,IDC_TITLE,g_bmedit_ft,1024); + GetDlgItemTextW(hwndDlg,IDC_FILE,g_bmedit_fn,1024); + case IDCANCEL: + EndDialog(hwndDlg,0); + return 0; + case IDC_EDIT_FN: + { + wchar_t fn[1024] = {0}; + GetDlgItemTextW(hwndDlg,IDC_FILE,fn,1024); + OPENFILENAMEW of = {0}; + of.lStructSize = sizeof(OPENFILENAMEW); + of.hwndOwner = hwndDlg; + of.nMaxFileTitle = 32; + of.lpstrFilter = (wchar_t*)SendMessage(plugin.hwndWinampParent,WM_WA_IPC,1,IPC_GET_EXTLISTW); + of.nMaxCustFilter = 1024; + of.lpstrFile = fn; + of.nMaxFile = 1024; + of.lpstrTitle = WASABI_API_LNGSTRINGW(IDS_BROWSE_FOR_BM_ENTRY); + of.Flags = OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_EXPLORER| + OFN_PATHMUSTEXIST|OFN_ENABLESIZING; + + if(GetOpenFileNameW(&of)) + { + SetDlgItemTextW(hwndDlg,IDC_FILE,fn); + } + GlobalFree((void*)of.lpstrFilter); + } + break; + } + return 0; + } + return 0; +} + +static void readbookmarks(int play1enqueue2=0) +{ + if (!play1enqueue2) m_bmlist.Clear(); + + int x=0; + FILE *fp=NULL; + wchar_t *fnp=(wchar_t*)SendMessage(plugin.hwndWinampParent,WM_WA_IPC,666,IPC_ADDBOOKMARKW); + if ((unsigned int)fnp < 65536) return; + + fp=_wfopen(fnp,L"rt"); + if (fp) + { + while (1) + { + char ft[4096] = {0}, fn[4096] = {0}; + fgets(fn,4096,fp); + if (feof(fp)) break; + fgets(ft,4096,fp); + if (feof(fp)) break; + if (ft[0] && fn[0]) + { + if (fn[strlen(fn)-1]=='\n') fn[strlen(fn)-1]=0; + if (ft[strlen(ft)-1]=='\n') ft[strlen(ft)-1]=0; + if (ft[0] && fn[0]) + { + if (!play1enqueue2) + { + m_bmlist.InsertItem(x,AutoWide(ft,CP_UTF8),0); + m_bmlist.SetItemText(x,1,AutoWide(fn,CP_UTF8)); + } + else + { + if (!x) + { + if(play1enqueue2==1) SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_DELETE); + } + //send the file to winamp + COPYDATASTRUCT cds = {0}; + cds.dwData = IPC_ENQUEUEFILEW; + cds.lpData = (void *)AutoWideDup(fn,CP_UTF8); + cds.cbData = (lstrlenW((wchar_t *) cds.lpData)+1)*sizeof(wchar_t); // include space for null char + SendMessage(plugin.hwndWinampParent,WM_COPYDATA,(WPARAM)NULL,(LPARAM)&cds); + } + x++; + } + } + } + fclose(fp); + } + + if (!play1enqueue2 && AGAVE_API_STATS) + { + AGAVE_API_STATS->SetStat(api_stats::BOOKMARK_COUNT, m_bmlist.GetCount()); + } + + if (x && play1enqueue2 == 1) + { + SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_STARTPLAY); + } +} + +static void writebookmarks() +{ + wchar_t *fnp = (wchar_t *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 666, IPC_ADDBOOKMARKW ); + + if ( (unsigned int)fnp < 65536 ) + return; + + BookmarkWriter bookmarks; + bookmarks.New( fnp ); + + int l = m_bmlist.GetCount(); + for ( int x = 0; x < l; x++ ) + { + wchar_t ftW[ 4096 ] = { 0 }, fnW[ 4096 ] = { 0 }; + m_bmlist.GetText( x, 0, ftW, ARRAYSIZE( ftW ) ); + m_bmlist.GetText( x, 1, fnW, ARRAYSIZE( fnW ) ); + bookmarks.Write( AutoChar( fnW, CP_UTF8 ), AutoChar( ftW, CP_UTF8 ) ); + } + + bookmarks.Close(); + + fnp = (wchar_t *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_ADDBOOKMARKW ); + + if ( (unsigned int)fnp < 65536 ) + return; + + bookmarks.New( fnp ); + + for ( int x = 0; x < l; x++ ) + { + char ft[ 4096 ] = { 0 }, fn[ 4096 ] = { 0 }; + + m_bmlist.GetText( x, 0, ft, sizeof( ft ) ); + m_bmlist.GetText( x, 1, fn, sizeof( fn ) ); + + bookmarks.Write( fn, ft ); + } + + bookmarks.Close(); +} + +static void bookmark_onTreeEnterDblClk() +{ + int enq = ( ( !!( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) ) ^ ( !!g_config->ReadInt( L"enqueuedef", 0 ) ) ); + readbookmarks( enq ? 2 : 1 ); +} + +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 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 == ID_BMWND_PLAYSELECTEDFILES) + { + playItem.fMask = MIIM_ID; + playPos = i; + GetMenuItemInfoW(listMenu, i, TRUE, &playItem); + } + else if (id == ID_BMWND_ENQUEUESELECTEDFILES) + { + enqueueItem.fMask = MIIM_ID; + enqueuePos= i; + GetMenuItemInfoW(listMenu, i, TRUE, &enqueueItem); + } + } + + playItem.wID = ID_BMWND_ENQUEUESELECTEDFILES; + enqueueItem.wID = ID_BMWND_PLAYSELECTEDFILES; + SetMenuItemInfoW(listMenu, playPos, TRUE, &playItem); + SetMenuItemInfoW(listMenu, enqueuePos, TRUE, &enqueueItem); +} + +void UpdateMenuItems(HWND hwndDlg, HMENU menu) +{ + bool swapPlayEnqueue=false; + if (g_config->ReadInt(L"enqueuedef", 0) == 1) + { + SwapPlayEnqueueInMenu(menu); + swapPlayEnqueue=true; + } + + SyncMenuWithAccelerators(hwndDlg, menu); + if (swapPlayEnqueue) SwapPlayEnqueueInMenu(menu); +} + +static int bookmark_contextMenu(INT_PTR param1, HWND hHost, POINTS pts) +{ + HNAVITEM hItem = (HNAVITEM)param1; + HNAVITEM myItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent, bookmark_treeItem); + if (hItem != myItem) + return FALSE; + + POINT pt; + POINTSTOPOINT(pt, pts); + if (-1 == pt.x || -1 == pt.y) + { + NAVITEMGETRECT itemRect; + itemRect.fItem = FALSE; + itemRect.hItem = hItem; + if (MLNavItem_GetRect(plugin.hwndLibraryParent, &itemRect)) + { + MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2); + pt.x = itemRect.rc.left + 2; + pt.y = itemRect.rc.top + 2; + } + } + + HMENU menu=GetSubMenu(g_context_menus,1); + + bool swapPlayEnqueue=false; + if (g_config->ReadInt(L"enqueuedef", 0) == 1) + { + SwapPlayEnqueueInMenu(menu); + swapPlayEnqueue=true; + } + + if(!IsWindow(m_hwnd)) + { + HACCEL accel = WASABI_API_LOADACCELERATORSW(IDR_VIEW_BM_ACCELERATORS); + int size = CopyAcceleratorTable(accel,0,0); + AppendMenuShortcuts(menu, &accel, size, MSF_REPLACE); + } + else + { + SyncMenuWithAccelerators(m_hwnd, menu); + } + + if (swapPlayEnqueue) + SwapPlayEnqueueInMenu(menu); + + int r = Menu_TrackPopup(plugin.hwndLibraryParent, menu, + TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_NONOTIFY, + pt.x, pt.y, hHost, NULL); + switch(r) + { + case ID_BMWND_PLAYSELECTEDFILES: + readbookmarks(1); + break; + case ID_BMWND_ENQUEUESELECTEDFILES: + readbookmarks(2); + break; + case ID_BMWND_HELP: + SENDWAIPC(plugin.hwndWinampParent, IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library"); + break; + } + Sleep(100); + MSG msg; + while(PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE)); //eat return + return TRUE; +} + +static void bookmarks_contextMenu(HWND hwndDlg, HWND from, int x, int y) +{ + if (from != m_bmlist.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 itemRect = {0}; + int selected = m_bmlist.GetNextSelected(); + if (selected != -1) // if something is selected we'll drop the menu from there + { + m_bmlist.GetItemRect(selected, &itemRect); + ClientToScreen(hwndDlg, (POINT *)&itemRect); + } + else // otherwise we'll drop it from the top-left corner of the listview, adjusting for the header location + { + GetWindowRect(hwndDlg, &itemRect); + + HWND hHeader = (HWND)SNDMSG(from, LVM_GETHEADER, 0, 0L); + RECT headerRect; + if ((WS_VISIBLE & GetWindowLongPtr(hHeader, GWL_STYLE)) && GetWindowRect(hHeader, &headerRect)) + { + itemRect.top += (headerRect.bottom - headerRect.top); + } + } + x = itemRect.left; + y = itemRect.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); + UpdateMenuItems(hwndDlg, menu); + ZeroMemory(&s, sizeof(librarySendToMenuStruct)); + + IPC_LIBRARY_SENDTOMENU = (INT_PTR)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 = CreatePopupMenu(); + + MENUITEMINFOW mii = {0}; + mii.cbSize = sizeof(MENUITEMINFOW); + mii.fMask = MIIM_SUBMENU; + mii.hSubMenu = s.build_hMenu; + SetMenuItemInfoW(menu, 2, TRUE, &mii); + } + + UINT menuStatus; + if (m_bmlist.GetNextSelected(-1) == -1) + { + menuStatus = MF_BYCOMMAND | MF_GRAYED; + EnableMenuItem(menu, 2, MF_BYPOSITION | MF_GRAYED); + } + else + { + menuStatus = MF_BYCOMMAND | MF_ENABLED; + EnableMenuItem(menu, 2, MF_BYPOSITION | MF_ENABLED); + } + + EnableMenuItem(menu, ID_BMWND_PLAYSELECTEDFILES, menuStatus); + EnableMenuItem(menu, ID_BMWND_ENQUEUESELECTEDFILES, menuStatus); + EnableMenuItem(menu, ID_BMWND_REMOVESELECTEDBOOKMARKS, menuStatus); + EnableMenuItem(menu, ID_BMWND_EDITSELECTEDBOOKMARKS, menuStatus); + + int r = Menu_TrackPopup(plugin.hwndLibraryParent, menu, + TPM_RETURNCMD | TPM_RIGHTBUTTON | TPM_LEFTBUTTON, + x, y, hwndDlg, NULL); + switch(LOWORD(r)) + { + case ID_BMWND_PLAYSELECTEDFILES: + case ID_BMWND_ENQUEUESELECTEDFILES: + case ID_BMWND_REMOVESELECTEDBOOKMARKS: + case ID_BMWND_EDITSELECTEDBOOKMARKS: + case ID_BMWND_SELECTALL: + SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(r,0),0); + break; + default: + if (s.mode == 2) + { + s.menu_id = r; + if (SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU) == 0xffffffff) + { + s.mode=3; + s.data_type=ML_TYPE_FILENAMESW; + + //std::vector<wchar_t> sendStr; + std::wstring sendStr; + + int l=m_bmlist.GetCount(); + for(int i=0;i<l;i++) + { + if (m_bmlist.GetSelected(i)) + { + wchar_t buf[1023] = {0}; + m_bmlist.GetText(i,1,buf,ARRAYSIZE(buf)-1); + // HAKAN: why (len + 1) ? + //sendStr.append(buf, wcslen(buf)+1); + sendStr.append(buf, wcslen(buf)); + } + } + // HAKAN: No need to add trailing zero + //sendStr.push_back(0); + + s.data = (void*)sendStr.c_str(); + + if(SendMessage(plugin.hwndWinampParent, WM_WA_IPC,(WPARAM)&s,IPC_LIBRARY_SENDTOMENU)!=1) + { + s.mode=3; + s.data_type=ML_TYPE_FILENAMES; + + //std::vector<char> sendStrA; + std::string sendStrA; + + int l=m_bmlist.GetCount(); + for(int i=0;i<l;i++) + { + if (m_bmlist.GetSelected(i)) + { + wchar_t buf[1023] = {0}; + m_bmlist.GetText(i,1,buf,ARRAYSIZE(buf)-1); + + // HAKAN: why (len + 1) ? + //sendStrA.append(AutoCharFn(buf), strlen(AutoCharFn(buf)) + 1); + sendStrA.append(AutoCharFn(buf), strlen(AutoCharFn(buf))); + } + } + // HAKAN: No need to add trailing zero + //sendStrA.push_back(0); + + s.data = (void*)sendStrA.c_str(); + + SendMessage(plugin.hwndWinampParent, WM_WA_IPC,(WPARAM)&s,IPC_LIBRARY_SENDTOMENU); + } + } + } + break; + } + + if (s.mode) + { + s.mode=4; + SendMessage(plugin.hwndWinampParent, WM_WA_IPC,(WPARAM)&s,IPC_LIBRARY_SENDTOMENU); // cleanup + } + + if (NULL != s.build_hMenu) + { + DestroyMenu(s.build_hMenu); + s.build_hMenu = NULL; + } + + Sleep(100); + MSG msg; + while(PeekMessage(&msg,NULL,WM_KEYFIRST,WM_KEYLAST,PM_REMOVE)); //eat return +} + +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_BUTTON_PLAY, IDC_BUTTON_ENQUEUE, IDC_BUTTON_CUSTOM, IDC_EDITBOOK, IDC_REMOVEBOOK, + GROUP_MAIN, IDC_LIST + }; + + INT index; + RECT rc; + RECT rg; + RECT 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_BUTTON_PLAY, buffer, ARRAYSIZE( buffer ) ); + LRESULT idealSize = MLSkinnedButton_GetIdealSize( GetDlgItem( hwnd, IDC_BUTTON_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_BUTTON_PLAY: + case IDC_BUTTON_ENQUEUE: + case IDC_BUTTON_CUSTOM: + case IDC_EDITBOOK: + case IDC_REMOVEBOOK: + if ( IDC_BUTTON_CUSTOM != pl->id || customAllowed ) + { + if ( groupBtn && pl->id == IDC_BUTTON_PLAY && enqueuedef == 1 ) + { + pl->flags |= SWP_HIDEWINDOW; + break; + } + + if ( groupBtn && pl->id == IDC_BUTTON_ENQUEUE && enqueuedef != 1 ) + { + pl->flags |= SWP_HIDEWINDOW; + break; + } + + if ( groupBtn && ( pl->id == IDC_BUTTON_PLAY || pl->id == IDC_BUTTON_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_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->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 ); +} + +static BOOL Bookmark_OnDisplayChange() +{ + ListView_SetTextColor(m_bmlist.getwnd(),dialogSkinner.Color(WADLG_ITEMFG)); + ListView_SetBkColor(m_bmlist.getwnd(),dialogSkinner.Color(WADLG_ITEMBG)); + ListView_SetTextBkColor(m_bmlist.getwnd(),dialogSkinner.Color(WADLG_ITEMBG)); + m_bmlist.SetFont(dialogSkinner.GetFont()); + LayoutWindows(m_hwnd, TRUE); + return 0; +} + +static BOOL Bookmark_OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags) +{ + if (GetCapture()==hwnd) + { + POINT p={x,y}; + ClientToScreen(hwnd,&p); + + if (WindowFromPoint(p) == m_bmlist.getwnd()) + { + SetCursor(hDragNDropCursor); + } + else + { + mlDropItemStruct m={0}; + m.type=ML_TYPE_FILENAMES; + m.p=p; + pluginHandleIpcMessage(ML_IPC_HANDLEDRAG,(int)&m); + } + } + return FALSE; +} + +static BOOL Bookmark_OnLButtonUp(HWND hwnd, int x, int y, UINT flags) +{ + if (GetCapture()==hwnd) + { + ReleaseCapture(); + POINT p={x,y}; + ClientToScreen(hwnd,&p); + + if (WindowFromPoint(p) == m_bmlist.getwnd()) + { + LVHITTESTINFO lvi; + lvi.pt=p; + ScreenToClient(m_bmlist.getwnd(),&lvi.pt); + ListView_HitTest(m_bmlist.getwnd(),&lvi); + + int num_items = m_bmlist.GetCount(); + + int destination_position=lvi.iItem; + if ((lvi.flags & (LVHT_ONITEM))); + else if (lvi.flags & LVHT_ABOVE) destination_position=0; + else if (lvi.flags & (LVHT_BELOW|LVHT_NOWHERE )) destination_position=num_items; + else return 0; + + int x = 0, dirty=0; + + for (; x < num_items; x ++) + { + m_bmlist.SetItemParam(x,0); + } + + for (x = 0; x < num_items; x ++) + { + int sel=m_bmlist.GetSelected(x); + if (sel && x != destination_position) + { + wchar_t ft[1024] = {0}, fn[1024] = {0}; + m_bmlist.GetText(x,0,ft,ARRAYSIZE(ft)); + m_bmlist.GetText(x,1,fn,ARRAYSIZE(fn)); + m_bmlist.DeleteItem(x); + if (x < destination_position) + { + x--; + } + + if (destination_position >= num_items) destination_position--; + + m_bmlist.InsertItem(destination_position,ft,1); + m_bmlist.SetItemText(destination_position,1,fn); + // have to do this otherwise first item isn't correctly flagged & reselected + m_bmlist.SetItemParam(destination_position,1); + + destination_position++; + + dirty=1; + } + else if (sel) destination_position++; + } + + int w=0; + for (x = 0; x < num_items; x ++) + { + if (m_bmlist.GetParam(x)) + { + if (!w) + { + w=1; + ListView_SetItemState(m_bmlist.getwnd(),x,LVIS_FOCUSED,LVIS_FOCUSED); + } + m_bmlist.SetSelected(x); + } + } + + if (dirty) writebookmarks(); + } + else + { + mlDropItemStruct m={0}; + m.type=ML_TYPE_FILENAMESW; + m.p=p; + m.flags=ML_HANDLEDRAG_FLAG_NOCURSOR; + + pluginHandleIpcMessage(ML_IPC_HANDLEDRAG,(int)&m); + + if (m.result>0) + { + wchar_t *buf=(wchar_t*)calloc(4096, sizeof(wchar_t)); + size_t buf_size=4096; + size_t buf_pos=0; + + int l=m_bmlist.GetCount(); + for(int i=0;i<l;i++) + { + if (m_bmlist.GetSelected(i)) + { + wchar_t tbuf[1024]={0}; + m_bmlist.GetText(i,1,tbuf,ARRAYSIZE(tbuf)-1); + tbuf[1023]=0; + size_t newsize=buf_pos + wcslen(tbuf) + 1; + if (newsize < buf_size) + { + size_t old_buf_size=buf_size; + buf_size=newsize+4096; + + wchar_t *data = (wchar_t*)realloc(buf, (buf_size + 1) * sizeof(wchar_t)); + if (data) + { + buf=data; + } + else + { + data=(wchar_t*)calloc((buf_size + 1), sizeof(wchar_t)); + if (data) + { + memcpy(data, buf, sizeof(wchar_t)*old_buf_size); + free(buf); + buf=data; + } + else buf_size = old_buf_size; + } + } + lstrcpynW(buf+buf_pos,tbuf,(int)buf_size); + buf_pos=newsize; + } + } + if (buf_pos) + { + buf[buf_pos]=0; + m.flags=0; + m.result=0; + m.data=(void*)buf; + pluginHandleIpcMessage(ML_IPC_HANDLEDROP,(int)&m); + } + free(buf); + } + } + } + return FALSE; +} + +void Bookmark_SelectAll(void) +{ + LVITEM item; + item.state = LVIS_SELECTED; + item.stateMask = LVIS_SELECTED; + SendMessageW(m_bmlist.getwnd(), LVM_SETITEMSTATE, -1, (LPARAM)&item); +} + +enum +{ + BPM_ECHO_WM_COMMAND = 0x1, // send WM_COMMAND and return value + BPM_WM_COMMAND = 0x2, // just send WM_COMMAND +}; + +BOOL Bookmark_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 Bookmark_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); + } + } + + Bookmark_ButtonPopupMenu(hwndDlg, idFrom, listMenu, BPM_WM_COMMAND); +} + +static BOOL Bookmark_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) +{ + switch(LOWORD(id)) + { + case IDC_BUTTON_PLAY: + case ID_BMWND_PLAYSELECTEDFILES: + case IDC_BUTTON_ENQUEUE: + case ID_BMWND_ENQUEUESELECTEDFILES: + case IDC_BUTTON_CUSTOM: + { + if (codeNotify == MLBN_DROPDOWN) + { + Bookmark_Play(hwnd, hwndCtl, id); + } + else + { + int action; + if (LOWORD(id) == IDC_BUTTON_PLAY || LOWORD(id) == ID_BMWND_PLAYSELECTEDFILES) + { + action = (codeNotify == 1) ? g_config->ReadInt(L"enqueuedef", 0) == 1 : 0; + } + else if (LOWORD(id) == IDC_BUTTON_ENQUEUE || LOWORD(id) == ID_BMWND_ENQUEUESELECTEDFILES) + { + action = (codeNotify == 1) ? g_config->ReadInt(L"enqueuedef", 0) != 1 : 1; + } + else + break; + + playFiles(action, 0); + } + break; + } + case ID_BMWND_EDITSELECTEDBOOKMARKS: + case IDC_EDITBOOK: + { + int dirty=0; + int x=0,l=m_bmlist.GetCount(); + while (x < l) + { + if (m_bmlist.GetSelected(x)) + { + dirty=1; + wchar_t fn[1024] = {0}, ft[1024] = {0}; + m_bmlist.GetText(x,0,ft,ARRAYSIZE(ft)); + m_bmlist.GetText(x,1,fn,ARRAYSIZE(fn)); + g_bmedit_fn=fn; + g_bmedit_ft=ft; + WASABI_API_DIALOGBOXW(IDD_EDITBOOKMARK,hwnd,BookMarkEditProc); + m_bmlist.SetItemText(x,0,ft); + m_bmlist.SetItemText(x,1,fn); + } + x++; + } + if (dirty) writebookmarks(); + } + break; + case ID_BMWND_REMOVESELECTEDBOOKMARKS: + case IDC_REMOVEBOOK: // remove + { + int dirty=0; + int x=0,l=m_bmlist.GetCount(); + while (x < l) + { + if (m_bmlist.GetSelected(x)) + { + dirty=1; + m_bmlist.DeleteItem(x); + l--; + } + else x++; + } + if (dirty) writebookmarks(); + } + break; + case ID_BMWND_SELECTALL: + Bookmark_SelectAll(); + break; + } + return FALSE; +} + +static BOOL Bookmark_OnDestroy(HWND hwnd) +{ + if (m_bmlist.getwnd()) + { + g_config->WriteInt(L"bm_col_title",m_bmlist.GetColumnWidth(0)); + g_config->WriteInt(L"bm_col_filename",m_bmlist.GetColumnWidth(1)); + } + + m_hwnd=0; + return FALSE; +} + +static void Bookmark_ManageButtons(HWND hwndDlg) +{ + int has_selection = m_bmlist.GetSelectedCount(); + + const int buttonids[] = { IDC_BUTTON_PLAY, IDC_BUTTON_ENQUEUE, IDC_BUTTON_CUSTOM, IDC_EDITBOOK, IDC_REMOVEBOOK}; + for (size_t i = 0; i != sizeof(buttonids)/sizeof(buttonids[0]); i++) + { + HWND controlHWND = GetDlgItem(hwndDlg, buttonids[i]); + EnableWindow(controlHWND, has_selection); + } +} + +static BOOL Bookmark_OnNotify( HWND hwnd, NMHDR *notification ) +{ + if ( notification->idFrom == IDC_LIST ) + { + if ( notification->code == NM_DBLCLK ) + { + playFiles( ( !!( g_config->ReadInt( L"enqueuedef", 0 ) == 1 ) ) ^ ( !!( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) ), 0 ); + } + else if ( notification->code == LVN_BEGINDRAG ) + { + SetCapture( hwnd ); + } + else if ( notification->code == LVN_ITEMCHANGED ) + { + Bookmark_ManageButtons( hwnd ); + } + } + return FALSE; +} + +void Bookmark_UpdateButtonText(HWND hwndDlg, int _enqueuedef) +{ + if (groupBtn) + { + switch(_enqueuedef) + { + case 1: + SetDlgItemTextW(hwndDlg, IDC_BUTTON_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_BUTTON_PLAY, pszTextW); + customAllowed = TRUE; + } + else + { + SetDlgItemTextW(hwndDlg, IDC_BUTTON_PLAY, view.play); + customAllowed = FALSE; + } + break; + } + } +} + +static BOOL Bookmark_OnInitDialog( HWND hwndDlg, HWND hwndFocus, LPARAM lParam ) +{ + m_hwnd = hwndDlg; + m_bmlist.setwnd( GetDlgItem( hwndDlg, IDC_LIST ) ); + + HACCEL accel = WASABI_API_LOADACCELERATORSW( IDR_VIEW_BM_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 ); + } + + // check the column widths and ensure that if <=0 it'll re-show + // (based on some forum reports where the width is set to zero somehow) + // -> shouldn't annoy anyone but you never know with the users, heh + int col_width1 = g_config->ReadInt( L"bm_col_title", 400 ); + if ( col_width1 <= 0 ) + col_width1 = 400; + + int col_width2 = g_config->ReadInt( L"bm_col_filename", 240 ); + if ( col_width2 <= 0 ) + col_width2 = 240; + + m_bmlist.AddCol( WASABI_API_LNGSTRINGW( IDS_BOOKMARK_TITLE ), col_width1 ); + m_bmlist.AddCol( WASABI_API_LNGSTRINGW( IDS_BOOKMARK_FN_URL ), col_width2 ); + + groupBtn = g_config->ReadInt( L"groupbtn", 1 ); + enqueuedef = ( g_config->ReadInt( L"enqueuedef", 0 ) == 1 ); + + Bookmark_OnDisplayChange(); + + m_headerhwnd = ListView_GetHeader( m_bmlist.getwnd() ); + + // 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_BUTTON_CUSTOM, IDC_BUTTON_ENQUEUE ), (INT_PTR)L"ml_bookmark" }; + 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_BUTTON_CUSTOM, pszTextW ); + } + else + customAllowed = FALSE; + + MLSKINWINDOW m = { 0 }; + m.skinType = SKINNEDWND_TYPE_DIALOG; + m.style = SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWS_USESKINFONT; + m.hwndToSkin = hwndDlg; + MLSkinWindow( plugin.hwndLibraryParent, &m ); + + m.skinType = SKINNEDWND_TYPE_LISTVIEW; + m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWLVS_FULLROWSELECT | SWLVS_DOUBLEBUFFER | SWLVS_ALTERNATEITEMS; + m.hwndToSkin = m_bmlist.getwnd(); + MLSkinWindow( mediaLibrary.library, &m ); + + m.skinType = SKINNEDWND_TYPE_BUTTON; + m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS | ( groupBtn ? SWBS_SPLITBUTTON : 0 ); + FLICKERFIX ff = { 0, FFM_ERASEINPAINT }; + const int buttonids[] = { IDC_BUTTON_PLAY, IDC_BUTTON_ENQUEUE, IDC_BUTTON_CUSTOM }; + for ( size_t i = 0; i != sizeof( buttonids ) / sizeof( buttonids[ 0 ] ); i++ ) + { + ff.hwnd = m.hwndToSkin = GetDlgItem( hwndDlg, buttonids[ i ] ); + if ( IsWindow( m.hwndToSkin ) ) + { + MLSkinWindow( plugin.hwndLibraryParent, &m ); + SENDMLIPC( plugin.hwndLibraryParent, ML_IPC_FLICKERFIX, (WPARAM)&ff ); + } + } + + m.style = SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS; + const int buttonidz[] = { IDC_EDITBOOK, IDC_REMOVEBOOK }; + for ( size_t i = 0; i != sizeof( buttonidz ) / sizeof( buttonidz[ 0 ] ); i++ ) + { + ff.hwnd = m.hwndToSkin = GetDlgItem( hwndDlg, buttonidz[ i ] ); + if ( IsWindow( m.hwndToSkin ) ) + { + MLSkinWindow( plugin.hwndLibraryParent, &m ); + SENDMLIPC( plugin.hwndLibraryParent, ML_IPC_FLICKERFIX, (WPARAM)&ff ); + } + } + + Bookmark_ManageButtons( hwndDlg ); + Bookmark_UpdateButtonText( hwndDlg, enqueuedef == 1 ); + + SetTimer( hwndDlg, 100, 15, NULL ); + + return TRUE; +} + +static void Bookmark_OnTimer(HWND hwnd, UINT id) +{ + if (id == 100) + { + KillTimer(hwnd,100); + // populate list + readbookmarks(); + } +} + +void Bookmark_DropFiles(HWND hwnd, HDROP hDrop) +{ + wchar_t temp[2048] = {0}; + int y = DragQueryFileW(hDrop, 0xffffffff, temp, 2048); + + for (int x = 0; x < y; x ++) + { + DragQueryFileW(hDrop, x, temp, 2048); + mediaLibrary.AddBookmarkW(temp); + } +} + +static BOOL Bookmark_OnMLDropItem(mlDropItemStruct *dis) +{ + if (dis) + { + if (dis->type != ML_TYPE_ITEMRECORDLISTW && dis->type != ML_TYPE_ITEMRECORDLIST && + dis->type != ML_TYPE_FILENAMES && dis->type != ML_TYPE_FILENAMESW && + dis->type != ML_TYPE_STREAMNAMES && dis->type != ML_TYPE_STREAMNAMESW && + dis->type != ML_TYPE_CDTRACKS && + dis->type != ML_TYPE_PLAYLIST && dis->type != ML_TYPE_PLAYLISTS) + { + dis->result=-1; + } + else + { + dis->result=1; + if (dis->data) + { + if (dis->type == ML_TYPE_ITEMRECORDLIST || dis->type == ML_TYPE_CDTRACKS) + { + itemRecordList *p=(itemRecordList *)dis->data; + for (int x = 0; x < p->Size; x ++) + mediaLibrary.AddBookmark(p->Items[x].filename); + } + else if (dis->type == ML_TYPE_ITEMRECORDLISTW) + { + itemRecordListW *p=(itemRecordListW *)dis->data; + for (int x = 0; x < p->Size; x ++) + mediaLibrary.AddBookmark(AutoChar(p->Items[x].filename)); + } + else if (dis->type == ML_TYPE_FILENAMES || dis->type == ML_TYPE_STREAMNAMES) // playlist + { + char *p=(char*)dis->data; + while (p && *p) + { + mediaLibrary.AddBookmark(p); + p+=strlen(p)+1; + } + } + else if (dis->type == ML_TYPE_FILENAMESW || dis->type == ML_TYPE_STREAMNAMESW) // playlist + { + wchar_t *p=(wchar_t*)dis->data; + while (p && *p) + { + mediaLibrary.AddBookmarkW(p); + p+=wcslen(p)+1; + } + } + else if(dis->type == ML_TYPE_PLAYLIST) + { + mediaLibrary.AddBookmarkW((wchar_t*)((mlPlaylist*)dis->data)->filename); + } + else if(dis->type == ML_TYPE_PLAYLISTS) + { + mlPlaylist **playlists = (mlPlaylist **)dis->data; + while (playlists && *playlists) + { + mlPlaylist *pl = *playlists; + mediaLibrary.AddBookmarkW((wchar_t*)pl->filename); + playlists++; + } + } + } + } + } + return FALSE; +} + +#define HANDLE_ML_DROPITEM(func) case ML_CHILDIPC_DROPITEM: return Bookmark_OnMLDropItem((mlDropItemStruct *)wParam); +INT_PTR CALLBACK view_bmDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam) +{ + INT_PTR a = dialogSkinner.Handle(hwndDlg, uMsg, wParam, lParam); + if (a) return a; + + switch(uMsg) + { + HANDLE_MSG(hwndDlg, WM_INITDIALOG, Bookmark_OnInitDialog); + HANDLE_MSG(hwndDlg, WM_TIMER, Bookmark_OnTimer); + HANDLE_MSG(hwndDlg, WM_COMMAND, Bookmark_OnCommand); + HANDLE_MSG(hwndDlg, WM_DESTROY, Bookmark_OnDestroy); + HANDLE_MSG(hwndDlg, WM_MOUSEMOVE, Bookmark_OnMouseMove); + HANDLE_MSG(hwndDlg, WM_LBUTTONUP, Bookmark_OnLButtonUp); + HANDLE_MSG(hwndDlg, WM_DROPFILES, Bookmark_DropFiles); + + 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_PAINT: + { + int tab[] = { IDC_LIST|DCW_SUNKENBORDER}; + dialogSkinner.Draw(hwndDlg, tab, sizeof(tab) / sizeof(tab[0])); + } + return 0; + + case WM_INITMENUPOPUP: + if (wParam && (HMENU)wParam == s.build_hMenu && s.mode==1) + { + myMenu = TRUE; + if(SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&s, IPC_LIBRARY_SENDTOMENU)==0xffffffff) + s.mode=2; + myMenu = FALSE; + } + return 0; + + case WM_DISPLAYCHANGE: + return Bookmark_OnDisplayChange(); + + case WM_NOTIFY: + return Bookmark_OnNotify(hwndDlg, (LPNMHDR)lParam); + + case WM_CONTEXTMENU: + bookmarks_contextMenu(hwndDlg, (HWND)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)); + return 0; + + case WM_APP + 104: + { + Bookmark_UpdateButtonText(hwndDlg, (int)wParam); + LayoutWindows(hwndDlg, TRUE); + return 0; + } + + case WM_ML_CHILDIPC: + if (lParam == ML_CHILDIPC_DROPITEM && wParam) + HANDLE_ML_DROPITEM(Bookmark_OnMLDropItem); + } + return FALSE; +}
\ No newline at end of file |