#include "dialogs.h" #include "singletons.h" #include //TODO: remove using namespace std; //TODO: remove #ifndef check HRESULT __hr__; #define check(__fun__, error_message) \ __hr__ = __fun__; \ if (FAILED(__hr__)) { \ Singleton::terminal->print(error_message); \ throw std::runtime_error(error_message); \ } #endif // CHECK #undef NTDDI_VERSION #define NTDDI_VERSION NTDDI_VISTA #undef _WIN32_WINNT #define _WIN32_WINNT _WIN32_WINNT_VISTA #include #include #include #include #include class WinString { public: WinString() : str(nullptr) { } WinString(const std::string &string); ~WinString() { CoTaskMemFree(static_cast(str)); } std::string operator()(); wchar_t** operator&() { return &str; } private: wchar_t* str; std::wstring s2ws(const std::string& str); std::string ws2s(const std::wstring& wstr); }; class CommonDialog { public: CommonDialog(CLSID type); void add_option(unsigned option); void set_title(const std::string &title); std::string show(); private: IFileDialog * dialog; DWORD options; }; class OpenDialog : public CommonDialog { public: OpenDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) { set_title(title); add_option(option); } }; class SaveDialog : public CommonDialog { public: SaveDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { set_title(title); add_option(option); } }; // { WINSTRING WinString::WinString(const std::string &string) { std::wstringstream ss; ss << s2ws(string); ss >> str; } std::string WinString::operator()() { std::string res; if (str != nullptr) { std::wstring ss(str); res = ws2s(ss); } return res; } // http://stackoverflow.com/questions/4804298/how-to-convert-wstring-into-string std::wstring WinString::s2ws(const std::string& str) { typedef std::codecvt_utf8 convert_typeX; std::wstring_convert converterX; return converterX.from_bytes(str); } std::string WinString::ws2s(const std::wstring& wstr) { typedef std::codecvt_utf8 convert_typeX; std::wstring_convert converterX; return converterX.to_bytes(wstr); } // WINSTRING } // { COMMON_DIALOG CommonDialog::CommonDialog(CLSID type) : dialog(nullptr) { check(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog)), "Failed to create instance"); check(dialog->GetOptions(&options), "Failed to get options from instance"); } void CommonDialog::set_title(const std::string &title) { auto tmp = std::wstring(title.begin(), title.end()); auto t = tmp.data(); check(dialog->SetTitle(t), "Failed to set dialog title"); } void CommonDialog::add_option(unsigned option) { check(dialog->SetOptions(options | option), "Failed to set options"); } std::string CommonDialog::show() { if(dialog->Show(nullptr)!=S_OK) { dialog->Release(); return ""; } IShellItem *result = nullptr; if(dialog->GetResult(&result)!=S_OK) { result->Release(); return ""; } WinString str; if(result->GetDisplayName(SIGDN_FILESYSPATH, &str)!=S_OK) return ""; result->Release(); dialog->Release(); return str(); } // COMMON_DIALOG }} std::string Dialog::select_folder() { return (OpenDialog("Select folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::new_file() { return (SaveDialog("Please choose your destination", 0)).show(); } std::string Dialog::new_folder() { return Dialog::select_folder(); } std::string Dialog::select_file() { return (OpenDialog("Open file", 0)).show(); } std::string Dialog::save_file(const boost::filesystem::path file_path) { //TODO: use file_path return (SaveDialog("Please choose your destination", 0)).show(); }