16#ifndef WIN32_LEAN_AND_MEAN
17#define WIN32_LEAN_AND_MEAN 1
29#include <emscripten.h>
32#ifndef _POSIX_C_SOURCE
33#define _POSIX_C_SOURCE 2
36#ifndef _DARWIN_C_SOURCE
37#define _DARWIN_C_SOURCE
60#ifndef PFD_HAS_IFILEDIALOG
61#define PFD_HAS_IFILEDIALOG 1
62#if (defined __MINGW64__ || defined __MINGW32__) && defined __GXX_ABI_VERSION
63#if __GXX_ABI_VERSION <= 1013
64#undef PFD_HAS_IFILEDIALOG
65#define PFD_HAS_IFILEDIALOG 0
99enum class opt : uint8_t {
112 return opt(uint8_t(a) | uint8_t(b));
115 return bool(uint8_t(a) & uint8_t(b));
124 static void verbose(
bool value);
128 explicit settings(
bool resync =
false);
167 std::string
result(
int* exit_code =
nullptr);
173 void start_func(std::function<std::string(
int*)>
const& fun);
174 static BOOL CALLBACK enum_windows_callback(HWND hwnd, LPARAM lParam);
176 void start(
int exit_code);
192 std::future<std::string> m_future;
193 std::set<HWND> m_windows;
194 std::condition_variable m_cond;
197#elif __EMSCRIPTEN__ || __NX__
211 dll(std::string
const& name);
214 template <
typename T>
class proc {
216 proc(dll
const& lib, std::string
const& sym)
217 : m_proc(
reinterpret_cast<T*
>((
void*)::GetProcAddress(lib.handle, sym.c_str()))) {
220 operator bool()
const {
221 return m_proc !=
nullptr;
223 operator T*()
const {
236 class ole32_dll :
public dll {
240 bool is_initialized();
247 class new_style_context {
250 ~new_style_context();
254 ULONG_PTR m_cookie = 0;
273 std::string
shell_quote(std::string
const& str)
const;
287 file_dialog(
type in_type, std::string
const& title, std::string
const& default_path =
"",
295 static int CALLBACK bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData);
296#if PFD_HAS_IFILEDIALOG
297 std::string select_folder_vista(IFileDialog* ifd,
bool force_path);
300 std::wstring m_wtitle;
301 std::wstring m_wdefault_path;
303 std::vector<std::string> m_vector_result;
315 static std::string
home();
350 open_file(std::string
const& title, std::string
const& default_path =
"",
353#if defined(__has_cpp_attribute)
354#if __has_cpp_attribute(deprecated)
356 [[deprecated(
"Use pfd::opt::multiselect instead of allow_multiselect")]]
359 open_file(std::string
const& title, std::string
const& default_path, std::vector<std::string>
const&
filters,
360 bool allow_multiselect);
362 std::vector<std::string>
result();
367 save_file(std::string
const& title, std::string
const& default_path =
"",
370#if defined(__has_cpp_attribute)
371#if __has_cpp_attribute(deprecated)
373 [[deprecated(
"Use pfd::opt::force_overwrite instead of confirm_overwrite")]]
376 save_file(std::string
const& title, std::string
const& default_path, std::vector<std::string>
const&
filters,
377 bool confirm_overwrite);
395#if !defined PFD_SKIP_IMPLEMENTATION
402static inline std::wstring str2wstr(std::string
const& str) {
403 int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (
int)str.size(),
nullptr, 0);
404 std::wstring ret(len,
'\0');
405 MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (
int)str.size(), (LPWSTR)ret.data(), (
int)ret.size());
409static inline std::string wstr2str(std::wstring
const& str) {
410 int len = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (
int)str.size(),
nullptr, 0,
nullptr,
nullptr);
411 std::string ret(len,
'\0');
412 WideCharToMultiByte(CP_UTF8, 0, str.c_str(), (
int)str.size(), (LPSTR)ret.data(), (
int)ret.size(),
nullptr,
nullptr);
416static inline bool is_vista() {
417 OSVERSIONINFOEXW osvi;
418 memset(&osvi, 0,
sizeof(osvi));
419 DWORDLONG
const mask =
420 VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL),
421 VER_MINORVERSION, VER_GREATER_EQUAL),
422 VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
423 osvi.dwOSVersionInfoSize =
sizeof(osvi);
424 osvi.dwMajorVersion = HIBYTE(_WIN32_WINNT_VISTA);
425 osvi.dwMinorVersion = LOBYTE(_WIN32_WINNT_VISTA);
426 osvi.wServicePackMajor = 0;
428 return VerifyVersionInfoW(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, mask) != FALSE;
434static inline bool ends_with(std::string
const& str, std::string
const& suffix) {
435 return suffix.size() <= str.size() && str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
438static inline bool starts_with(std::string
const& str, std::string
const& prefix) {
439 return prefix.size() <= str.size() && str.compare(0, prefix.size(), prefix) == 0;
446 auto attr = GetFileAttributesA(
path.c_str());
447 return attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY);
453 return stat(
path.c_str(), &s) == 0 && S_ISDIR(s.st_mode);
459static inline std::string
getenv(std::string
const& str) {
463 if (_dupenv_s(&
buf, &size, str.c_str()) == 0 &&
buf) {
464 std::string ret(
buf);
470 auto buf = std::getenv(str.c_str());
486 auto match_no = std::regex(
"(|0|no|false)", std::regex_constants::icase);
487 if (!std::regex_match(pfd_verbose, match_no))
501 if (desktop_name == std::string(
"gnome"))
503 else if (desktop_name == std::string(
"KDE"))
545 async.
start_process({
"/bin/sh",
"-c",
"which " + program });
547 return exit_code == 0;
569 return flags[size_t(in_flag)];
573 return const_cast<bool&
>(
static_cast<settings const*
>(
this)->flags(in_flag));
581 if (user_profile.size() > 0)
584 HANDLE token =
nullptr;
585 DWORD len = MAX_PATH;
586 char buf[MAX_PATH] = {
'\0' };
587 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) {
588 dll userenv(
"userenv.dll");
589 dll::proc<BOOL WINAPI(HANDLE, LPSTR, LPDWORD)> get_user_profile_directory(userenv,
"GetUserProfileDirectoryA");
590 get_user_profile_directory(token,
buf, &len);
604#if defined(_SC_GETPW_R_SIZE_MAX)
605 auto size_max = sysconf(_SC_GETPW_R_SIZE_MAX);
607 len = size_t(size_max);
609 std::vector<char>
buf(len);
610 struct passwd pwd, *result;
611 if (getpwuid_r(getuid(), &pwd,
buf.data(),
buf.size(), &result) == 0)
612 return result->pw_dir;
636 if (m_future.valid()) {
638 auto previous_windows = m_windows;
639 EnumWindows(&enum_windows_callback, (LPARAM)
this);
640 for (
auto hwnd : m_windows)
641 if (previous_windows.find(hwnd) == previous_windows.end()) {
642 SendMessage(hwnd, WM_CLOSE, 0, 0);
644 SendMessage(hwnd, WM_COMMAND, IDNO, 0);
647#elif __EMSCRIPTEN__ || __NX__
658inline BOOL CALLBACK internal::executor::enum_windows_callback(HWND hwnd, LPARAM lParam) {
662 auto tid = GetWindowThreadProcessId(hwnd, &pid);
663 if (tid == that->m_tid)
664 that->m_windows.insert(hwnd);
670inline void internal::executor::start_func(std::function<std::string(
int*)>
const& fun) {
673 auto trampoline = [fun,
this]() {
675 m_tid = GetCurrentThreadId();
676 EnumWindows(&enum_windows_callback, (LPARAM)
this);
678 return fun(&m_exit_code);
681 std::unique_lock<std::mutex> lock(m_mutex);
682 m_future = std::async(std::launch::async, trampoline);
688inline void internal::executor::start(
int exit_code) {
689 m_exit_code = exit_code;
699 if (pipe(
in) != 0 || pipe(
out) != 0)
710 dup2(
in[0], STDIN_FILENO);
711 dup2(
out[1], STDOUT_FILENO);
714 int fd = open(
"/dev/null", O_WRONLY);
715 dup2(fd, STDERR_FILENO);
718 std::vector<char*> args;
719 std::transform(command.cbegin(), command.cend(), std::back_inserter(args),
720 [](std::string
const& s) { return const_cast<char*>(s.c_str()); });
721 args.push_back(
nullptr);
723 execvp(args[0], args.data());
729 auto flags = fcntl(
m_fd, F_GETFL);
730 fcntl(
m_fd, F_SETFL, flags | O_NONBLOCK);
745 if (m_future.valid()) {
746 auto status = m_future.wait_for(std::chrono::milliseconds(timeout));
747 if (status != std::future_status::ready) {
752 while (PeekMessage(&msg,
nullptr, 0, 0, PM_REMOVE)) {
753 TranslateMessage(&msg);
754 DispatchMessage(&msg);
761#elif __EMSCRIPTEN__ || __NX__
766 ssize_t received = read(
m_fd,
buf, BUFSIZ);
777 pid_t child = waitpid(
m_pid, &status, WNOHANG);
778 if (child !=
m_pid && (child >= 0 || errno != ECHILD)) {
780 std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
801inline internal::platform::dll::dll(std::string
const& name) : handle(::LoadLibraryA(name.c_str())) {
804inline internal::platform::dll::~dll() {
806 ::FreeLibrary(handle);
813inline internal::platform::ole32_dll::ole32_dll() : dll(
"ole32.dll") {
816 auto coinit = proc<HRESULT WINAPI(LPVOID, DWORD)>(*
this,
"CoInitializeEx");
817 m_state = coinit(
nullptr, COINIT_MULTITHREADED);
820inline internal::platform::ole32_dll::~ole32_dll() {
821 if (is_initialized())
822 proc<void WINAPI()>(*
this,
"CoUninitialize")();
825inline bool internal::platform::ole32_dll::is_initialized() {
826 return m_state == S_OK || m_state == S_FALSE;
833inline internal::platform::new_style_context::new_style_context() {
835 static HANDLE hctx = create();
837 if (hctx != INVALID_HANDLE_VALUE)
838 ActivateActCtx(hctx, &m_cookie);
841inline internal::platform::new_style_context::~new_style_context() {
842 DeactivateActCtx(0, m_cookie);
845inline HANDLE internal::platform::new_style_context::create() {
853 dll comdlg32(
"comdlg32.dll");
856 UINT len = ::GetSystemDirectoryA(
nullptr, 0);
857 std::string sys_dir(len,
'\0');
858 ::GetSystemDirectoryA(&sys_dir[0], len);
864 ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID,
874 return ::CreateActCtxA(&act_ctx);
881 return m_async->ready(timeout);
893 return {
"osascript" };
910 return "yesnocancel";
912 return "retrycancel";
914 return "abortretryignore";
933 return "information";
939inline std::ostream&
operator<<(std::ostream& s, std::vector<std::string>
const& v) {
942 s << (not_first++ ?
" " :
"") << e;
951 return "'" + std::regex_replace(str, std::regex(
"['\"]"),
"$&$&") +
"'";
958 return "\"" + std::regex_replace(str, std::regex(
"[\\\\\"]"),
"\\$&") +
"\"";
964 return "'" + std::regex_replace(str, std::regex(
"'"),
"'\\''") +
"'";
970 std::string
const& default_path ,
971 std::vector<std::string>
const&
filters ,
974 std::string filter_list;
975 std::regex whitespace(
" *");
976 for (
size_t i = 0; i + 1 <
filters.size(); i += 2) {
977 filter_list +=
filters[i] +
'\0';
978 filter_list += std::regex_replace(
filters[i + 1], whitespace,
";") +
'\0';
982 m_async->start_func([
this, in_type, title, default_path, filter_list, options](
int* exit_code) -> std::string {
984 m_wtitle = internal::str2wstr(title);
985 m_wdefault_path = internal::str2wstr(default_path);
986 auto wfilter_list = internal::str2wstr(filter_list);
996#if PFD_HAS_IFILEDIALOG
1000 HRESULT hr = dll::proc<HRESULT WINAPI(REFCLSID, LPUNKNOWN, DWORD, REFIID, LPVOID*)>(
1001 ole32,
"CoCreateInstance")(CLSID_FileOpenDialog,
nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ifd));
1010 memset(&bi, 0,
sizeof(bi));
1012 bi.lpfn = &bffcallback;
1013 bi.lParam = (LPARAM)
this;
1016 if (ole32.is_initialized())
1017 bi.ulFlags |= BIF_NEWDIALOGSTYLE;
1018 bi.ulFlags |= BIF_EDITBOX;
1019 bi.ulFlags |= BIF_STATUSTEXT;
1022 auto* list = SHBrowseForFolderW(&bi);
1025 auto buffer =
new wchar_t[MAX_PATH];
1026 SHGetPathFromIDListW(list, buffer);
1027 dll::proc<void WINAPI(LPVOID)>(ole32,
"CoTaskMemFree")(list);
1028 ret = internal::wstr2str(buffer);
1035 memset(&ofn, 0,
sizeof(ofn));
1036 ofn.lStructSize =
sizeof(OPENFILENAMEW);
1037 ofn.hwndOwner = GetActiveWindow();
1039 ofn.lpstrFilter = wfilter_list.c_str();
1041 auto woutput = std::wstring(MAX_PATH * 256, L
'\0');
1042 ofn.lpstrFile = (LPWSTR)woutput.data();
1043 ofn.nMaxFile = (DWORD)woutput.size();
1044 if (!m_wdefault_path.empty()) {
1048 auto path_attr = GetFileAttributesW(m_wdefault_path.c_str());
1049 if (path_attr != INVALID_FILE_ATTRIBUTES && (path_attr & FILE_ATTRIBUTE_DIRECTORY))
1050 ofn.lpstrInitialDir = m_wdefault_path.c_str();
1051 else if (m_wdefault_path.size() <= woutput.size())
1053 StringCchCopyW(ofn.lpstrFile, MAX_PATH * 256 + 1, m_wdefault_path.c_str());
1055 ofn.lpstrFileTitle = (LPWSTR)m_wdefault_path.data();
1056 ofn.nMaxFileTitle = (DWORD)m_wdefault_path.size();
1059 ofn.lpstrTitle = m_wtitle.c_str();
1060 ofn.Flags = OFN_NOCHANGEDIR | OFN_EXPLORER;
1062 dll comdlg32(
"comdlg32.dll");
1065 new_style_context ctx;
1069 ofn.Flags |= OFN_OVERWRITEPROMPT;
1071 dll::proc<BOOL WINAPI(LPOPENFILENAMEW)> get_save_file_name(comdlg32,
"GetSaveFileNameW");
1072 if (get_save_file_name(&ofn) == 0)
1074 return internal::wstr2str(woutput.c_str());
1077 ofn.Flags |= OFN_ALLOWMULTISELECT;
1078 ofn.Flags |= OFN_PATHMUSTEXIST;
1080 dll::proc<BOOL WINAPI(LPOPENFILENAMEW)> get_open_file_name(comdlg32,
"GetOpenFileNameW");
1081 if (get_open_file_name(&ofn) == 0)
1086 for (
wchar_t const* p = woutput.c_str(); *p;) {
1087 auto filename = internal::wstr2str(p);
1093 prefix = filename +
"/";
1097 m_vector_result.push_back(prefix + filename);
1113 std::string script =
"set ret to choose";
1116 script +=
" file name";
1122 script +=
" with multiple selections allowed";
1125 script +=
" folder";
1129 if (default_path.size()) {
1131 script +=
" default location ";
1133 script +=
" default name ";
1141 std::string patterns;
1142 for (
size_t i = 0; i <
filters.size() / 2; ++i)
1143 patterns +=
" " +
filters[2 * i + 1];
1148 std::regex sep(
"\\s+");
1149 std::string filter_list;
1150 bool has_filter =
true;
1151 std::sregex_token_iterator iter(patterns.begin(), patterns.end(), sep, -1);
1152 std::sregex_token_iterator end;
1153 for (; iter != end; ++iter) {
1154 auto pat = iter->str();
1155 if (pat ==
"*" || pat ==
"*.*")
1161 if (has_filter && filter_list.size() > 0) {
1167 script +=
" of type {\"///\"" + filter_list +
"}";
1172 script +=
"\nset s to \"\"";
1173 script +=
"\nrepeat with i in ret";
1174 script +=
"\n set s to s & (POSIX path of i) & \"\\n\"";
1175 script +=
"\nend repeat";
1176 script +=
"\ncopy s to stdout";
1178 script +=
"\nPOSIX path of ret";
1181 command.push_back(
"-e");
1182 command.push_back(script);
1184 command.push_back(
"--file-selection");
1188 auto filename_arg =
"--filename=" + default_path;
1190 filename_arg +=
"/";
1191 command.push_back(filename_arg);
1193 command.push_back(
"--title");
1194 command.push_back(title);
1195 command.push_back(
"--separator=\n");
1197 for (
size_t i = 0; i <
filters.size() / 2; ++i) {
1198 command.push_back(
"--file-filter");
1203 command.push_back(
"--save");
1205 command.push_back(
"--directory");
1207 command.push_back(
"--confirm-overwrite");
1209 command.push_back(
"--multiple");
1213 command.push_back(
"--getsavefilename");
1216 command.push_back(
"--getopenfilename");
1219 command.push_back(
"--getexistingdirectory");
1223 command.push_back(
"--multiple");
1224 command.push_back(
"--separate-output");
1227 command.push_back(default_path);
1230 for (
size_t i = 0; i <
filters.size() / 2; ++i)
1232 command.push_back(
filter);
1234 command.push_back(
"--title");
1235 command.push_back(title);
1239 std::cerr <<
"pfd: " << command << std::endl;
1241 m_async->start_process(command);
1252 while (!ret.empty() && (ret.back() ==
'\n' || ret.back() ==
'/'))
1261 return m_vector_result;
1263 std::vector<std::string> ret;
1264 auto result =
m_async->result();
1267 auto i = result.find(
'\n');
1268 if (i == 0 || i == std::string::npos)
1270 ret.push_back(result.substr(0, i));
1271 result = result.substr(i + 1, result.size());
1279inline int CALLBACK internal::file_dialog::bffcallback(HWND hwnd, UINT uMsg, LPARAM, LPARAM pData) {
1282 case BFFM_INITIALIZED:
1283 SendMessage(hwnd, BFFM_SETSELECTIONW, TRUE, (LPARAM)inst->m_wdefault_path.c_str());
1289#if PFD_HAS_IFILEDIALOG
1290inline std::string internal::file_dialog::select_folder_vista(IFileDialog* ifd,
bool force_path) {
1296 dll shell32(
"shell32.dll");
1297 dll::proc<HRESULT WINAPI(PCWSTR, IBindCtx*, REFIID,
void**)> create_item(shell32,
"SHCreateItemFromParsingName");
1302 auto hr = create_item(m_wdefault_path.c_str(),
nullptr, IID_PPV_ARGS(&folder));
1310 if (SUCCEEDED(hr)) {
1312 ifd->SetFolder(folder);
1314 ifd->SetDefaultFolder(folder);
1319 ifd->SetOptions(FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM);
1320 ifd->SetTitle(m_wtitle.c_str());
1322 hr = ifd->Show(GetActiveWindow());
1323 if (SUCCEEDED(hr)) {
1325 hr = ifd->GetResult(&item);
1326 if (SUCCEEDED(hr)) {
1327 wchar_t* wname =
nullptr;
1330 if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, &wname))) {
1331 result = internal::wstr2str(std::wstring(wname));
1332 dll::proc<void WINAPI(LPVOID)>(ole32_dll(),
"CoTaskMemFree")(wname);
1334 if (SUCCEEDED(item->GetDisplayName(SIGDN_NORMALDISPLAY, &wname))) {
1335 auto name = internal::wstr2str(std::wstring(wname));
1336 dll::proc<void WINAPI(LPVOID)>(ole32_dll(),
"CoTaskMemFree")(wname);
1337 std::cerr <<
"pfd: failed to get path for " << name << std::endl;
1339 std::cerr <<
"pfd: item of unknown type selected" << std::endl;
1363 struct notify_icon_data :
public NOTIFYICONDATAW {
1364 ~notify_icon_data() {
1365 Shell_NotifyIconW(NIM_DELETE,
this);
1369 static std::shared_ptr<notify_icon_data> nid;
1375 nid = std::make_shared<notify_icon_data>();
1378 nid->cbSize = NOTIFYICONDATAW_V2_SIZE;
1379 nid->hWnd =
nullptr;
1390 nid->uFlags = NIF_MESSAGE | NIF_ICON | NIF_INFO;
1401 nid->dwInfoFlags = NIIF_WARNING;
1404 nid->dwInfoFlags = NIIF_ERROR;
1407 nid->dwInfoFlags = NIIF_INFO;
1411 ENUMRESNAMEPROC icon_enum_callback = [](HMODULE, LPCTSTR, LPTSTR lpName, LONG_PTR lParam) -> BOOL {
1412 ((NOTIFYICONDATAW*)lParam)->hIcon = ::LoadIcon(GetModuleHandle(
nullptr), lpName);
1416 nid->hIcon = ::LoadIcon(
nullptr, IDI_APPLICATION);
1417 ::EnumResourceNames(
nullptr, RT_GROUP_ICON, icon_enum_callback, (LONG_PTR)nid.get());
1419 nid->uTimeout = 5000;
1421 StringCchCopyW(nid->szInfoTitle, ARRAYSIZE(nid->szInfoTitle), internal::str2wstr(title).c_str());
1422 StringCchCopyW(nid->szInfo, ARRAYSIZE(nid->szInfo), internal::str2wstr(
message).c_str());
1425 Shell_NotifyIconW(NIM_ADD, nid.get());
1434 command.push_back(
"-e");
1437 command.push_back(
"--notification");
1438 command.push_back(
"--window-icon");
1440 command.push_back(
"--text");
1441 command.push_back(title +
"\n" +
message);
1443 command.push_back(
"--icon");
1445 command.push_back(
"--title");
1446 command.push_back(title);
1447 command.push_back(
"--passivepopup");
1449 command.push_back(
"5");
1453 std::cerr <<
"pfd: " << command << std::endl;
1455 m_async->start_process(command);
1466 UINT style = MB_SYSTEMMODAL;
1469 style |= MB_ICONWARNING;
1472 style |= MB_ICONERROR;
1475 style |= MB_ICONQUESTION;
1478 style |= MB_ICONINFORMATION;
1484 style |= MB_OKCANCEL;
1490 style |= MB_YESNOCANCEL;
1493 style |= MB_RETRYCANCEL;
1496 style |= MB_ABORTRETRYIGNORE;
1511 m_async->start_func([text, title, style](
int* exit_code) -> std::string {
1512 auto wtext = internal::str2wstr(text);
1513 auto wtitle = internal::str2wstr(title);
1515 new_style_context ctx;
1516 *exit_code = MessageBoxW(GetActiveWindow(), wtext.c_str(), wtitle.c_str(), style);
1521 std::string full_message;
1524 full_message =
"⚠️";
1537 full_message +=
' ' + title +
"\n\n" + text;
1544 return window.confirm(UTF8ToString($0)) ? 0 : -1;
1545 alert(UTF8ToString($0));
1557 script +=
"buttons {\"OK\", \"Cancel\"}"
1558 " default button \"OK\""
1559 " cancel button \"Cancel\"";
1562 script +=
"buttons {\"Yes\", \"No\"}"
1563 " default button \"Yes\""
1564 " cancel button \"No\"";
1568 script +=
"buttons {\"Yes\", \"No\", \"Cancel\"}"
1569 " default button \"Yes\""
1570 " cancel button \"Cancel\"";
1573 script +=
"buttons {\"Retry\", \"Cancel\"}"
1574 " default button \"Retry\""
1575 " cancel button \"Cancel\"";
1578 script +=
"buttons {\"Abort\", \"Retry\", \"Ignore\"}"
1579 " default button \"Abort\""
1580 " cancel button \"Retry\"";
1585 script +=
"buttons {\"OK\"}"
1586 " default button \"OK\""
1587 " cancel button \"OK\"";
1593 script +=
" with icon ";
1595#define PFD_OSX_ICON(n) \
1596 "alias ((path to library folder from system domain) as text " \
1597 "& \"CoreServices:CoreTypes.bundle:Contents:Resources:" n ".icns\")"
1603 script +=
"caution";
1614 command.push_back(
"-e");
1615 command.push_back(script);
1619 command.insert(command.end(), {
"--question",
"--cancel-label=Cancel",
"--ok-label=OK" });
1624 command.insert(command.end(), {
"--question",
"--switch",
"--extra-button=No",
"--extra-button=Yes" });
1627 command.insert(command.end(), {
"--question",
"--switch",
"--extra-button=Cancel",
"--extra-button=No",
1628 "--extra-button=Yes" });
1631 command.insert(command.end(),
1632 {
"--question",
"--switch",
"--extra-button=Cancel",
"--extra-button=Retry" });
1635 command.insert(command.end(), {
"--question",
"--switch",
"--extra-button=Ignore",
1636 "--extra-button=Abort",
"--extra-button=Retry" });
1642 command.push_back(
"--error");
1645 command.push_back(
"--warning");
1648 command.push_back(
"--info");
1653 command.insert(command.end(), {
"--title", title,
"--width=300",
"--height=0",
1655 "--text", text,
"--icon-name=dialog-" + get_icon_name(_icon) });
1660 command.push_back(
"--error");
1663 command.push_back(
"--sorry");
1666 command.push_back(
"--msgbox");
1670 std::string
flag =
"--";
1676 command.push_back(
flag);
1683 command.push_back(text);
1684 command.push_back(
"--title");
1685 command.push_back(title);
1689 command.insert(command.end(), {
"--yes-label",
"OK",
"--no-label",
"Cancel" });
1693 std::cerr <<
"pfd: " << command << std::endl;
1695 m_async->start_process(command);
1701 auto ret =
m_async->result(&exit_code);
1726 std::vector<std::string>
const&
filters ,
1732 std::vector<std::string>
const&
filters,
bool allow_multiselect)
1743 std::vector<std::string>
const&
filters ,
1749 std::vector<std::string>
const&
filters,
bool confirm_overwrite)
static const char * filters[3]
Definition ImguiUI.cpp:121
Definition portable-file-dialogs.h:259
dialog()
Definition portable-file-dialogs.h:888
std::string shell_quote(std::string const &str) const
Definition portable-file-dialogs.h:963
bool kill() const
Definition portable-file-dialogs.h:884
bool ready(int timeout=default_wait_timeout) const
Definition portable-file-dialogs.h:880
std::shared_ptr< executor > m_async
Definition portable-file-dialogs.h:276
std::vector< std::string > desktop_helper() const
Definition portable-file-dialogs.h:891
std::string powershell_quote(std::string const &str) const
Definition portable-file-dialogs.h:950
static std::string buttons_to_name(choice _choice)
Definition portable-file-dialogs.h:903
std::string osascript_quote(std::string const &str) const
Definition portable-file-dialogs.h:957
static std::string get_icon_name(icon _icon)
Definition portable-file-dialogs.h:920
Definition portable-file-dialogs.h:162
std::string m_stdout
Definition portable-file-dialogs.h:189
std::string result(int *exit_code=nullptr)
Definition portable-file-dialogs.h:627
int m_fd
Definition portable-file-dialogs.h:201
~executor()
Definition portable-file-dialogs.h:736
void stop()
Definition portable-file-dialogs.h:792
bool m_running
Definition portable-file-dialogs.h:188
pid_t m_pid
Definition portable-file-dialogs.h:200
bool ready(int timeout=default_wait_timeout)
Definition portable-file-dialogs.h:740
friend class dialog
Definition portable-file-dialogs.h:163
bool kill()
Definition portable-file-dialogs.h:634
void start_process(std::vector< std::string > const &command)
Definition portable-file-dialogs.h:693
int m_exit_code
Definition portable-file-dialogs.h:190
Definition portable-file-dialogs.h:279
file_dialog(type in_type, std::string const &title, std::string const &default_path="", std::vector< std::string > const &filters={}, opt options=opt::none)
Definition portable-file-dialogs.h:969
type
Definition portable-file-dialogs.h:281
@ save
Definition portable-file-dialogs.h:283
@ open
Definition portable-file-dialogs.h:282
@ folder
Definition portable-file-dialogs.h:284
std::string string_result()
Definition portable-file-dialogs.h:1245
std::vector< std::string > vector_result()
Definition portable-file-dialogs.h:1258
Definition portable-file-dialogs.h:332
message(std::string const &title, std::string const &text, choice _choice=choice::ok_cancel, icon _icon=icon::info)
Definition portable-file-dialogs.h:1461
std::map< int, button > m_mappings
Definition portable-file-dialogs.h:341
button result()
Definition portable-file-dialogs.h:1699
notify(std::string const &title, std::string const &message, icon _icon=icon::info)
Definition portable-file-dialogs.h:1355
open_file(std::string const &title, std::string const &default_path="", std::vector< std::string > const &filters={ "All Files", "*" }, opt options=opt::none)
Definition portable-file-dialogs.h:1725
std::vector< std::string > result()
Definition portable-file-dialogs.h:1736
Definition portable-file-dialogs.h:313
static std::string home()
Definition portable-file-dialogs.h:577
static std::string separator()
Definition portable-file-dialogs.h:617
save_file(std::string const &title, std::string const &default_path="", std::vector< std::string > const &filters={ "All Files", "*" }, opt options=opt::none)
Definition portable-file-dialogs.h:1742
std::string result()
Definition portable-file-dialogs.h:1753
std::string result()
Definition portable-file-dialogs.h:1764
select_folder(std::string const &title, std::string const &default_path="", opt options=opt::none)
Definition portable-file-dialogs.h:1759
bool is_zenity() const
Definition portable-file-dialogs.h:559
static void verbose(bool value)
Definition portable-file-dialogs.h:526
bool const & flags(flag in_flag) const
Definition portable-file-dialogs.h:567
bool is_osascript() const
Definition portable-file-dialogs.h:551
static bool available()
Definition portable-file-dialogs.h:511
static void rescan()
Definition portable-file-dialogs.h:530
flag
Definition portable-file-dialogs.h:136
@ is_scanned
Definition portable-file-dialogs.h:137
@ has_matedialog
Definition portable-file-dialogs.h:141
@ has_qarma
Definition portable-file-dialogs.h:142
@ has_kdialog
Definition portable-file-dialogs.h:143
@ max_flag
Definition portable-file-dialogs.h:146
@ is_verbose
Definition portable-file-dialogs.h:138
@ is_vista
Definition portable-file-dialogs.h:144
@ has_zenity
Definition portable-file-dialogs.h:140
settings(bool resync=false)
Definition portable-file-dialogs.h:479
bool is_kdialog() const
Definition portable-file-dialogs.h:563
bool check_program(std::string const &program)
Definition portable-file-dialogs.h:535
uint16_t in
Definition mixer.c:80
int16_t filter[8]
Definition mixer.c:94
uint16_t out
Definition mixer.c:81
union @111115220225173102313045065244126153342261214353::@304166376113356371145235255022050055005326174300 buf
Definition portable-file-dialogs.h:157
static bool starts_with(std::string const &str, std::string const &prefix)
Definition portable-file-dialogs.h:438
static bool is_directory(std::string const &path)
Definition portable-file-dialogs.h:444
static std::string getenv(std::string const &str)
Definition portable-file-dialogs.h:459
static bool ends_with(std::string const &str, std::string const &suffix)
Definition portable-file-dialogs.h:434
static int const default_wait_timeout
Definition portable-file-dialogs.h:160
Definition portable-file-dialogs.h:70
opt
Definition portable-file-dialogs.h:99
@ none
Definition portable-file-dialogs.h:100
@ force_path
Definition portable-file-dialogs.h:108
@ force_overwrite
Definition portable-file-dialogs.h:104
@ multiselect
Definition portable-file-dialogs.h:102
choice
Definition portable-file-dialogs.h:82
@ yes_no
Definition portable-file-dialogs.h:85
@ ok
Definition portable-file-dialogs.h:83
@ yes_no_cancel
Definition portable-file-dialogs.h:86
@ retry_cancel
Definition portable-file-dialogs.h:87
@ ok_cancel
Definition portable-file-dialogs.h:84
@ abort_retry_ignore
Definition portable-file-dialogs.h:88
icon
Definition portable-file-dialogs.h:91
@ question
Definition portable-file-dialogs.h:95
@ warning
Definition portable-file-dialogs.h:93
@ info
Definition portable-file-dialogs.h:92
@ error
Definition portable-file-dialogs.h:94
button
Definition portable-file-dialogs.h:72
@ cancel
Definition portable-file-dialogs.h:73
@ retry
Definition portable-file-dialogs.h:78
@ ok
Definition portable-file-dialogs.h:74
@ ignore
Definition portable-file-dialogs.h:79
@ abort
Definition portable-file-dialogs.h:77
@ no
Definition portable-file-dialogs.h:76
@ yes
Definition portable-file-dialogs.h:75
opt operator|(opt a, opt b)
Definition portable-file-dialogs.h:111
bool operator&(opt a, opt b)
Definition portable-file-dialogs.h:114
std::ostream & operator<<(std::ostream &s, std::vector< std::string > const &v)
Definition portable-file-dialogs.h:939