diff --git a/juci/api.cc b/juci/api.cc index cf1099d..eefe937 100644 --- a/juci/api.cc +++ b/juci/api.cc @@ -1,16 +1,16 @@ #include "api.h" #include "logging.h" +#include "singletons.h" Menu::Controller* PluginApi::menu_; Notebook::Controller* PluginApi::notebook_; ///////////////////////////// //// API ServiceProvider //// ///////////////////////////// -PluginApi::PluginApi(Menu::Controller& menu_ctl_, - Notebook::Controller& notebook_ctl_) { +PluginApi::PluginApi() { DEBUG("Adding pointers for the API"); - menu_ = &menu_ctl_; - notebook_ = ¬ebook_ctl_; + notebook_ = Singleton::notebook(); + menu_ = Singleton::menu(); DEBUG("Initiating plugins(from plugins.py).."); #ifndef __APPLE__ InitPlugins(); //TODO: fix this @@ -18,11 +18,6 @@ PluginApi::PluginApi(Menu::Controller& menu_ctl_, DEBUG("Plugins initiated.."); } -PluginApi::~PluginApi() { - menu_ = NULL; - notebook_ = NULL; -} - std::string PluginApi::ProjectPath() { int MAXPATHLEN = 50; char temp[MAXPATHLEN]; @@ -69,7 +64,7 @@ void PluginApi::AddMenuElement(std::string plugin_name) { DEBUG("Adding menu element for "+plugin_name); AddMenuXml(plugin_name, "PluginMenu"); std::string plugin_action_name = plugin_name+"Menu"; - menu_->keybindings_.action_group_menu() + Singleton::keybindings()->action_group_menu ->add(Gtk::Action::create(plugin_action_name, plugin_name)); } @@ -79,7 +74,7 @@ void PluginApi::AddSubMenuElement(std::string parent_menu, std::string plugin_path, std::string menu_keybinding) { AddSubMenuXml(menu_func_name, parent_menu); - menu_->keybindings_.action_group_menu() + Singleton::keybindings()->action_group_menu ->add(Gtk::Action::create(menu_func_name, menu_name), Gtk::AccelKey(menu_keybinding), @@ -89,7 +84,7 @@ void PluginApi::AddSubMenuElement(std::string parent_menu, } void PluginApi::AddMenuXml(std::string plugin_name, std::string parent_menu) { - std::string temp_menu = menu_->keybindings_.model_.menu_ui_string(); + std::string temp_menu = Singleton::keybindings()->menu_ui_string; std::size_t plugin_menu_pos = temp_menu.find(parent_menu); // +2 gets you outside of the tag:<'menu_name'> ref: keybindings.cc plugin_menu_pos+=parent_menu.size() +2; @@ -99,13 +94,13 @@ void PluginApi::AddMenuXml(std::string plugin_name, std::string parent_menu) { " " " "; - menu_->keybindings_.model_.menu_ui_string_ = + Singleton::keybindings()->menu_ui_string = menu_prefix + menu_input + menu_suffix; } void PluginApi::AddSubMenuXml(std::string plugin_name, std::string parent_menu) { - std::string temp_menu = menu_->keybindings_.model_.menu_ui_string(); + std::string temp_menu = Singleton::keybindings()->menu_ui_string; std::size_t parent_menu_pos = temp_menu.find(parent_menu); // +2 gets you outside of the tag:<'menu_name'> ref: keybindings.cc @@ -114,7 +109,7 @@ void PluginApi::AddSubMenuXml(std::string plugin_name, std::string menu_suffix = temp_menu.substr(parent_menu_pos); std::string menu_input =""; - menu_->keybindings_.model_.menu_ui_string_ = + Singleton::keybindings()->menu_ui_string = menu_prefix + menu_input + menu_suffix; } @@ -221,7 +216,7 @@ void libjuci::IterToWordEnd(Gtk::TextIter &iter) { Glib::RefPtr libjuci::BufferFromNotebook() { return Glib::RefPtr(PluginApi::notebook_ - ->CurrentTextView().get_buffer()); + ->CurrentSourceView()->get_buffer()); } Gtk::TextIter libjuci::IterFromNotebook() { diff --git a/juci/api.h b/juci/api.h index 900d206..64e72c1 100644 --- a/juci/api.h +++ b/juci/api.h @@ -12,8 +12,7 @@ //////////////////// class PluginApi { public: - PluginApi(Menu::Controller&, Notebook::Controller&); - ~PluginApi(); + PluginApi(); static Menu::Controller* menu_; static Notebook::Controller* notebook_; static void InitPlugins(); diff --git a/juci/config.cc b/juci/config.cc index 9fa2a69..6096a9e 100644 --- a/juci/config.cc +++ b/juci/config.cc @@ -1,8 +1,8 @@ +#include "singletons.h" #include "config.h" #include "logging.h" -MainConfig::MainConfig() : - keybindings_cfg() { +MainConfig::MainConfig() { INFO("Reading config file"); boost::property_tree::json_parser::read_json("config.json", cfg_); INFO("Config file read"); @@ -13,7 +13,7 @@ MainConfig::MainConfig() : } void MainConfig::GenerateSource() { - auto source_cfg=Singletons::Config::source(); + auto source_cfg=Singleton::Config::source(); DEBUG("Fetching source cfg"); // boost::property_tree::ptree auto source_json = cfg_.get_child("source"); @@ -58,39 +58,42 @@ void MainConfig::GenerateSource() { } void MainConfig::GenerateTerminalCommands() { + auto terminal_cfg=Singleton::Config::terminal(); boost::property_tree::ptree source_json = cfg_.get_child("project"); boost::property_tree::ptree compile_commands_json = source_json.get_child("compile_commands"); boost::property_tree::ptree run_commands_json = source_json.get_child("run_commands"); for (auto &i : compile_commands_json) { - terminal_cfg.compile_commands.emplace_back(i.second.get_value()); + terminal_cfg->compile_commands.emplace_back(i.second.get_value()); } for (auto &i : run_commands_json) { - terminal_cfg.run_command=(i.second.get_value()); //TODO: run_commands array->one run_command? + terminal_cfg->run_command=(i.second.get_value()); //TODO: run_commands array->one run_command? } } void MainConfig::GenerateKeybindings() { + auto keybindings_cfg=Singleton::Config::keybindings(); DEBUG("Fetching keybindings"); std::string line; std::ifstream menu_xml("menu.xml"); if (menu_xml.is_open()) { while (getline(menu_xml, line)) - keybindings_cfg.AppendXml(line); + keybindings_cfg->AppendXml(line); } boost::property_tree::ptree keys_json = cfg_.get_child("keybindings"); for (auto &i : keys_json) - keybindings_cfg.key_map()[i.first] = i.second.get_value(); + keybindings_cfg->key_map[i.first] = i.second.get_value(); DEBUG("Keybindings fetched"); } void MainConfig::GenerateDirectoryFilter() { + auto dir_cfg=Singleton::Config::directories(); DEBUG("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"); for ( auto &i : except_json ) - dir_cfg.AddException(i.second.get_value()); + dir_cfg->AddException(i.second.get_value()); for ( auto &i : ignore_json ) - dir_cfg.AddIgnore(i.second.get_value()); + dir_cfg->AddIgnore(i.second.get_value()); DEBUG("Directory filter fetched"); } diff --git a/juci/config.h b/juci/config.h index c6913fc..e08c17b 100644 --- a/juci/config.h +++ b/juci/config.h @@ -4,17 +4,9 @@ #include #include #include -#include "singletons.h" -#include "keybindings.h" -#include "source.h" -#include "directories.h" -#include "terminal.h" class MainConfig { public: - Terminal::Config terminal_cfg; - Keybindings::Config keybindings_cfg; - Directories::Config dir_cfg; MainConfig(); void PrintMenu(); void GenerateSource(); diff --git a/juci/directories.cc b/juci/directories.cc index 6e8ca9e..65a28dd 100644 --- a/juci/directories.cc +++ b/juci/directories.cc @@ -1,8 +1,8 @@ #include "directories.h" #include "logging.h" +#include "singletons.h" -Directories::Controller::Controller(Directories::Config& cfg) : - config_(cfg) { +Directories::Controller::Controller() { DEBUG("adding treeview to scrolledwindow"); m_ScrolledWindow.add(m_TreeView); m_ScrolledWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); @@ -29,10 +29,10 @@ open_folder(const boost::filesystem::path& dir_path) { bool Directories::Controller::IsIgnored(std::string path) { DEBUG("Checking if file-/directory is filtered"); std::transform(path.begin(), path.end(), path.begin(), ::tolower); - if (config().IsException(path)) { + if (Singleton::Config::directories()->IsException(path)) { return false; } - if (config().IsIgnored(path)) { + if (Singleton::Config::directories()->IsIgnored(path)) { return true; } return false; @@ -156,12 +156,6 @@ GetCmakeVarValue(const boost::filesystem::path& dir_path, std::string command_na return "no project name"; } -Directories::Config::Config() { -} -Directories::Config::Config(Directories::Config& cfg) : - ignore_list_(cfg.ignore_list()), exception_list_(cfg.exception_list()) { -} - void Directories::Config::AddIgnore(std::string filter) { ignore_list_.push_back(filter); } diff --git a/juci/directories.h b/juci/directories.h index ff7d195..c6363c5 100644 --- a/juci/directories.h +++ b/juci/directories.h @@ -14,8 +14,6 @@ namespace Directories { class Config { public: - Config(Config &original); - Config(); std::vector ignore_list() { return ignore_list_; } std::vector exception_list() { return exception_list_; } void AddIgnore(std::string filter); @@ -43,10 +41,8 @@ namespace Directories { class Controller { public: Controller(); - Controller(Directories::Config& cfg); View& view() { return view_;} Model& model() { return model_;} - Directories::Config& config() { return config_;} Gtk::ScrolledWindow& widget() {return m_ScrolledWindow;} void open_folder(const boost::filesystem::path& dir_path); void list_dirs(const boost::filesystem::path& dir_path, @@ -64,7 +60,6 @@ namespace Directories { private: View view_; Model model_; - Directories::Config config_; protected: void on_treeview_row_activated(const Gtk::TreeModel::Path& path, diff --git a/juci/juci.cc b/juci/juci.cc index f19e7da..0785b9a 100644 --- a/juci/juci.cc +++ b/juci/juci.cc @@ -1,4 +1,5 @@ #include "juci.h" +#include "singletons.h" void init_logging() { add_common_attributes(); @@ -36,11 +37,11 @@ void Juci::on_activate() { window->show(); if(directory!="") { //TODO: use the following instead, window->notebook.open_directory(directory); - window->notebook.project_path=directory; - window->notebook.directories.open_folder(directory); + Singleton::notebook()->project_path=directory; + Singleton::notebook()->directories.open_folder(directory); } for(auto &f: files) - window->notebook.OnOpenFile(f); + Singleton::notebook()->OnOpenFile(f); } int main(int argc, char *argv[]) { diff --git a/juci/keybindings.cc b/juci/keybindings.cc index 2408155..afd2821 100644 --- a/juci/keybindings.cc +++ b/juci/keybindings.cc @@ -1,65 +1,41 @@ #include "keybindings.h" +#include "singletons.h" -Keybindings::Model::Model(Keybindings::Config &config) : - menu_ui_string_(config.menu_xml()) { - /* hidden_ui_string_ = - " " - " " - " " - " " - " ";*/ +Keybindings::Keybindings() { + menu_ui_string=Singleton::Config::keybindings()->menu_xml; + action_group_menu = Gtk::ActionGroup::create(); + ui_manager_menu = Gtk::UIManager::create(); + action_group_hidden = Gtk::ActionGroup::create(); + ui_manager_hidden = Gtk::UIManager::create(); } -Keybindings::Model::~Model() { -} - -Keybindings::Controller::Controller(Keybindings::Config &config) : - config_(config), model_(config) { - action_group_menu_ = Gtk::ActionGroup::create(); - ui_manager_menu_ = Gtk::UIManager::create(); - action_group_hidden_ = Gtk::ActionGroup::create(); - ui_manager_hidden_ = Gtk::UIManager::create(); -} - -Keybindings::Controller::~Controller() { -} - -void Keybindings::Controller::BuildMenu() { +void Keybindings::BuildMenu() { try { - ui_manager_menu_->add_ui_from_string(model_.menu_ui_string()); + ui_manager_menu->add_ui_from_string(menu_ui_string); } catch (const Glib::Error &ex) { std::cerr << "building menu failed" << ex.what(); } - ui_manager_menu_->insert_action_group(action_group_menu_); + ui_manager_menu->insert_action_group(action_group_menu); } -void Keybindings::Controller::BuildHiddenMenu() { +void Keybindings::BuildHiddenMenu() { try { - ui_manager_hidden_->add_ui_from_string(model_.hidden_ui_string()); + ui_manager_hidden->add_ui_from_string(hidden_ui_string); } catch (const Glib::Error &ex) { std::cerr << "building hidden menu failed" << ex.what(); } - ui_manager_hidden_->insert_action_group(action_group_hidden_); -} - -Keybindings::Config::Config(Keybindings::Config &original) { - SetMenu(original.menu_xml()); - SetKeyMap(original.key_map()); + ui_manager_hidden->insert_action_group(action_group_hidden); } -Keybindings::Config::Config() { - menu_xml_ = ""; - } - void Keybindings::Config::AppendXml(std::string &child) { - menu_xml_ += child; + menu_xml += child; } void Keybindings::Config::SetMenu(std::string &menu_xml) { - menu_xml_ = menu_xml; + menu_xml = menu_xml; } void Keybindings::Config::SetKeyMap(std::unordered_map &key_map) { - key_map_ = key_map; + key_map = key_map; } diff --git a/juci/keybindings.h b/juci/keybindings.h index eafccd5..deba952 100644 --- a/juci/keybindings.h +++ b/juci/keybindings.h @@ -2,65 +2,31 @@ #ifndef JUCI_KEYBINDINGS_H_ #define JUCI_KEYBINDINGS_H_ +#include #include -#include "gtkmm.h" #include -//#include "config.h" //TODO :: remove? - -namespace Keybindings { +class Keybindings { +public: class Config { public: - Config(Config &original); - Config(); - std::string& menu_xml() { return menu_xml_; } - std::unordered_map& key_map() { return key_map_; } void AppendXml(std::string &child); void SetMenu(std::string &menu_xml); void SetKeyMap(std::unordered_map &key_map); - private: - std::unordered_map key_map_; - std::string menu_xml_; - std::string hidden_ui_string_; + std::unordered_map key_map; + std::string menu_xml; };//Config - - class Model { - public: - Model(Keybindings::Config &config); - virtual ~Model(); - std::string menu_ui_string() { return menu_ui_string_; } - std::string hidden_ui_string() { return hidden_ui_string_; } - //private: - std::string menu_ui_string_; - std::string hidden_ui_string_; - }; // Model - class Controller { - public: - explicit Controller(Keybindings::Config &config); - virtual ~Controller(); - Glib::RefPtr action_group_menu() { - return action_group_menu_; - }; - Glib::RefPtr ui_manager_menu() { - return ui_manager_menu_; - }; - Glib::RefPtr action_group_hidden() { - return action_group_hidden_; - }; - Glib::RefPtr ui_manager_hidden() { - return ui_manager_hidden_; - }; - void BuildMenu(); - void BuildHiddenMenu(); - // protected: - Glib::RefPtr ui_manager_menu_; - Glib::RefPtr action_group_menu_; - Glib::RefPtr ui_manager_hidden_; - Glib::RefPtr action_group_hidden_; - // private: - Keybindings::Config config_; - Keybindings::Model model_; - };//Controller -} + Keybindings(); + void BuildMenu(); + void BuildHiddenMenu(); + + std::string menu_ui_string; + std::string hidden_ui_string; + + Glib::RefPtr ui_manager_menu; + Glib::RefPtr action_group_menu; + Glib::RefPtr ui_manager_hidden; + Glib::RefPtr action_group_hidden; +}; #endif // JUCI_KEYBINDINGS_H_ diff --git a/juci/menu.cc b/juci/menu.cc index 0f09906..774ba00 100644 --- a/juci/menu.cc +++ b/juci/menu.cc @@ -1,4 +1,5 @@ #include "menu.h" +#include "singletons.h" Menu::View::View(Gtk::Orientation orientation) : view_(orientation) { @@ -11,43 +12,42 @@ Gtk::Box &Menu::View::view( return view_; } -Menu::Controller::Controller(Keybindings::Controller& keybindings) : - menu_view_(Gtk::ORIENTATION_VERTICAL), - keybindings_(keybindings) { - keybindings_.action_group_menu()->add(Gtk::Action::create("FileNew", +Menu::Controller::Controller() : menu_view_(Gtk::ORIENTATION_VERTICAL) { + auto keybindings=Singleton::keybindings(); + keybindings->action_group_menu->add(Gtk::Action::create("FileNew", "New File")); - keybindings_.action_group_menu()->add(Gtk::Action::create("EditMenu", + keybindings->action_group_menu->add(Gtk::Action::create("EditMenu", Gtk::Stock::EDIT)); - keybindings_.action_group_menu()->add(Gtk::Action::create("WindowMenu", + keybindings->action_group_menu->add(Gtk::Action::create("WindowMenu", "_Window")); - keybindings_.action_group_menu()->add(Gtk::Action::create("WindowSplitWindow", + keybindings->action_group_menu->add(Gtk::Action::create("WindowSplitWindow", "Split window"), - Gtk::AccelKey(keybindings_.config_ - .key_map()["split_window"]),//"S"), + Gtk::AccelKey(Singleton::Config::keybindings() + ->key_map["split_window"]),//"S"), [this]() { OnWindowSplitWindow(); }); - keybindings_.action_group_menu()->add(Gtk::Action::create("ProjectMenu", + keybindings->action_group_menu->add(Gtk::Action::create("ProjectMenu", "P_roject")); - keybindings_.action_group_menu()->add(Gtk::Action::create("PluginMenu", + keybindings->action_group_menu->add(Gtk::Action::create("PluginMenu", "_Plugins")); - keybindings_.action_group_menu()->add(Gtk::Action::create("HelpMenu", + keybindings->action_group_menu->add(Gtk::Action::create("HelpMenu", Gtk::Stock::HELP)); - keybindings_.action_group_menu()->add(Gtk::Action::create("HelpAbout", + keybindings->action_group_menu->add(Gtk::Action::create("HelpAbout", Gtk::Stock::ABOUT), [this]() { OnHelpAbout(); }); - keybindings_.action_group_hidden()->add(Gtk::Action::create("Test"), + keybindings->action_group_hidden->add(Gtk::Action::create("Test"), Gtk::AccelKey("K"), [this]() { OnHelpAbout(); }); - //keybindings_.BuildMenu(); // moved to window.cc - keybindings_.BuildHiddenMenu(); + //keybindings->BuildMenu(); // moved to window.cc + keybindings->BuildHiddenMenu(); } // Controller Gtk::Box &Menu::Controller::view() { - return menu_view_.view(keybindings_.ui_manager_menu()); + return menu_view_.view(Singleton::keybindings()->ui_manager_menu); } void Menu::Controller::OnPluginAddSnippet() { //TODO(Forgi add you snippet magic code) diff --git a/juci/menu.h b/juci/menu.h index f743999..0396e96 100644 --- a/juci/menu.h +++ b/juci/menu.h @@ -2,8 +2,7 @@ #define JUCI_MENU_H_ #include -#include "gtkmm.h" -#include "keybindings.h" +#include namespace Menu { class View { @@ -15,10 +14,9 @@ namespace Menu { }; // class View class Controller { public: - explicit Controller(Keybindings::Controller& keybindings); + Controller(); Gtk::Box &view(); - Keybindings::Controller &keybindings_; View menu_view_; void OnFileNewEmptyfile(); void OnFileNewCCFile(); diff --git a/juci/notebook.cc b/juci/notebook.cc index 1398225..ac149d8 100644 --- a/juci/notebook.cc +++ b/juci/notebook.cc @@ -1,6 +1,7 @@ #include #include "notebook.h" #include "logging.h" +#include "singletons.h" #include // c-library @@ -9,95 +10,86 @@ Notebook::View::View() { set_position(120); } -Notebook::Controller::Controller(Keybindings::Controller& keybindings, - Terminal::Controller& terminal, - Directories::Config& dir_cfg) : - terminal(terminal), - directories(dir_cfg) { +Notebook::Controller::Controller() : + directories() { INFO("Create notebook"); - refClipboard_ = Gtk::Clipboard::get(); + clipboard = Gtk::Clipboard::get(); view.pack1(directories.widget(), true, true); - CreateKeybindings(keybindings); + CreateKeybindings(); INFO("Notebook Controller Success"); } // Constructor -void Notebook::Controller::CreateKeybindings(Keybindings::Controller - &keybindings) { +void Notebook::Controller::CreateKeybindings() { + auto keybindings=Singleton::keybindings(); + auto keybindings_cfg=Singleton::Config::keybindings(); INFO("Notebook create signal handlers"); directories.m_TreeView.signal_row_activated() .connect(sigc::mem_fun(*this, &Notebook::Controller::OnDirectoryNavigation)); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("FileMenu", Gtk::Stock::FILE)); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("FileNewFile", "New file"), - Gtk::AccelKey(keybindings.config_ - .key_map()["new_file"]), + Gtk::AccelKey(keybindings_cfg->key_map["new_file"]), [this]() { OnFileNewFile(); }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("WindowCloseTab", "Close tab"), - Gtk::AccelKey(keybindings.config_ - .key_map()["close_tab"]), + Gtk::AccelKey(keybindings_cfg->key_map["close_tab"]), [this]() { OnCloseCurrentPage(); }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditFind", "Find"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_find"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_find"]), [this]() { entry.show_search(""); }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditCopy", "Copy"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_copy"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_copy"]), [this]() { if (Pages() != 0) { - CurrentTextView().get_buffer()->copy_clipboard(refClipboard_); + CurrentSourceView()->get_buffer()->copy_clipboard(clipboard); } }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditCut", "Cut"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_cut"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_cut"]), [this]() { if (Pages() != 0) { - CurrentTextView().get_buffer()->cut_clipboard(refClipboard_); + CurrentSourceView()->get_buffer()->cut_clipboard(clipboard); } }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditPaste", "Paste"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_paste"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_paste"]), [this]() { if (Pages() != 0) { - CurrentTextView().get_buffer()->paste_clipboard(refClipboard_); + CurrentSourceView()->get_buffer()->paste_clipboard(clipboard); } }); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditUndo", "Undo"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_undo"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_undo"]), [this]() { INFO("On undo"); Glib::RefPtr undo_manager = - CurrentTextView().get_source_buffer()->get_undo_manager(); + CurrentSourceView()->get_source_buffer()->get_undo_manager(); if (Pages() != 0 && undo_manager->can_undo()) { undo_manager->undo(); } @@ -105,15 +97,14 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller } ); - keybindings.action_group_menu()-> + keybindings->action_group_menu-> add(Gtk::Action::create("EditRedo", "Redo"), - Gtk::AccelKey(keybindings.config_ - .key_map()["edit_redo"]), + Gtk::AccelKey(keybindings_cfg->key_map["edit_redo"]), [this]() { INFO("On Redo"); Glib::RefPtr undo_manager = - CurrentTextView().get_source_buffer()->get_undo_manager(); + CurrentSourceView()->get_source_buffer()->get_undo_manager(); if (Pages() != 0 && undo_manager->can_redo()) { undo_manager->redo(); } @@ -162,56 +153,42 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller INFO("Notebook signal handlers sucsess"); } -Notebook::Controller::~Controller() { - INFO("Notebook destructor"); - for (auto &i : editor_vec_) delete i; - for (auto &i : scrolledtext_vec_) delete i; -} - void Notebook::Controller::OnOpenFile(std::string path) { INFO("Notebook open file"); INFO("Notebook create page"); - text_vec_.emplace_back(new Source::Controller(path, project_path, terminal)); - scrolledtext_vec_.push_back(new Gtk::ScrolledWindow()); - editor_vec_.push_back(new Gtk::HBox()); - scrolledtext_vec_.back()->add(*text_vec_.back()->view); - editor_vec_.back()->pack_start(*scrolledtext_vec_.back(), true, true); - size_t pos = path.find_last_of("/\\"); // TODO #windows - std::string filename=path; - if(pos!=std::string::npos) - filename=path.substr(pos+1); - Notebook().append_page(*editor_vec_.back(), filename); - Notebook().show_all_children(); - Notebook().set_current_page(Pages()-1); - Notebook().set_focus_child(*text_vec_.back()->view); + source_views.emplace_back(new Source(path, project_path)); + scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); + hboxes.emplace_back(new Gtk::HBox()); + scrolled_windows.back()->add(*source_views.back()->view); + hboxes.back()->pack_start(*scrolled_windows.back(), true, true); + boost::filesystem::path file_path(source_views.back()->view->file_path); + std::string title=file_path.filename().string(); + view.notebook.append_page(*hboxes.back(), title); + view.notebook.show_all_children(); + view.notebook.set_current_page(Pages()-1); + view.notebook.set_focus_child(*source_views.back()->view); + CurrentSourceView()->get_buffer()->set_modified(false); //Add star on tab label when the page is not saved: - //TODO: instead use Gtk::TextBuffer::set_modified and Gtk::TextBuffer::get_modified - text_vec_.back()->buffer()->signal_changed().connect([this]() { - if(text_vec_.at(CurrentPage())->is_saved) { - std::string path=CurrentTextView().file_path; - size_t pos = path.find_last_of("/\\"); - std::string filename=path; - if(pos!=std::string::npos) - filename=path.substr(pos+1); - Notebook().set_tab_label_text(*(Notebook().get_nth_page(CurrentPage())), filename+"*"); - } - text_vec_.at(CurrentPage())->is_saved=false; + CurrentSourceView()->get_buffer()->signal_modified_changed().connect([this]() { + boost::filesystem::path file_path(CurrentSourceView()->file_path); + std::string title=file_path.filename().string(); + if(CurrentSourceView()->get_buffer()->get_modified()) + title+="*"; + view.notebook.set_tab_label_text(*(view.notebook.get_nth_page(CurrentPage())), title); }); } void Notebook::Controller::OnCloseCurrentPage() { INFO("Notebook close page"); if (Pages() != 0) { - if(!text_vec_.at(CurrentPage())->is_saved){ + if(CurrentSourceView()->get_buffer()->get_modified()){ AskToSaveDialog(); } int page = CurrentPage(); - Notebook().remove_page(page); - delete scrolledtext_vec_.at(page); - delete editor_vec_.at(page); - text_vec_.erase(text_vec_.begin()+ page); - scrolledtext_vec_.erase(scrolledtext_vec_.begin()+page); - editor_vec_.erase(editor_vec_.begin()+page); + view.notebook.remove_page(page); + source_views.erase(source_views.begin()+ page); + scrolled_windows.erase(scrolled_windows.begin()+page); + hboxes.erase(hboxes.begin()+page); } } void Notebook::Controller::OnFileNewFile() { @@ -220,10 +197,10 @@ void Notebook::Controller::OnFileNewFile() { void Notebook::Controller::search(bool forward) { INFO("Notebook search"); - auto start = CurrentTextView().search_start; - auto end = CurrentTextView().search_end; + auto start = CurrentSourceView()->search_start; + auto end = CurrentSourceView()->search_end; // fetch buffer and greate settings - auto buffer = CurrentTextView().get_source_buffer(); + auto buffer = CurrentSourceView()->get_source_buffer(); auto settings = gtk_source_search_settings_new(); // get search text from entry gtk_source_search_settings_set_search_text(settings, entry().c_str()); @@ -247,9 +224,9 @@ void Notebook::Controller::search(bool forward) { end.gobj()); } buffer->apply_tag_by_name("search", start, end); - CurrentTextView().scroll_to(end); - CurrentTextView().search_start = start; - CurrentTextView().search_end = end; + CurrentSourceView()->scroll_to(end); + CurrentSourceView()->search_start = start; + CurrentSourceView()->search_end = end; } void Notebook::Controller @@ -274,40 +251,34 @@ void Notebook::Controller } } -Source::View& Notebook::Controller::CurrentTextView() { +Source::View* Notebook::Controller::CurrentSourceView() { INFO("Getting sourceview"); - return *text_vec_.at(CurrentPage())->view; + return source_views.at(CurrentPage())->view.get(); } int Notebook::Controller::CurrentPage() { - return Notebook().get_current_page(); + return view.notebook.get_current_page(); } int Notebook::Controller::Pages() { - return Notebook().get_n_pages(); -} -Gtk::Notebook& Notebook::Controller::Notebook() { - return view.notebook; + return view.notebook.get_n_pages(); } bool Notebook::Controller:: OnSaveFile() { - std::string path=CurrentTextView().file_path; + std::string path=CurrentSourceView()->file_path; return OnSaveFile(path); } bool Notebook::Controller:: OnSaveFile(std::string path) { INFO("Notebook save file with path"); - if (path != "") { + if (path != "" && CurrentSourceView()->get_buffer()->get_modified()) { std::ofstream file; file.open (path); - file << CurrentTextView().get_buffer()->get_text(); + file << CurrentSourceView()->get_buffer()->get_text(); file.close(); - CurrentTextView().file_path=path; - size_t pos = path.find_last_of("/\\"); - std::string filename=path; - if(pos!=std::string::npos) - filename=path.substr(pos+1); - Notebook().set_tab_label_text(*Notebook().get_nth_page(CurrentPage()), filename); - text_vec_.at(CurrentPage())->is_saved=true; + boost::filesystem::path path(CurrentSourceView()->file_path); + std::string title=path.filename().string(); + view.notebook.set_tab_label_text(*view.notebook.get_nth_page(CurrentPage()), title); + CurrentSourceView()->get_buffer()->set_modified(false); return true; } return false; @@ -350,7 +321,7 @@ void Notebook::Controller::AskToSaveDialog() { false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO); dialog.set_secondary_text( "Do you want to save: " + - CurrentTextView().file_path+" ?"); + CurrentSourceView()->file_path+" ?"); DEBUG("AskToSaveDialog: run dialog"); int result = dialog.run(); diff --git a/juci/notebook.h b/juci/notebook.h index 8ff76b1..13808c2 100644 --- a/juci/notebook.h +++ b/juci/notebook.h @@ -11,8 +11,6 @@ #include #include #include "clangmm.h" -#include "keybindings.h" -#include "terminal.h" namespace Notebook { class View : public Gtk::Paned { @@ -22,13 +20,9 @@ namespace Notebook { }; class Controller { public: - Controller(Keybindings::Controller& keybindings, - Terminal::Controller& terminal, - Directories::Config& dir_cfg); - ~Controller(); - Source::View& CurrentTextView(); + Controller(); + Source::View* CurrentSourceView(); int CurrentPage(); - Gtk::Notebook& Notebook(); void OnCloseCurrentPage(); void OnFileNewFile(); bool OnSaveFile(); @@ -43,18 +37,14 @@ namespace Notebook { std::string project_path; Directories::Controller directories; //Todo: make private after creating open_directory() Entry entry; - std::vector > text_vec_; + std::vector > source_views; private: - void CreateKeybindings(Keybindings::Controller& keybindings); + void CreateKeybindings(); void AskToSaveDialog(); - Glib::RefPtr m_refBuilder; - Glib::RefPtr refActionGroup; - Terminal::Controller& terminal; - std::vector scrolledtext_vec_; - std::vector editor_vec_; - std::list listTargets_; - Glib::RefPtr refClipboard_; + std::vector > scrolled_windows; + std::vector > hboxes; + Glib::RefPtr clipboard; }; // class controller } // namespace Notebook #endif // JUCI_NOTEBOOK_H_ diff --git a/juci/singletons.cc b/juci/singletons.cc index eaa2909..08ba603 100644 --- a/juci/singletons.cc +++ b/juci/singletons.cc @@ -1,3 +1,31 @@ #include "singletons.h" -std::unique_ptr Singletons::Config::source_=std::unique_ptr(new Source::Config()); +std::unique_ptr Singleton::Config::source_=std::unique_ptr(new Source::Config()); +std::unique_ptr Singleton::Config::terminal_=std::unique_ptr(new Terminal::Config()); +std::unique_ptr Singleton::Config::directories_=std::unique_ptr(new Directories::Config()); +std::unique_ptr Singleton::Config::keybindings_=std::unique_ptr(new Keybindings::Config()); + +std::unique_ptr Singleton::terminal_=std::unique_ptr(); +std::unique_ptr Singleton::keybindings_=std::unique_ptr(); +std::unique_ptr Singleton::notebook_=std::unique_ptr(); +std::unique_ptr Singleton::menu_=std::unique_ptr(); +Terminal::Controller *Singleton::terminal() { + if(!terminal_) + terminal_=std::unique_ptr(new Terminal::Controller()); + return terminal_.get(); +} +Keybindings *Singleton::keybindings() { + if(!keybindings_) + keybindings_=std::unique_ptr(new Keybindings()); + return keybindings_.get(); +} +Notebook::Controller *Singleton::notebook() { + if(!notebook_) + notebook_=std::unique_ptr(new Notebook::Controller()); + return notebook_.get(); +} +Menu::Controller *Singleton::menu() { + if(!menu_) + menu_=std::unique_ptr(new Menu::Controller()); + return menu_.get(); +} \ No newline at end of file diff --git a/juci/singletons.h b/juci/singletons.h index 6098094..35221ef 100644 --- a/juci/singletons.h +++ b/juci/singletons.h @@ -5,16 +5,33 @@ #include "source.h" #include "directories.h" #include "terminal.h" +#include "notebook.h" +#include "menu.h" -namespace Singletons { +class Singleton { +public: class Config { public: - static Source::Config *source() { - return source_.get(); - } + static Source::Config *source() {return source_.get();} + static Terminal::Config *terminal() {return terminal_.get();} + static Directories::Config *directories() {return directories_.get();} + static Keybindings::Config *keybindings() {return keybindings_.get();} private: static std::unique_ptr source_; + static std::unique_ptr terminal_; + static std::unique_ptr directories_; + static std::unique_ptr keybindings_; }; -} + + static Terminal::Controller *terminal(); + static Keybindings *keybindings(); + static Notebook::Controller *notebook(); + static Menu::Controller *menu(); +private: + static std::unique_ptr terminal_; + static std::unique_ptr keybindings_; + static std::unique_ptr notebook_; + static std::unique_ptr menu_; +}; #endif // JUCI_SINGLETONS_H_ diff --git a/juci/source.cc b/juci/source.cc index abc00c0..f01d35b 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -29,19 +29,19 @@ Source::View::View(const std::string& file_path, const std::string& project_path file_path(file_path), project_path(project_path) { Gsv::init(); set_smart_home_end(Gsv::SMART_HOME_END_BEFORE); - set_show_line_numbers(Singletons::Config::source()->show_line_numbers); - set_highlight_current_line(Singletons::Config::source()->highlight_current_line); + set_show_line_numbers(Singleton::Config::source()->show_line_numbers); + set_highlight_current_line(Singleton::Config::source()->highlight_current_line); sourcefile s(file_path); get_source_buffer()->get_undo_manager()->begin_not_undoable_action(); get_source_buffer()->set_text(s.get_content()); get_source_buffer()->get_undo_manager()->end_not_undoable_action(); search_start = search_end = this->get_buffer()->end(); - override_font(Pango::FontDescription(Singletons::Config::source()->font)); + override_font(Pango::FontDescription(Singleton::Config::source()->font)); - override_background_color(Gdk::RGBA(Singletons::Config::source()->background)); - override_background_color(Gdk::RGBA(Singletons::Config::source()->background_selected), Gtk::StateFlags::STATE_FLAG_SELECTED); - for (auto &item : Singletons::Config::source()->tags) { + override_background_color(Gdk::RGBA(Singleton::Config::source()->background)); + override_background_color(Gdk::RGBA(Singleton::Config::source()->background_selected), Gtk::StateFlags::STATE_FLAG_SELECTED); + for (auto &item : Singleton::Config::source()->tags) { get_source_buffer()->create_tag(item.first)->property_foreground() = item.second; } } @@ -64,7 +64,7 @@ string Source::View::get_line_before_insert() { //Basic indentation bool Source::View::on_key_press_event(GdkEventKey* key) { - auto config=Singletons::Config::source(); + auto config=Singleton::Config::source(); const std::regex spaces_regex(std::string("^(")+config->tab_char+"*).*$"); //Indent as in next or previous line if(key->keyval==GDK_KEY_Return && key->state==0) { @@ -142,17 +142,14 @@ bool Source::View::on_key_press_event(GdkEventKey* key) { return Gsv::View::on_key_press_event(key); } -////////////////// -//// ClangView /// -////////////////// -clang::Index Source::ClangView::clang_index(0, 0); +///////////////////////// +//// ClangViewParse /// +///////////////////////// +clang::Index Source::ClangViewParse::clang_index(0, 0); -Source::ClangView::ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal): -Source::View(file_path, project_path), terminal(terminal), -parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { - similar_tokens_tag=get_buffer()->create_tag(); - similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; - +Source::ClangViewParse::ClangViewParse(const std::string& file_path, const std::string& project_path): +Source::View(file_path, project_path), +parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { int start_offset = get_source_buffer()->begin().get_offset(); int end_offset = get_source_buffer()->end().get_offset(); auto buffer_map=get_buffer_map(); @@ -185,7 +182,7 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { parse_thread_go=true; }); - parsing_in_progress=this->terminal.print_in_progress("Parsing "+file_path); + parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path); parse_done.connect([this](){ if(parse_thread_mapped) { if(parsing_mutex.try_lock()) { @@ -228,16 +225,12 @@ parse_thread_go(true), parse_thread_mapped(false), parse_thread_stop(false) { start_reparse(); type_tooltips.hide(); diagnostic_tooltips.hide(); - if(last_similar_tokens_tagged!="") { - get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); - last_similar_tokens_tagged=""; - } }); - get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangView::on_mark_set), false); + get_buffer()->signal_mark_set().connect(sigc::mem_fun(*this, &Source::ClangViewParse::on_mark_set), false); } -Source::ClangView::~ClangView() { +Source::ClangViewParse::~ClangViewParse() { //TODO: Is it possible to stop the clang-process in progress? parsing_in_progress->cancel("canceled"); parse_thread_stop=true; @@ -247,7 +240,7 @@ Source::ClangView::~ClangView() { parsing_mutex.unlock(); } -void Source::ClangView:: +void Source::ClangViewParse:: init_syntax_highlighting(const std::map &buffers, int start_offset, @@ -260,13 +253,13 @@ init_syntax_highlighting(const std::map clang_tokens=clang_tu->get_tokens(0, buffers.find(file_path)->second.size()-1); } -std::map Source::ClangView::get_buffer_map() const { +std::map Source::ClangViewParse::get_buffer_map() const { std::map buffer_map; buffer_map[file_path]=get_source_buffer()->get_text().raw(); return buffer_map; } -void Source::ClangView::start_reparse() { +void Source::ClangViewParse::start_reparse() { parse_thread_mapped=false; clang_readable=false; delayed_reparse_connection.disconnect(); @@ -276,14 +269,13 @@ void Source::ClangView::start_reparse() { }, 1000); } -int Source::ClangView::reparse(const std::map &buffer) { +int Source::ClangViewParse::reparse(const std::map &buffer) { int status = clang_tu->ReparseTranslationUnit(buffer); clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer_map.find(file_path)->second.size()-1); return status; } -std::vector Source::ClangView:: -get_compilation_commands() { +std::vector Source::ClangViewParse::get_compilation_commands() { clang::CompilationDatabase db(project_path); clang::CompileCommands commands(file_path, db); std::vector cmds = commands.get_commands(); @@ -299,7 +291,7 @@ get_compilation_commands() { return arguments; } -void Source::ClangView::update_syntax() { +void Source::ClangViewParse::update_syntax() { std::vector ranges; for (auto &token : *clang_tokens) { if(token.get_kind()==0) // PunctuationToken @@ -321,19 +313,19 @@ void Source::ClangView::update_syntax() { for (auto &range : ranges) { std::string type = std::to_string(range.kind); try { - Singletons::Config::source()->types.at(type); + Singleton::Config::source()->types.at(type); } catch (std::exception) { continue; } Gtk::TextIter begin_iter = buffer->get_iter_at_offset(range.start_offset); Gtk::TextIter end_iter = buffer->get_iter_at_offset(range.end_offset); - buffer->apply_tag_by_name(Singletons::Config::source()->types.at(type), + buffer->apply_tag_by_name(Singleton::Config::source()->types.at(type), begin_iter, end_iter); } } -void Source::ClangView::update_diagnostics() { +void Source::ClangViewParse::update_diagnostics() { diagnostic_tooltips.clear(); auto diagnostics=clang_tu->get_diagnostics(); for(auto &diagnostic: diagnostics) { @@ -371,7 +363,7 @@ void Source::ClangView::update_diagnostics() { } } -void Source::ClangView::update_types() { +void Source::ClangViewParse::update_types() { type_tooltips.clear(); for(auto &token: *clang_tokens) { if(token.has_type()) { @@ -391,7 +383,7 @@ void Source::ClangView::update_types() { } } -bool Source::ClangView::on_motion_notify_event(GdkEventMotion* event) { +bool Source::ClangViewParse::on_motion_notify_event(GdkEventMotion* event) { delayed_tooltips_connection.disconnect(); if(clang_readable) { Gdk::Rectangle rectangle(event->x, event->y, 1, 1); @@ -407,7 +399,7 @@ bool Source::ClangView::on_motion_notify_event(GdkEventMotion* event) { return Source::View::on_motion_notify_event(event); } -void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark) { +void Source::ClangViewParse::on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark) { if(get_buffer()->get_has_selection() && mark->get_name()=="selection_bound") delayed_tooltips_connection.disconnect(); @@ -429,47 +421,18 @@ void Source::ClangView::on_mark_set(const Gtk::TextBuffer::iterator& iterator, c return false; }, 500); type_tooltips.hide(); - diagnostic_tooltips.hide(); - - bool found=false; - if(clang_readable) { - for(auto &token: *clang_tokens) { - if(token.has_type()) { - auto insert_offset=(unsigned)get_buffer()->get_insert()->get_iter().get_offset(); - if(insert_offset>=token.offsets.first && insert_offset<=token.offsets.second) { - found=true; - auto referenced=token.get_cursor().get_referenced(); - if(referenced) { - auto usr_and_spelling=referenced.get_usr()+token.get_spelling(); - if(last_similar_tokens_tagged!=usr_and_spelling) { - get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); - auto offsets=clang_tokens->get_similar_token_offsets(token); - for(auto &offset: offsets) { - get_buffer()->apply_tag(similar_tokens_tag, get_buffer()->get_iter_at_offset(offset.first), get_buffer()->get_iter_at_offset(offset.second)); - } - last_similar_tokens_tagged=usr_and_spelling; - break; - } - } - } - } - } - } - if(!found && last_similar_tokens_tagged!="") { - get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); - last_similar_tokens_tagged=""; - } + diagnostic_tooltips.hide(); } } -bool Source::ClangView::on_focus_out_event(GdkEventFocus* event) { +bool Source::ClangViewParse::on_focus_out_event(GdkEventFocus* event) { delayed_tooltips_connection.disconnect(); type_tooltips.hide(); diagnostic_tooltips.hide(); return Source::View::on_focus_out_event(event); } -bool Source::ClangView::on_scroll_event(GdkEventScroll* event) { +bool Source::ClangViewParse::on_scroll_event(GdkEventScroll* event) { delayed_tooltips_connection.disconnect(); type_tooltips.hide(); diagnostic_tooltips.hide(); @@ -478,8 +441,8 @@ bool Source::ClangView::on_scroll_event(GdkEventScroll* event) { //Clang indentation //TODO: replace indentation methods with a better implementation or maybe use libclang -bool Source::ClangView::on_key_press_event(GdkEventKey* key) { - auto config=Singletons::Config::source(); +bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { + auto config=Singleton::Config::source(); const std::regex bracket_regex(std::string("^(")+config->tab_char+"*).*\\{ *$"); const std::regex no_bracket_statement_regex(std::string("^(")+config->tab_char+"*)(if|for|else if|catch|while) *\\(.*[^;}] *$"); const std::regex no_bracket_no_para_statement_regex(std::string("^(")+config->tab_char+"*)(else|try|do) *$"); @@ -566,8 +529,8 @@ bool Source::ClangView::on_key_press_event(GdkEventKey* key) { ////////////////////////////// //// ClangViewAutocomplete /// ////////////////////////////// -Source::ClangViewAutocomplete::ClangViewAutocomplete(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal): -Source::ClangView(file_path, project_path, terminal), selection_dialog(*this), autocomplete_cancel_starting(false) { +Source::ClangViewAutocomplete::ClangViewAutocomplete(const std::string& file_path, const std::string& project_path): +Source::ClangViewParse(file_path, project_path), selection_dialog(*this), autocomplete_cancel_starting(false) { selection_dialog.on_hide=[this](){ start_reparse(); }; @@ -606,7 +569,7 @@ bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { if(selection_dialog.on_key_press(key)) return true; } - return ClangView::on_key_press_event(key); + return ClangViewParse::on_key_press_event(key); } bool Source::ClangViewAutocomplete::on_focus_out_event(GdkEventFocus* event) { @@ -614,13 +577,13 @@ bool Source::ClangViewAutocomplete::on_focus_out_event(GdkEventFocus* event) { selection_dialog.hide(); } - return Source::ClangView::on_focus_out_event(event); + return Source::ClangViewParse::on_focus_out_event(event); } void Source::ClangViewAutocomplete::start_autocomplete() { - const std::regex autocomplete_keys("[a-zA-Z0-9_>\\.:]"); - std::smatch sm; - if(!std::regex_match(std::string()+(char)last_keyval, sm, autocomplete_keys)) { + if(!((last_keyval>='0' && last_keyval<='9') || + (last_keyval>='a' && last_keyval<='z') || (last_keyval>='A' && last_keyval<='Z') || + last_keyval=='_' || last_keyval=='>' || last_keyval=='.' || last_keyval==':')) { autocomplete_cancel_starting=true; return; } @@ -628,6 +591,7 @@ void Source::ClangViewAutocomplete::start_autocomplete() { if((std::count(line.begin(), line.end(), '\"')%2)!=1 && line.find("//")==std::string::npos) { const std::regex in_specified_namespace("^(.*[a-zA-Z0-9_\\)])(->|\\.|::)([a-zA-Z0-9_]*)$"); const std::regex within_namespace("^(.*)([^a-zA-Z0-9_]+)([a-zA-Z0-9_]{3,})$"); + std::smatch sm; if(std::regex_match(line, sm, in_specified_namespace)) { prefix_mutex.lock(); prefix=sm[3].str(); @@ -730,7 +694,7 @@ get_autocomplete_suggestions(int line_number, int column, std::mapcreate_tag(); + similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; + + get_buffer()->signal_changed().connect([this]() { + if(last_similar_tokens_tagged!="") { + get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); + last_similar_tokens_tagged=""; + } + }); + + get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark){ + if(mark->get_name()=="insert") { + bool found=false; + if(clang_readable) { + for(auto &token: *clang_tokens) { + if(token.has_type()) { + auto insert_offset=(unsigned)get_buffer()->get_insert()->get_iter().get_offset(); + if(insert_offset>=token.offsets.first && insert_offset<=token.offsets.second) { + found=true; + auto referenced=token.get_cursor().get_referenced(); + if(referenced) { + auto usr_and_spelling=referenced.get_usr()+token.get_spelling(); + if(last_similar_tokens_tagged!=usr_and_spelling) { + get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); + auto offsets=clang_tokens->get_similar_token_offsets(token); + for(auto &offset: offsets) { + get_buffer()->apply_tag(similar_tokens_tag, get_buffer()->get_iter_at_offset(offset.first), get_buffer()->get_iter_at_offset(offset.second)); + } + last_similar_tokens_tagged=usr_and_spelling; + break; + } + } + } + } + } + } + if(!found && last_similar_tokens_tagged!="") { + get_buffer()->remove_tag(similar_tokens_tag, get_buffer()->begin(), get_buffer()->end()); + last_similar_tokens_tagged=""; + } + } + }); +} + +//////////////// +//// Source //// +//////////////// + +Source::Source(const std::string& file_path, std::string project_path) { if(project_path=="") { project_path=boost::filesystem::path(file_path).parent_path().string(); } - if (Singletons::Config::source()->legal_extension(file_path.substr(file_path.find_last_of(".") + 1))) - view=std::unique_ptr(new ClangViewAutocomplete(file_path, project_path, terminal)); + if (Singleton::Config::source()->legal_extension(file_path.substr(file_path.find_last_of(".") + 1))) + view=std::unique_ptr(new ClangView(file_path, project_path)); else view=std::unique_ptr(new GenericView(file_path, project_path)); INFO("Source Controller with childs constructed"); } - -Glib::RefPtr Source::Controller::buffer() { - return view->get_source_buffer(); -} diff --git a/juci/source.h b/juci/source.h index 7a2a05a..6762980 100644 --- a/juci/source.h +++ b/juci/source.h @@ -14,7 +14,8 @@ #include "tooltips.h" #include "selectiondialog.h" -namespace Source { +class Source { +public: class Config { public: bool legal_extension(std::string e) const ; @@ -59,25 +60,23 @@ namespace Source { public: GenericView(const std::string& file_path, const std::string& project_path): View(file_path, project_path) {} - protected: - bool on_key_press_event(GdkEventKey* key) { - return Source::View::on_key_press_event(key); - } }; - class ClangView : public View { + class ClangViewParse : public View { public: - ClangView(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal); - ~ClangView(); + ClangViewParse(const std::string& file_path, const std::string& project_path); + ~ClangViewParse(); protected: void start_reparse(); bool on_key_press_event(GdkEventKey* key); bool on_focus_out_event(GdkEventFocus* event); std::unique_ptr clang_tu; - std::map get_buffer_map() const; std::mutex parsing_mutex; + std::unique_ptr clang_tokens; + bool clang_readable=false; sigc::connection delayed_reparse_connection; private: + std::map get_buffer_map() const; // inits the syntax highligthing on file open void init_syntax_highlighting(const std::map &buffers, @@ -92,15 +91,10 @@ namespace Source { bool on_motion_notify_event(GdkEventMotion* event); void on_mark_set(const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark); sigc::connection delayed_tooltips_connection; - Glib::RefPtr similar_tokens_tag; - std::string last_similar_tokens_tagged; bool on_scroll_event(GdkEventScroll* event); static clang::Index clang_index; - std::unique_ptr clang_tokens; - bool clang_readable=false; std::vector get_compilation_commands(); - Terminal::Controller& terminal; std::shared_ptr parsing_in_progress; Glib::Dispatcher parse_done; @@ -112,10 +106,10 @@ namespace Source { std::atomic parse_thread_mapped; std::atomic parse_thread_stop; }; - - class ClangViewAutocomplete : public ClangView { + + class ClangViewAutocomplete : public ClangViewParse { public: - ClangViewAutocomplete(const std::string& file_path, const std::string& project_path, Terminal::Controller& terminal); + ClangViewAutocomplete(const std::string& file_path, const std::string& project_path); protected: bool on_key_press_event(GdkEventKey* key); bool on_focus_out_event(GdkEventFocus* event); @@ -133,14 +127,22 @@ namespace Source { std::mutex prefix_mutex; }; - class Controller { + class ClangViewRefactor : public ClangViewAutocomplete { public: - Controller(const std::string& file_path, std::string project_path, Terminal::Controller& terminal); - Glib::RefPtr buffer(); - - bool is_saved = true; - - std::unique_ptr view; - }; // class Controller -} // namespace Source + ClangViewRefactor(const std::string& file_path, const std::string& project_path); + private: + Glib::RefPtr similar_tokens_tag; + std::string last_similar_tokens_tagged; + }; + + class ClangView : public ClangViewRefactor { + public: + ClangView(const std::string& file_path, const std::string& project_path): + ClangViewRefactor(file_path, project_path) {} + }; + + Source(const std::string& file_path, std::string project_path); + + std::unique_ptr view; +}; // class Source #endif // JUCI_SOURCE_H_ diff --git a/juci/terminal.cc b/juci/terminal.cc index cce7496..20f1033 100644 --- a/juci/terminal.cc +++ b/juci/terminal.cc @@ -1,10 +1,11 @@ #include "terminal.h" #include #include "logging.h" +#include "singletons.h" -Terminal::InProgress::InProgress(Controller& terminal, const std::string& start_msg): terminal(terminal), stop(false) { +Terminal::InProgress::InProgress(const std::string& start_msg): stop(false) { waiting_print.connect([this](){ - this->terminal.print(line_nr-1, "."); + Singleton::terminal()->print(line_nr-1, "."); }); start(start_msg); } @@ -16,7 +17,7 @@ Terminal::InProgress::~InProgress() { } void Terminal::InProgress::start(const std::string& msg) { - line_nr=this->terminal.print(msg+"...\n"); + line_nr=Singleton::terminal()->print(msg+"...\n"); wait_thread=std::thread([this](){ size_t c=0; while(!stop) { @@ -31,14 +32,14 @@ void Terminal::InProgress::start(const std::string& msg) { void Terminal::InProgress::done(const std::string& msg) { if(!stop) { stop=true; - this->terminal.print(line_nr-1, msg); + Singleton::terminal()->print(line_nr-1, msg); } } void Terminal::InProgress::cancel(const std::string& msg) { if(!stop) { stop=true; - this->terminal.print(line_nr-1, msg); + Singleton::terminal()->print(line_nr-1, msg); } } @@ -48,8 +49,7 @@ Terminal::View::View(){ add(scrolled_window); } -Terminal::Controller::Controller(Terminal::Config& cfg) : - config(cfg) { +Terminal::Controller::Controller() { folder_command_ = ""; } @@ -65,7 +65,7 @@ void Terminal::Controller::Compile(){ view.text_view.get_buffer()->set_text(""); DEBUG("Terminal: Compile: running cmake command"); - std::vector commands = config.compile_commands; + std::vector commands = Singleton::Config::terminal()->compile_commands; for (size_t it = 0; it < commands.size(); ++it) { ExecuteCommand(commands.at(it), "r"); @@ -79,7 +79,7 @@ void Terminal::Controller::Run(std::string executable) { print("juCi++ execute: " + executable + "\n"); DEBUG("Terminal: Compile: running run command: "); DEBUG_VAR(executable); - ExecuteCommand("cd "+config.run_command + "; ./"+executable, "r"); + ExecuteCommand("cd "+Singleton::Config::terminal()->run_command + "; ./"+executable, "r"); print("\n"); } @@ -100,7 +100,7 @@ void Terminal::Controller::print(int line_nr, std::string message){ } std::shared_ptr Terminal::Controller::print_in_progress(std::string start_msg) { - std::shared_ptr in_progress=std::shared_ptr(new Terminal::InProgress(*this, start_msg)); + std::shared_ptr in_progress=std::shared_ptr(new Terminal::InProgress(start_msg)); return in_progress; } diff --git a/juci/terminal.h b/juci/terminal.h index 317e43e..a5e779b 100644 --- a/juci/terminal.h +++ b/juci/terminal.h @@ -27,13 +27,12 @@ namespace Terminal { //Temporary solution for displaying functions in progress, and when they are done. class InProgress { public: - InProgress(Controller& terminal, const std::string& start_msg); + InProgress(const std::string& start_msg); ~InProgress(); void done(const std::string& msg); void cancel(const std::string& msg); private: void start(const std::string& msg); - Controller& terminal; int line_nr; std::atomic stop; Glib::Dispatcher waiting_print; @@ -42,7 +41,7 @@ namespace Terminal { class Controller { public: - Controller(Terminal::Config& cfg); + Controller(); void SetFolderCommand(boost::filesystem::path CMake_path); void Run(std::string executable); void Compile(); @@ -51,7 +50,6 @@ namespace Terminal { std::shared_ptr print_in_progress(std::string start_msg); Terminal::View view; private: - Terminal::Config& config; void ExecuteCommand(std::string command, std::string mode); bool OnButtonRealeaseEvent(GdkEventKey* key); bool ExistInConsole(std::string string); diff --git a/juci/tooltips.cc b/juci/tooltips.cc index 01d05f5..62b9476 100644 --- a/juci/tooltips.cc +++ b/juci/tooltips.cc @@ -46,7 +46,7 @@ void Tooltip::adjust(bool disregard_drawn) { tooltip_widget=std::unique_ptr(new Gtk::TextView(this->get_buffer())); tooltip_widget->set_editable(false); - tooltip_widget->override_background_color(Gdk::RGBA(Singletons::Config::source()->background_tooltips)); + tooltip_widget->override_background_color(Gdk::RGBA(Singleton::Config::source()->background_tooltips)); window->add(*tooltip_widget); auto layout=Pango::Layout::create(tooltip_widget->get_pango_context()); diff --git a/juci/window.cc b/juci/window.cc index e281538..4d71aa6 100644 --- a/juci/window.cc +++ b/juci/window.cc @@ -1,128 +1,124 @@ #include "window.h" #include "logging.h" +#include "singletons.h" Window::Window() : - window_box_(Gtk::ORIENTATION_VERTICAL), - main_config(), - keybindings(main_config.keybindings_cfg), - terminal(main_config.terminal_cfg), - notebook(keybindings, terminal, - main_config.dir_cfg), - menu(keybindings), - api(menu, notebook) { + window_box_(Gtk::ORIENTATION_VERTICAL) { INFO("Create Window"); set_title("juCi++"); set_default_size(600, 400); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(window_box_); - keybindings.action_group_menu()->add(Gtk::Action::create("FileQuit", + auto keybindings=Singleton::keybindings(); + auto keybindings_cfg=Singleton::Config::keybindings(); + keybindings->action_group_menu->add(Gtk::Action::create("FileQuit", "Quit juCi++"), - Gtk::AccelKey(keybindings.config_ - .key_map()["quit"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["quit"]), [this]() { OnWindowHide(); }); - keybindings.action_group_menu()->add(Gtk::Action::create("FileOpenFile", + keybindings->action_group_menu->add(Gtk::Action::create("FileOpenFile", "Open file"), - Gtk::AccelKey(keybindings.config_ - .key_map()["open_file"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["open_file"]), [this]() { OnOpenFile(); }); - keybindings.action_group_menu()->add(Gtk::Action::create("FileOpenFolder", + keybindings->action_group_menu->add(Gtk::Action::create("FileOpenFolder", "Open folder"), - Gtk::AccelKey(keybindings.config_ - .key_map()["open_folder"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["open_folder"]), [this]() { OnFileOpenFolder(); }); - keybindings. - action_group_menu()-> + keybindings-> + action_group_menu-> add(Gtk::Action::create("FileSaveAs", "Save as"), - Gtk::AccelKey(keybindings.config_ - .key_map()["save_as"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["save_as"]), [this]() { SaveFileAs(); }); - keybindings. - action_group_menu()-> + keybindings-> + action_group_menu-> add(Gtk::Action::create("FileSave", "Save"), - Gtk::AccelKey(keybindings.config_ - .key_map()["save"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["save"]), [this]() { SaveFile(); }); - keybindings. - action_group_menu()-> + keybindings-> + action_group_menu-> add(Gtk::Action::create("ProjectCompileAndRun", "Compile And Run"), - Gtk::AccelKey(keybindings.config_ - .key_map()["compile_and_run"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["compile_and_run"]), [this]() { SaveFile(); if (running.try_lock()) { - std::thread execute([=]() { - std::string path = notebook.CurrentTextView().file_path; + std::thread execute([this]() { + std::string path = Singleton::notebook()->CurrentSourceView()->file_path; size_t pos = path.find_last_of("/\\"); if(pos != std::string::npos) { path.erase(path.begin()+pos,path.end()); - terminal.SetFolderCommand(path); + Singleton::terminal()->SetFolderCommand(path); } - terminal.Compile(); - std::string executable = notebook.directories. + Singleton::terminal()->Compile(); + std::string executable = Singleton::notebook()->directories. GetCmakeVarValue(path,"add_executable"); - terminal.Run(executable); + Singleton::terminal()->Run(executable); running.unlock(); }); execute.detach(); } }); - keybindings. - action_group_menu()-> + keybindings-> + action_group_menu-> add(Gtk::Action::create("ProjectCompile", "Compile"), - Gtk::AccelKey(keybindings.config_ - .key_map()["compile"]), + Gtk::AccelKey(keybindings_cfg + ->key_map["compile"]), [this]() { SaveFile(); if (running.try_lock()) { - std::thread execute([=]() { - std::string path = notebook.CurrentTextView().file_path; + std::thread execute([this]() { + std::string path = Singleton::notebook()->CurrentSourceView()->file_path; size_t pos = path.find_last_of("/\\"); if(pos != std::string::npos){ path.erase(path.begin()+pos,path.end()); - terminal.SetFolderCommand(path); + Singleton::terminal()->SetFolderCommand(path); } - terminal.Compile(); + Singleton::terminal()->Compile(); running.unlock(); }); execute.detach(); } }); - add_accel_group(keybindings.ui_manager_menu()->get_accel_group()); - add_accel_group(keybindings.ui_manager_hidden()->get_accel_group()); - keybindings.BuildMenu(); + add_accel_group(keybindings->ui_manager_menu->get_accel_group()); + add_accel_group(keybindings->ui_manager_hidden->get_accel_group()); + keybindings->BuildMenu(); - window_box_.pack_start(menu.view(), Gtk::PACK_SHRINK); + window_box_.pack_start(Singleton::menu()->view(), Gtk::PACK_SHRINK); - window_box_.pack_start(notebook.entry, Gtk::PACK_SHRINK); + window_box_.pack_start(Singleton::notebook()->entry, Gtk::PACK_SHRINK); paned_.set_position(300); - paned_.pack1(notebook.view, true, false); - paned_.pack2(terminal.view, true, true); + paned_.pack1(Singleton::notebook()->view, true, false); + paned_.pack2(Singleton::terminal()->view, true, true); window_box_.pack_end(paned_); show_all_children(); INFO("Window created"); } // Window constructor void Window::OnWindowHide() { - for(size_t c=0;csource_views.size();c++) + Singleton::notebook()->OnCloseCurrentPage(); //TODO: This only works on one page at the momemt. Change to Singleton::notebook()->close_page(page_nr); hide(); } void Window::OnFileOpenFolder() { @@ -141,8 +137,8 @@ void Window::OnFileOpenFolder() { case(Gtk::RESPONSE_OK): { std::string project_path=dialog.get_filename(); - notebook.project_path=project_path; - notebook.directories.open_folder(project_path); + Singleton::notebook()->project_path=project_path; + Singleton::notebook()->directories.open_folder(project_path); break; } case(Gtk::RESPONSE_CANCEL): @@ -190,7 +186,7 @@ void Window::OnOpenFile() { switch (result) { case(Gtk::RESPONSE_OK): { std::string path = dialog.get_filename(); - notebook.OnOpenFile(path); + Singleton::notebook()->OnOpenFile(path); break; } case(Gtk::RESPONSE_CANCEL): { @@ -203,20 +199,19 @@ void Window::OnOpenFile() { } bool Window::SaveFile() { - if(notebook.OnSaveFile()) { - terminal.print("File saved to: " + - notebook.CurrentTextView().file_path+"\n"); + if(Singleton::notebook()->OnSaveFile()) { + Singleton::terminal()->print("File saved to: " + + Singleton::notebook()->CurrentSourceView()->file_path+"\n"); return true; } - terminal.print("File not saved"); return false; } bool Window::SaveFileAs() { - if(notebook.OnSaveFile(notebook.OnSaveFileAs())){ - terminal.print("File saved to: " + - notebook.CurrentTextView().file_path+"\n"); + if(Singleton::notebook()->OnSaveFile(Singleton::notebook()->OnSaveFileAs())){ + Singleton::terminal()->print("File saved to: " + + Singleton::notebook()->CurrentSourceView()->file_path+"\n"); return true; } - terminal.print("File not saved"); + Singleton::terminal()->print("File not saved"); return false; } diff --git a/juci/window.h b/juci/window.h index 782029a..2dce670 100644 --- a/juci/window.h +++ b/juci/window.h @@ -3,7 +3,6 @@ #include "api.h" #include "config.h" -#include "terminal.h" #include @@ -15,10 +14,6 @@ public: virtual ~Window() { } MainConfig main_config; - Keybindings::Controller keybindings; - Menu::Controller menu; - Notebook::Controller notebook; - Terminal::Controller terminal; PluginApi api; private: