From 99d63ba477547adb88e0007c75048bbba170a99d Mon Sep 17 00:00:00 2001 From: eidheim Date: Tue, 13 Sep 2016 09:42:09 +0200 Subject: [PATCH] Updated status bar, and cleanup of update signals affecting status bar and tab texts --- src/config.cc | 16 ++-- src/config.h | 4 +- src/debug_lldb.cc | 2 +- src/directories.cc | 24 +----- src/git.cc | 21 ++++++ src/git.h | 2 + src/juci.cc | 2 +- src/notebook.cc | 148 ++++++++++++++++++++++++++++++++----- src/notebook.h | 9 ++- src/project.cc | 2 +- src/source.cc | 35 +++++---- src/source.h | 16 ++-- src/source_clang.cc | 67 ++++++++--------- src/source_clang.h | 2 +- src/source_diff.cc | 17 ++++- src/source_diff.h | 10 ++- src/window.cc | 58 +++++++++------ tests/source_clang_test.cc | 6 +- 18 files changed, 298 insertions(+), 143 deletions(-) diff --git a/src/config.cc b/src/config.cc index cb2c880..f43e70c 100644 --- a/src/config.cc +++ b/src/config.cc @@ -12,12 +12,12 @@ Config::Config() { for (auto &variable : environment_variables) { ptr=std::getenv(variable.c_str()); if (ptr!=nullptr && boost::filesystem::exists(ptr)) { - home /= ptr; - home /= ".juci"; + home_path = ptr; + home_juci_path = home_path / ".juci"; break; } } - if(home.empty()) { + if(home_juci_path.empty()) { std::string searched_envs = "["; for(auto &variable : environment_variables) searched_envs+=variable+", "; @@ -34,7 +34,7 @@ Config::Config() { } void Config::load() { - auto config_json = (home/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support + auto config_json = (home_juci_path/"config"/"config.json").string(); // This causes some redundant copies, but assures windows support try { find_or_create_config_files(); boost::property_tree::json_parser::read_json(config_json, cfg); @@ -52,7 +52,7 @@ void Config::load() { } void Config::find_or_create_config_files() { - auto config_dir = home/"config"; + auto config_dir = home_juci_path/"config"; auto config_json = config_dir/"config.json"; boost::filesystem::create_directories(config_dir); // io exp captured by calling method @@ -60,7 +60,7 @@ void Config::find_or_create_config_files() { if (!boost::filesystem::exists(config_json)) filesystem::write(config_json, default_config_file); - auto juci_style_path = home/"styles"; + auto juci_style_path = home_juci_path/"styles"; boost::filesystem::create_directories(juci_style_path); // io exp captured by calling method juci_style_path/="juci-light.xml"; @@ -168,7 +168,7 @@ void Config::update_config_file() { if(cfg.count("version")>0) cfg.find("version")->second.data()=default_cfg.get("version"); - auto style_path=home/"styles"; + auto style_path=home_juci_path/"styles"; filesystem::write(style_path/"juci-light.xml", juci_light_style); filesystem::write(style_path/"juci-dark.xml", juci_dark_style); filesystem::write(style_path/"juci-dark-blue.xml", juci_dark_blue_style); @@ -183,7 +183,7 @@ void Config::update_config_file() { cfg_ok&=add_missing_nodes(default_cfg); cfg_ok&=remove_deprecated_nodes(default_cfg, cfg); if(!cfg_ok) - boost::property_tree::write_json((home/"config"/"config.json").string(), cfg); + boost::property_tree::write_json((home_juci_path/"config"/"config.json").string(), cfg); } void Config::get_source() { diff --git a/src/config.h b/src/config.h index abcfa73..d3580bc 100644 --- a/src/config.h +++ b/src/config.h @@ -96,7 +96,8 @@ public: Project project; Source source; - const boost::filesystem::path& juci_home_path() const { return home; } + boost::filesystem::path home_path; + boost::filesystem::path home_juci_path; private: void find_or_create_config_files(); @@ -107,6 +108,5 @@ private: void get_source(); boost::property_tree::ptree cfg; - boost::filesystem::path home; }; #endif diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc index 36f683e..a88ff6c 100644 --- a/src/debug_lldb.cc +++ b/src/debug_lldb.cc @@ -174,7 +174,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat if(line_entry.IsValid()) { lldb::SBStream stream; line_entry.GetFileSpec().GetDescription(stream); - status +=" - "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line_entry.GetLine()); + status +=" "+boost::filesystem::path(stream.GetData()).filename().string()+":"+std::to_string(line_entry.GetLine()); } } status_callback(status); diff --git a/src/directories.cc b/src/directories.cc index cad6bea..301e5a6 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -94,19 +94,11 @@ bool Directories::TreeStore::drag_data_received_vfunc(const TreeModel::Path &pat auto new_file_path=target_path; for(;file_it!=view->file_path.end();file_it++) new_file_path/=*file_it; - { - std::unique_lock lock(view->file_path_mutex); - view->file_path=new_file_path; - } - g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed"); + view->rename(new_file_path); } } else if(view->file_path==source_path) { - { - std::unique_lock lock(view->file_path_mutex); - view->file_path=target_path; - } - g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed"); + view->rename(target_path); break; } } @@ -299,19 +291,11 @@ Directories::Directories() : Gtk::ListViewText(1) { auto new_file_path=target_path; for(;file_it!=view->file_path.end();file_it++) new_file_path/=*file_it; - { - std::unique_lock lock(view->file_path_mutex); - view->file_path=new_file_path; - } - g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed"); + view->rename(new_file_path); } } else if(view->file_path==*source_path) { - { - std::unique_lock lock(view->file_path_mutex); - view->file_path=target_path; - } - g_signal_emit_by_name(view->get_buffer()->gobj(), "modified_changed"); + view->rename(target_path); std::string old_language_id; if(view->language) diff --git a/src/git.cc b/src/git.cc index 88dfab4..550b957 100644 --- a/src/git.cc +++ b/src/git.cc @@ -242,6 +242,27 @@ Git::Repository::Diff Git::Repository::get_diff(const boost::filesystem::path &p return Diff(path, repository.get()); } +std::string Git::Repository::get_branch() noexcept { + std::string branch; + git_reference *reference; + if(git_repository_head(&reference, repository.get())==0) { + if(auto reference_name_cstr=git_reference_name(reference)) { + std::string reference_name(reference_name_cstr); + size_t pos; + if((pos=reference_name.rfind('/'))!=std::string::npos) { + if(pos+1 lock(mutex); if(!initialized) { diff --git a/src/git.h b/src/git.h index 9d41ac5..a8f7bfb 100644 --- a/src/git.h +++ b/src/git.h @@ -79,6 +79,8 @@ public: Diff get_diff(const boost::filesystem::path &path); + std::string get_branch() noexcept; + Glib::RefPtr monitor; }; diff --git a/src/juci.cc b/src/juci.cc index 4deab78..54cf50b 100644 --- a/src/juci.cc +++ b/src/juci.cc @@ -49,7 +49,7 @@ void Application::on_activate() { if(directories.empty() && files.empty()) { try { boost::property_tree::ptree pt; - boost::property_tree::read_json((Config::get().juci_home_path()/"last_session.json").string(), pt); + boost::property_tree::read_json((Config::get().home_juci_path/"last_session.json").string(), pt); auto folder=pt.get("folder"); if(!folder.empty() && boost::filesystem::exists(folder) && boost::filesystem::is_directory(folder)) directories.emplace_back(folder); diff --git a/src/notebook.cc b/src/notebook.cc index 62e7659..9320d11 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -170,13 +170,112 @@ void Notebook::open(const boost::filesystem::path &file_path, size_t notebook_in view->hide_tooltips(); } }; - source_views.back()->on_update_status=[this](Source::View* view, const std::string &status_text) { - if(get_current_view()==view) - status.set_text(status_text+" "); + source_views.back()->update_status_location=[this](Source::View* view) { + if(get_current_view()==view) { + auto iter=view->get_buffer()->get_insert()->get_iter(); + status_location.set_text(" "+std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1)); + } + }; + source_views.back()->update_status_file_path=[this](Source::View* view) { + if(get_current_view()==view) { + if(filesystem::file_in_path(view->file_path, Config::get().home_path)) { + auto relative_path=filesystem::get_relative_path(view->file_path, Config::get().home_path); + if(!relative_path.empty()) { + status_file_path.set_text((" ~"/relative_path).string()); + return; + } + } + status_file_path.set_text(" "+view->file_path.string()); + } + }; + source_views.back()->update_status_branch=[this](Source::DiffView* view) { + if(get_current_view()==view) { + if(!view->status_branch.empty()) + status_branch.set_text(" ("+view->status_branch+")"); + else + status_branch.set_text(""); + } + }; + source_views.back()->update_tab_label=[this](Source::View *view) { + std::string title=view->file_path.filename().string(); + if(view->get_buffer()->get_modified()) + title+='*'; + else + title+=' '; + for(size_t c=0;clabel.set_text(title); + tab_label->set_tooltip_text(view->file_path.string()); + update_status(view); + return; + } + } }; - source_views.back()->on_update_info=[this](Source::View* view, const std::string &info_text) { + source_views.back()->update_status_diagnostics=[this](Source::View* view) { + if(get_current_view()==view) { + std::string diagnostic_info; + + auto num_warnings=std::get<0>(view->status_diagnostics); + auto num_errors=std::get<1>(view->status_diagnostics); + auto num_fix_its=std::get<2>(view->status_diagnostics); + if(num_warnings>0 || num_errors>0 || num_fix_its>0) { + auto normal_color=get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_NORMAL); + Gdk::RGBA yellow; + yellow.set_rgba(1.0, 1.0, 0.2); + double factor=0.5; + yellow.set_red(normal_color.get_red()+factor*(yellow.get_red()-normal_color.get_red())); + yellow.set_green(normal_color.get_green()+factor*(yellow.get_green()-normal_color.get_green())); + yellow.set_blue(normal_color.get_blue()+factor*(yellow.get_blue()-normal_color.get_blue())); + Gdk::RGBA red; + red.set_rgba(1.0, 0.0, 0.0); + factor=0.5; + red.set_red(normal_color.get_red()+factor*(red.get_red()-normal_color.get_red())); + red.set_green(normal_color.get_green()+factor*(red.get_green()-normal_color.get_green())); + red.set_blue(normal_color.get_blue()+factor*(red.get_blue()-normal_color.get_blue())); + Gdk::RGBA green; + green.set_rgba(0.0, 1.0, 0.0); + factor=0.4; + green.set_red(normal_color.get_red()+factor*(green.get_red()-normal_color.get_red())); + green.set_green(normal_color.get_green()+factor*(green.get_green()-normal_color.get_green())); + green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue())); + + std::stringstream yellow_ss, red_ss, green_ss; + yellow_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(yellow.get_red_u()>>8) << std::setw(2) << (int)(yellow.get_green_u()>>8) << std::setw(2) << (int)(yellow.get_blue_u()>>8); + red_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(red.get_red_u()>>8) << std::setw(2) << (int)(red.get_green_u()>>8) << std::setw(2) << (int)(red.get_blue_u()>>8); + green_ss << std::hex << std::setfill('0') << std::setw(2) << (int)(green.get_red_u()>>8) << std::setw(2) << (int)(green.get_green_u()>>8) << std::setw(2) << (int)(green.get_blue_u()>>8); + if(num_warnings>0) { + diagnostic_info+=""; + diagnostic_info+=std::to_string(num_warnings)+" warning"; + if(num_warnings>1) + diagnostic_info+='s'; + diagnostic_info+=""; + } + if(num_errors>0) { + if(num_warnings>0) + diagnostic_info+=", "; + diagnostic_info+=""; + diagnostic_info+=std::to_string(num_errors)+" error"; + if(num_errors>1) + diagnostic_info+='s'; + diagnostic_info+=""; + } + if(num_fix_its>0) { + if(num_warnings>0 || num_errors>0) + diagnostic_info+=", "; + diagnostic_info+=""; + diagnostic_info+=std::to_string(num_fix_its)+" fix it"; + if(num_fix_its>1) + diagnostic_info+='s'; + diagnostic_info+=""; + } + } + status_diagnostics.set_markup(diagnostic_info); + } + }; + source_views.back()->update_status_state=[this](Source::View* view) { if(get_current_view()==view) - info.set_text(" "+info_text); + status_state.set_text(view->status_state+" "); }; scrolled_windows.emplace_back(new Gtk::ScrolledWindow()); @@ -200,20 +299,8 @@ void Notebook::open(const boost::filesystem::path &file_path, size_t notebook_in //Add star on tab label when the page is not saved: source_view->get_buffer()->signal_modified_changed().connect([this, source_view]() { - std::string title=source_view->file_path.filename().string(); - if(source_view->get_buffer()->get_modified()) - title+='*'; - else - title+=' '; - - for(size_t c=0;clabel.set_text(title); - tab_label->set_tooltip_text(source_view->file_path.string()); - return; - } - } + if(source_view->update_tab_label) + source_view->update_tab_label(source_view); }); source_view->signal_focus_in_event().connect([this, source_view](GdkEventFocus *) { @@ -319,7 +406,7 @@ void Notebook::save_session() { pt_root.add_child("files", pt_files); if(auto view=Notebook::get().get_current_view()) pt_root.put("current_file", view->file_path.string()); - boost::property_tree::write_json((Config::get().juci_home_path()/"last_session.json").string(), pt_root); + boost::property_tree::write_json((Config::get().home_juci_path/"last_session.json").string(), pt_root); } catch(const std::exception &) {} } @@ -438,6 +525,27 @@ boost::filesystem::path Notebook::get_current_folder() { return boost::filesystem::path(); } +void Notebook::update_status(Source::View *view) { + if(view->update_status_location) + view->update_status_location(view); + if(view->update_status_file_path) + view->update_status_file_path(view); + if(view->update_status_branch) + view->update_status_branch(view); + if(view->update_status_diagnostics) + view->update_status_diagnostics(view); + if(view->update_status_state) + view->update_status_state(view); +} + +void Notebook::clear_status() { + status_location.set_text(""); + status_file_path.set_text(""); + status_branch.set_text(""); + status_diagnostics.set_text(""); + status_state.set_text(""); +} + size_t Notebook::get_index(Source::View *view) { for(size_t c=0;c on_change_page; std::function on_close_page; diff --git a/src/project.cc b/src/project.cc index d8d8108..cc9b37c 100644 --- a/src/project.cc +++ b/src/project.cc @@ -73,7 +73,7 @@ void Project::debug_update_status(const std::string &new_debug_status) { if(debug_status.empty()) debug_status_label().set_text(""); else - debug_status_label().set_text("debug: "+debug_status); + debug_status_label().set_text(debug_status); debug_activate_menu_items(); } diff --git a/src/source.cc b/src/source.cc index 3b39d2c..f874a8f 100644 --- a/src/source.cc +++ b/src/source.cc @@ -89,7 +89,7 @@ const std::regex Source::View::bracket_regex("^([ \\t]*).*\\{ *$"); const std::regex Source::View::no_bracket_statement_regex("^([ \\t]*)(if|for|else if|while) *\\(.*[^;}] *$"); const std::regex Source::View::no_bracket_no_para_statement_regex("^([ \\t]*)(else) *$"); -Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr language): Gsv::View(), SpellCheckView(), DiffView(file_path), language(language) { +Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr language): Gsv::View(), SpellCheckView(), DiffView(file_path), language(language), status_diagnostics(0, 0, 0) { get_source_buffer()->begin_not_undoable_action(); last_read_time=std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); if(language) { @@ -147,7 +147,8 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtrsignal_changed().connect([this](){ - set_info(info); + if(update_status_location) + update_status_location(this); }); signal_realize().connect([this] { @@ -379,6 +380,17 @@ Source::View::View(const boost::filesystem::path &file_path, Glib::RefPtr lock(file_path_mutex); + file_path=path; + } + if(update_status_file_path) + update_status_file_path(this); + if(update_tab_label) + update_tab_label(this); +} + void Source::View::set_tab_char_and_size(char tab_char, unsigned tab_size) { this->tab_char=tab_char; this->tab_size=tab_size; @@ -459,7 +471,7 @@ 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((Config::get().juci_home_path()/"styles").string()); + style_scheme_manager->prepend_search_path((Config::get().home_juci_path/"styles").string()); if(Config::get().source.style.size()>0) { auto scheme = style_scheme_manager->get_scheme(Config::get().source.style); @@ -596,7 +608,8 @@ void Source::View::set_tooltip_and_dialog_events() { if(selection_dialog) selection_dialog->hide(); - set_info(info); + if(update_status_location) + update_status_location(this); } }); @@ -853,20 +866,6 @@ void Source::View::hide_dialogs() { autocomplete_dialog->hide(); } -void Source::View::set_status(const std::string &status) { - this->status=status; - if(on_update_status) - on_update_status(this, status); -} - -void Source::View::set_info(const std::string &info) { - this->info=info; - auto iter=get_buffer()->get_insert()->get_iter(); - auto positions=std::to_string(iter.get_line()+1)+":"+std::to_string(iter.get_line_offset()+1); - if(on_update_info) - on_update_info(this, positions+" "+info); -} - std::string Source::View::get_line(const Gtk::TextIter &iter) { auto line_start_it = get_buffer()->get_iter_at_line(iter.get_line()); auto line_end_it = get_iter_at_line_end(iter.get_line()); diff --git a/src/source.h b/src/source.h index d7cd6f2..8da8c82 100644 --- a/src/source.h +++ b/src/source.h @@ -9,6 +9,7 @@ #include #include #include +#include namespace Source { Glib::RefPtr guess_language(const boost::filesystem::path &file_path); @@ -43,6 +44,8 @@ namespace Source { View(const boost::filesystem::path &file_path, Glib::RefPtr language); ~View(); + void rename(const boost::filesystem::path &path); + virtual bool save(const std::vector &views); void configure() override; @@ -84,12 +87,13 @@ namespace Source { void hide_tooltips() override; void hide_dialogs() override; - std::function on_update_status; - std::function on_update_info; - void set_status(const std::string &status); - void set_info(const std::string &info); - std::string status; - std::string info; + std::function update_tab_label; + std::function update_status_location; + std::function update_status_file_path; + std::function update_status_diagnostics; + std::function update_status_state; + std::tuple status_diagnostics; + std::string status_state; void set_tab_char_and_size(char tab_char, unsigned tab_size); std::pair get_tab_char_and_size() {return {tab_char, tab_size};} diff --git a/src/source_clang.cc b/src/source_clang.cc index fbffb8c..7cb664e 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -108,7 +108,9 @@ void Source::ClangViewParse::parse_initialize() { clang_tokens=clang_tu->get_tokens(0, buffer.bytes()-1); update_syntax(); - set_status("parsing..."); + status_state="parsing..."; + if(update_status_state) + update_status_state(this); parse_thread=std::thread([this]() { while(true) { while(parse_state==ParseState::PROCESSING && parse_process_state!=ParseProcessState::STARTING && parse_process_state!=ParseProcessState::PROCESSING) @@ -137,7 +139,7 @@ void Source::ClangViewParse::parse_initialize() { auto expected=ParseProcessState::PROCESSING; if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::POSTPROCESSING)) { clang_tokens=clang_tu->get_tokens(0, parse_thread_buffer.bytes()-1); - diagnostics=clang_tu->get_diagnostics(); + clang_diagnostics=clang_tu->get_diagnostics(); parse_lock.unlock(); dispatcher.post([this] { std::unique_lock parse_lock(parse_mutex, std::defer_lock); @@ -147,7 +149,9 @@ void Source::ClangViewParse::parse_initialize() { update_syntax(); update_diagnostics(); parsed=true; - set_status(""); + status_state=""; + if(update_status_state) + update_status_state(this); } parse_lock.unlock(); } @@ -161,8 +165,12 @@ void Source::ClangViewParse::parse_initialize() { parse_lock.unlock(); dispatcher.post([this] { Terminal::get().print("Error: failed to reparse "+this->file_path.string()+".\n", true); - set_status(""); - set_info(""); + status_state=""; + if(update_status_state) + update_status_state(this); + status_diagnostics=std::make_tuple(0, 0, 0); + if(update_status_diagnostics) + update_status_diagnostics(this); parsing_in_progress->cancel("failed"); }); } @@ -181,8 +189,11 @@ void Source::ClangViewParse::soft_reparse() { delayed_reparse_connection=Glib::signal_timeout().connect([this]() { parsed=false; auto expected=ParseProcessState::IDLE; - if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) - set_status("parsing..."); + if(parse_process_state.compare_exchange_strong(expected, ParseProcessState::STARTING)) { + status_state="parsing..."; + if(update_status_state) + update_status_state(this); + } return false; }, 1000); } @@ -276,7 +287,7 @@ void Source::ClangViewParse::update_diagnostics() { size_t num_warnings=0; size_t num_errors=0; size_t num_fix_its=0; - for(auto &diagnostic: diagnostics) { + for(auto &diagnostic: clang_diagnostics) { if(diagnostic.path==file_path.string()) { int line=diagnostic.offsets.first.line-1; if(line<0 || line>=get_buffer()->get_line_count()) @@ -356,27 +367,9 @@ void Source::ClangViewParse::update_diagnostics() { } } } - std::string diagnostic_info; - if(num_warnings>0) { - diagnostic_info+=std::to_string(num_warnings)+" warning"; - if(num_warnings>1) - diagnostic_info+='s'; - } - if(num_errors>0) { - if(num_warnings>0) - diagnostic_info+=", "; - diagnostic_info+=std::to_string(num_errors)+" error"; - if(num_errors>1) - diagnostic_info+='s'; - } - if(num_fix_its>0) { - if(num_warnings>0 || num_errors>0) - diagnostic_info+=", "; - diagnostic_info+=std::to_string(num_fix_its)+" fix it"; - if(num_fix_its>1) - diagnostic_info+='s'; - } - set_info(" "+diagnostic_info); + status_diagnostics=std::make_tuple(num_warnings, num_errors, num_fix_its); + if(update_status_diagnostics) + update_status_diagnostics(this); } void Source::ClangViewParse::show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { @@ -674,7 +667,9 @@ void Source::ClangViewAutocomplete::autocomplete() { autocomplete_state=AutocompleteState::STARTING; - set_status("autocomplete..."); + status_state="autocomplete..."; + if(update_status_state) + update_status_state(this); if(autocomplete_thread.joinable()) autocomplete_thread.join(); auto buffer=std::make_shared(get_buffer()->get_text()); @@ -697,12 +692,16 @@ void Source::ClangViewAutocomplete::autocomplete() { if(parse_state==ParseState::PROCESSING) { dispatcher.post([this, autocomplete_data] { if(autocomplete_state==AutocompleteState::CANCELED) { - set_status(""); + status_state=""; + if(update_status_state) + update_status_state(this); soft_reparse(); autocomplete_state=AutocompleteState::IDLE; } else if(autocomplete_state==AutocompleteState::RESTARTING) { - set_status(""); + status_state=""; + if(update_status_state) + update_status_state(this); soft_reparse(); autocomplete_state=AutocompleteState::IDLE; autocomplete_check(); @@ -729,7 +728,9 @@ void Source::ClangViewAutocomplete::autocomplete() { } } autocomplete_data->clear(); - set_status(""); + status_state=""; + if(update_status_state) + update_status_state(this); autocomplete_state=AutocompleteState::IDLE; if (!autocomplete_dialog_rows.empty()) { get_buffer()->begin_user_action(); diff --git a/src/source_clang.h b/src/source_clang.h index f429a42..0baba5d 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -49,7 +49,7 @@ namespace Source { std::set last_syntax_tags; void update_diagnostics(); - std::vector diagnostics; + std::vector clang_diagnostics; static clang::Index clang_index; std::vector get_compilation_commands(); diff --git a/src/source_diff.cc b/src/source_diff.cc index 67136ff..834dfba 100644 --- a/src/source_diff.cc +++ b/src/source_diff.cc @@ -170,8 +170,15 @@ void Source::DiffView::configure() { parse_thread=std::thread([this]() { try { diff=get_diff(); + status_branch=repository->get_branch(); } - catch(const std::exception &) {} + catch(const std::exception &) { + status_branch=""; + } + dispatcher.post([this] { + if(update_status_branch) + update_status_branch(this); + }); try { while(true) { @@ -199,6 +206,11 @@ void Source::DiffView::configure() { if(monitor_changed.compare_exchange_strong(expected_monitor_changed, false)) { try { diff=get_diff(); + status_branch=repository->get_branch(); + dispatcher.post([this] { + if(update_status_branch) + update_status_branch(this); + }); } catch(const std::exception &) { dispatcher.post([this] { @@ -208,6 +220,9 @@ void Source::DiffView::configure() { get_buffer()->remove_tag(renderer->tag_removed_below, get_buffer()->begin(), get_buffer()->end()); get_buffer()->remove_tag(renderer->tag_removed_above, get_buffer()->begin(), get_buffer()->end()); renderer->queue_draw(); + status_branch=""; + if(update_status_branch) + update_status_branch(this); }); } } diff --git a/src/source_diff.h b/src/source_diff.h index 4f25684..2578410 100644 --- a/src/source_diff.h +++ b/src/source_diff.h @@ -33,16 +33,20 @@ namespace Source { DiffView(const boost::filesystem::path &file_path); ~DiffView(); + boost::filesystem::path file_path; + protected: + std::mutex file_path_mutex; + public: virtual void configure(); + std::function update_status_branch; + std::string status_branch; + Gtk::TextIter get_iter_at_line_end(int line_nr); void git_goto_next_diff(); std::string git_get_diff_details(); - boost::filesystem::path file_path; - ///Only needed when using file_path in a thread, or when changing file_path - std::mutex file_path_mutex; private: std::unique_ptr renderer; Dispatcher dispatcher; diff --git a/src/window.cc b/src/window.cc index d7ec0b0..c7cdfa6 100644 --- a/src/window.cc +++ b/src/window.cc @@ -54,14 +54,26 @@ Window::Window() { hpaned->pack1(*directories_scrolled_window, Gtk::SHRINK); hpaned->pack2(*notebook_and_terminal_vpaned, Gtk::SHRINK); - auto info_and_status_hbox=Gtk::manage(new Gtk::HBox()); - info_and_status_hbox->pack_start(Notebook::get().info, Gtk::PACK_SHRINK); - info_and_status_hbox->set_center_widget(Project::debug_status_label()); - info_and_status_hbox->pack_end(Notebook::get().status, Gtk::PACK_SHRINK); + auto status_hbox=Gtk::manage(new Gtk::HBox()); + status_hbox->set_homogeneous(true); + auto status_left_hbox=Gtk::manage(new Gtk::HBox()); + status_left_hbox->pack_start(Notebook::get().status_file_path, Gtk::PACK_SHRINK); + status_left_hbox->pack_start(Notebook::get().status_branch, Gtk::PACK_SHRINK); + status_left_hbox->pack_start(Notebook::get().status_location, Gtk::PACK_SHRINK); + status_hbox->pack_start(*status_left_hbox); + auto status_right_vbox=Gtk::manage(new Gtk::HBox()); + status_right_vbox->pack_end(Notebook::get().status_state, Gtk::PACK_SHRINK); + auto status_right_overlay=Gtk::manage(new Gtk::Overlay()); + status_right_overlay->add(*status_right_vbox); + status_right_overlay->add_overlay(Notebook::get().status_diagnostics); + status_hbox->pack_end(*status_right_overlay); + auto status_overlay=Gtk::manage(new Gtk::Overlay()); + status_overlay->add(*status_hbox); + status_overlay->add_overlay(Project::debug_status_label()); auto vbox=Gtk::manage(new Gtk::VBox()); vbox->pack_start(*hpaned); - vbox->pack_start(*info_and_status_hbox, Gtk::PACK_SHRINK); + vbox->pack_start(*status_overlay, Gtk::PACK_SHRINK); auto overlay_vbox=Gtk::manage(new Gtk::VBox()); auto overlay_hbox=Gtk::manage(new Gtk::HBox()); @@ -122,15 +134,14 @@ Window::Window() { else if(view->soft_reparse_needed) view->soft_reparse(); - view->set_status(view->status); - view->set_info(view->info); + Notebook::get().update_status(view); #ifdef JUCI_ENABLE_DEBUG if(Project::debugging) Project::debug_update_stop(); #endif }; - Notebook::get().on_close_page=[](Source::View *view) { + Notebook::get().on_close_page=[this](Source::View *view) { #ifdef JUCI_ENABLE_DEBUG if(Project::current && Project::debugging) { auto iter=view->get_buffer()->begin(); @@ -143,6 +154,13 @@ Window::Window() { } #endif EntryBox::get().hide(); + if(auto view=Notebook::get().get_current_view()) + Notebook::get().update_status(view); + else { + Notebook::get().clear_status(); + + activate_menu_items(); + } }; signal_focus_out_event().connect([](GdkEventFocus *event) { @@ -155,6 +173,8 @@ Window::Window() { Gtk::Settings::get_default()->connect_property_changed("gtk-theme-name", [this] { Directories::get().update(); + if(auto view=Notebook::get().get_current_view()) + Notebook::get().update_status(view); }); about.signal_response().connect([this](int d){ @@ -187,9 +207,11 @@ void Window::configure() { css_provider=Gtk::CssProvider::get_named(Config::get().window.theme_name, Config::get().window.theme_variant); //TODO: add check if theme exists, or else write error to terminal Gtk::StyleContext::add_provider_for_screen(screen, css_provider, GTK_STYLE_PROVIDER_PRIORITY_SETTINGS); - Directories::get().update(); Menu::get().set_keys(); Terminal::get().configure(); + Directories::get().update(); + if(auto view=Notebook::get().get_current_view()) + Notebook::get().update_status(view); } void Window::set_menu_actions() { @@ -200,7 +222,7 @@ void Window::set_menu_actions() { about.present(); }); menu.add_action("preferences", [this]() { - Notebook::get().open(Config::get().juci_home_path()/"config"/"config.json"); + Notebook::get().open(Config::get().home_juci_path/"config"/"config.json"); }); menu.add_action("quit", [this]() { close(); @@ -326,7 +348,7 @@ void Window::set_menu_actions() { menu.add_action("save", [this]() { if(auto view=Notebook::get().get_current_view()) { if(Notebook::get().save_current()) { - if(view->file_path==Config::get().juci_home_path()/"config"/"config.json") { + if(view->file_path==Config::get().home_juci_path/"config"/"config.json") { configure(); for(size_t c=0;cconfigure(); @@ -1031,18 +1053,8 @@ void Window::set_menu_actions() { Notebook::get().previous(); }); menu.add_action("close_tab", [this]() { - if(Notebook::get().get_current_view() && Notebook::get().close_current()) { - if(auto view=Notebook::get().get_current_view()) { - view->set_status(view->status); - view->set_info(view->info); - } - else { - Notebook::get().status.set_text(""); - Notebook::get().info.set_text(""); - - activate_menu_items(); - } - } + if(Notebook::get().get_current_view()) + Notebook::get().close_current(); }); menu.add_action("window_toggle_split", [this] { Notebook::get().toggle_split(); diff --git a/tests/source_clang_test.cc b/tests/source_clang_test.cc index 44cb09c..6e5fab5 100644 --- a/tests/source_clang_test.cc +++ b/tests/source_clang_test.cc @@ -32,7 +32,7 @@ int main() { Gsv::LanguageManager::get_default()->get_language("cpp")); while(!clang_view->parsed) flush_events(); - g_assert_cmpuint(clang_view->diagnostics.size(), ==, 0); + g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0); //test get_declaration and get_implementation clang_view->place_cursor_at_line_index(13, 7); @@ -69,7 +69,7 @@ int main() { iter.backward_char(); token=clang_view->get_token(iter); g_assert_cmpstr(token.c_str(), ==, "RenamedTestClass"); - g_assert_cmpuint(clang_view->diagnostics.size(), ==, 0); + g_assert_cmpuint(clang_view->clang_diagnostics.size(), ==, 0); clang_view->get_buffer()->set_text(saved_main); clang_view->save({clang_view}); @@ -77,7 +77,7 @@ int main() { clang_view->get_buffer()->set_text(main_error); while(!clang_view->parsed) flush_events(); - g_assert_cmpuint(clang_view->diagnostics.size(), >, 0); + g_assert_cmpuint(clang_view->clang_diagnostics.size(), >, 0); g_assert_cmpuint(clang_view->get_fix_its().size(), >, 0); clang_view->async_delete();