diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2da1c6f..e1e7ef9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,7 +28,15 @@ find_package(LibClang REQUIRED) #find_package(PythonLibs 2.7) #find_package(Boost 1.55 COMPONENTS python thread log system filesystem REQUIRED) -find_package(Boost 1.55 COMPONENTS thread log system filesystem REQUIRED) + +set(BOOST_DEP thread log system filesystem) + +if(MSYS) + list(APPEND BOOST_DEP locale) +endif() + + +find_package(Boost 1.55 COMPONENTS ${BOOST_DEP} REQUIRED) pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED) # The name GTKMM is set here for the variables abouve diff --git a/src/dialogs.h b/src/dialogs.h index 086a93b..5b71b0c 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -17,50 +17,36 @@ class Dialog { #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); -}; +#include class CommonDialog { public: CommonDialog(CLSID type); + /** available options are listed https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */ void add_option(unsigned option); - void set_title(const std::string &title); + void set_title(std::string &&title); + /** Sets the extensions the browser can find */ + void set_default_file_extension(std::string &&file_extension); + /** Sets the directory to start browsing */ + void set_default_folder(const std::string &directory_path); + /** Returns the selected item's path as a string */ std::string show(); -private: +protected: 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); - } + OpenDialog(std::string &&title, unsigned option); }; - class SaveDialog : public CommonDialog { public: - SaveDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { - set_title(title); - add_option(option); - } + SaveDialog(std::string &&title, unsigned option); +private: + std::vector extensions; }; + #endif // __WIN32 #endif // JUCI_DIALOG_H_ diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index d7b2791..ecee64c 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,7 +1,7 @@ #ifdef _WIN32 #include "dialogs.h" #include "singletons.h" - +#include #ifndef check HRESULT __hr__; #define check(__fun__, error_message) \ @@ -12,68 +12,66 @@ HRESULT __hr__; } #endif // CHECK - -// { 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::set_title(std::string &&title) { + auto ptr = boost::locale::conv::utf_to_utf(title).data(); + check(dialog->SetTitle(ptr), "Failed to set dialog title"); } - void CommonDialog::add_option(unsigned option) { check(dialog->SetOptions(options | option), "Failed to set options"); } - +void CommonDialog::set_default_file_extension(std::string &&file_extension) { + auto ptr = boost::locale::conv::utf_to_utf(file_extension).data(); + check(dialog->SetDefaultExtension(ptr), "Failed to set file extension"); +} +void CommonDialog::set_default_folder(const std::string &directory_path) { + IShellItem * folder = nullptr; + auto ptr = boost::locale::conv::utf_to_utf(directory_path).data(); + check(SHCreateItemFromParsingName(ptr, nullptr, IID_PPV_ARGS(&folder)), "Failed to create string"); + check(dialog->SetDefaultFolder(folder), "Failed to set default folder"); + folder->Release(); +} std::string CommonDialog::show() { try { check(dialog->Show(nullptr), "Failed to show dialog"); IShellItem *result = nullptr; check(dialog->GetResult(&result), "Failed to get result from dialog"); - WinString str; + LPWSTR str = nullptr; check(result->GetDisplayName(SIGDN_FILESYSPATH, &str), "Failed to get display name from dialog"); result->Release(); - return str(); + auto res = boost::locale::conv::utf_to_utf(str); + CoTaskMemFree(str); + return res; } catch (std::exception e) { return ""; } } -// COMMON_DIALOG }} + +OpenDialog::OpenDialog(std::string &&title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) { + set_title(std::move(title)); + add_option(option); + auto dirs = Singleton::directories()->current_path; + set_default_folder(dirs.empty() ? boost::filesystem::current_path().string() : dirs.string()); +} + +SaveDialog::SaveDialog(std::string &&title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { + set_title(std::move(title)); + add_option(option); + auto dirs = Singleton::directories()->current_path; + set_default_folder(dirs.empty() ? boost::filesystem::current_path().string() : dirs.string()); + extensions.emplace_back(COMDLG_FILTERSPEC{L"Default", L"*.h;*.cpp"}); + extensions.emplace_back(COMDLG_FILTERSPEC{L"GoogleStyle", L"*.cc;*.h"}); + extensions.emplace_back(COMDLG_FILTERSPEC{L"BoostStyle", L"*.hpp;*.cpp"}); + extensions.emplace_back(COMDLG_FILTERSPEC{L"Other", L"*.cxx;*.c"}); + check(dialog->SetFileTypes(extensions.size(), extensions.data()), "Failed to set extensions"); + set_default_file_extension("Default"); +} + +// DIALOGS }} std::string Dialog::select_folder() { return (OpenDialog("Select folder", FOS_PICKFOLDERS)).show(); }