From ec4fc631ba49371e4e0ca60a2c20a3dc7bfee643 Mon Sep 17 00:00:00 2001 From: "U-ole-PC\\ole" Date: Tue, 3 Nov 2015 14:31:52 +0100 Subject: [PATCH] Cleanup of dialogs, as well as fixing a couple of crashes. --- src/CMakeLists.txt | 10 +--- src/dialogs.cc | 6 +-- src/dialogs.h | 6 +-- src/dialogs_win.cc | 126 ++++++++++++++++++++++++--------------------- src/directories.cc | 6 +-- src/window.cc | 6 +-- 6 files changed, 79 insertions(+), 81 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1e7ef9..2da1c6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,15 +28,7 @@ find_package(LibClang REQUIRED) #find_package(PythonLibs 2.7) #find_package(Boost 1.55 COMPONENTS python 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) +find_package(Boost 1.55 COMPONENTS thread log system filesystem REQUIRED) pkg_check_modules(GTKMM gtkmm-3.0 REQUIRED) # The name GTKMM is set here for the variables abouve diff --git a/src/dialogs.cc b/src/dialogs.cc index cb9b8b3..5604250 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -25,7 +25,7 @@ std::string open_dialog(const std::string &title, return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; } -std::string Dialog::select_folder() { +std::string Dialog::open_folder() { return open_dialog("Please choose a folder", {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Open", Gtk::RESPONSE_OK)}, Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); @@ -43,13 +43,13 @@ std::string Dialog::new_folder() { Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); } -std::string Dialog::select_file() { +std::string Dialog::open_file() { return open_dialog("Please choose a file", {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)}, Gtk::FILE_CHOOSER_ACTION_OPEN); } -std::string Dialog::save_file(const boost::filesystem::path file_path) { +std::string Dialog::save_file_as(const boost::filesystem::path &file_path) { return open_dialog("Please choose a file", {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Save", Gtk::RESPONSE_OK)}, Gtk::FILE_CHOOSER_ACTION_SAVE, file_path.string()); diff --git a/src/dialogs.h b/src/dialogs.h index 435e207..4977ce6 100644 --- a/src/dialogs.h +++ b/src/dialogs.h @@ -5,11 +5,11 @@ class Dialog { public: - static std::string select_folder(); - static std::string select_file(); + static std::string open_folder(); + static std::string open_file(); static std::string new_file(); static std::string new_folder(); - static std::string save_file(const boost::filesystem::path file_path); + static std::string save_file_as(const boost::filesystem::path &file_path); }; #endif //JUCI_DIALOG_H_ diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index 2c67116..c840a08 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,6 +1,5 @@ #include "dialogs.h" #include "singletons.h" -#include #undef NTDDI_VERSION #define NTDDI_VERSION NTDDI_VISTA @@ -14,26 +13,16 @@ #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 - class CommonDialog { public: CommonDialog(CLSID type); - /** available options are listed https://msdn.microsoft.com/en-gb/library/windows/desktop/dn457282(v=vs.85).aspx */ + /** available options are listed at 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(const std::wstring &title); /** Sets the extensions the browser can find */ - void set_default_file_extension(const std::string &file_extension); + void set_default_file_extension(const std::wstring &file_extension); /** Sets the directory to start browsing */ - void set_default_folder(const std::string &directory_path); + void set_default_folder(const std::wstring &directory_path); /** Returns the selected item's path as a string */ std::string show(); @@ -45,55 +34,64 @@ protected: class OpenDialog : public CommonDialog { public: - OpenDialog(const std::string &title, unsigned option); + OpenDialog(const std::wstring &title, unsigned option=0); }; class SaveDialog : public CommonDialog { public: - SaveDialog(const std::string &title, unsigned option); + SaveDialog(const std::wstring &title, const boost::filesystem::path &file_path="", unsigned option=0); private: std::vector extensions; }; -// { COMMON_DIALOG CommonDialog::CommonDialog(CLSID type) : dialog(nullptr) { - if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))!=S_OK) { - error=true; - return; - } - if(dialog->GetOptions(&options)!=S_OK) - error=true; + if(CoCreateInstance(type, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))!=S_OK) { + error=true; + return; + } + if(dialog->GetOptions(&options)!=S_OK) + error=true; } -void CommonDialog::set_title(const std::string &title) { + +void CommonDialog::set_title(const std::wstring &title) { if(error) return; - auto ptr = boost::locale::conv::utf_to_utf(title).data(); - if(dialog->SetTitle(ptr)!=S_OK) + if(dialog->SetTitle(title.c_str())!=S_OK) error=true; } + void CommonDialog::add_option(unsigned option) { if(error) return; if(dialog->SetOptions(options | option)!=S_OK) error=true; } -void CommonDialog::set_default_file_extension(const std::string &file_extension) { + +void CommonDialog::set_default_file_extension(const std::wstring &file_extension) { if(error) return; - auto ptr = boost::locale::conv::utf_to_utf(file_extension).data(); - if(dialog->SetDefaultExtension(ptr)!=S_OK) + if(dialog->SetDefaultExtension(file_extension.c_str())!=S_OK) error=true; } -void CommonDialog::set_default_folder(const std::string &directory_path) { + +void CommonDialog::set_default_folder(const std::wstring &directory_path) { if(error) return; + + std::wstring path=directory_path; + size_t pos=0; + while((pos=path.find(L'/', pos))!=std::wstring::npos) {//TODO: issue bug report on boost::filesystem::path::native on MSYS2 + path.replace(pos, 1, L"\\"); + pos++; + } + IShellItem * folder = nullptr; - auto ptr = boost::locale::conv::utf_to_utf(directory_path).data(); - if(SHCreateItemFromParsingName(ptr, nullptr, IID_PPV_ARGS(&folder))!=S_OK) { + if(SHCreateItemFromParsingName(path.c_str(), nullptr, IID_PPV_ARGS(&folder))!=S_OK) { error=true; return; } - auto result=dialog->SetDefaultFolder(folder) + auto hresult=dialog->SetDefaultFolder(folder); folder->Release(); - if(result!=S_OK) + if(hresult!=S_OK) error=true; } + std::string CommonDialog::show() { if(error) return ""; if(dialog->Show(nullptr)!=S_OK) { @@ -107,54 +105,62 @@ std::string CommonDialog::show() { return ""; } LPWSTR str = nullptr; - auto result=result->GetDisplayName(SIGDN_FILESYSPATH, &str); + auto hresult=result->GetDisplayName(SIGDN_FILESYSPATH, &str); result->Release(); dialog->Release(); - if(result!=S_OK) + if(hresult!=S_OK) return ""; - auto res = boost::locale::conv::utf_to_utf(str); + std::wstring wstr(str); + std::string res(wstr.begin(), wstr.end()); CoTaskMemFree(str); return res; } -OpenDialog::OpenDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) { +OpenDialog::OpenDialog(const std::wstring &title, unsigned option) : CommonDialog(CLSID_FileOpenDialog) { set_title(title); add_option(option); - auto dirs = Singleton::directories()->current_path; - set_default_folder(dirs.empty() ? boost::filesystem::current_path().string() : dirs.string()); + auto dirs = Singleton::directories->current_path; + set_default_folder(dirs.empty() ? boost::filesystem::current_path().native() : dirs.native()); } -SaveDialog::SaveDialog(const std::string &title, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { +SaveDialog::SaveDialog(const std::wstring &title, const boost::filesystem::path &file_path, unsigned option) : CommonDialog(CLSID_FileSaveDialog) { set_title(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"); + if(!file_path.empty()) { + set_default_folder(file_path.parent_path().native()); + if(file_path.has_extension()) { + auto extension=(L"*"+file_path.extension().native()).c_str(); + extensions.emplace_back(COMDLG_FILTERSPEC{extension, extension}); + set_default_file_extension(extension); + } + } + else { + auto dirs = Singleton::directories->current_path; + set_default_folder(dirs.empty() ? boost::filesystem::current_path().native() : dirs.native()); + } + extensions.emplace_back(COMDLG_FILTERSPEC{L"All files", L"*.*"}); + if(dialog->SetFileTypes(extensions.size(), extensions.data())!=S_OK) { + error=true; + return; + } } -// DIALOGS }} -std::string Dialog::select_folder() { - return (OpenDialog("Select folder", FOS_PICKFOLDERS)).show(); +std::string Dialog::open_folder() { + return (OpenDialog(L"Open Folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::new_file() { - return (SaveDialog("Please choose your destination", 0)).show(); + return (SaveDialog(L"New File")).show(); } std::string Dialog::new_folder() { - return Dialog::select_folder(); + return (OpenDialog(L"New Folder", FOS_PICKFOLDERS)).show(); } -std::string Dialog::select_file() { - return (OpenDialog("Open file", 0)).show(); +std::string Dialog::open_file() { + return (OpenDialog(L"Open File")).show(); } -std::string Dialog::save_file(const boost::filesystem::path file_path) { - //TODO: use file_path - return (SaveDialog("Please choose your destination", 0)).show(); +std::string Dialog::save_file_as(const boost::filesystem::path &file_path) { + return (SaveDialog(L"Save File As", file_path)).show(); } diff --git a/src/directories.cc b/src/directories.cc index ab109d0..14d774f 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -118,9 +118,9 @@ Directories::~Directories() { } void Directories::open(const boost::filesystem::path& dir_path) { - JDEBUG("start"); - if(dir_path.empty()) - return; + JDEBUG("start"); + if(dir_path.empty()) + return; tree_store->clear(); update_mutex.lock(); diff --git a/src/window.cc b/src/window.cc index 74ce8cc..388c94d 100644 --- a/src/window.cc +++ b/src/window.cc @@ -215,12 +215,12 @@ void Window::set_menu_actions() { }); menu->add_action("open_file", [this]() { - auto path=Dialog::select_file(); + auto path=Dialog::open_file(); if(path!="") notebook.open(path); }); menu->add_action("open_folder", [this]() { - auto path = Dialog::select_folder(); + auto path = Dialog::open_folder(); if (path!="" && boost::filesystem::exists(path)) Singleton::directories->open(path); }); @@ -242,7 +242,7 @@ void Window::set_menu_actions() { }); menu->add_action("save_as", [this]() { if(notebook.get_current_page()!=-1) { - auto path = Dialog::save_file(notebook.get_current_view()->file_path); + auto path = Dialog::save_file_as(notebook.get_current_view()->file_path); if(path!="") { std::ofstream file(path); if(file) {