diff options
Diffstat (limited to 'Src/Winamp/OpenFileDialog.cpp')
-rw-r--r-- | Src/Winamp/OpenFileDialog.cpp | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/Src/Winamp/OpenFileDialog.cpp b/Src/Winamp/OpenFileDialog.cpp new file mode 100644 index 00000000..d25c0538 --- /dev/null +++ b/Src/Winamp/OpenFileDialog.cpp @@ -0,0 +1,467 @@ +/** (c) Nullsoft, Inc. C O N F I D E N T I A L + ** Filename: + ** Project: + ** Description: + ** Author: + ** Created: + **/ + +#include "main.h" +#include "resource.h" +#include "strutil.h" +#include "../nu/AutoChar.h" +#include "api.h" +#include <shlwapi.h> +#include <shobjidl.h> + +/*static wchar_t *inc(wchar_t *p, size_t &size, int extra=0) +{ + int len = lstrlenW(p) + extra; + size-=len; + p+=len; + return p; +}*/ + +#if 0 +extern std::vector<In_Module*> in_modules; +void getNewFileVistaPlus(int clearlist, HWND hwnd, const wchar_t *path) +{ + IFileOpenDialog *pFileOpen; + static int qq; + if (qq) return; + qq = 1; + HRESULT hr = CoCreateInstance(__uuidof(FileOpenDialog), NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFileOpen)); + if (SUCCEEDED(hr)) + { + wchar_t titleStr[128] = {0}; + + pFileOpen->SetTitle(getStringW((clearlist ? IDS_OFD_OPEN_FILES : IDS_OFD_ADD_FILES_TO_PLAYLIST),titleStr,128)); + pFileOpen->SetDefaultExtension(L""); + pFileOpen->SetOptions(FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT | FOS_NOREADONLYRETURN | FOS_PATHMUSTEXIST); + if(!clearlist) pFileOpen->SetOkButtonLabel(L"Add"); + + IShellItem* shellItem; + hr = SHCreateItemFromParsingName((!path ? WASABI_API_APP->path_getWorkingPath() : path), 0, IID_IShellItem, reinterpret_cast<void**>(&shellItem)); + if (SUCCEEDED(hr)) + { + pFileOpen->SetFolder(shellItem); + } + + wchar_t *fsb = in_getfltstrW(TRUE); + int filterNum = 0; + // allocate enough for the number of input plug-ins plus 'all supported' and 'all files' + COMDLG_FILTERSPEC *fileTypes = new COMDLG_FILTERSPEC[in_modules.size() + 2]; + while(fsb && *fsb && *fsb+1) + { + int len = lstrlenW(fsb) + 1; + wchar_t *fsb2 = fsb + len; + fileTypes[filterNum].pszName = fsb; + fileTypes[filterNum].pszSpec = fsb2; + CharUpperBuffW(fsb2, lstrlenW(fsb2)); + filterNum++; + fsb += len + lstrlenW(fsb2) + 1; + } + + pFileOpen->SetFileTypes(filterNum, fileTypes); + + if (hwnd == hMainWindow) + UninitDragDrops(); + + hr = pFileOpen->Show(hwnd); + if (SUCCEEDED(hr)) + { + IShellItemArray *pItems; + hr = pFileOpen->GetResults(&pItems); + if (SUCCEEDED(hr)) + { + IEnumShellItems *sItems; + hr = pItems->EnumItems(&sItems); + if (SUCCEEDED(hr)) + { + DWORD numItems = 0; + pItems->GetCount(&numItems); + + int sp; + if (clearlist) + { + sp = 0; PlayList_delete(); + } + else sp = PlayList_getlength(); + + if(numItems <= 1) + { + IShellItem *pItem; + if(sItems->Next(1, &pItem, NULL) == S_OK) + { + LPWSTR folderpath = NULL; + LPWSTR filepath = NULL; + hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &filepath); + if (SUCCEEDED(hr)) + { + IShellItem *ppItem; + hr = pItem->GetParent(&ppItem); + if (SUCCEEDED(hr)) + { + hr = ppItem->GetDisplayName(SIGDN_FILESYSPATH, &folderpath); + if (SUCCEEDED(hr)) + { + WASABI_API_APP->path_setWorkingPath(folderpath); + } + } + + if (LoadPlaylist(filepath, 1, 0) == -1) // if not a playlist file + { + PlayList_append(filepath, 0); + } + + CoTaskMemFree(filepath); + CoTaskMemFree(folderpath); + } + } + pItem->Release(); + } + else + { + size_t size = ((numItems + 1) * MAX_PATH); + wchar_t *temp = (wchar_t *)GlobalAlloc(GPTR, size * sizeof(wchar_t)), *p = temp; + IShellItem *pItem; + while(sItems->Next(1, &pItem, NULL) == S_OK) + { + LPWSTR folderpath = NULL; + LPWSTR filepath = NULL; + hr = pItem->GetDisplayName(SIGDN_NORMALDISPLAY, &filepath); + if (SUCCEEDED(hr)) + { + // replicate how lpstrFile is filled under a multiple select + // -> selected folder followed by each filename \0 separated + if(p == temp) + { + IShellItem *ppItem; + hr = pItem->GetParent(&ppItem); + if (SUCCEEDED(hr)) + { + hr = ppItem->GetDisplayName(SIGDN_FILESYSPATH, &folderpath); + if (SUCCEEDED(hr)) + { + WASABI_API_APP->path_setWorkingPath(folderpath); + + if(StringCchCatW(p, size, folderpath) == S_OK) + { + int len = lstrlenW(folderpath) + 1; + p += len; + size -= len; + } + } + } + } + + if(StringCchCatW(p, size, filepath) == S_OK) + { + int len = lstrlenW(filepath) + 1; + p += len; + size -= len; + } + + CoTaskMemFree(filepath); + CoTaskMemFree(folderpath); + } + pItem->Release(); + } + + PlayList_addfromdlg(temp); + if (config_rofiob&1) PlayList_sort(2, sp); + + GlobalFree(temp); + } + + if (clearlist) + BeginPlayback(); + + sItems->Release(); + } + pItems->Release(); + } + } + pFileOpen->Release(); + GlobalFree(fsb); + + if (hwnd == hMainWindow) + InitDragDrops(); + for(;;) + { + MSG msg; + if (!PeekMessage(&msg, hMainWindow, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) + break; + } + } + qq = 0; +} +#endif + +void getNewFile(int clearlist, HWND hwnd, const wchar_t *path) // if clearlist is 1, playlist is cleared +{ + // TODO - Egg was having stability issues with this so keeping disabled until resolved + // on Vista and up use the IFileOpenDialog interface as it + // allows us to get around the MAX_PATH file filter issues + /*if(IsVista()) + { + getNewFileVistaPlus(clearlist, hwnd, path); + return; + }*/ + + // otherwise revert to using the older pre-Vista methods + const int len = 256 * 1024 - 128; + + wchar_t oldCurPath[MAX_PATH] = {0}, titleStr[128] = {0}; + + GetCurrentDirectoryW(MAX_PATH, oldCurPath); + wchar_t *temp, *fsb; + OPENFILENAMEW l = {sizeof(OPENFILENAMEW),0}; + static int q; + if (q) return; + q = 1; + temp = (wchar_t *)GlobalAlloc(GPTR, len * sizeof(wchar_t)); + l.lStructSize = sizeof(l); + l.hwndOwner = hwnd; + l.lpstrFilter = fsb = in_getfltstrW(FALSE); + + l.lpstrFile = temp; + l.nMaxFile = len - 1; + l.lpstrTitle = getStringW((clearlist ? IDS_OFD_OPEN_FILES : IDS_OFD_ADD_FILES_TO_PLAYLIST),titleStr,128); + l.lpstrDefExt = L""; + l.lpstrInitialDir = path; + if (!l.lpstrInitialDir) l.lpstrInitialDir = WASABI_API_APP->path_getWorkingPath(); + + l.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_ALLOWMULTISELECT + | OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST; + if (hwnd == hMainWindow) + UninitDragDrops(); + if (GetOpenFileNameW(&l)) + { + wchar_t newCurPath[MAX_PATH] = {0}; + GetCurrentDirectoryW(MAX_PATH, newCurPath); + WASABI_API_APP->path_setWorkingPath(newCurPath); + int sp; + if (clearlist) + { + sp = 0; PlayList_delete(); + } + else sp = PlayList_getlength(); + if (temp[lstrlenW(temp)+1]) + { + PlayList_addfromdlg(temp); + if (config_rofiob&1) PlayList_sort(2, sp); + } + else + { + if (LoadPlaylist(temp, 1, 0) == -1) // if not a playlist file + { + PlayList_append(temp, 0); + } + } + if (clearlist) + BeginPlayback(); + } + SetCurrentDirectoryW(oldCurPath); + + if (hwnd == hMainWindow) + InitDragDrops(); + for(;;) + { + MSG msg; + if (!PeekMessage(&msg, hMainWindow, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE)) + break; + } + GlobalFree(fsb); + GlobalFree(temp); + q = 0; +} + +static wchar_t loc[FILENAME_SIZE]; +int ResizeComboBoxDropDown(HWND hwndDlg, UINT id, const char* str, int width){ + SIZE size = {0}; + HWND control = GetDlgItem(hwndDlg, id); + HDC hdc = GetDC(control); + // get and select parent dialog's font so that it'll calculate things correctly + HFONT font = (HFONT)SendMessageW(hwndDlg,WM_GETFONT,0,0), oldfont = (HFONT)SelectObject(hdc,font); + GetTextExtentPoint32A(hdc, str, lstrlenA(str)+1, &size); + + int ret = width; + if(size.cx > width) + { + SendDlgItemMessage(hwndDlg, id, CB_SETDROPPEDWIDTH, size.cx, 0); + ret = size.cx; + } + + SelectObject(hdc, oldfont); + ReleaseDC(control, hdc); + return ret; +} + +int ResizeComboBoxDropDownW(HWND hwndDlg, UINT id, const wchar_t *str, int width){ + SIZE size = {0}; + HWND control = GetDlgItem(hwndDlg, id); + HDC hdc = GetDC(control); + // get and select parent dialog's font so that it'll calculate things correctly + HFONT font = (HFONT)SendMessageW(hwndDlg,WM_GETFONT,0,0), oldfont = (HFONT)SelectObject(hdc,font); + GetTextExtentPoint32W(hdc, str, (int) wcslen(str)+1, &size); + + int ret = width; + if(size.cx > width) + { + SendDlgItemMessage(hwndDlg, id, CB_SETDROPPEDWIDTH, size.cx, 0); + ret = size.cx; + } + + SelectObject(hdc, oldfont); + ReleaseDC(control, hdc); + return ret; +} + +static LRESULT WINAPI locProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_INITDIALOG: + if(lParam) SetWindowTextW(hwndDlg, getStringW(IDS_ADD_URL, NULL, 0)); + SendDlgItemMessageW(hwndDlg, IDC_URL_NEW, CB_LIMITTEXT, sizeof(loc)/sizeof(*loc) - 1, 0); + { + int width = 0, x = 0; + HWND h = GetDlgItem(hwndDlg, IDC_URL_NEW); + SendMessageW(h, CB_SETHORIZONTALEXTENT, 400, 0); + while(1) + { + char s[123] = {0}; + wchar_t name[FILENAME_SIZE] = {0}; + StringCchPrintfA(s, 123, "RecentURL%d", x + 1); + _r_sW(s, name, 123); + if (!name[0]) break; + SendMessageW(h, CB_ADDSTRING, 0, (LPARAM)name); + width = ResizeComboBoxDropDownW(hwndDlg, IDC_URL_NEW, name, width); + x++; + } + + // show add / open loc window and restore last position as applicable + POINT pt = {loc_rect.left, loc_rect.top}; + if (!windowOffScreen(hwndDlg, pt)) + SetWindowPos(hwndDlg, HWND_TOP, loc_rect.left, loc_rect.top, 0, 0, SWP_NOSIZE | SWP_NOSENDCHANGING); + } + + SetDlgItemTextW(hwndDlg, IDC_URL_NEW, loc); + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + GetDlgItemTextW(hwndDlg, IDC_URL_NEW, loc, sizeof(loc)/sizeof(*loc) - 1); + { + wchar_t *p = loc; + while (IsCharSpaceW(*p)) p = CharNextW(p); + if (!*p) EndDialog(hwndDlg, 1); + else recent_add(loc); + } + case IDCANCEL: + GetWindowRect(hwndDlg, &loc_rect); + EndDialog(hwndDlg, (LOWORD(wParam) == IDCANCEL)); + return FALSE; + case IDRESET: + if (LPMessageBox(hwndDlg, IDS_RESET_URLS, IDS_RESET_URLS_TITLE, MB_ICONQUESTION | MB_YESNO) == IDYES) + { + int x = 1; + while(1) + { + char s[123] = {0}; + wchar_t name[FILENAME_SIZE] = {0}; + StringCchPrintfA(s, 123, "RecentURL%d", x); + _r_sW(s, name, 123); + _w_sW(s, 0); + if (!name[0]) break; + x++; + } + + // clear out but keep what's been currently entered so as not to annoy people... + GetDlgItemTextW(hwndDlg, IDC_URL_NEW, loc, ARRAYSIZE(loc)); + SendDlgItemMessage(hwndDlg, IDC_URL_NEW, CB_RESETCONTENT, 0, 0); + SetDlgItemTextW(hwndDlg, IDC_URL_NEW, loc); + } + return FALSE; + } + return FALSE; + case WM_CLOSE: + EndDialog(hwndDlg, 2); + return FALSE; + } + return 0; +} + +LRESULT getNewLocation(int clearlist, HWND hwnd) // if clearlist is 1, playlist is cleared +{ + static int q; + if (q) return 0; + q = 1; + if (!LPDialogBoxParamW(IDD_OPENLOC, hwnd, (DLGPROC)locProc, !clearlist)) + { + wchar_t *beg = loc; + wchar_t *l = loc; + wchar_t buf[FILENAME_SIZE] = {0}; + wchar_t *pEnd; + + while (IsCharSpaceW(*l)) l = CharNextW(l); + + if (!wcsstr(l, L":/") && !wcsstr(l, L":\\")) + { + StringCchPrintfW(buf, FILENAME_SIZE, L"http://%s", l); + l = buf; + beg = buf; + } + + if (clearlist < 0) + { + int psize = WideCharToMultiByte(CP_ACP, 0, l, -1, 0, 0, NULL, NULL); + char* p = (char*)GlobalAlloc(GPTR, psize); + WideCharToMultiByte(CP_ACP, 0, l, -1, p, psize, NULL, NULL); + + //trim any trailing spaces + //l = p + lstrlen(p) - 1; + if (IsCharSpaceW(*l)) + { + while (IsCharSpaceW(*l)) + l = CharPrevW(beg, l); + *CharNextW(l) = 0; + } + + q = 0; + return (LRESULT)p; + } + + pEnd = GetLastCharacterW(l); + if (IsCharSpaceW(*pEnd)) + { + while (IsCharSpaceW(*pEnd)) + pEnd = CharPrevW(l, pEnd); + *CharNextW(pEnd) = 0; + } + + /* benski> CUT because 'idir' doesn't seem to be used + int idir=0; + HANDLE h; + WIN32_FIND_DATA d; + h = FindFirstFile(l,&d); + if (h!=INVALID_HANDLE_VALUE) + { + FindClose(h); + if (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + idir=1; + } + } + */ + if (clearlist) + PlayList_delete(); + PlayList_appendthing(l, 0, 0); + if (clearlist) + BeginPlayback(); + } + q = 0; + return 0; +}
\ No newline at end of file |