From 908a7092bc345bd96d8a3143e8355ff95f0a24b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 13 Sep 2015 18:51:40 +0200 Subject: [PATCH 01/14] Clean dialogs and add some windows support --- src/CMakeLists.txt | 9 +- src/dialogs.cc | 50 +++++++++ src/dialogs.h | 14 +++ src/dialogs_win.cc | 52 ++++++++++ src/juci.cc | 2 +- src/singletons.cc | 7 ++ src/singletons.h | 2 + src/window.cc | 253 ++++++++++++++------------------------------- src/window.h | 7 -- 9 files changed, 208 insertions(+), 188 deletions(-) create mode 100644 src/dialogs.cc create mode 100644 src/dialogs.h create mode 100644 src/dialogs_win.cc diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cbdb24..deec0b9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,13 +88,18 @@ set(source_files juci.h tooltips.cc singletons.h singletons.cc + dialogs.h cmake.h cmake.cc) if(MSYS) - list(APPEND source_files terminal_win.cc) + list(APPEND source_files terminal_win.cc dialogs_win.cc) + list(APPEND source_files dialogs_win.cc) + message("MSYS detected") else() - list(APPEND source_files terminal.cc) + list(APPEND source_files terminal.cc dialogs.cc) + list(APPEND source_files dialogs.cc) + message("UNIX detected") endif() if(${validation}) diff --git a/src/dialogs.cc b/src/dialogs.cc new file mode 100644 index 0000000..8ff3882 --- /dev/null +++ b/src/dialogs.cc @@ -0,0 +1,50 @@ +#include "dialogs.h" +#include "singletons.h" +#include +#include + +std::string open_dialog(const std::string &title, + const std::vector> buttons, + Gtk::FileChooserAction gtk_options) { + Gtk::FileChooserDialog dialog(title, gtk_options); + if(Singleton::directories()->current_path!="") + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), Singleton::directories()->current_path.string().c_str()); + else + gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); + dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); + // dialog.set_transient_for(parent); TODO add parent + for (auto &button : buttons) + dialog.add_button(button.first, button.second); + return dialog.run() == Gtk::RESPONSE_OK ? dialog.get_filename() : ""; +} + + +std::string Dialog::select_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); +} + +std::string Dialog::new_file() { + return open_dialog("Please create a new file", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_SAVE); +} + +std::string Dialog::new_folder() { + return open_dialog("Please create a new folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); +} + +std::string Dialog::select_file() { + return open_dialog("Please choose a folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_OPEN); +} + +std::string Dialog::save_file() { + 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_OPEN); +} \ No newline at end of file diff --git a/src/dialogs.h b/src/dialogs.h new file mode 100644 index 0000000..5acf6ea --- /dev/null +++ b/src/dialogs.h @@ -0,0 +1,14 @@ +#ifndef JUCI_DIALOG_H_ +#define JUCI_DIALOG_H_ +#include + +class Dialog { + public: + static std::string select_folder(); + static std::string select_file(); + static std::string new_file(); + static std::string new_folder(); + static std::string save_file(); +}; // namespace Dialog + +#endif // JUCI_DIALOG_H_ \ No newline at end of file diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc new file mode 100644 index 0000000..f245f31 --- /dev/null +++ b/src/dialogs_win.cc @@ -0,0 +1,52 @@ +#include "dialogs.h" +#include +#include + +std::string Dialog::select_folder() { + char selected_folder[MAX_PATH]; + char init_path[MAX_PATH]; + auto title = "Please select a folder"; + selected_folder[0] = 0; + init_path[0] = 0; + + BROWSEINFOA browse; + browse.hwndOwner = 0; + browse.pidlRoot = NULL; + browse.lpszTitle = title; + browse.pszDisplayName = init_path; + browse.ulFlags = 0; + browse.lpfn = NULL; + auto result = SHBrowseForFolder(&browse); + + if(result) + SHGetPathFromIDListA(result, selected_folder); + + std::string dir(selected_folder); + return dir; +} +/* +std::string Dialog::new_file() { + return open_dialog("Please create a new file", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_SAVE); +} + +std::string Dialog::new_folder() { + return open_dialog("Please create a new folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); +} + +std::string Dialog::select_file() { + return open_dialog("Please choose a folder", + {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)}, + Gtk::FILE_CHOOSER_ACTION_OPEN); +} + +std::string Dialog::save_file() { + 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_OPEN); +} + +*/ \ No newline at end of file diff --git a/src/juci.cc b/src/juci.cc index a97b8ee..c83eb47 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -45,7 +45,7 @@ void app::on_activate() { bool first_directory=true; for(auto &directory: directories) { if(first_directory) { - window->directories.open(directory); + Singleton::directories()->open(directory); first_directory=false; } else { diff --git a/src/singletons.cc b/src/singletons.cc index 4633763..9040d55 100644 --- a/src/singletons.cc +++ b/src/singletons.cc @@ -5,12 +5,19 @@ std::unique_ptr Singleton::Config::directories_=std::unique std::unique_ptr Singleton::Config::terminal_=std::unique_ptr(new Terminal::Config()); std::unique_ptr Singleton::Config::window_ = std::unique_ptr(new Window::Config()); std::unique_ptr Singleton::terminal_=std::unique_ptr(); +std::unique_ptr Singleton::directories_=std::unique_ptr(); Terminal *Singleton::terminal() { if(!terminal_) terminal_=std::unique_ptr(new Terminal()); return terminal_.get(); } + +Directories *Singleton::directories() { + if(!directories_) + directories_=std::unique_ptr(new Directories()); + return directories_.get(); +} std::unique_ptr Singleton::status_=std::unique_ptr(); Gtk::Label *Singleton::status() { if(!status_) diff --git a/src/singletons.h b/src/singletons.h index 8fa6a86..33297ea 100644 --- a/src/singletons.h +++ b/src/singletons.h @@ -30,12 +30,14 @@ public: static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; } static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; } static Terminal *terminal(); + static Directories *directories(); static Gtk::Label *status(); static Gtk::Label *info(); private: static std::unique_ptr terminal_; static std::unique_ptr status_; static std::unique_ptr info_; + static std::unique_ptr directories_; }; #endif // JUCI_SINGLETONS_H_ diff --git a/src/window.cc b/src/window.cc index 13bfa5a..0daf779 100644 --- a/src/window.cc +++ b/src/window.cc @@ -5,6 +5,7 @@ #include "config.h" //#include "api.h" #include +#include "dialogs.h" #include //TODO: remove using namespace std; //TODO: remove @@ -30,7 +31,7 @@ void Window::generate_keybindings() { } } -Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compiling(false) { +Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) { DEBUG("start"); set_title("juCi++"); set_default_size(600, 400); @@ -42,7 +43,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil create_menu(); box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK); - directory_and_notebook_panes.pack1(directories, Gtk::SHRINK); + directory_and_notebook_panes.pack1(*Singleton::directories(), Gtk::SHRINK); notebook_vbox.pack_start(notebook); notebook_vbox.pack_end(entry_box, Gtk::PACK_SHRINK); directory_and_notebook_panes.pack2(notebook_vbox, Gtk::SHRINK); @@ -60,7 +61,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil box.pack_end(vpaned); show_all_children(); - directories.on_row_activated=[this](const std::string &file) { + Singleton::directories()->on_row_activated=[this](const std::string &file) { notebook.open(file); }; @@ -100,7 +101,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceRename"))) menu_item->set_sensitive((bool)notebook.get_current_view()->rename_similar_tokens); - directories.select(notebook.get_current_view()->file_path); + Singleton::directories()->select(notebook.get_current_view()->file_path); if(auto source_view=dynamic_cast(notebook.get_current_view())) { if(source_view->reparse_needed) { @@ -140,23 +141,86 @@ void Window::create_menu() { hide(); }); menu.action_group->add(Gtk::Action::create("FileNewFile", "New File"), Gtk::AccelKey(menu.key_map["new_file"]), [this]() { - new_file_dialog(); + boost::filesystem::path path = Dialog::new_file(); + if(path!="") { + if(boost::filesystem::exists(path)) { + Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + } + else { + if(juci::filesystem::write(path)) { + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + notebook.open(path.string()); + Singleton::terminal()->print("New file "+path.string()+" created.\n"); + } + else + Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n"); + } + } }); menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(menu.key_map["new_folder"]), [this]() { - new_folder_dialog(); + auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + boost::filesystem::path path = Dialog::new_folder(); + if(boost::filesystem::last_write_time(path)>=time_now) { + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + Singleton::terminal()->print("New folder "+path.string()+" created.\n"); + } + else + Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + Singleton::directories()->select(path); }); menu.action_group->add(Gtk::Action::create("FileNewProject", "New Project")); menu.action_group->add(Gtk::Action::create("FileNewProjectCpp", "C++"), [this]() { - new_cpp_project_dialog(); + boost::filesystem::path project_path = Dialog::new_folder(); + auto project_name=project_path.filename().string(); + for(size_t c=0;cprint("Error: "+cmakelists_path.string()+" already exists.\n"); + return; + } + if(boost::filesystem::exists(cpp_main_path)) { + Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n"); + return; + } + std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n"; + std::string cpp_main="#include \n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n"; + if(juci::filesystem::write(cmakelists_path, cmakelists) && juci::filesystem::write(cpp_main_path, cpp_main)) { + Singleton::directories()->open(project_path); + notebook.open(cpp_main_path); + Singleton::terminal()->print("C++ project "+project_name+" created.\n"); + } + else + Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n"); }); menu.action_group->add(Gtk::Action::create("FileOpenFile", "Open File"), Gtk::AccelKey(menu.key_map["open_file"]), [this]() { - open_file_dialog(); + notebook.open(Dialog::select_file()); }); menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() { - open_folder_dialog(); + Singleton::directories()->open(Dialog::select_folder()); }); menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { - save_file_dialog(); + auto path = Dialog::save_file(); + if(path.size()>0) { + std::ofstream file(path); + if(file) { + file << notebook.get_current_view()->get_buffer()->get_text(); + file.close(); + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + notebook.open(path); + Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); + } + else + Singleton::terminal()->print("Error saving file\n"); + } }); menu.action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu.key_map["save"]), [this]() { @@ -301,7 +365,7 @@ void Window::create_menu() { if(content!="") { last_run_command=content; Singleton::terminal()->async_print("Running: "+content+'\n'); - Singleton::terminal()->async_execute(content, directories.current_path, [this, content](int exit_code){ + Singleton::terminal()->async_execute(content, Singleton::directories()->current_path, [this, content](int exit_code){ Singleton::terminal()->async_print(content+" returned: "+boost::lexical_cast(exit_code)+'\n'); }); } @@ -388,173 +452,6 @@ void Window::hide() { Gtk::Window::hide(); } -void Window::new_file_dialog() { - Gtk::FileChooserDialog dialog("Please create a new file", Gtk::FILE_CHOOSER_ACTION_SAVE); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Save", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path path = dialog.get_filename(); - if(path!="") { - if(boost::filesystem::exists(path)) { - Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); - } - else { - if(juci::filesystem::write(path)) { - if(directories.current_path!="") - directories.update(); - notebook.open(path.string()); - Singleton::terminal()->print("New file "+path.string()+" created.\n"); - } - else - Singleton::terminal()->print("Error: could not create new file "+path.string()+".\n"); - } - } - } -} - -void Window::new_folder_dialog() { - auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - Gtk::FileChooserDialog dialog("Please create a new folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Create", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path path=dialog.get_filename(); - if(boost::filesystem::last_write_time(path)>=time_now) { - if(directories.current_path!="") - directories.update(); - Singleton::terminal()->print("New folder "+path.string()+" created.\n"); - } - else - Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); - directories.select(path); - } -} - -void Window::new_cpp_project_dialog() { - Gtk::FileChooserDialog dialog("Please create and/or choose a folder", Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Create", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - boost::filesystem::path project_path=dialog.get_filename(); - auto project_name=project_path.filename().string(); - for(size_t c=0;cprint("Error: "+cmakelists_path.string()+" already exists.\n"); - return; - } - if(boost::filesystem::exists(cpp_main_path)) { - Singleton::terminal()->print("Error: "+cpp_main_path.string()+" already exists.\n"); - return; - } - std::string cmakelists="cmake_minimum_required(VERSION 2.8)\n\nproject("+project_name+")\n\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -std=c++1y -Wall\")\n\nadd_executable("+project_name+" main.cpp)\n"; - std::string cpp_main="#include \n\nusing namespace std;\n\nint main() {\n cout << \"Hello World!\" << endl;\n\n return 0;\n}\n"; - if(juci::filesystem::write(cmakelists_path, cmakelists) && juci::filesystem::write(cpp_main_path, cpp_main)) { - directories.open(project_path); - notebook.open(cpp_main_path); - Singleton::terminal()->print("C++ project "+project_name+" created.\n"); - } - else - Singleton::terminal()->print("Error: Could not create project "+project_path.string()+"\n"); - } -} - -void Window::open_folder_dialog() { - Gtk::FileChooserDialog dialog("Please choose a folder", Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_OK); - - int result = dialog.run(); - - if(result==Gtk::RESPONSE_OK) { - std::string project_path=dialog.get_filename(); - directories.open(project_path); - } -} - -void Window::open_file_dialog() { - Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN); - if(directories.current_path!="") - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), directories.current_path.string().c_str()); - else - gtk_file_chooser_set_current_folder((GtkFileChooser*)dialog.gobj(), boost::filesystem::current_path().string().c_str()); - dialog.set_transient_for(*this); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Open", Gtk::RESPONSE_OK); - - int result = dialog.run(); - - if(result==Gtk::RESPONSE_OK) { - std::string path = dialog.get_filename(); - notebook.open(path); - } -} - -void Window::save_file_dialog() { - if(notebook.get_current_page()==-1) - return; - Gtk::FileChooserDialog dialog(*this, "Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE); - gtk_file_chooser_set_filename((GtkFileChooser*)dialog.gobj(), notebook.get_current_view()->file_path.string().c_str()); - dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS); - dialog.add_button("Cancel", Gtk::RESPONSE_CANCEL); - dialog.add_button("Save", Gtk::RESPONSE_OK); - - int result = dialog.run(); - if(result==Gtk::RESPONSE_OK) { - auto path = dialog.get_filename(); - if(path.size()>0) { - std::ofstream file(path); - if(file) { - file << notebook.get_current_view()->get_buffer()->get_text(); - file.close(); - if(directories.current_path!="") - directories.update(); - notebook.open(path); - Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); - } - else - Singleton::terminal()->print("Error saving file\n"); - } - } -} - void Window::search_and_replace_entry() { entry_box.clear(); entry_box.labels.emplace_back(); diff --git a/src/window.h b/src/window.h index 5c8b349..5cfb91f 100644 --- a/src/window.h +++ b/src/window.h @@ -12,7 +12,6 @@ class Window : public Gtk::Window { public: Window(); - Directories directories; Notebook notebook; class Config { public: @@ -41,12 +40,6 @@ private: void create_menu(); void hide(); - void new_file_dialog(); - void new_folder_dialog(); - void new_cpp_project_dialog(); - void open_folder_dialog(); - void open_file_dialog(); - void save_file_dialog(); void search_and_replace_entry(); void goto_line_entry(); void rename_token_entry(); From 9df554750540bdfe1b14a223bdddd784624fe45f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Sun, 13 Sep 2015 21:25:18 +0200 Subject: [PATCH 02/14] Change implementation to Vista and up --- src/dialogs_win.cc | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index f245f31..c9e6f57 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,33 +1,26 @@ #include "dialogs.h" -#include -#include +#include +#include +#include +#include + +#ifndef check(__fun__) +#define MESSAGE "An error occurred when trying open windows dialog" +#define check(__fun__) auto __hr__ = __fun__; if(FAILED(__hr__)) Singleton::terminal()->print(MESSAGE) +#endif + std::string Dialog::select_folder() { - char selected_folder[MAX_PATH]; - char init_path[MAX_PATH]; - auto title = "Please select a folder"; - selected_folder[0] = 0; - init_path[0] = 0; - - BROWSEINFOA browse; - browse.hwndOwner = 0; - browse.pidlRoot = NULL; - browse.lpszTitle = title; - browse.pszDisplayName = init_path; - browse.ulFlags = 0; - browse.lpfn = NULL; - auto result = SHBrowseForFolder(&browse); + IFileOpenDialog *dialog = nullptr; + check(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))); + DWORD options; + check(dialog->GetOptions(&options)); - if(result) - SHGetPathFromIDListA(result, selected_folder); - - std::string dir(selected_folder); - return dir; } /* std::string Dialog::new_file() { return open_dialog("Please create a new file", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, + {std::make_pair("Cancel", Gtk::RESPONSECANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, Gtk::FILE_CHOOSER_ACTION_SAVE); } From ddeeb1998906bd9bf11671d98427be84dd12465b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 21 Sep 2015 18:42:22 +0200 Subject: [PATCH 03/14] Vista implementation of pick folder --- src/CMakeLists.txt | 6 ++-- src/dialogs_win.cc | 81 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index deec0b9..7bf09cc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -93,18 +93,18 @@ set(source_files juci.h cmake.cc) if(MSYS) - list(APPEND source_files terminal_win.cc dialogs_win.cc) + list(APPEND source_files terminal_win.cc) list(APPEND source_files dialogs_win.cc) message("MSYS detected") else() - list(APPEND source_files terminal.cc dialogs.cc) + list(APPEND source_files terminal.cc) list(APPEND source_files dialogs.cc) message("UNIX detected") endif() if(${validation}) add_executable(${project_name} ${source_files}) - + # add_library(${module} SHARED # api # api_ext) diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index c9e6f57..acf03bd 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,45 +1,78 @@ #include "dialogs.h" +#include #include #include #include -#include +#include "singletons.h" +#include -#ifndef check(__fun__) +#ifndef check #define MESSAGE "An error occurred when trying open windows dialog" -#define check(__fun__) auto __hr__ = __fun__; if(FAILED(__hr__)) Singleton::terminal()->print(MESSAGE) +HRESULT __hr__; +#define check(__fun__) __hr__ = __fun__; if(FAILED(__hr__)) Singleton::terminal()->print(MESSAGE) #endif +class win_string { + public: + win_string() : str(nullptr) { } + ~win_string() { CoTaskMemFree(static_cast(str)); } + std::string operator()(){ + std::string res; + if (str != nullptr) { + std::wstringstream ss; + ss << str; + res = std::string(ss.str().begin(), ss.str().end()); + } + return res; + } + wchar_t** operator&() { return &str; } + private: + wchar_t* str; +}; -std::string Dialog::select_folder() { - IFileOpenDialog *dialog = nullptr; - check(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))); - DWORD options; - check(dialog->GetOptions(&options)); +class CommonDialog { + public: + CommonDialog() : dialog(nullptr) { + check(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))); + check(dialog->GetOptions(&options)); + } + CommonDialog(const std::string &title, unsigned option) : CommonDialog() { + set_title(title); + add_option(option); + } + void set_title(const std::string &title) { check(dialog->SetTitle(title)); } + void add_option(unsigned option) { check(dialog->SetOptions(options | option)); } + std::string show() { + check(dialog->Show(nullptr)); + IShellItem *result = nullptr; + check(dialog->GetResult(&result)); + win_string str; + check(result->GetDisplayName(SIGDN_FILESYSPATH, &str));; + result->Release(); + return str(); + } + private: + IFileOpenDialog * dialog; + DWORD options; +}; + +std::string Dialog::select_folder() { + return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); } -/* + std::string Dialog::new_file() { - return open_dialog("Please create a new file", - {std::make_pair("Cancel", Gtk::RESPONSECANCEL), std::make_pair("Save", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_SAVE); + return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::new_folder() { - return open_dialog("Please create a new folder", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Create", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_CREATE_FOLDER); + return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::select_file() { - return open_dialog("Please choose a folder", - {std::make_pair("Cancel", Gtk::RESPONSE_CANCEL),std::make_pair("Select", Gtk::RESPONSE_OK)}, - Gtk::FILE_CHOOSER_ACTION_OPEN); + return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); } std::string Dialog::save_file() { - 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_OPEN); -} - -*/ \ No newline at end of file + return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); +} \ No newline at end of file From 317e5a8528be28cd0f586b71cbe1cd251c578c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 21 Sep 2015 19:19:47 +0200 Subject: [PATCH 04/14] Rename logging function due to namespace conflict --- src/config.cc | 4 ++-- src/directories.cc | 14 +++++++------- src/juci.cc | 2 +- src/logging.h | 14 +++++++------- src/notebook.cc | 18 +++++++++--------- src/source.cc | 6 +++--- src/terminal.cc | 8 ++++---- src/window.cc | 4 ++-- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/config.cc b/src/config.cc index d7bcaa1..75e750c 100644 --- a/src/config.cc +++ b/src/config.cc @@ -65,7 +65,7 @@ void MainConfig::GenerateSource() { void MainConfig::GenerateDirectoryFilter() { auto dir_cfg=Singleton::Config::directories(); - DEBUG("Fetching directory filter"); + JDEBUG("Fetching directory filter"); boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter"); boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); @@ -73,5 +73,5 @@ void MainConfig::GenerateDirectoryFilter() { dir_cfg->exceptions.emplace_back(i.second.get_value()); for ( auto &i : ignore_json ) dir_cfg->ignored.emplace_back(i.second.get_value()); - DEBUG("Directory filter fetched"); + JDEBUG("Directory filter fetched"); } diff --git a/src/directories.cc b/src/directories.cc index 5a761a4..5416936 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -23,7 +23,7 @@ namespace sigc { } Directories::Directories() : stop_update_thread(false) { - DEBUG("start"); + JDEBUG("start"); add(tree_view); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); tree_store = Gtk::TreeStore::create(column_record); @@ -120,7 +120,7 @@ Directories::~Directories() { } void Directories::open(const boost::filesystem::path& dir_path) { - DEBUG("start"); + JDEBUG("start"); if(dir_path=="") return; @@ -142,21 +142,21 @@ void Directories::open(const boost::filesystem::path& dir_path) { current_path=dir_path; - DEBUG("end"); + JDEBUG("end"); } void Directories::update() { - DEBUG("start"); + JDEBUG("start"); update_mutex.lock(); for(auto &last_write_time: last_write_times) { add_path(last_write_time.first, last_write_time.second.first); } update_mutex.unlock(); - DEBUG("end"); + JDEBUG("end"); } void Directories::select(const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); if(current_path=="") return; @@ -196,7 +196,7 @@ void Directories::select(const boost::filesystem::path &path) { } return false; }); - DEBUG("end"); + JDEBUG("end"); } bool Directories::ignored(std::string path) { diff --git a/src/juci.cc b/src/juci.cc index c83eb47..c4164bc 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -9,7 +9,7 @@ void init_logging() { boost::log::add_common_attributes(); boost::log::add_file_log(boost::log::keywords::file_name = Singleton::log_dir() + "juci.log", boost::log::keywords::auto_flush = true); - INFO("Logging initalized"); + JINFO("Logging initalized"); } int app::on_command_line(const Glib::RefPtr &cmd) { diff --git a/src/logging.h b/src/logging.h index fbd9f89..7fd780b 100644 --- a/src/logging.h +++ b/src/logging.h @@ -15,12 +15,12 @@ #define INFO_VAR(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define WARNING_VAR(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define FATAL_VAR(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define ERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define TRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define DEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define INFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define WARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define FATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define ERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; +#define JTRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JDEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JINFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JWARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JFATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; #endif // JUCI_LOGGING_H_ diff --git a/src/notebook.cc b/src/notebook.cc index 40b9874..041f8c1 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -48,7 +48,7 @@ Source::View* Notebook::get_current_view() { } void Notebook::open(const boost::filesystem::path &file_path) { - DEBUG("start"); + JDEBUG("start"); for(int c=0;cfile_path) { set_current_page(c); @@ -124,13 +124,13 @@ void Notebook::open(const boost::filesystem::path &file_path) { set_tab_label_text(*(get_nth_page(page)), title); }); - DEBUG("end"); + JDEBUG("end"); } bool Notebook::save(int page, bool reparse_needed) { - DEBUG("start"); + JDEBUG("start"); if(page>=size()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } auto view=get_view(page); @@ -166,12 +166,12 @@ bool Notebook::save(int page, bool reparse_needed) { } } } - DEBUG("end true"); + JDEBUG("end true"); return true; } Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n"); } - DEBUG("end false"); + JDEBUG("end false"); return false; } @@ -182,11 +182,11 @@ bool Notebook::save_current() { } bool Notebook::close_current_page() { - DEBUG("start"); + JDEBUG("start"); if (get_current_page()!=-1) { if(get_current_view()->get_buffer()->get_modified()){ if(!save_modified_dialog()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } } @@ -202,7 +202,7 @@ bool Notebook::close_current_page() { scrolled_windows.erase(scrolled_windows.begin()+index); hboxes.erase(hboxes.begin()+index); } - DEBUG("end true"); + JDEBUG("end true"); return true; } diff --git a/src/source.cc b/src/source.cc index 98cb8ff..b25a30c 100644 --- a/src/source.cc +++ b/src/source.cc @@ -972,7 +972,7 @@ clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): Source::View(file_path, language), project_path(project_path), parse_error(false) { - DEBUG("start"); + JDEBUG("start"); auto scheme = get_source_buffer()->get_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); for (auto &item : Singleton::Config::source()->clang_types) { @@ -991,7 +991,7 @@ Source::View(file_path, language), project_path(project_path), parse_error(false // // if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background(); // // if (style->property_underline_set()) tag->property_underline() = style->property_underline(); } else - INFO("Style " + item.second + " not found in " + scheme->get_name()); + JINFO("Style " + item.second + " not found in " + scheme->get_name()); } } @@ -1039,7 +1039,7 @@ Source::View(file_path, language), project_path(project_path), parse_error(false bracket_regex=std::regex(std::string("^(")+tab_char+"*).*\\{ *$"); no_bracket_statement_regex=std::regex(std::string("^(")+tab_char+"*)(if|for|else if|catch|while) *\\(.*[^;}] *$"); no_bracket_no_para_statement_regex=std::regex(std::string("^(")+tab_char+"*)(else|try|do) *$"); - DEBUG("end"); + JDEBUG("end"); } Source::ClangViewParse::~ClangViewParse() { diff --git a/src/terminal.cc b/src/terminal.cc index eb96fcf..7cee28b 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -154,7 +154,7 @@ Terminal::Terminal() { } int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); @@ -192,14 +192,14 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path close(stdout_fd); close(stderr_fd); - DEBUG("end"); + JDEBUG("end"); return exit_code; } } void Terminal::async_execute(const std::string &command, const boost::filesystem::path &path, std::function callback) { std::thread async_execute_thread([this, command, path, callback](){ - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; async_executes_mutex.lock(); stdin_buffer.clear(); @@ -254,7 +254,7 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem if(callback) callback(exit_code); - DEBUG("end"); + JDEBUG("end"); } }); async_execute_thread.detach(); diff --git a/src/window.cc b/src/window.cc index 0daf779..8ac72a6 100644 --- a/src/window.cc +++ b/src/window.cc @@ -32,7 +32,7 @@ void Window::generate_keybindings() { } Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) { - DEBUG("start"); + JDEBUG("start"); set_title("juCi++"); set_default_size(600, 400); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); @@ -133,7 +133,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::director about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); - DEBUG("end"); + JDEBUG("end"); } // Window constructor void Window::create_menu() { From 2ea1e1821abf88c1b5ff1b42ac67fdd24dadfb64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 21 Sep 2015 19:19:47 +0200 Subject: [PATCH 05/14] Rename logging function due to namespace conflict --- src/config.cc | 4 ++-- src/directories.cc | 14 +++++++------- src/juci.cc | 2 +- src/logging.h | 14 +++++++------- src/notebook.cc | 18 +++++++++--------- src/source.cc | 6 +++--- src/terminal.cc | 8 ++++---- src/terminal_win.cc | 4 ++-- src/window.cc | 4 ++-- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/config.cc b/src/config.cc index d7bcaa1..75e750c 100644 --- a/src/config.cc +++ b/src/config.cc @@ -65,7 +65,7 @@ void MainConfig::GenerateSource() { void MainConfig::GenerateDirectoryFilter() { auto dir_cfg=Singleton::Config::directories(); - DEBUG("Fetching directory filter"); + JDEBUG("Fetching directory filter"); boost::property_tree::ptree dir_json = cfg.get_child("directoryfilter"); boost::property_tree::ptree ignore_json = dir_json.get_child("ignore"); boost::property_tree::ptree except_json = dir_json.get_child("exceptions"); @@ -73,5 +73,5 @@ void MainConfig::GenerateDirectoryFilter() { dir_cfg->exceptions.emplace_back(i.second.get_value()); for ( auto &i : ignore_json ) dir_cfg->ignored.emplace_back(i.second.get_value()); - DEBUG("Directory filter fetched"); + JDEBUG("Directory filter fetched"); } diff --git a/src/directories.cc b/src/directories.cc index 5a761a4..5416936 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -23,7 +23,7 @@ namespace sigc { } Directories::Directories() : stop_update_thread(false) { - DEBUG("start"); + JDEBUG("start"); add(tree_view); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); tree_store = Gtk::TreeStore::create(column_record); @@ -120,7 +120,7 @@ Directories::~Directories() { } void Directories::open(const boost::filesystem::path& dir_path) { - DEBUG("start"); + JDEBUG("start"); if(dir_path=="") return; @@ -142,21 +142,21 @@ void Directories::open(const boost::filesystem::path& dir_path) { current_path=dir_path; - DEBUG("end"); + JDEBUG("end"); } void Directories::update() { - DEBUG("start"); + JDEBUG("start"); update_mutex.lock(); for(auto &last_write_time: last_write_times) { add_path(last_write_time.first, last_write_time.second.first); } update_mutex.unlock(); - DEBUG("end"); + JDEBUG("end"); } void Directories::select(const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); if(current_path=="") return; @@ -196,7 +196,7 @@ void Directories::select(const boost::filesystem::path &path) { } return false; }); - DEBUG("end"); + JDEBUG("end"); } bool Directories::ignored(std::string path) { diff --git a/src/juci.cc b/src/juci.cc index c83eb47..c4164bc 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -9,7 +9,7 @@ void init_logging() { boost::log::add_common_attributes(); boost::log::add_file_log(boost::log::keywords::file_name = Singleton::log_dir() + "juci.log", boost::log::keywords::auto_flush = true); - INFO("Logging initalized"); + JINFO("Logging initalized"); } int app::on_command_line(const Glib::RefPtr &cmd) { diff --git a/src/logging.h b/src/logging.h index fbd9f89..7fd780b 100644 --- a/src/logging.h +++ b/src/logging.h @@ -15,12 +15,12 @@ #define INFO_VAR(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define WARNING_VAR(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; #define FATAL_VAR(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define ERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; -#define TRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define DEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define INFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define WARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define FATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; -#define ERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR_VAR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): " << #x << "=<" << x << ">"; +#define JTRACE(x) BOOST_LOG_TRIVIAL(trace) << "** Trace: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JDEBUG(x) BOOST_LOG_TRIVIAL(debug) << "** Debug: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JINFO(x) BOOST_LOG_TRIVIAL(info) << "** Info: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JWARNING(x) BOOST_LOG_TRIVIAL(warning) << "** Warning: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JFATAL(x) BOOST_LOG_TRIVIAL(fatal) << "** Fatal: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; +#define JERROR(x) BOOST_LOG_TRIVIAL(error) << "** Error: " << __FILE__ << "@" << __func__ << "(" << __LINE__ << "): \"" << x << "\""; #endif // JUCI_LOGGING_H_ diff --git a/src/notebook.cc b/src/notebook.cc index 40b9874..041f8c1 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -48,7 +48,7 @@ Source::View* Notebook::get_current_view() { } void Notebook::open(const boost::filesystem::path &file_path) { - DEBUG("start"); + JDEBUG("start"); for(int c=0;cfile_path) { set_current_page(c); @@ -124,13 +124,13 @@ void Notebook::open(const boost::filesystem::path &file_path) { set_tab_label_text(*(get_nth_page(page)), title); }); - DEBUG("end"); + JDEBUG("end"); } bool Notebook::save(int page, bool reparse_needed) { - DEBUG("start"); + JDEBUG("start"); if(page>=size()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } auto view=get_view(page); @@ -166,12 +166,12 @@ bool Notebook::save(int page, bool reparse_needed) { } } } - DEBUG("end true"); + JDEBUG("end true"); return true; } Singleton::terminal()->print("Error: could not save file " +view->file_path.string()+"\n"); } - DEBUG("end false"); + JDEBUG("end false"); return false; } @@ -182,11 +182,11 @@ bool Notebook::save_current() { } bool Notebook::close_current_page() { - DEBUG("start"); + JDEBUG("start"); if (get_current_page()!=-1) { if(get_current_view()->get_buffer()->get_modified()){ if(!save_modified_dialog()) { - DEBUG("end false"); + JDEBUG("end false"); return false; } } @@ -202,7 +202,7 @@ bool Notebook::close_current_page() { scrolled_windows.erase(scrolled_windows.begin()+index); hboxes.erase(hboxes.begin()+index); } - DEBUG("end true"); + JDEBUG("end true"); return true; } diff --git a/src/source.cc b/src/source.cc index 98cb8ff..b25a30c 100644 --- a/src/source.cc +++ b/src/source.cc @@ -972,7 +972,7 @@ clang::Index Source::ClangViewParse::clang_index(0, 0); Source::ClangViewParse::ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language): Source::View(file_path, language), project_path(project_path), parse_error(false) { - DEBUG("start"); + JDEBUG("start"); auto scheme = get_source_buffer()->get_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); for (auto &item : Singleton::Config::source()->clang_types) { @@ -991,7 +991,7 @@ Source::View(file_path, language), project_path(project_path), parse_error(false // // if (style->property_line_background_set()) tag->property_line_background() = style->property_line_background(); // // if (style->property_underline_set()) tag->property_underline() = style->property_underline(); } else - INFO("Style " + item.second + " not found in " + scheme->get_name()); + JINFO("Style " + item.second + " not found in " + scheme->get_name()); } } @@ -1039,7 +1039,7 @@ Source::View(file_path, language), project_path(project_path), parse_error(false bracket_regex=std::regex(std::string("^(")+tab_char+"*).*\\{ *$"); no_bracket_statement_regex=std::regex(std::string("^(")+tab_char+"*)(if|for|else if|catch|while) *\\(.*[^;}] *$"); no_bracket_no_para_statement_regex=std::regex(std::string("^(")+tab_char+"*)(else|try|do) *$"); - DEBUG("end"); + JDEBUG("end"); } Source::ClangViewParse::~ClangViewParse() { diff --git a/src/terminal.cc b/src/terminal.cc index eb96fcf..7cee28b 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -154,7 +154,7 @@ Terminal::Terminal() { } int Terminal::execute(const std::string &command, const boost::filesystem::path &path) { - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; auto pid=popen3(command, path.string(), &stdin_fd, &stdout_fd, &stderr_fd); @@ -192,14 +192,14 @@ int Terminal::execute(const std::string &command, const boost::filesystem::path close(stdout_fd); close(stderr_fd); - DEBUG("end"); + JDEBUG("end"); return exit_code; } } void Terminal::async_execute(const std::string &command, const boost::filesystem::path &path, std::function callback) { std::thread async_execute_thread([this, command, path, callback](){ - DEBUG("start"); + JDEBUG("start"); int stdin_fd, stdout_fd, stderr_fd; async_executes_mutex.lock(); stdin_buffer.clear(); @@ -254,7 +254,7 @@ void Terminal::async_execute(const std::string &command, const boost::filesystem if(callback) callback(exit_code); - DEBUG("end"); + JDEBUG("end"); } }); async_execute_thread.detach(); diff --git a/src/terminal_win.cc b/src/terminal_win.cc index e79014d..8cd9238 100644 --- a/src/terminal_win.cc +++ b/src/terminal_win.cc @@ -332,7 +332,7 @@ void Terminal::kill_async_executes(bool force) { } int Terminal::print(const std::string &message, bool bold){ - INFO("Terminal: PrintMessage"); + JINFO("Terminal: PrintMessage"); if(bold) get_buffer()->insert_with_tag(get_buffer()->end(), message, bold_tag); else @@ -349,7 +349,7 @@ int Terminal::print(const std::string &message, bool bold){ } void Terminal::print(int line_nr, const std::string &message){ - INFO("Terminal: PrintMessage at line " << line_nr); + JINFO("Terminal: PrintMessage at line " << line_nr); auto iter=get_buffer()->get_iter_at_line(line_nr); while(!iter.ends_line()) iter++; diff --git a/src/window.cc b/src/window.cc index 0daf779..8ac72a6 100644 --- a/src/window.cc +++ b/src/window.cc @@ -32,7 +32,7 @@ void Window::generate_keybindings() { } Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) { - DEBUG("start"); + JDEBUG("start"); set_title("juCi++"); set_default_size(600, 400); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); @@ -133,7 +133,7 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::director about.set_comments("This is an open source IDE with high-end features to make your programming experience juicy"); about.set_license_type(Gtk::License::LICENSE_MIT_X11); about.set_transient_for(*this); - DEBUG("end"); + JDEBUG("end"); } // Window constructor void Window::create_menu() { From f9269690cb31cd3b315cc8000d5c706d27be7311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 21 Sep 2015 19:56:04 +0200 Subject: [PATCH 06/14] Create enum for options --- src/dialogs_win.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index acf03bd..e6ab2fc 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -57,22 +57,31 @@ class CommonDialog { DWORD options; }; +enum FILEOPENOPTIONS { + OVERWRITEPROMPT = 0x2, STRICTFILETYPES = 0x4, NOCHANGEDIR = 0x8, PICKFOLDERS = 0x20, + FORCEFILESYSTEM = 0x40, ALLNONSTORAGEITEMS = 0x80, NOVALIDATE = 0x100, ALLOWMULTISELECT = 0x200, + PATHMUSTEXIST = 0x800, FILEMUSTEXIST = 0x1000, CREATEPROMPT = 0x2000, SHAREAWARE = 0x4000, + NOREADONLYRETURN = 0x8000, NOTESTFILECREATE = 0x10000, HIDEMRUPLACES = 0x20000, + HIDEPINNEDPLACES = 0x40000, NODEREFERENCELINKS = 0x100000, DONTADDTORECENT = 0x2000000, + FORCESHOWHIDDEN = 0x10000000, DEFAULTNOMINIMODE = 0x20000000, FORCEPREVIEWPANEON = 0x40000000 +}; + std::string Dialog::select_folder() { - return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); + return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); } std::string Dialog::new_file() { - return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); + return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); } std::string Dialog::new_folder() { - return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); + return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); } std::string Dialog::select_file() { - return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); + return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); } std::string Dialog::save_file() { - return (CommonDialog("Please select a folder", FOS_PICKFOLDERS)).show(); + return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); } \ No newline at end of file From 893ebe79bf501ada8e4e073bc1b671ce6ddb27ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Mon, 28 Sep 2015 22:42:55 +0200 Subject: [PATCH 07/14] Better fault toleranse when exitin dialogs unusually --- src/CMakeLists.txt | 6 ++-- src/dialogs.cc | 2 +- src/dialogs_win.cc | 77 ++++------------------------------------------ src/singletons.h | 6 ++-- src/window.cc | 26 +++++++++++----- 5 files changed, 33 insertions(+), 84 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7bf09cc..db08352 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,7 +88,6 @@ set(source_files juci.h tooltips.cc singletons.h singletons.cc - dialogs.h cmake.h cmake.cc) @@ -98,6 +97,7 @@ if(MSYS) message("MSYS detected") else() list(APPEND source_files terminal.cc) + list(APPEND source_files dialogs.h) list(APPEND source_files dialogs.cc) message("UNIX detected") endif() @@ -115,6 +115,7 @@ if(${validation}) ${GTKMM_INCLUDE_DIRS} ${GTKSVMM_INCLUDE_DIRS} ${LCL_INCLUDE_DIRS} + "C:/msys64/mingw64/include/dialogs" ${LIBCLANG_INCLUDE_DIRS} ${ASPELL_INCLUDE_DIR}) @@ -124,6 +125,7 @@ if(${validation}) ${Boost_LIBRARY_DIRS} # ${PYTHON_INCLUDE_DIRS} ${LCL_LIBRARY_DIRS} + C:/msys64/mingw64/bin ${LIBCLANG_LIBRARY_DIRS}) # set_target_properties(${module} @@ -132,11 +134,11 @@ if(${validation}) # target_link_libraries(${module} ${PYTHON_LIBRARIES} ${Boost_LIBRARIES}) # target_link_libraries(${module} ${Boost_LIBRARIES}) - target_link_libraries(${project_name} ${LIBCLANG_LIBRARIES} ${LCL_LIBRARIES} ${GTKMM_LIBRARIES} + "C:/msys64/mingw64/bin/libdialogs.dll" ${GTKSVMM_LIBRARIES} ${Boost_LIBRARIES} ${ASPELL_LIBRARIES} diff --git a/src/dialogs.cc b/src/dialogs.cc index 8ff3882..e1e424f 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -1,4 +1,4 @@ -#include "dialogs.h" +#include #include "singletons.h" #include #include diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index e6ab2fc..24133b1 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,87 +1,22 @@ #include "dialogs.h" -#include -#include -#include -#include -#include "singletons.h" -#include - -#ifndef check -#define MESSAGE "An error occurred when trying open windows dialog" -HRESULT __hr__; -#define check(__fun__) __hr__ = __fun__; if(FAILED(__hr__)) Singleton::terminal()->print(MESSAGE) -#endif - -class win_string { - public: - win_string() : str(nullptr) { } - ~win_string() { CoTaskMemFree(static_cast(str)); } - std::string operator()(){ - std::string res; - if (str != nullptr) { - std::wstringstream ss; - ss << str; - res = std::string(ss.str().begin(), ss.str().end()); - } - return res; - } - wchar_t** operator&() { return &str; } - private: - wchar_t* str; -}; - -class CommonDialog { - public: - CommonDialog() : dialog(nullptr) { - check(CoCreateInstance(CLSID_FileOpenDialog, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dialog))); - check(dialog->GetOptions(&options)); - } - CommonDialog(const std::string &title, unsigned option) : CommonDialog() { - set_title(title); - add_option(option); - } - void set_title(const std::string &title) { check(dialog->SetTitle(title)); } - void add_option(unsigned option) { check(dialog->SetOptions(options | option)); } - std::string show() { - check(dialog->Show(nullptr)); - IShellItem *result = nullptr; - check(dialog->GetResult(&result)); - win_string str; - check(result->GetDisplayName(SIGDN_FILESYSPATH, &str));; - result->Release(); - return str(); - } - - private: - IFileOpenDialog * dialog; - DWORD options; -}; - -enum FILEOPENOPTIONS { - OVERWRITEPROMPT = 0x2, STRICTFILETYPES = 0x4, NOCHANGEDIR = 0x8, PICKFOLDERS = 0x20, - FORCEFILESYSTEM = 0x40, ALLNONSTORAGEITEMS = 0x80, NOVALIDATE = 0x100, ALLOWMULTISELECT = 0x200, - PATHMUSTEXIST = 0x800, FILEMUSTEXIST = 0x1000, CREATEPROMPT = 0x2000, SHAREAWARE = 0x4000, - NOREADONLYRETURN = 0x8000, NOTESTFILECREATE = 0x10000, HIDEMRUPLACES = 0x20000, - HIDEPINNEDPLACES = 0x40000, NODEREFERENCELINKS = 0x100000, DONTADDTORECENT = 0x2000000, - FORCESHOWHIDDEN = 0x10000000, DEFAULTNOMINIMODE = 0x20000000, FORCEPREVIEWPANEON = 0x40000000 -}; +#include std::string Dialog::select_folder() { - return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); + return c_select_folder(); } std::string Dialog::new_file() { - return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); + return c_new_file(); } std::string Dialog::new_folder() { - return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); + return c_new_folder(); } std::string Dialog::select_file() { - return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); + return c_select_file(); } std::string Dialog::save_file() { - return (CommonDialog("Please select a folder", PICKFOLDERS)).show(); + return c_save_file(); } \ No newline at end of file diff --git a/src/singletons.h b/src/singletons.h index 33297ea..f4fc2be 100644 --- a/src/singletons.h +++ b/src/singletons.h @@ -26,9 +26,9 @@ public: static std::unique_ptr directories_; static std::unique_ptr terminal_; }; - static std::string config_dir() { return std::string(getenv("HOME")) + "/.juci/config/"; } - static std::string log_dir() { return std::string(getenv("HOME")) + "/.juci/log/"; } - static std::string style_dir() { return std::string(getenv("HOME")) + "/.juci/styles/"; } + static std::string config_dir() { return std::string(getenv("AppData")) + "/.juci/config/"; } + static std::string log_dir() { return std::string(getenv("AppData")) + "/.juci/log/"; } + static std::string style_dir() { return std::string(getenv("AppData")) + "/.juci/styles/"; } static Terminal *terminal(); static Directories *directories(); static Gtk::Label *status(); diff --git a/src/window.cc b/src/window.cc index 8ac72a6..7eeef82 100644 --- a/src/window.cc +++ b/src/window.cc @@ -38,6 +38,10 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::director set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(box); + auto i = Gtk::IconTheme::get_default(); + for (auto &c : i->get_search_path()) + Singleton::terminal()->print(c + "\n"); + generate_keybindings(); //PluginApi(&this->notebook, &this->menu); create_menu(); @@ -161,13 +165,17 @@ void Window::create_menu() { menu.action_group->add(Gtk::Action::create("FileNewFolder", "New Folder"), Gtk::AccelKey(menu.key_map["new_folder"]), [this]() { auto time_now=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); boost::filesystem::path path = Dialog::new_folder(); - if(boost::filesystem::last_write_time(path)>=time_now) { - if(Singleton::directories()->current_path!="") - Singleton::directories()->update(); - Singleton::terminal()->print("New folder "+path.string()+" created.\n"); + if(boost::filesystem::exists(path)) { + if(boost::filesystem::last_write_time(path)>=time_now) { + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + Singleton::terminal()->print("New folder "+path.string()+" created.\n"); + } + else + Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); + } else { + Singleton::terminal()->print("Cancel \n"); } - else - Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); Singleton::directories()->select(path); }); menu.action_group->add(Gtk::Action::create("FileNewProject", "New Project")); @@ -204,7 +212,11 @@ void Window::create_menu() { notebook.open(Dialog::select_file()); }); menu.action_group->add(Gtk::Action::create("FileOpenFolder", "Open Folder"), Gtk::AccelKey(menu.key_map["open_folder"]), [this]() { - Singleton::directories()->open(Dialog::select_folder()); + auto path = Dialog::select_folder(); + if (boost::filesystem::exists(path)) + Singleton::directories()->open(path); + else + Singleton::terminal()->print("Cancel \n"); }); menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { auto path = Dialog::save_file(); From 90ab171054db4383143c1a606b7c659bbcba5f05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 8 Oct 2015 15:09:11 +0200 Subject: [PATCH 08/14] More dynamic cmakelists and guarding of windows code --- src/CMakeLists.txt | 12 ++++++++++-- src/dialogs_win.cc | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 82e9cfe..aa08c91 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -70,6 +70,7 @@ set(source_files juci.h sourcefile.cc window.cc window.h + dialogs.h # api.h # api.cc notebook.cc @@ -88,11 +89,16 @@ set(source_files juci.h if(MSYS) list(APPEND source_files terminal_win.cc) - list(APPEND source_files dialogs_win.cc) + list(APPEND source_files dialogs_win.cc) + set(DIALOGS_INCLUDE_DIRS "../WIN-packages/") + # if (64 bit) + set(DIALOGS_LIBRARY_DIRS "../WIN-packages/x64/libdialogs.dll") + # else + # set(DIALOGS_LIBRARY_DIRS "../WIN-packages/x32/libdialogs.dll") + #TODO figure out how to do this.... message("MSYS detected") else() list(APPEND source_files terminal.cc) - list(APPEND source_files dialogs.h) list(APPEND source_files dialogs.cc) message("UNIX detected") endif() @@ -110,6 +116,7 @@ if(${validation}) ${GTKMM_INCLUDE_DIRS} ${GTKSVMM_INCLUDE_DIRS} ${LCL_INCLUDE_DIRS} + ${DIALOGS_INCLUDE_DIRS} ${LIBCLANG_INCLUDE_DIRS} ${ASPELL_INCLUDE_DIR}) @@ -134,6 +141,7 @@ if(${validation}) ${GTKSVMM_LIBRARIES} ${Boost_LIBRARIES} ${ASPELL_LIBRARIES} + ${DIALOGS_LIBRARIES} # ${PYTHON_LIBRARIES} ) diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index 24133b1..dd3ed51 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,3 +1,4 @@ +#ifdef _WIN32 #include "dialogs.h" #include @@ -19,4 +20,5 @@ std::string Dialog::select_file() { std::string Dialog::save_file() { return c_save_file(); -} \ No newline at end of file +} +#endif \ No newline at end of file From ec7f35e392ca35b874aa7d6137482797be88bd43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 8 Oct 2015 15:33:51 +0200 Subject: [PATCH 09/14] Add precompiled libraries --- WIN-packages/x64/libdialogs.dll | Bin 0 -> 74752 bytes WIN-packages/x86/libdialogs.dll | Bin 0 -> 26624 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 WIN-packages/x64/libdialogs.dll create mode 100644 WIN-packages/x86/libdialogs.dll diff --git a/WIN-packages/x64/libdialogs.dll b/WIN-packages/x64/libdialogs.dll new file mode 100644 index 0000000000000000000000000000000000000000..79bce1bbfa13b57360df67271a6cf37b0e96dc6e GIT binary patch literal 74752 zcmeEv30PCd*Y^z&KoJwrD7Z$&inUr4wJKT@7QK<6xLa3TP^<_Pg1Z()Dlw+wzAvqH zsaEU0*MbY+4p_Ikp;irI6>Y1y)O^1)H#Y>t+WwdKd*1Kk@?_@TGiT16Ip@sGndM$W z`lfL99LG7}XEt-(Uc_{%Soqh0vxMU+*4|%{+ga{(oxKw6={h|kM#d>)VxvdI4j!!> zIyfpSTBjTmu8fV3QjUyL26pML934F@yosx8c`pm;S+fe&we_iE28*!VR%K`}AX6H&vJec9N*}0rO zcN;l0g32mcv(O-p8}@}Wm)@&NFEOovtE+UetH^Q70huL0>sLZ7XZH!HzHo2HagGdB z6myhHLd9jrh2cTSBt~yO3y@HI33nRU8=6amB9XN%(NRh`la!GYf*1*xjJw=x9M{SQ zT=G_Vo#W=)0(~Uh1`A)dVDY|*E_|F04{eqqAeO1_CGeFT7uF09w5 zsjbG(=2F3onh0oIS_LG?Q85zKQyV1QsyHsSNsNH_jS~Q(6@E6Cis+3L@RAis zKwY>hh#e5yTq?rz@fkXN1jkjUq)-IV5m&7gyx6$dp-5sf4nsQeSEDq%@W^N&-le1% z1Vpdy8+iVJ{;#@D(UrFwMxOV$I)bZ^d!8SZnfI_Sg3&Dz6uKk0?Su;f(wHXv>1RO25lp65k2;z$Lxj(T0v%ci#!nI)IqRfI0F8C1h-)jd9OnejCV!g z(;vavP6#%ZL$LM}1Uh=W(gZ-UtSL zh@da=cauo1rqq6Q5v12du!~S~DZxO&U8-ACl29NO^gRje1;O-0xw#C%GJ<^>hTx7H z0*>(76VdmmmTnypTvZ`hMK$k5M0*ma-a!bWiODm>%V5gE6RFvRyuUGmV{H(GRYq`< zh_0l(U8%?{db~*bxK8C7TOf$gAh_2B!E2JsKEf-YyQ+f`%ydEUD?Nr%j!oVOa_BLe zf)9xCjQR-D>9H{}-lqYA9mMGrQmur@_aL*VO^W)M#1up|N~RnJN~rQag6AY09l@e0 zcv26+U}8M88iIOcNM91Yavvi2hPZk}*=~`sN~tuSvUMTyy+{z-h?iGV1RupA_?iUP zm8NJJN*N52<5x7t6hSx-}m5}{NRs%aDxJDd=k|E8Yat~3to6$a46DkYJ zBv2-Se_sN;UhC!DtGBv`x|g~)pZGw;RSDa?0ZGu-)mf} zYVpz_->3QRn#40^S?xfM)0or!Th(Y5|BN?C_@TT5ZW%^g7?p z*Q_<%<@Gu*Z{DD7%JWIbbxuGxhdQV521m-3IH{?ei&s!`C?&h_erI%!X2nBK31^EU zo1dB-=;bp#HNN}-2k@4+6M-SHsYm@(xCV)ZDxEKt{k|oSYy9GPMkghRYw4g6X$r`_Oof9i3ztP*sUIiYJm4d85@;p(u zkc2RsqW|W&{EECm=M`f>lGZSc1i|Xf+n)*YO*Nb|E3SG-xD>OZG00KvG=@`V#U+Ai z3=Uo-qD}^F9UIZfA-Z(lAgG8>JgQO;QV&%3A2jgDzi$)&4h7zjR*VB?Uu0fAEe7Ue zV_^NgBFHRaLJWnx;R$cJtoeZ~57*~GzP||e<@ZcBeH|niC_B_rYY33@iJ4|iqf|bz zP%_q)H@f<*#Y9RWg{U;faT1N+pJNDGpFtm0h559e=n?12lVVSrW;`>S^J_tu@wK%2 zp`bOk7VkXgGqY8anY| zIvD`16cfq6Bi>W0?r5Y+YHWtf+sm^SXMfVHSX)KH$#!RH|D@V}O#+P@OiVAG^_=69QpW+og*SG0X5Cn*UK%fe7ERiI`w zM&z7H&gz-T8x{KBVJQkbmMpbjP4(-KxB{=G$UP1E{3` z#wFVGWl{kN)ad$nCGqLvdz{yo=k=Wc;+@Tk0Ah(r_wB|E21}v$RjKrT6NGY=CBnGg z(o9OB*R@o7YXo|ce~X^hp!T5dF0oJ^>%tq{H0D%O3({If0Bci-Z)X4-q6K^yo&0qwPNH%FC)_$xc$`P z(NNT88cq9qsi-gEQU8CjFCm$s_N|IWID;E+uw$LHLF>jwZ)jVB5?b-*FjVbmtCIaP zWb_zIK_uVAG-t>-pty`n(APLq#cJ79%-yD9RDi~;EUg?-zbJ2NvGUHj71Jrw2Nz4< zQ9Pa5n~lB=m(7X@tUINU7lTgHtZ=6%rr+X{5L`e=9`b(c@Pyv29E9LlNo1;2`yvnZ zGVgan7f6QBT2%#RRBoml1-6z^tXWydeQH~Re-Os(PZ(KL#MnCr71V#~g9Nf8_|4wT zZ#GD)KE$){QR=qg3I5FMdwBW4&kMvehE0Fg#I<^V7{CNHZ}4G9!`tD&WR9F~!7APO zq#W6Fy@hfpwOK9l^KeoEy;==VY{Thf8uEqAsl)vf+xm0yf6$=N%5?n^)tJT+dhTOt zh-coAMa^p@ZncI$uNWqxN=!sOFnTh)U6hYfLs_eIx1=&EtxPL_B`O%!w5XErDbow0 zI`wD**m}G2L?inLF%5;z)Q2cxd4ra~yNCGT>^wIs##fYZPmf4+uKQIel{cIN|RrJ{Y1$WrJan&S^v}da}{g z-??S-rU6RMjLsLP098)#fM@qOPGM!+GsHgCtjMSU&MVq-u5Tl7-NC|j2gbE9z=|`4 zDr|slCGdz5rj=l-G}yEnuJ`+Ayi*?l>Gbe|s4#Qyj;VXEVq=2FP(Ym_y2Qk@GCtA# zdJOuP7x^t%&j_b5JCEPHX`^uQ&+hTr_t9~VslsPu2%T33-zZJ%mpay=ld&ya(B5c! zCrxegspBZfuT0E_3G*AnB(Df9>M)K^daA1}cq%BW5_M(g2_su)#hML`&DPZO^R5sIQ-hDhsXv26c_$db)!zc|onz0|yQKk9I$&{*ip0H2cK) zs>biRAn2xlEogU*Ax)4l$#)DY1Gh*JvgBPt#z1bFuNDcpg4XEJlBApwVwJM9t(5QF z6QoQwNiMbM_E}{N->-y>F;#<%hwCfE{pV%O#&1jxG0ri2Lw6s_>mxA;p$)>aunO>; zH%LPspg+*7!+3pHv_y>u{D16z@`g)nmgM^@*;iA{eC{|&F#E5KG_4_(H(X%zUL_v& zqcDI3dt(k%aULxY{0_tv<_P+o)HM+NCGrC++PF*b19|-*IOee6lWcV=>58tV_$V*c zZPZ7{P@4$l4O9m-hcL)YRmwp0cRHg|aHxM0x+V=Rl3bpiqie}0j>odaha@o{-q17z z)o?-ogzB5pf(0wUJ!@zuO?U3l@J5&x&!3Dy?3&zJ*HmE~Rl(9NLG2T59!p`V7zllj zH$0ViC*M?5+#9o~7v?ceW<{hUJT`vn3)<6+ZNVEmH9$8r775)c!IZ+d%7jSc0owzG z!E;V+z$fPB@_N2dAZ0jViXc27tuZU+64E=bH~860%SpIC=l!yXv2#)?%UHpkpZc6J z2M0$D=F*6{-7L|NX)5@Iq$cuLwN(C0CkYA6Ei^0sfO)->H$q_gB!fqfrt?y=&RfaT z=xBJXF_^T%GMHa#Tt&=;$Id0wZAwgG$qOBeT;rF<%lr$(MKHhgv4r;#!;>)P^^>6L zq^Gj!DQNH-V_P^z7y}5)jbUBE=ItrI^>~lCdT@G89hrd5x^PY66k5OuF~GcN(pewQ zdwxAyD!aq$$HP?}4ua4Ypfi-vxRnMY zi49=hF`mj%t!Q*?${^MrlWzn)ozWVO(Le_Qu*SnGgL(|it9OeA%c7M^i<0I-A!bE? zoHu|Gh)PN>sia7T)skV+%4H49%w*MVvNf}=Z%OSuDiSrcV^7*?2?@g~%5P%Pj*RL7 z&G3fvrqvz)iE^kuC1a(s z$QnlBmqhk3L$@}J{x=1I52uEK5z*2xoMUTK!>Gv`2Kqd`nl%l!x>;_xUP8iWO#+)4 z0dh7t8!Jblzfqg&cPJ7)TXl9JlRN2~I$ZBC{(q`vSmdqq@({Y75ONo3>75$H5Z=($ z13ft7PHYebvB3<)8U&d&>VoZ=F)c(yp?UL-3PQ-e#3JoEW@}=*(4mpD_MI1$TdZMV zdxiC0&rJn>>mh*Ga5Tb)O4cB7aKap?H#{7x@l>`sRFoFw*05OKS|B&=V0(a6X21WTK9* zRndkEZ*0q}WqZ&uogV(%CTaq$L_fcz$UhT&7;$L^z3qQz)S&hOHX~_%g+?N*L>MMu zcs5zKsQe1q*nDLs32VWhkgcXsq1NxLM&|zpBT$U+ZU>JzP@Gwj&Y-A20Tb2HSaDg ztvzTi3DTb|3;-Hx4;@*1upMF1B4~uQS}ytyON+pGOXe?{bWwuXFEQ<)RlLM0!@n4N z|0mjowSU6=7M%r~)5@9gPc3BA#OO}Jn-izSsFv-zxb4og}BnHfYT*yzCV?TYadEs(eJGKf7F z@zRAoTX^vokgdEtJpV3Uh{I;7#eE##63-?26B_U_$<-RL1A-YY^@coiIkAUiMMofCBXYNJLH(&z|3G+XO;c+#K{V}Jw&1tlGy(liAW<;Ix_ zKumbvUN&PLZVZ{S-8qT3+Na%g#F~lWuuB@S)#l^K@Of53doJES-AU5UY?gClCs=Gd z(cVtex|u8~6blQ!sUd#Na4?DLCZ`&B&~T|FZ^j#w+Jxr?aTODDW$Jyj$elL;ITD`3 zg-FbGQtz`TP$z&AbL|tJzY3~;T%DLEl_h-ykfpwP6X@P-x0kZ#FD>0l{&P^R;i_dx zIZTrgaEYc$8ht-!jee8|TcIe_(pfO9+iPeDG<@f^8f@`Nzsjah#?9~)-tV<;j0UHh zu&1P=C2B0M%<{qs5;SNWS)d1&0}oi7V+S0xUKn&SozCEm^S#)F*l@-i>XU+jwia)k zE@WNiK`P%q~>>T$6*S@ zz!e1B0ysCnEx<|v>@L_Bzy7}onO%B*rE2vtjNMU! zr46AC*<0F>KTj5Ka0yJtQ3Xte?Wr+&1sE%6?2jkrIU2Ig-A98-xYa)4M1ne5ZpHch zmbSI8EXfsCr1kSt$>wJW8*OMJn88px!5jl?A#_mch+yHl|5!!;C<7_RTdU{9ev9eT z;^kwNi{?%*nB)F(3Jrw29<$yZn<9rb*c54j^=Qjd80PnqbO$*!2$Liqk9lb1X*;-; z0MY_&H(>$Iy3m9<1E!fMkVxxXI~glO>ZxYMuqV_~g!Nf@EDEs~*3F6+awOfsuS6mL zND4*B#p_Qq_#zP$qDh+-+Y5?`pspwaVabDebX|)Jf$AG5EK--KZzx*1mgAqIIq3^^;rz{^7nhePa7m?~w% zy@59W@;rj7CvCZj#~F>0UN^D-e+eY{j3CPnn$+VA9%=hONQOR>^#VVm+tliVW(4{E z8mJ$=2gvuFkV&f_eFO93(Psg0vH;8kcof)bWJJ6Rc0zp5k$}`;I6t5^hTV7J44V7t^NbGRv)Q$2C*CHGH^&N$chql7GxvjA^NBo-q3Rf?{`5q zJqAMxZ=7t!!5zrJEIT6SkF?W*={R-T7{t+82hAXm&{rSU7<-|o?Tjt&!#M1alqyR; zj?ou~GN%NhSC%Cmz>~EgU~sb92?%kFbGMyv?#3AM$kh8Zi5%>h5A%A)Rs8k5RG?`M zK|g9R)2^y*l%dHkqzM_}|8y2}hUG%~4O*0yCF1Y~CeGrSP-oc}1Keg)5KJKtCIZURy<-vSgJzRA9<&I*RRG$f0Nk!m5BeV4xjh%5KI^exfdY|u z-I4>_WB~^W5;EHq+f?L5mK1}I8)$<{BfN2ZX@r*xgp-O0-#=g>>`8>*Q8RG(h^qBH zbc4evK~7Mzb1ViFR2C^@1C>vLr;^PDsP}A9&yw0qc_+xc(1(P`=*&t7vbL#5skK^9 z<__#Pz-Dy+2OZ1*Bd8XCMx1~0hR@JXzF>pEld)ZRI;ZG&Sl5BKZglg0*=(YC1R6Fg zjBsL30VA%tu;y#3Pa;RVsa&*>XOFXcY?z1>21=WGAI*`fpoIvTwKD(1+a;!#$I&hi z(5B*U+j%9CA&&uPCU9#VasN#{U_W~5gH&oi*7I9OUMorJi;u}Qoz)ssi6ALmUVc;QQ|m( z*vU|3l7G(Y`(Uv$20oQ^Wrl@ecJK^pe2fz;!htx*47yFJx8hK3!I zbD&qma0Gp5Q>ziHOdnHZhS`iBn|bJB75kVv0?JO9_2CmIdBxBOM5o9M=vgJ^lw{D; zONX7JQDOY2H~>9WN5aHPoNId%&U-sEsbr$dnF=~)#fy7LHcDT{B0~Az0xuYJ*zki> znK%s1qwB&9l1(biidK1)Los*{MVLpJe*A#rpakJyn{%vqbgd7i_A%W~CpB2kt@%S= zTH|uB1aOI&0wy(am@VA?XG-`7HV1w2`cUlPPkpc&MM7t6P6eGQg|ksmfe#WOp>hzP zZ;mrB$M7qNG~yt(nxv|2+DMVDq~c1V0FSN`Ga>!2+|)uLqrl2q^F{LoG9<_ zrG)gnne$EEFQ_43yASh+LvF}+ zw;^v8N5JR}CfOI^%qjc?r@ddkmd()6Q|kfu;@q@2i$I12FXkJFIp34Vn`(7X`5U62 zN*o8BO-8p5$Jr2a0|Q=0iK=8A;d>)Xx&s}UL_EQ9ip+qwg34Y3u6b z)yKdH@48krHAB-)a#D=0a`yByJu#EYtH*@zS{OxGhb>t5+0#yXQYU;qlGA+xWh?oN z4#Jxm`YG_p>8K1ma!1<0PftgcMTh*1sb3m%2$(x67d=|MaZn?Aex7R&LzB?mgT+327lt=XnS^+j%FNu33sebcB?2tOTN8ex(TSjo2J z0O6J*;cz0%>j!%9rPdqn`dQv^#^jBfk-JVlc!^36ggnGHn;vwQEQ_3aE0*BYw<0V$ zp(1$d%jvPqQ!mjs|D8u{8DWh;dTbDUjXMC@x8`Mc+kN`qc5S^K}_@6vvJPaX>`--?d9LArwOP!_@tmiYp_sALsJu@{zZ2)j0fN36( zV1RoJJ%1!eHk8*(SEdP_`!q(ZX9I>emeuK!^^Hdlm~?x=q|v1kP6NzWP2r%8l-l5} zJ>xAS=p$k(J*WZt3u*wsrjnfq`y=9nO;tP6RCO79T<(=c1q*T;0GYe~d6jBVvoom| zZ~7f%ER!$Y0(WM`7M3jiegu-K-`59aP!q)qg+ce=(V@@RV@XIKbkVH%?HW;1)cB5~ zkPOqrI%w(t{VQ()7_}*e%|A=(_u_sq^%niQP}MVnitG2xex~0B&{Hw}29tb5{q6u# z3H=`Wu@wC-VrKkK{U(9--`8(%;-pBw2iW7A`mKo(75a@L1wy}98Ox;Kp18yQ;m?#T zJsXbb9r~@rOhM6hBjtd8m(~6s(Qm2xblL|dM17VclP+qnji{<6_4yh*o@lS_6Nq`6 z_BxT|A?ouskV@$DAv!Q}#)`Gqj01%CPJQkI?Z2ZB60)efId&w{J*Eqk7(vC>eIEjK7*;M zCH2{457TEf_Ed`La}%jh)Mq6iS@fBBLMe8^)zR0#q0--(9N($ZTOj}URl1YelU1c2 ztc*8RI^iN!qUK4`8C2SuaZM`SzME9qh$Txu7=q+?s5FLYU$JBz5rj$$tN*uEYOa42 z25GLpn}w+t=>9MZkFqeGg_$fo!NOB4Jj22)7Ur<RJY$@`-k6JlO%;A5Pj^AjNkbt{~>&=|5!Qvuy8A&X7K%LafQiJ<>crdF z-af8=$~kBa*}6(Ulet`U*1L7gUv`+{Fbc?VV;CN8Mbz(A7^%sydNu222bp|(91DcGF4N|&Nk73KDLt%DgN`L_rr(FYQvWzIr_Oa+`(~Apsutu`S53O z+@HkTJvqXs9hc|b-SLJ5(AzakKsLQZkiJFtMrkF2V((Eed3so)E5F|Z#7#a->9oR7 zQq`naoLFw1cweIPrl3mV3uG(Ot*I>vhuzdcB-@?J^sO;uQJhx~w6RGkTYyP89%sQI zifc!BVq+N{1BHs%F&27*fUQkD_C0QD4c_pQGhTej!!i$Nng{L7yoArws8o9-iS6D$ z1fZ_`J|{}c1QQw3$^en=nKFPnJykctbPsS$OzrV(8jX9?4+7vA-S?-U#&*I`{Lur_ zF}hywj@-2&8nlmwraXa+66w3Tv2^{j?0j)$53d8!c@)7Gf$dMZZn%z)6K%{ z&@`Wj(umlK)8QCzrs-ECgCR5mEU}+7?Ls=1fHqJb8~x4njhZH=nh=}e64n@fU~=sEH5w#oM!3iDvuw_pJqNMm~`dT_r0RgP4W&d`I>LC?7#q;~*y0f8caYv36GC z%ymt-No0M6^malXt$s;yjtlP%!#)+z98MCj{>_Y~ai%glZ7{wiQmg z63*xtrRNC4=AC=fL7)k5^rK%y(pl4sE!4eX9pW!G30WT_()_$6&4@Q>uKPPQ6Cd!j z5~4IkZ)UxA?-gK(0cwhMA^oA3u;5+(j^WL=;{D-fGZb0j{&Ef+jcv+)_)5klz=*!>#oiJ}fvxsoRNzb+@B!z^i5*5f-4H{{vTXn_v?tZZBJg zAC(G%uG=YRhJ%C#l_I#o^*+r|^;!p|2*lB0*J~mW8Rv`xhm%NBiEn-{#kQ`0bq^7E z?;~zZLrFJQ?+@o&uvm>WCZ6{peu&2z74$J=GWkpd+op%87CSkHS`R_3Nj}~d`8=U| z8Kl7k)=Lk5Pxb#Ap&*mxxD#Zu&T=PKlVq|IFavFD>MLV;#&!Kzlr?vgEq{MiCozq^ zvreA`uvEsP>j83WWmJ~RY(aUZI+n`daF28WF>j;n`a)%=& zuG#NITkZ9DMzvu>l_lbKdOqb- znp2TaN%?T#QyEv6VA#4cQ}!M0%D69gIe|5`0p8rC`?OC z{ezPF2Nj%Bv*K7LDfvJlYDqiMq3C9C0LQFoM{rn7Gd^*c7v670WADSGYN1-p^6Bgp zJJzbDjZbV;Q+E%tW<^Ctjy@HKar7_U4Hb@?S-EJ>vh5%)eAxjYuo8wb3g;9v1U_09 z@ex6Mgcb3TPRzv==i>`xGiM~4?IvwwoV@#E3b6Fn>q!>bsG#rR#GCE;bD5SQM{AJQ zWNB$?L)JbOS;VdOjZOeTBObS8(#80Q^Y217?ND`FyaE>JTsg#80WC4r12ZTFz!BmK z2_Z&@;~{>Tx>{<3rUH(h#JZ>rYG-@)p01-NG0i*wCO)Weq!@XtCh?(;czYaJ-y6~w zN0VDi;(y~&8gHLAwH1ASJpPw`F6fMgx8^-?e7k7aWckB+gF}5EQ~_}6A58fh%w{OM zjx~YD1Q1_*1ap;rQww<6Hdht8$oPlNgt^96N&Yh{C&CS*vqqrfWa_$(%})kY!1uhd z{Z}*{W#wUl(Gi&Bp9=IWv>1&C>nSDPp;>CayXhx}hKceOK=U7zphekOp2ut95AOv^ zaRiI6UCj5wd=u|UlRuPa`W-poZdOfvDZvyEgXcJJnT z4Kb-E6hcxBIKobPo7$j~qOAT&j4ETVBhAvBq)q3U&GD1?q0(WvLFZhDMHS>zTeH?R zWUtV=)E@D@apqUHM_rjW;`L(tEZnljtu9 zbrTPJ=ih*#;UpM|uMLR)THJylkotA^7H?MY~MD z67R&%P)x(v0x6YnxCQ)#cFT~;&AhC0n4S|~5fkdkup&g|)>s-;iELKiTjBCGY2Y$C zJYPiv5Mezg-u`)ErthPjG{rmPwGJG(!Tz|b6Vgq60PsDYl*-Ej@vaoDP?V%C)(-Zw z`70U_sXO&m+}vD@y0gZRnO76UXw}2$dIYI?ubfIYNY*!md<_LYyHq{(*(Gx(H77xw zY_PJ}x{^-}_u%*g&Az_Tcu6CwlC&wx=KYSuM`Q64A847DM$jPa6bH%i{SQ20v8gHD z_Yv-mAxhy{MbAM>WRvr0xk}y__r5`L-ZzcMnk!wPR1XinVqtzqAPr2aq(7{tLg;Im z&$95in;s#ce|CnG>P!Y!A(s>!LVEh!^zVP6YFa!6NFjdo1@;F}3=|lt!Ntu)g&mxr9Cs8qI zuSNz`?_Er#vPnczGHy-p6I+%XaPz|8`h{XOLWQ`81PEqDFVMuI33;TTN3#rLP=Rdz z5xVE8&^uT{qtaAnMGkH;K9qlYrFv=|DZhzmW3`^jz=kQJe`XYdYTp?`6I3m#CFFoF z!$z38TOM;Yzp*Z`232yK4mu%3OabN)wW)d~CN&Z8bD* zbZ&eNyer`lU&X*HjZ<@9MBYs-v>PMCw{lcVBs%dcKc;L<7~iB#Hp|vaEfedSEyt0% zT6{DfeOwjZ;72Ee(d(Txbzg~AevwZ+;>`P9kG*5@9;|PQzCl`iPgz{A!3N9=5C!d* zSb!)_`x)x@&uE+LhhIf~sK1ko{as?X3Ei+SrnQ5Y3oEIzuLBKf8Pd*pBx_YqEr`;E zM+O>BsHZ+285OPxG~@)iWE##*ebO;JDn8I~DbVEvTQXH+w4eHTs5&HY>Tl|JU4(k- zlkh0rNVUt)E|-yZ*!MV*KCTZc2%3(MM1~Xw8l;mpz>+fc1Af={d_^x0x!zia2BJ>P zbf{m@-Yg5$OZx(&T`In&r1NeU=4i+1>a>fYsG4-^^H*4URF19A!}Xy*2uil*NSq6@ zOOR8EoI&`Il;_l&oUDL!D+}W$QK|z{?U1?`;{>PgnG0rq3G}-($%|M7f5cBnAz0E6 zFv<4cF2_jPA=7F2{c73%o0a3DGNd1XRhs2zNZ-R9`YM)GJ+3=p)QHo9m?Vo&yQSn^ z(24iNZc32c%dxFvd^3Zza4C9#Oy>;gJ>0;^xTirTrCxdyPr6EpnaT|58Qh|E<4Ec$ z++l?Y!vR~H`>(Y3H!ZO^#5c9Iv=8_|yJM~UFxip8Rq-a2yLK zuy7I!9a&hom!>>NPL=$XK8q_Z@3N;d36x2oOaf&RD3d^$1j-~(CV?^ulu4jW0%Z~? zlfeI82^5{DH0S>BtwkB9zUSeJSHXQ2bBAHvd$WeG`^_ z?9bje2ghmOLpdp>7i59v&!eECZTo1%~tPOejVS zbW7?b0tZ|o=<}wAkTBD4R2O~FIH+XDmm)18OKBo6_TLh#pePc#j09yPa`q*^>iBn0 zOyIk&y-VOWb*J0EU4Zoxr%Dm{0k{Keat5yw_g z6}3eLYB?TZv-E$_@GU6e|C6NSWEBql7!^zF;=toaW7xNGq_y#YL2T`2b_}Z79I3<~=h+#Y)ZF7B3=O(@Zac zJTpW%RF#)vMZkYor-tXlItGbB&d!8FMoO*GH4}&Q4L;Q;70=4I;9J1fi0G;Q;J8o=q$L0JtV6nZ5&x_4th4}1@~$S5q}66@t+2B+9I6Nm<@JrGs{GV*_X$#i$7xG?_5|U&yxHTJr&XkJ`6Ga$AHy{6A;r?5}&>>;q_dA_d$&B zg>fl}m5Avoi7!BlLP}S@D8er(e@btQbnzno`ME3l;Bl)st&K4>K05#aSK z=@t74&(4-O&H~5RRT+Qy@8>M`u{<}gBs{OSz>_R+3wv)ws=EUI7bWV~vTLFLlq<^v zk{FPR>eyy{cCjBuk z$8BK+z}Hm!LWHMo*jdfx(;T z8^KlCJOgl5aef}3+>!Qa@|*A{Z-L)_OSw}f&gwoe2letVUa#>5hbB$m7#w&oCgK>-P7$yZIrzEg z_&~(Zop>^`H29g8+cOd#X1OgM#DzIa=S>sw3oak2*1u}D+k!(}*rG-EyNK``T?)>` zzRq!*u@>|rJ~}JHUwt=T{zJoaZeO}G_<0fjPmzavXS7f_=b%x|Kppu9`>*D6@td+mc#iIPTe}@CLpFcx zc)9(^0qsTj?YGcRSa~~nT#K`ATShu_jheU*5%H5>w0`h?;W72}I;{@n% z+S-pzUOa2dq8aBpABugy`*aSA;))OTDTr@RiT^&T&g=4f%YT|FMYwRsGGG^P4?XPYwU9YH(JK-Xi=! zg9n%V+WV`vmG5-+ve!@DMfe|G*QFYE=D6+p6?T>Wh1Ki(!u#;@FR$jfZObZ7e{SNH z$4%q1+-5C7yJ-BQNu;x}i+2S7Dd6LPf7xTF2v15?jCARGI&l8?-Z$1pKF60Ih3n2+ z>UHZaaHS#kS4~+p$0=Y_ zlVu)ZO)Jb3;o}Wy2dnJ=Ffifh%ukL~=-?;9m);$`cJIzg>N#tNr5`-e+((4_rVNQ0 zdfU6x+7YgM5*+Vd6ycY$=AU10oEWrY=a~WfzjH|z;r3fMb9q0c2YuNvYt_8&H=RZJ z?b??bx83k<$QqxHUMrgS!{{blhvxM%=YGJ4>^i2JI=R~EeImTswaxt6wqEK@w|A|t z-*h{<;Oq(??(+IX?mo>|;~MqfX`H)Og#Y|!#LTO;mD*YP>fr&q*3}o`>mP4*NSS{y zaN$k=g=^fq-4fxW*MGb_sdjYGSIc?D$`?rn5#Ih#+~?z8w$-f5m~ykTS0A+qKX86| zjl9Kk0@ul!Zafvcx2*{O^wVn1YG3#*c+r;1hZ=ryprr_3HF-k((m5XLB^R%3cg{RD zT!fe7pDrEN=RNIuW!ke@&QZ5TxISpx8r_@?8vPo_ueLN=wqArA8uac^U7h2WxRlwI zRqtOs>vw%ZN5EGUhr3SBO&nBVsQSlhVcT`mS}Kvw!?)Pg^S8ja?7S6pWE;lK4`Ju_ z?l(m`i4D*9*UX1M&<5p>-&`QVW8KV}tM^9-&P`Gb>%K0ah6vA!dzsee!PmjN+-F^x zGh?^4A6u1h>g<4qCjV8h{DXau&bTY$$C(~oTQoAF^P%@z@Aln%$X$eAl)QI!rSz5m z>J{(*S!efo>uf0QE#;ctQm?$Xz+b-w-e2kz*J=AGepUS{AAd5z`&*Hpq`l*xk%7*0m>1rPwupn%qg4y{)MZoOJ1-{Qr~geVT#qjn)Eu!L|9VO8eyf??+M^=e`=ELCv>w9)4mJ3A>b)-= z4~y_ggPR;smdkcq>H@tSzK|xuA8zwouybCv+u}8V@1F6q2yYVH@Al7JTJWk$tq!{V z@l#b1p0xX$9Z9>T{F2K9?&r*CX0>PK<;IftCZd1)ws^l6dsCL*rW*XN9e|fl`A($s zs{SuypPzIJ*#GH)-VJoU28-}tMrV(IxT%iHxMI%8?Sn5^`)B{({_HjS&n&kEGtmzp zU!5Z2FVHj&YqM>c|GFs87Qb`}u<|+QWwra>E58U%$y>Q<=Dsk=`-azunLT-PM^)EBih%j)S`cX9~aAi{^YA5}4XaVr0H-Iv#Ow_Y9- z;RhDa+4$g8A+k+-~;TT7A#gRBv6mGW@$bVf{pS#t+q7KD=A0^PxU{ zZh2LhN~hJ?wQKje8x_*>f|H)E8#(fKJL@=gY|femKdtoEPM2(2>G;`7HxYmImOBe? zep(|qr9wJiabvQ#2yZf_#s?J}f1*mPRV#X$Z~rDDyzAao6^`G@4_FgZFk)h*8CnrO z^~bG$?3z_Qc)q5ZVr7LmYri*W(}el`%U9Cwyb$~>G5R=G7lg}O=e+K=UtGuz=SdE0 zRXE($-$;`&;mad417=)_h#MDZjuGMOFP-V#sr?55 z^Fn=|1SUSS`g^~tv)g{!HplJYM(Xz(UJ>!PI{cwscsnW^X1XK7dsn%#^J2_E z{>zV}PxkHaVJE^*T>Y%>D_!Nl*?W$Sl74sVq6j~<#m#w!OAqbJ*dDW{?JewPVuF57fJkb!l*8VP9+iP}j5Dx9-k?AuEr3er{H5 zbUP8hl44Nk$D`)*U&nq@n7lN^>i@*Or9I|SQc%QTS`EOfqsCW9{^y`DJXt#Xx{jk05#%&VmB*#uVzxk(# zj)&}4EL_m+a+nCOmh(z75q2cem1#-?i(vS_R=lG#xFXC>>1PS)HfAk zJVg3415fY#V)^jExsoPBhLze?9EuG(?tm1FmQUQ)~I z|1bLF&-78NlKC0-^Gy|JUAN9_I;h`U(dF9(>Q$@!wtbL$yr)QK)M?*?pU*IdGqy`Mflavw_e@lS0gCp(8A$?ujwBd2-m@!)Xzr8 zo(fu*+N5dPl{%k@@c5mdytnt^9)7mdj&W0E{8D;-KbDFGY?M@e|!*@^;*P(j_Tk zYD>lIj6)(kecOWM+B<7#*A8**EdeOug`Aq}uiFs}{<0MosMVw3P@id@p%Jw8sq1#_RVh zJeplJFY8)$;jk9YsR6TJpC9u@_lmL`L81UrK9PyhsIYOew;Oy-|*EIYrmSaTOV#5v@&>4 zZoSi&Kbt&D#6LP}SlZ$zbGm%(kl#2vW`)&$zU|d$Ur$5j&P(-@B?opt_Y?6iXZua~ zw#AMv-;DTu)^{y#S^Jq?O>Q1BPA&}GeXZiy9U-HC5%GQF9u~a1yR74?`WwOyH(&Fm z2!9c^&aFwSYC&_G*Q)6L$R|mJkKdRw=2fAh!;)i`;RNikhQvUTtthf01tPtUnx6p~GTHE(q>9vr(Q9s`fxw>Sg zh~Ir;i}?*tj0;ZOVtTDBSIOGXoc(RXR^Nb4!O3woPS)7`jX}hpH#Th7cU~ER({3eJ zeQ#sr9uYp^dHb{zSSNo>gAk%MqBmfgZv-6+;)5~;!9`dzkGPeKQN)QYDHv_B2R<| zzGYr8pvSjgA6~uFf06U*?fb8d%@px9j~isB_4E#zH?a3FleS!r6X7o(MV)#YaIC{Z z&#vb`Tlo285#F|n@2It7B7=Xd6Lfv~dHb(K_=Zoz&-D zj2OAE^PZp9jpni@JrvAYIRmWWeo493nobZ8& zzdEb@)0=lr2JNbLv)?L1L#zMukyqf|h{$eT=3o2Zbsa+wD*bXRhV8YP7Y+uA489Fa0|ALZ_V%Z@Ei8{MP7dYgj&AOujeHjhbLIq6YLw``R?=`W$-lfz3Og1Fapsy(;aCQ6ax|UcXc7INYyE zgh;3E;X_|M@ySL18J1n+Vt;QD?y!IC^|@``LcUt--{Sr5xz=^3nss(u{`}5+fg2zB zY;fFsZjp$8Z`a2Swk8MgKR&vZSu+@CD!Z4Z_S(SQZs#2hzLK{zQL$J2YYB1 ze0^kB-o-zritx$q`-3*f?{}EFr`P?Iar3Qu*%du=!S<`)ciH&o=UaPhu4e7uChff9 zR)4LFYGuOO4vN(&sUn?Cv+B&<_@G6=RNsWpbDAHv_8Z>~Ruz0wrG2MwdyMV7_Vd(4 z5r2!k)uJT}l7m-;s4l|mUezSuII}>z#3-%od9D2z5kBh7^zdnu4{P+t(+}G1pJnyO8sG0w z_x_2%z%@rln;QHQVD&48yuYpbrS}^J%sN})gKpoS?kCdmX+7yl!-VWk^KZA?uO25) z6XE`C_I3-X|EYTF<<#rrM`rF2;onxD;U=)$|<^6|&ZNMq1YvZpCUeP@tHg%!DH3#%fGd^jysPW$1X`I^b4Bm(fa1sIpNm+ zb4I6fEw&jx@?V&KwCckjwvH3&uRnQzNnGykfDH?Ke*eo%XI~MXX*n;@=N;z?LhlLZ z3M#$j`~>ZL4~~qC9$I2QJlB$MriFgVa~CXMY%J}~hmTc8hDVLiS^FsBF-0K}&O=lY zVv%o((|c9vMKN_2q4<3RZ{QotOioOz06295za#B;OBx=z`4s#&F8P~$vSLC7xZD!I zQM9#%zL8P}D3iedS_#;ib&Q*Y+j|pdqVRjyMftL9@N#YLDKF6yFZ>%SGu^B3Bl@LX zS-=;a3R`^DtvIE8j8@yE9m((p0A(~Ht(I6Juq4USG>Y-|2CdP9Ezz7staAV{8723T@lb5l|`2= ze(GEB36JXJfZrt>oD|&uZ5t#axQLDvKc&?>hfU-DU!k=a^&p<;vaN@+4Q(M+2yOLp z33>MdFZnIFVm``43sPA&cyi3t{#BldE|o2%8(g-06F;S0wtOoqNw^r4kF%BUyeMC? z4c=m#d&*3-#LJcsqF>rogpL2@g}jBpgU|NPi}J~>UMDe8P8L)J7KD;BCcyY3-e8ie=dHL*u z8&4t*#Z*RV?VZXkyZ$u^bn712{qXMgrmJgP27aLpH@7dyc|m#&Xw!dm-1xYb&HG10 zj}Gsz9yWSp)JPnV9juFv?Jpejjq5)S$&n+6SRR|i3>(6jpoyqB8LjrOu~n9ti2)T3CHdug!^?BwI!8`1tQ@E4;mj$T zJ8_C;Zn>@x@ay4(G99_f&Ex`4GT;sa9$>%~U?uqW ztRv+-hE&dVk8ul=`*0lby4Av~=>LeZ=uPPCUxYA<0Yi09%#UigQ?+L&k5EDO?pRQjKQ@MX2rZT0-Pgfnp;yj0*J~i-~X&kp1c1V1dv<18!LDiIlR3UuDe@@xw~0=Q^X zKZ{d43?}sx_~{m6LdIc4)y{z`qKz+%9BcyeBMyjxF^%-%&`oi&&JgTPSfNjfvC)YNH0aVIrhHv3&%@-x^W=ttTs9*nxtv8T(w9^z$5qiu zxhlgPxGFvDxhl==xGK3s4S77ua~`l;k74L%dN^<%&Fwjl0wLA2x-(b3hdWobxtw#^ z?vyKyaR{UKx!S@P<;Q!5telelrCUu$uI4Zo&@0cC@8-z**epvv;!BSHfMSKEf2eQi zA6g(LJq97BtEok9`z=m-I%3lQ9mLG$;KUPtEyT3m(9ZI#K}_@kVwa`Q2=(-IRAxN=YI zd`MoY$U8wmVd<+adPuj#?iP9dUPnM0QCHx16=Lxcb)bf}ys zh>3@aHarjo+i_N`gJ)f5t}fcRTP(BWRHqn6*3Lt1>gcmjD5ouADxWSfrt%X2r}meG zm@X=teqx$NQLZ6sxLyK^!4iwv7RDb&Id?7$pLd3$= zsGr4T*|W@I$F)2Kq#KBdCgIVw1u@a0tK@hn@*>JZVu!UXAK;6=vnTpHT{-lh&KRql zI8XSkp3M}wM2qog@sr#X@QZ<`fN!e+4*ADz#|Sw02H@Ka13B(<8@m+StsC>b$afa} zVKGnNLHND`e#=V9W998FK2o`Aju@Y1T(#ILxs_uog^4upgWmoyjynXJ6w}4{=w=sM zn$KjFNr`^&t#FdrG>hygc9w9?{)n+3;5Nhpr{{7Kt{goxx~^RLSj&9H*@1J8b%?PK zBMl&3^g%^kSf0z#b6tE7!6M%yksQ}`H1L-RG0RJO3__z zw6xIAEQLPR!vuI~Wr!qbZ-y@0az9Ep0Y&hDAnlLkHm?*dX@h70a#gNtU65 z;s%ci7Zc*x=UPfWi63wI_p4e);eWXVntgqv@sdUycY1&_XZTNo?@j#!SswLSA1aGi zQ0PI5!~TDM^0_9Q_Y`H&q`kUVYRjo z#ijD{QI|&KE%I;gHCFfx)ga*uRytL$ze9RZZ=hMu{=zN>^;R{bj75+@07|I}iO+hK zCKuiKnD9X(qlQPn!_IJqcn~YCltN0Q%kb&UF;lK^=D3usR^G~P{`W~Br3${qMr%pW zu{MbK8P-dNVV#BEWF3#61MX80_pgp~W%!0<3gUw`@IA+8I5&m2e>&io^@!ub5U>1ZR-wzBcecGZ(R&5_@wfONDqme!n1Z7GjS& z$V+g<+wdzySy_lL)aAHI;6YiB;|Af!gH8P zt|jFH#L1oQ=2z|9oqu7cj&Ty(aYEY7`fks+&E4*Gch5OT{D`Wka@A5!sG=^aBFBkn zB+ii$1^P!pmS|BF`iF%o2qHj`DwIDekGwUssKKz|ne>00s{ z@Kx)CSRbO8I)}i&h8dT%r*<|+CUa$hI-VtwOWXk!;K#tJdge~*d5Ao~di(=l0Drjw zzfh-YBXPk^j2(Uw{LE(jk8L6F2qci71EYK^=WXmC1D!@}#kW)70}<-L7r@<7Q0fOC zjxko+X2BCs{Uz#y&$kknfiJWXiy_~0jyeUfnt)vt{Za5m;>>56uM1#RCu`#}{epjl zj??x6xMe%>VfaHkSdTl2nNmLl9_itoIqa|M72?}{tT*^`U{^n5ho1!R--GYrtG~f} zcu@7fu@n3*v4TV z;z!W4@Tb7(eb@qDt@HmNbP9e1d;_Y!!g>Ph23V``Y4FET6uv$##1IsM9|2E8?eJ&8 zD^NdtWrF^oeei1}LMPy}V9dZz@OkhVC=Xu%zna7j_#SXzkh<_Ez|W@W2R;NIg+}3D zG09s)@4#OHS3b@>{)axnO;A026ih)q@E-Uyv=_brz6-5{U$LKdPz!uJxEJb#Pk6q*t^UFT;N(N&TqWo2+5^j(~ihVB}pN6Ywv= z%UrL_37>h-$Gcx-9PlznB6BJiF8lH0AHW}GUCFrcFQ8Z9WjyyHv;v>V80bCF+whB@ zMGws90js&9B;KoVd6R#?R}|i@^w%nES9mGr_cxzy zw^O#F(eJlY;fTWDDEz_}zx*+U;|k9xd|zR0#IN^ygO7J^_A#VztHQLx=M=u8@OKKA zKkT>bQg~3|w8GU&|C0*)6y8oB-HPsHRN1X?jY6UDlJd_vg{KuxDjZe#oWgG^Twd05 zD@J?-b$+G#drRTz+uZ+%TK5MP4k$dL@GAo`8oP4IcK8v6(Y3W?_2g^v2HGhDnx$6tn4X#5v{EdlN)Dcui&SA9r8J{ z-y>UwY~w?-^`4a1C-g1!S-fugzFE9(F0?{!EML5C-q=42l`dX47xK*f^7}-y-CWwS zpkrpkg6|;f(cS&qj7*zj7{X2)b+v0{Qt7^>k(?FRbAu^QyCy2VJEnE@?-9@35z+du z2_){0^;7bkEb)Vcb0gmrcDFXQME3~sJz2xfd77QnN-=Cdm^i1#PedeAA6cdC)*UO_ z;umjkjm2WEvA$3^suYDQB9SIDaaBZH*3urq4ADd{U8Kf3?YNoAM$0%i{M{VuMq#+N zE*fiXDk0|GPdmSj7E2_EnJ>_k;rMMO`k{3cX^+Se-i3}1%e*?+?)O%CCwJFxl=;uber5D1;Bw~ZMtFCkagW3(15j^}M)oQzxUTqhOTa@0? z+{Kug&`phv#e7E;s2#pZ?QP6hlnMJwWyH-nbF@~n$r5EkppJJ zn6={;8aKsSN@HkY<$T>u=4U##eK*`f=lJjwoDu8Gqrc^r<+Eyi`TSCX=pN|}y)weI zd~kcD5*B%BRH-GAWIE@jKC~9bcBCSrwHWNWl8j!T$m(Sg$@6e-%BoJTs(;d|!@5B$ zdC3yL+I${cTyj5o5PMS?Yfmn8%`ZjIoVHK>f0hYRz1-%YI-E_GKS|2YZ=|N$SDok`wh-M zb8wK|UcP*N4ae|ujx|$bne0t-vqs!Zawezz4uyCSd1<8OOqHgr*3x`oRfxXk9lc#W z9ot%Ge6vZ&-sP4rT2`0F<0Q?pWtI!@yCq^PG?JQW-h@brdqk#`+#;SYlJd4D)=M3x zC*3PH%<`HcB0_VGlzc5hs+D)XI=`HKc+7)_X6dAE4`_xpWIDE$F)VDXzp9398F|yw zJbfTdPYptIj6sHiHdT`3Mq1jTh8Z*RMm*;kO-d28A4kze@D1S(9;V4wzOA8fsL!xh5U13D@{b>zW!VL(k4F7AGrrc_P)+H3jKo0wT`Z6$Y-lUTab z@D?n->yED(UUSZI@M^bX#|_sN*`+<@(UnCayQITa2e#A3o=e!;%|=FYGD4NxbA~hA zZ8%BW$;fS(nr)KqtkJ6LwRa@=(aG69IYSIRfl&NeN_P%3YndMM^)Z(L7?Km8t7tJ@ zIkkS}PIJJ~o#AHImn(Xf$UD5hPyED0PW1pb|3loObkPI1$pahIeraX(Z{Oti&C2x_@&C~S72G@J z{ZkyedUXD8dW7bYf2xwa7nQSmh4|LO;j*jMeTxufyQ7`PrF7iux>_A!@7lgX;^oaO%3a221oOTb!ESC@G)L@i$h=Zz`P!ql>gcA zj!W_L#XzyW*j?-|ri$5OzBp1W6i16=#S_KJ;;Y4};;G_v@l5e@QA~(w-UXq}>WR=q z_eB51zKM~E!o=vrsfp={{K>+}(UVePMX65oX!hvX(dnaNJT#sfA00n49ym66?98!c W$Enj@AyxoltZGcc;^%+wf&T)2c1O?v literal 0 HcmV?d00001 diff --git a/WIN-packages/x86/libdialogs.dll b/WIN-packages/x86/libdialogs.dll new file mode 100644 index 0000000000000000000000000000000000000000..0ecb1c9ac7ce7e41d581a88b9287f82a27d841d4 GIT binary patch literal 26624 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 P0sR<1MFhhC;OqYY#$R{s literal 0 HcmV?d00001 From f15720112eb64524bfd64c27f8f5b5ad074a9411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 8 Oct 2015 15:42:29 +0200 Subject: [PATCH 10/14] Add header for dlls --- WIN-packages/dialogs_win.h | 11 +++++++++++ src/dialogs_win.cc | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 WIN-packages/dialogs_win.h diff --git a/WIN-packages/dialogs_win.h b/WIN-packages/dialogs_win.h new file mode 100644 index 0000000..37a1d37 --- /dev/null +++ b/WIN-packages/dialogs_win.h @@ -0,0 +1,11 @@ +extern "C" { +#ifndef JUCI_C_DIALOGS +#define JUCI_C_DIALOGS + __declspec(dllimport) const char* c_select_folder(); + __declspec(dllimport) const char* c_select_file(); + __declspec(dllimport) const char* c_new_file(); + __declspec(dllimport) const char* c_new_folder(); + __declspec(dllimport) const char* c_save_file(); +#endif // JUCI_C_DIALOGS +}; + diff --git a/src/dialogs_win.cc b/src/dialogs_win.cc index dd3ed51..e6891ee 100644 --- a/src/dialogs_win.cc +++ b/src/dialogs_win.cc @@ -1,6 +1,6 @@ #ifdef _WIN32 #include "dialogs.h" -#include +#include std::string Dialog::select_folder() { return c_select_folder(); @@ -21,4 +21,4 @@ std::string Dialog::select_file() { std::string Dialog::save_file() { return c_save_file(); } -#endif \ No newline at end of file +#endif From 97034b43b6535fd43653ae2675d4e608e46bdd5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 8 Oct 2015 16:05:03 +0200 Subject: [PATCH 11/14] Tested on windows and debian --- src/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aa08c91..a3d2b33 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -90,11 +90,12 @@ set(source_files juci.h if(MSYS) list(APPEND source_files terminal_win.cc) list(APPEND source_files dialogs_win.cc) - set(DIALOGS_INCLUDE_DIRS "../WIN-packages/") + set(DIALOGS_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/WIN-packages/") # if (64 bit) - set(DIALOGS_LIBRARY_DIRS "../WIN-packages/x64/libdialogs.dll") + set(DIALOGS_LIBRARIES "${CMAKE_SOURCE_DIR}/WIN-packages/x64/libdialogs.dll") + message(${DIALOGS_LIBRARIES}) # else - # set(DIALOGS_LIBRARY_DIRS "../WIN-packages/x32/libdialogs.dll") + # set(DIALOGS_LIBRARIES "${CMAKE_SOURCE_DIR}/WIN-packages/x32/libdialogs.dll") #TODO figure out how to do this.... message("MSYS detected") else() From 7dd4f9783c967f16ace8ecf4c0e1c44edcaadc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Thu, 8 Oct 2015 16:10:31 +0200 Subject: [PATCH 12/14] Use reference instead of copy --- src/dialogs.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dialogs.cc b/src/dialogs.cc index 8ff3882..8009e02 100644 --- a/src/dialogs.cc +++ b/src/dialogs.cc @@ -4,7 +4,7 @@ #include std::string open_dialog(const std::string &title, - const std::vector> buttons, + const std::vector> &buttons, Gtk::FileChooserAction gtk_options) { Gtk::FileChooserDialog dialog(title, gtk_options); if(Singleton::directories()->current_path!="") @@ -47,4 +47,5 @@ std::string Dialog::save_file() { 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_OPEN); -} \ No newline at end of file +} + From bf92d588c473689a6f9baae8b2b0fa5fbccac470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 16 Oct 2015 13:06:14 +0200 Subject: [PATCH 13/14] Remove directories from Notebook --- src/notebook.cc | 4 +++- src/notebook.h | 3 +-- src/window.cc | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/notebook.cc b/src/notebook.cc index c22c448..9299009 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -27,7 +27,7 @@ namespace sigc { #endif } -Notebook::Notebook(Directories &directories) : Gtk::Notebook(), directories(directories) { +Notebook::Notebook() : Gtk::Notebook() { Gsv::init(); } @@ -71,6 +71,7 @@ void Notebook::open(const boost::filesystem::path &file_path) { auto language=Source::guess_language(file_path); if(language && (language->get_id()=="chdr" || language->get_id()=="cpphdr" || language->get_id()=="c" || language->get_id()=="cpp" || language->get_id()=="objc")) { boost::filesystem::path project_path; + auto directories = *Singleton::directories(); if(directories.cmake && directories.cmake->project_path!="" && file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/') { project_path=directories.cmake->project_path; if(boost::filesystem::exists(project_path.string()+"/CMakeLists.txt") && !boost::filesystem::exists(project_path.string()+"/compile_commands.json")) @@ -180,6 +181,7 @@ bool Notebook::save(int page, bool reparse_needed) { //If CMakeLists.txt have been modified: //TODO: recreate cmake even without directories open? if(view->file_path.filename()=="CMakeLists.txt") { + auto directories = *Singleton::directories(); if(directories.cmake && directories.cmake->project_path!="" && view->file_path.generic_string().substr(0, directories.cmake->project_path.generic_string().size()+1)==directories.cmake->project_path.generic_string()+'/' && CMake::create_compile_commands(directories.cmake->project_path)) { for(auto source_view: source_views) { if(auto source_clang_view=dynamic_cast(source_view)) { diff --git a/src/notebook.h b/src/notebook.h index b8f6b69..3af9887 100644 --- a/src/notebook.h +++ b/src/notebook.h @@ -12,7 +12,7 @@ class Notebook : public Gtk::Notebook { public: - Notebook(Directories &directories); + Notebook(); Source::View* get_view(int page); size_t get_index(int page); int size(); @@ -25,7 +25,6 @@ public: private: bool save_modified_dialog(); - Directories &directories; std::vector source_views; //Is NOT freed in destructor, this is intended for quick program exit. std::vector > source_maps; std::vector > scrolled_windows; diff --git a/src/window.cc b/src/window.cc index 55da6cd..880a3d8 100644 --- a/src/window.cc +++ b/src/window.cc @@ -30,7 +30,7 @@ void Window::generate_keybindings() { } } -Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(*Singleton::directories()), compiling(false) { +Window::Window() : box(Gtk::ORIENTATION_VERTICAL), compiling(false) { JDEBUG("start"); set_title("juCi++"); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); From 140ae6a821beb87f6e93836ceb2627a6a304e329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8rgen=20Lien=20Sell=C3=A6g?= Date: Fri, 16 Oct 2015 13:08:22 +0200 Subject: [PATCH 14/14] Fix indention and error message --- src/window.cc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/window.cc b/src/window.cc index 880a3d8..851fac5 100644 --- a/src/window.cc +++ b/src/window.cc @@ -195,7 +195,7 @@ void Window::create_menu() { else Singleton::terminal()->print("Error: "+path.string()+" already exists.\n"); } else { - Singleton::terminal()->print("Cancel \n"); + Singleton::terminal()->print("Dialog was closed \n"); } Singleton::directories()->select(path); }); @@ -237,24 +237,24 @@ void Window::create_menu() { if (boost::filesystem::exists(path)) Singleton::directories()->open(path); else - Singleton::terminal()->print("Cancel \n"); + Singleton::terminal()->print("Dialog was closed \n"); }); menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { - auto path = Dialog::save_file(); - if(path.size()>0) { - std::ofstream file(path); - if(file) { - file << notebook.get_current_view()->get_buffer()->get_text(); - file.close(); - if(Singleton::directories()->current_path!="") - Singleton::directories()->update(); - notebook.open(path); - Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); - } - else - Singleton::terminal()->print("Error saving file\n"); + auto path = Dialog::save_file(); + if(path.size()>0) { + std::ofstream file(path); + if(file) { + file << notebook.get_current_view()->get_buffer()->get_text(); + file.close(); + if(Singleton::directories()->current_path!="") + Singleton::directories()->update(); + notebook.open(path); + Singleton::terminal()->print("File saved to: " + notebook.get_current_view()->file_path.string()+"\n"); } - }); + else + Singleton::terminal()->print("Error saving file\n"); + } +}); menu.action_group->add(Gtk::Action::create("Preferences", "Preferences..."), Gtk::AccelKey(menu.key_map["preferences"]), [this]() { notebook.open(Singleton::config_dir()+"config.json"); });