/** (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 #include /*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_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(&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; }