From 2ad7b432def88851901f20d0cf2a7fa149608bf5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 16 Sep 2015 16:37:36 +0200 Subject: [PATCH] Now reconfigures juci when config.json is saved, although could not do this for keybindings due to depricated functions I guess. Also some smaller fixes. --- README.md | 2 +- src/config.cc | 2 + src/files.h | 1 + src/juci.cc | 8 +- src/menu.cc | 11 +- src/menu.h | 1 - src/source.cc | 353 +++++++++++++++++++++++++++++--------------------- src/source.h | 4 + src/window.cc | 28 +++- src/window.h | 1 + 10 files changed, 243 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index 8fb39cb..bea62b4 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ towards libclang with speed in mind. * Refactoring across files * Highlighting of similar types * Spell checking depending on file context -* Basic editor functionallity +* Basic editor functionality * Write your own plugins in python (disabled at the moment) ## Dependencies ## diff --git a/src/config.cc b/src/config.cc index dc6f934..d05f5f9 100644 --- a/src/config.cc +++ b/src/config.cc @@ -80,6 +80,8 @@ void MainConfig::update_config_file() { if(cfg.count("version")>0) cfg.find("version")->second.data()=default_cfg.get("version"); } + else + return; } catch(const std::exception &e) { cfg_ok=false; diff --git a/src/files.h b/src/files.h index 931d8fa..62d7577 100644 --- a/src/files.h +++ b/src/files.h @@ -47,6 +47,7 @@ const std::string configjson = " \"open_file\": \"o\",\n" " \"save\": \"s\",\n" " \"save_as\": \"s\",\n" +" \"preferences\": \"comma\",\n" " \"quit\": \"q\",\n" " \"split_window\": \"s\",\n" " \"close_tab\": \"w\",\n" diff --git a/src/juci.cc b/src/juci.cc index a97b8ee..67075d2 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -1,6 +1,5 @@ #include "juci.h" #include "singletons.h" -#include "config.h" #include using namespace std; //TODO: remove @@ -69,12 +68,7 @@ void app::on_activate() { } app::app() : Gtk::Application("no.sout.juci", Gio::APPLICATION_NON_UNIQUE | Gio::APPLICATION_HANDLES_COMMAND_LINE) { - MainConfig(); // Read the configs here - auto style_context = Gtk::StyleContext::create(); - auto screen = Gdk::Screen::get_default(); - auto css_provider = Gtk::CssProvider::get_named(Singleton::Config::window()->theme_name, Singleton::Config::window()->theme_variant); - //TODO: add check if theme exists, or else write error to Singleton::terminal() - style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + } int main(int argc, char *argv[]) { diff --git a/src/menu.cc b/src/menu.cc index 6f0d2ef..1357ca9 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -1,15 +1,14 @@ #include "menu.h" #include -Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { +Menu::Menu() { action_group = Gtk::ActionGroup::create(); ui_manager = Gtk::UIManager::create(); - + ui_manager->insert_action_group(action_group); + action_group->add(Gtk::Action::create("FileMenu", "File")); action_group->add(Gtk::Action::create("EditMenu", "Edit")); action_group->add(Gtk::Action::create("WindowMenu", "_Window")); - action_group->add(Gtk::Action::create("WindowSplitWindow", "Split window"), Gtk::AccelKey(key_map["split_window"]), [this]() { - }); action_group->add(Gtk::Action::create("ProjectMenu", "P_roject")); action_group->add(Gtk::Action::create("SourceMenu", "_Source")); action_group->add(Gtk::Action::create("PluginMenu", "_Plugins")); @@ -31,6 +30,8 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { " \n" " \n" " \n" + " \n" + " \n" " \n" " \n" " \n" @@ -61,7 +62,6 @@ Menu::Menu() : box(Gtk::ORIENTATION_VERTICAL) { " \n" " \n" " \n" - " \n" " \n" " \n" " \n" @@ -83,5 +83,6 @@ void Menu::build() { catch (const Glib::Error &ex) { std::cerr << "building menu failed" << ex.what(); } + ui_manager->insert_action_group(action_group); } diff --git a/src/menu.h b/src/menu.h index 257854e..86d7639 100644 --- a/src/menu.h +++ b/src/menu.h @@ -11,7 +11,6 @@ public: Gtk::Widget& get_widget(); void build(); - Gtk::Box box; std::unordered_map key_map; std::string ui_xml; Glib::RefPtr ui_manager; diff --git a/src/source.cc b/src/source.cc index 00e7f2e..8c62866 100644 --- a/src/source.cc +++ b/src/source.cc @@ -78,13 +78,158 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrcreate_tag("def:warning"); + get_buffer()->create_tag("def:warning_underline"); + get_buffer()->create_tag("def:error"); + get_buffer()->create_tag("def:error_underline"); + get_buffer()->create_tag("def:note_background"); + get_buffer()->create_tag("def:note"); + if(spellcheck_config==NULL) + spellcheck_config=new_aspell_config(); + spellcheck_checker=NULL; + auto tag=get_buffer()->create_tag("spellcheck_error"); + tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; + + configure(); + + get_buffer()->signal_changed().connect([this](){ + if(spellcheck_checker==NULL) + return; + + delayed_spellcheck_suggestions_connection.disconnect(); + + auto iter=get_buffer()->get_insert()->get_iter(); + bool ends_line=iter.ends_line(); + if(iter.backward_char()) { + auto context_iter=iter; + bool backward_success=true; + if(ends_line || *iter=='/' || *iter=='*') //iter_has_context_class is sadly bugged + backward_success=context_iter.backward_char(); + if(backward_success) { + if(last_keyval_is_backspace && !is_word_iter(iter) && iter.forward_char()) {} //backspace fix + if((spellcheck_all && !get_source_buffer()->iter_has_context_class(context_iter, "no-spell-check")) || get_source_buffer()->iter_has_context_class(context_iter, "comment") || get_source_buffer()->iter_has_context_class(context_iter, "string")) { + if(!is_word_iter(iter)) { //Might have used space or - to split two words + auto first=iter; + auto second=iter; + if(first.backward_char() && second.forward_char() && !second.starts_line()) { + get_buffer()->remove_tag_by_name("spellcheck_error", first, second); + auto word=spellcheck_get_word(first); + spellcheck_word(word.first, word.second); + word=spellcheck_get_word(second); + spellcheck_word(word.first, word.second); + } + } + else { + auto word=spellcheck_get_word(iter); + spellcheck_word(word.first, word.second); + } + } + } + } + delayed_spellcheck_error_clear.disconnect(); + delayed_spellcheck_error_clear=Glib::signal_timeout().connect([this]() { + auto iter=get_buffer()->begin(); + Gtk::TextIter begin_no_spellcheck_iter; + if(spellcheck_all) { + bool spell_check=!get_source_buffer()->iter_has_context_class(iter, "no-spell-check"); + if(!spell_check) + begin_no_spellcheck_iter=iter; + while(iter!=get_buffer()->end()) { + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter, "no-spell-check")) + iter=get_buffer()->end(); + + spell_check=!spell_check; + if(!spell_check) + begin_no_spellcheck_iter=iter; + else + get_buffer()->remove_tag_by_name("spellcheck_error", begin_no_spellcheck_iter, iter); + } + return false; + } + + bool spell_check=get_source_buffer()->iter_has_context_class(iter, "string") || get_source_buffer()->iter_has_context_class(iter, "comment"); + if(!spell_check) + begin_no_spellcheck_iter=iter; + while(iter!=get_buffer()->end()) { + auto iter1=iter; + auto iter2=iter; + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string")) + iter1=get_buffer()->end(); + if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment")) + iter2=get_buffer()->end(); + + if(iter2remove_tag_by_name("spellcheck_error", begin_no_spellcheck_iter, iter); + } + return false; + }, 1000); + }); + + get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iter, const Glib::RefPtr& mark) { + if(spellcheck_checker==NULL) + return; + + if(mark->get_name()=="insert") { + if(spellcheck_suggestions_dialog_shown) + spellcheck_suggestions_dialog->hide(); + delayed_spellcheck_suggestions_connection.disconnect(); + delayed_spellcheck_suggestions_connection=Glib::signal_timeout().connect([this]() { + auto tags=get_buffer()->get_insert()->get_iter().get_tags(); + bool need_suggestions=false; + for(auto &tag: tags) { + if(tag->property_name()=="spellcheck_error") { + need_suggestions=true; + break; + } + } + if(need_suggestions) { + spellcheck_suggestions_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false)); + spellcheck_suggestions_dialog->on_hide=[this](){ + spellcheck_suggestions_dialog_shown=false; + }; + auto word=spellcheck_get_word(get_buffer()->get_insert()->get_iter()); + auto suggestions=spellcheck_get_suggestions(word.first, word.second); + if(suggestions.size()==0) + return false; + for(auto &suggestion: suggestions) + spellcheck_suggestions_dialog->add_row(suggestion); + spellcheck_suggestions_dialog->on_select=[this, word](const std::string& selected, bool hide_window) { + get_source_buffer()->begin_user_action(); + get_buffer()->erase(word.first, word.second); + get_buffer()->insert(get_buffer()->get_insert()->get_iter(), selected); + get_source_buffer()->end_user_action(); + delayed_tooltips_connection.disconnect(); + }; + spellcheck_suggestions_dialog->show(); + spellcheck_suggestions_dialog_shown=true; + } + return false; + }, 500); + } + }); + + get_buffer()->signal_changed().connect([this](){ + set_info(info); + }); + + set_tooltip_events(); +} + +void Source::View::configure() { //TODO: Move this to notebook? Might take up too much memory doing this for every tab. auto style_scheme_manager=Gsv::StyleSchemeManager::get_default(); style_scheme_manager->prepend_search_path(Singleton::style_dir()); - + if(Singleton::Config::source()->style.size()>0) { auto scheme = style_scheme_manager->get_scheme(Singleton::Config::source()->style); - + if(scheme) get_source_buffer()->set_style_scheme(scheme); else @@ -93,6 +238,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrwrap_lines) set_wrap_mode(Gtk::WrapMode::WRAP_CHAR); + else + set_wrap_mode(Gtk::WrapMode::WRAP_NONE); property_highlight_current_line() = Singleton::Config::source()->highlight_current_line; property_show_line_numbers() = Singleton::Config::source()->show_line_numbers; if(Singleton::Config::source()->font.size()>0) @@ -102,8 +249,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_style_scheme(); auto tag_table=get_buffer()->get_tag_table(); auto style=scheme->get_style("def:warning"); - auto diagnostic_tag=get_source_buffer()->create_tag("def:warning"); - auto diagnostic_tag_underline=get_source_buffer()->create_tag("def:warning_underline"); + auto diagnostic_tag=get_buffer()->get_tag_table()->lookup("def:warning"); + auto diagnostic_tag_underline=get_buffer()->get_tag_table()->lookup("def:warning_underline"); if(style && (style->property_foreground_set() || style->property_background_set())) { Glib::ustring warning_property; if(style->property_foreground_set()) { @@ -112,7 +259,7 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrproperty_background_set()) warning_property=style->property_background().get_value(); - + diagnostic_tag_underline->property_underline()=Pango::Underline::UNDERLINE_ERROR; auto tag_class=G_OBJECT_GET_CLASS(diagnostic_tag_underline->gobj()); //For older GTK+ 3 versions: auto param_spec=g_object_class_find_property(tag_class, "underline-rgba"); @@ -121,8 +268,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_style("def:error"); - diagnostic_tag=get_source_buffer()->create_tag("def:error"); - diagnostic_tag_underline=get_source_buffer()->create_tag("def:error_underline"); + diagnostic_tag=get_buffer()->get_tag_table()->lookup("def:error"); + diagnostic_tag_underline=get_buffer()->get_tag_table()->lookup("def:error_underline"); if(style && (style->property_foreground_set() || style->property_background_set())) { Glib::ustring error_property; if(style->property_foreground_set()) { @@ -140,18 +287,30 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrget_style("def:note"); - auto note_tag=get_source_buffer()->create_tag("def:note_background"); + auto note_tag=get_buffer()->get_tag_table()->lookup("def:note_background"); if(style->property_background_set()) { note_tag->property_background()=style->property_background(); } - note_tag=get_source_buffer()->create_tag("def:note"); + note_tag=get_buffer()->get_tag_table()->lookup("def:note"); if(style->property_foreground_set()) { note_tag->property_foreground()=style->property_foreground(); } - + + if(Singleton::Config::source()->spellcheck_language.size()>0) + aspell_config_replace(spellcheck_config, "lang", Singleton::Config::source()->spellcheck_language.c_str()); + spellcheck_possible_err=new_aspell_speller(spellcheck_config); + if(spellcheck_checker!=NULL) + delete_aspell_speller(spellcheck_checker); + spellcheck_checker=NULL; + if (aspell_error_number(spellcheck_possible_err) != 0) + std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl; + else + spellcheck_checker = to_aspell_speller(spellcheck_possible_err); + get_buffer()->remove_tag_by_name("spellcheck_error", get_buffer()->begin(), get_buffer()->end()); + tab_char=Singleton::Config::source()->default_tab_char; tab_size=Singleton::Config::source()->default_tab_size; if(Singleton::Config::source()->auto_tab_char_and_size) { @@ -170,133 +329,11 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrspellcheck_language.size()>0) - aspell_config_replace(spellcheck_config, "lang", Singleton::Config::source()->spellcheck_language.c_str()); - } - - spellcheck_possible_err=new_aspell_speller(spellcheck_config); - spellcheck_checker=NULL; - if (aspell_error_number(spellcheck_possible_err) != 0) - std::cerr << "Spell check error: " << aspell_error_message(spellcheck_possible_err) << std::endl; - else { - spellcheck_checker = to_aspell_speller(spellcheck_possible_err); - - auto tag=get_buffer()->create_tag("spellcheck_error"); - tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; - - get_buffer()->signal_changed().connect([this](){ - delayed_spellcheck_suggestions_connection.disconnect(); - - auto iter=get_buffer()->get_insert()->get_iter(); - bool ends_line=iter.ends_line(); - if(iter.backward_char()) { - auto context_iter=iter; - bool backward_success=true; - if(ends_line || *iter=='/' || *iter=='*') //iter_has_context_class is sadly bugged - backward_success=context_iter.backward_char(); - if(backward_success) { - if(last_keyval_is_backspace && !is_word_iter(iter) && iter.forward_char()) {} //backspace fix - if((spellcheck_all && !get_source_buffer()->iter_has_context_class(context_iter, "no-spell-check")) || get_source_buffer()->iter_has_context_class(context_iter, "comment") || get_source_buffer()->iter_has_context_class(context_iter, "string")) { - if(!is_word_iter(iter)) { //Might have used space or - to split two words - auto first=iter; - auto second=iter; - if(first.backward_char() && second.forward_char() && !second.starts_line()) { - get_buffer()->remove_tag_by_name("spellcheck_error", first, second); - auto word=spellcheck_get_word(first); - spellcheck_word(word.first, word.second); - word=spellcheck_get_word(second); - spellcheck_word(word.first, word.second); - } - } - else { - auto word=spellcheck_get_word(iter); - spellcheck_word(word.first, word.second); - } - } - } - } - delayed_spellcheck_error_clear.disconnect(); - delayed_spellcheck_error_clear=Glib::signal_timeout().connect([this]() { - auto iter=get_buffer()->begin(); - bool spell_check=get_source_buffer()->iter_has_context_class(iter, "string") || get_source_buffer()->iter_has_context_class(iter, "comment"); - Gtk::TextIter begin_no_spellcheck_iter; - if(!spell_check) - begin_no_spellcheck_iter=iter; - while(iter!=get_buffer()->end()) { - auto iter1=iter; - auto iter2=iter; - if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter1, "string")) - iter1=get_buffer()->end(); - if(!get_source_buffer()->iter_forward_to_context_class_toggle(iter2, "comment")) - iter2=get_buffer()->end(); - - if(iter2remove_tag_by_name("spellcheck_error", begin_no_spellcheck_iter, iter); - } - return false; - }, 1000); - }); - - get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iter, const Glib::RefPtr& mark) { - if(mark->get_name()=="insert") { - if(spellcheck_suggestions_dialog_shown) - spellcheck_suggestions_dialog->hide(); - delayed_spellcheck_suggestions_connection.disconnect(); - delayed_spellcheck_suggestions_connection=Glib::signal_timeout().connect([this]() { - auto tags=get_buffer()->get_insert()->get_iter().get_tags(); - bool need_suggestions=false; - for(auto &tag: tags) { - if(tag->property_name()=="spellcheck_error") { - need_suggestions=true; - break; - } - } - if(need_suggestions) { - spellcheck_suggestions_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false)); - spellcheck_suggestions_dialog->on_hide=[this](){ - spellcheck_suggestions_dialog_shown=false; - }; - auto word=spellcheck_get_word(get_buffer()->get_insert()->get_iter()); - auto suggestions=spellcheck_get_suggestions(word.first, word.second); - if(suggestions.size()==0) - return false; - for(auto &suggestion: suggestions) - spellcheck_suggestions_dialog->add_row(suggestion); - spellcheck_suggestions_dialog->on_select=[this, word](const std::string& selected, bool hide_window) { - get_source_buffer()->begin_user_action(); - get_buffer()->erase(word.first, word.second); - get_buffer()->insert(get_buffer()->get_insert()->get_iter(), selected); - get_source_buffer()->end_user_action(); - delayed_tooltips_connection.disconnect(); - }; - spellcheck_suggestions_dialog->show(); - spellcheck_suggestions_dialog_shown=true; - } - return false; - }, 500); - } - }); - } - - get_buffer()->signal_changed().connect([this](){ - set_info(info); - }); - - set_tooltip_events(); } void Source::View::set_tooltip_events() { @@ -981,27 +1018,14 @@ 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"); - auto scheme = get_source_buffer()->get_style_scheme(); + auto tag_table=get_buffer()->get_tag_table(); for (auto &item : Singleton::Config::source()->clang_types) { if(!tag_table->lookup(item.second)) { - auto style = scheme->get_style(item.second); - auto tag = get_source_buffer()->create_tag(item.second); - if (style) { - if (style->property_foreground_set()) - tag->property_foreground() = style->property_foreground(); - if (style->property_background_set()) - tag->property_background() = style->property_background(); - if (style->property_strikethrough_set()) - tag->property_strikethrough() = style->property_strikethrough(); - // // if (style->property_bold_set()) tag->property_weight() = style->property_bold(); - // // if (style->property_italic_set()) tag->property_italic() = style->property_italic(); - // // 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()); + get_buffer()->create_tag(item.second); } } + configure(); parsing_in_progress=Singleton::terminal()->print_in_progress("Parsing "+file_path.string()); //GTK-calls must happen in main thread, so the parse_thread @@ -1043,10 +1067,37 @@ Source::View(file_path, language), project_path(project_path), parse_error(false diagnostic_tooltips.hide(); }); + DEBUG("end"); +} + +void Source::ClangViewParse::configure() { + Source::View::configure(); + + auto scheme = get_source_buffer()->get_style_scheme(); + auto tag_table=get_buffer()->get_tag_table(); + for (auto &item : Singleton::Config::source()->clang_types) { + auto tag = get_buffer()->get_tag_table()->lookup(item.second); + if(tag) { + auto style = scheme->get_style(item.second); + if (style) { + if (style->property_foreground_set()) + tag->property_foreground() = style->property_foreground(); + if (style->property_background_set()) + tag->property_background() = style->property_background(); + if (style->property_strikethrough_set()) + tag->property_strikethrough() = style->property_strikethrough(); + // // if (style->property_bold_set()) tag->property_weight() = style->property_bold(); + // // if (style->property_italic_set()) tag->property_italic() = style->property_italic(); + // // 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()); + } + } + 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"); } Source::ClangViewParse::~ClangViewParse() { diff --git a/src/source.h b/src/source.h index a77bd10..2cb0264 100644 --- a/src/source.h +++ b/src/source.h @@ -55,6 +55,8 @@ namespace Source { View(const boost::filesystem::path &file_path, Glib::RefPtr language); ~View(); + virtual void configure(); + void search_highlight(const std::string &text, bool case_sensitive, bool regex); std::function update_search_occurrences; void search_forward(); @@ -141,6 +143,8 @@ namespace Source { public: ClangViewParse(const boost::filesystem::path &file_path, const boost::filesystem::path& project_path, Glib::RefPtr language); ~ClangViewParse(); + void configure(); + boost::filesystem::path project_path; void start_reparse(); bool reparse_needed=false; diff --git a/src/window.cc b/src/window.cc index 9045a86..a347f92 100644 --- a/src/window.cc +++ b/src/window.cc @@ -36,10 +36,15 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil set_default_size(600, 400); set_events(Gdk::POINTER_MOTION_MASK|Gdk::FOCUS_CHANGE_MASK|Gdk::SCROLL_MASK); add(box); + + configure(); + //PluginApi(&this->notebook, &this->menu); + //TODO: Do not use deprecated ui_manager? And make menu shortcuts update when config.json is saved (in configure()) generate_keybindings(); - //PluginApi(&this->notebook, &this->menu); create_menu(); + menu.build(); + add_accel_group(menu.ui_manager->get_accel_group()); box.pack_start(menu.get_widget(), Gtk::PACK_SHRINK); directory_and_notebook_panes.pack1(directories, Gtk::SHRINK); @@ -135,6 +140,15 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil DEBUG("end"); } // Window constructor +void Window::configure() { + MainConfig(); // Read the configs here + auto style_context = Gtk::StyleContext::create(); + auto screen = Gdk::Screen::get_default(); + auto css_provider = Gtk::CssProvider::get_named(Singleton::Config::window()->theme_name, Singleton::Config::window()->theme_variant); + //TODO: add check if theme exists, or else write error to Singleton::terminal() + style_context->add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); +} + void Window::create_menu() { menu.action_group->add(Gtk::Action::create("FileQuit", "Quit juCi++"), Gtk::AccelKey(menu.key_map["quit"]), [this]() { hide(); @@ -158,9 +172,19 @@ void Window::create_menu() { menu.action_group->add(Gtk::Action::create("FileSaveAs", "Save As"), Gtk::AccelKey(menu.key_map["save_as"]), [this]() { save_file_dialog(); }); + menu.action_group->add(Gtk::Action::create("Preferences", "Preferences..."), Gtk::AccelKey(menu.key_map["preferences"]), [this]() { + notebook.open(Singleton::config_dir()+"config.json"); + }); menu.action_group->add(Gtk::Action::create("FileSave", "Save"), Gtk::AccelKey(menu.key_map["save"]), [this]() { notebook.save_current(); + if(notebook.get_current_page()!=-1) { + if(notebook.get_current_view()->file_path==Singleton::config_dir()+"config.json") { + configure(); + for(int c=0;cconfigure(); + } + } }); menu.action_group->add(Gtk::Action::create("EditCopy", "Copy"), Gtk::AccelKey(menu.key_map["edit_copy"]), [this]() { @@ -335,8 +359,6 @@ void Window::create_menu() { about.show(); about.present(); }); - add_accel_group(menu.ui_manager->get_accel_group()); - menu.build(); } bool Window::on_key_press_event(GdkEventKey *event) { diff --git a/src/window.h b/src/window.h index 5c8b349..2fcdd49 100644 --- a/src/window.h +++ b/src/window.h @@ -39,6 +39,7 @@ private: Menu menu; std::atomic compiling; + void configure(); void create_menu(); void hide(); void new_file_dialog();