From 43f2043be1c481ae4c123d44a5f2125e76db3b5f Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Apr 2020 10:44:15 +0200 Subject: [PATCH] Cleanup of textbuffer tags and tooltips --- src/autocomplete.cc | 4 +- src/project.cc | 4 +- src/source.cc | 33 ++++------------ src/source.h | 5 +-- src/source_clang.cc | 18 ++++----- src/source_language_protocol.cc | 53 +++++++++++++------------ src/tooltips.cc | 68 +++++++++++++++++++++++---------- src/tooltips.h | 10 +++-- src/window.cc | 8 ++-- tests/stubs/tooltips.cc | 4 +- 10 files changed, 106 insertions(+), 101 deletions(-) diff --git a/src/autocomplete.cc b/src/autocomplete.cc index c11392d..c5056b0 100644 --- a/src/autocomplete.cc +++ b/src/autocomplete.cc @@ -162,8 +162,8 @@ void Autocomplete::setup_dialog() { else { tooltips.clear(); auto iter = CompletionDialog::get()->start_mark->get_iter(); - tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), [tooltip = std::move(tooltip)](const Glib::RefPtr &buffer) { - buffer->insert(buffer->get_insert()->get_iter(), tooltip); + tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), [tooltip_text = std::move(tooltip)](Tooltip &tooltip) { + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), tooltip_text); }); tooltips.show(true); diff --git a/src/project.cc b/src/project.cc index 7dde15c..d8b26dc 100644 --- a/src/project.cc +++ b/src/project.cc @@ -623,7 +623,7 @@ void Project::LLDB::debug_show_variables() { } self->debug_variable_tooltips.clear(); - auto set_tooltip_buffer = [rows, index](const Glib::RefPtr &buffer) { + auto set_tooltip_buffer = [rows, index](Tooltip &tooltip) { auto variable = (*rows)[index]; Glib::ustring value = variable.value; @@ -634,7 +634,7 @@ void Project::LLDB::debug_show_variables() { next_char_iter++; value.replace(iter, next_char_iter, "?"); } - buffer->insert(buffer->get_insert()->get_iter(), value.substr(0, value.size() - 1)); + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), value.substr(0, value.size() - 1)); } }; if(view) { diff --git a/src/source.cc b/src/source.cc index ffe120d..a9373e4 100644 --- a/src/source.cc +++ b/src/source.cc @@ -153,8 +153,6 @@ Source::View::View(const boost::filesystem::path &file_path, const Glib::RefPtr< mark_attr_debug_breakpoint_and_stop->set_background(rgba); set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102); - link_tag = get_buffer()->create_tag("link"); - hide_tag = get_buffer()->create_tag(); hide_tag->property_scale() = 0.25; @@ -433,9 +431,6 @@ void Source::View::configure() { } //TODO: clear tag_class and param_spec? - link_tag->property_foreground_rgba() = get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK); - link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE; - if(Config::get().menu.keys["source_show_completion"].empty()) { get_completion()->unblock_interactive(); interactive_completion = true; @@ -735,8 +730,8 @@ void Source::View::setup_format_style(bool is_generic_view) { if(start == end) start.backward_char(); - add_diagnostic_tooltip(start, end, true, [error_message = sm[1].str()](const Glib::RefPtr &buffer) { - buffer->insert_at_cursor(error_message); + add_diagnostic_tooltip(start, end, true, [error_message = sm[1].str()](Tooltip &tooltip) { + tooltip.buffer->insert_at_cursor(error_message); }); } catch(...) { @@ -1544,29 +1539,15 @@ void Source::View::show_or_hide() { get_buffer()->apply_tag(hide_tag, start, end); } -void Source::View::insert_with_links_tagged(const Glib::RefPtr &buffer, const std::string &text) { - static std::regex http_regex("(https?://[a-zA-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=]+[a-zA-Z0-9\\-_~/@$*+;=])"); - std::smatch sm; - std::sregex_iterator it(text.begin(), text.end(), http_regex); - std::sregex_iterator end; - size_t start_pos = 0; - for(; it != end; ++it) { - buffer->insert(buffer->get_insert()->get_iter(), &text[start_pos], &text[it->position()]); - buffer->insert_with_tag(buffer->get_insert()->get_iter(), &text[it->position()], &text[it->position() + it->length()], link_tag); - start_pos = it->position() + it->length(); - } - buffer->insert(buffer->get_insert()->get_iter(), &text[start_pos], &text[text.size()]); -} - -void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function &)> &&set_buffer) { +void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function &&set_buffer) { diagnostic_offsets.emplace(start.get_offset()); std::string severity_tag_name = error ? "def:error" : "def:warning"; - diagnostic_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [error, severity_tag_name, set_buffer = std::move(set_buffer)](const Glib::RefPtr &buffer) { - buffer->insert_with_tag(buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name); - buffer->insert(buffer->get_insert()->get_iter(), ":\n"); - set_buffer(buffer); + diagnostic_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [error, severity_tag_name, set_buffer = std::move(set_buffer)](Tooltip &tooltip) { + tooltip.buffer->insert_with_tag(tooltip.buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name); + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), ":\n"); + set_buffer(tooltip); }); get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end); diff --git a/src/source.h b/src/source.h index 38fb506..8f8eaf7 100644 --- a/src/source.h +++ b/src/source.h @@ -111,13 +111,10 @@ namespace Source { virtual void apply_clickable_tag(const Gtk::TextIter &iter) {} bool clickable_tag_applied = false; - Glib::RefPtr link_tag; /// Used in tooltips - void insert_with_links_tagged(const Glib::RefPtr &buffer, const std::string &text); - Glib::RefPtr hide_tag; virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); } - void add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function &)> &&set_buffer); + void add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function &&set_buffer); void clear_diagnostic_tooltips(); std::set diagnostic_offsets; void place_cursor_at_next_diagnostic(); diff --git a/src/source_clang.cc b/src/source_clang.cc index 8668178..509587f 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -316,13 +316,9 @@ void Source::ClangViewParse::update_diagnostics() { end = get_buffer()->get_iter_at_line_index(line, index); bool error = false; - std::string severity_tag_name; - if(diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) { - severity_tag_name = "def:warning"; + if(diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) num_warnings++; - } else { - severity_tag_name = "def:error"; num_errors++; error = true; } @@ -354,8 +350,8 @@ void Source::ClangViewParse::update_diagnostics() { if(!fix_its_string.empty()) diagnostic.spelling += "\n\n" + fix_its_string; - add_diagnostic_tooltip(start, end, error, [spelling = std::move(diagnostic.spelling)](const Glib::RefPtr &buffer) { - buffer->insert_at_cursor(spelling); + add_diagnostic_tooltip(start, end, error, [spelling = std::move(diagnostic.spelling)](Tooltip &tooltip) { + tooltip.buffer->insert_at_cursor(spelling); }); } } @@ -391,12 +387,12 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) auto start = get_buffer()->get_iter_at_line_index(token_offsets.first.line - 1, token_offsets.first.index - 1); auto end = get_buffer()->get_iter_at_line_index(token_offsets.second.line - 1, token_offsets.second.index - 1); - type_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [this, token](const Glib::RefPtr &buffer) { + type_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [this, token](Tooltip &tooltip) { auto cursor = token.get_cursor(); - buffer->insert(buffer->get_insert()->get_iter(), "Type: " + cursor.get_type_description()); + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), "Type: " + cursor.get_type_description()); auto brief_comment = cursor.get_brief_comments(); if(brief_comment != "") - insert_with_links_tagged(buffer, "\n\n" + brief_comment); + tooltip.insert_with_links_tagged("\n\n" + brief_comment); #ifdef JUCI_ENABLE_DEBUG if(Debug::LLDB::get().is_stopped()) { @@ -529,7 +525,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) next_char_iter++; debug_value.replace(iter, next_char_iter, "?"); } - buffer->insert(buffer->get_insert()->get_iter(), (buffer->size() > 0 ? "\n\n" : "") + value_type + ": " + debug_value.substr(pos + 3, debug_value.size() - (pos + 3) - 1)); + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), (tooltip.buffer->size() > 0 ? "\n\n" : "") + value_type + ": " + debug_value.substr(pos + 3, debug_value.size() - (pos + 3) - 1)); } } } diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc index b353513..b807ae0 100644 --- a/src/source_language_protocol.cc +++ b/src/source_language_protocol.cc @@ -944,40 +944,39 @@ void Source::LanguageProtocolView::update_diagnostics(const std::vector= 2) { - severity_tag_name = "def:warning"; + if(diagnostic.severity >= 2) num_warnings++; - } else { - severity_tag_name = "def:error"; num_errors++; error = true; } - add_diagnostic_tooltip(start, end, error, [this, diagnostic = std::move(diagnostic)](const Glib::RefPtr &buffer) { - buffer->insert_at_cursor(diagnostic.message); - - for(size_t i = 0; i < diagnostic.related_informations.size(); ++i) { - auto link = filesystem::get_relative_path(diagnostic.related_informations[i].location.file, file_path.parent_path()).string(); - link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.line + 1); - link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.character + 1); - - if(i == 0) - buffer->insert_at_cursor("\n\n"); - buffer->insert_at_cursor(diagnostic.related_informations[i].message); - buffer->insert_at_cursor(": "); - auto pos = buffer->get_insert()->get_iter(); - buffer->insert_with_tag(pos, link, link_tag); - if(i != diagnostic.related_informations.size() - 1) - buffer->insert_at_cursor("\n"); + add_diagnostic_tooltip(start, end, error, [this, diagnostic = std::move(diagnostic)](Tooltip &tooltip) { + tooltip.buffer->insert_at_cursor(diagnostic.message); + + if(!diagnostic.related_informations.empty()) { + auto link_tag = tooltip.buffer->get_tag_table()->lookup("link"); + for(size_t i = 0; i < diagnostic.related_informations.size(); ++i) { + auto link = filesystem::get_relative_path(diagnostic.related_informations[i].location.file, file_path.parent_path()).string(); + link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.line + 1); + link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.character + 1); + + if(i == 0) + tooltip.buffer->insert_at_cursor("\n\n"); + tooltip.buffer->insert_at_cursor(diagnostic.related_informations[i].message); + tooltip.buffer->insert_at_cursor(": "); + auto pos = tooltip.buffer->get_insert()->get_iter(); + tooltip.buffer->insert_with_tag(pos, link, link_tag); + if(i != diagnostic.related_informations.size() - 1) + tooltip.buffer->insert_at_cursor("\n"); + } } }); } for(auto &mark : type_coverage_marks) { - add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), false, [](const Glib::RefPtr &buffer) { - buffer->insert_at_cursor(type_coverage_message); + add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), false, [](Tooltip &tooltip) { + tooltip.buffer->insert_at_cursor(type_coverage_message); }); num_warnings++; } @@ -1036,7 +1035,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect while(!tooltip.empty() && tooltip.back() == '\n') { tooltip.pop_back(); // Remove unnecessary newlines } - dispatcher.post([this, offset, tooltip = std::move(tooltip), current_request] { + dispatcher.post([this, offset, tooltip_text = std::move(tooltip), current_request] { if(current_request != request_count) return; if(Notebook::get().get_current_view() != this) @@ -1052,8 +1051,8 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect } while(((*end >= 'A' && *end <= 'Z') || (*end >= 'a' && *end <= 'z') || (*end >= '0' && *end <= '9') || *end == '_') && end.forward_char()) { } - type_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [this, offset, tooltip = std::move(tooltip)](const Glib::RefPtr &buffer) { - insert_with_links_tagged(buffer, tooltip); + type_tooltips.emplace_back(this, get_buffer()->create_mark(start), get_buffer()->create_mark(end), [this, offset, tooltip_text = std::move(tooltip_text)](Tooltip &tooltip) { + tooltip.insert_with_links_tagged(tooltip_text); #ifdef JUCI_ENABLE_DEBUG if(language_id == "rust" && capabilities.definition) { @@ -1084,7 +1083,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect next_char_iter++; debug_value.replace(iter, next_char_iter, "?"); } - buffer->insert(buffer->get_insert()->get_iter(), "\n\n" + value_type + ": " + debug_value.substr(pos + 3, debug_value.size() - (pos + 3) - 1)); + tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), "\n\n" + value_type + ": " + debug_value.substr(pos + 3, debug_value.size() - (pos + 3) - 1)); } } } diff --git a/src/tooltips.cc b/src/tooltips.cc index 0a62d29..01edc1f 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -8,7 +8,7 @@ std::set Tooltips::shown_tooltips; Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle(); Tooltip::Tooltip(Gtk::TextView *text_view, Glib::RefPtr start_mark_, - Glib::RefPtr end_mark_, std::function &)> set_buffer_) + Glib::RefPtr end_mark_, std::function set_buffer_) : start_mark(std::move(start_mark_)), end_mark(std::move(end_mark_)), text_view(text_view), set_buffer(std::move(set_buffer_)) {} Tooltip::~Tooltip() { @@ -73,21 +73,32 @@ void Tooltip::show(bool disregard_drawn, const std::function &on_motion) box->get_style_context()->add_class("juci_tooltip_box"); window->add(*box); + buffer = Gtk::TextBuffer::create(); + if(text_view) { - text_buffer = Gtk::TextBuffer::create(text_view->get_buffer()->get_tag_table()); - link_tag = text_buffer->get_tag_table()->lookup("link"); - } - else { - text_buffer = Gtk::TextBuffer::create(); - link_tag = text_buffer->create_tag("link"); - link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE; - link_tag->property_foreground_rgba() = window->get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK); + auto tag = text_view->get_buffer()->get_tag_table()->lookup("def:warning"); + auto new_tag = buffer->create_tag("def:warning"); + if(tag->property_foreground_set()) + new_tag->property_foreground_rgba() = tag->property_foreground_rgba().get_value(); + if(tag->property_background_set()) + new_tag->property_background_rgba() = tag->property_background_rgba().get_value(); + + tag = text_view->get_buffer()->get_tag_table()->lookup("def:error"); + new_tag = buffer->create_tag("def:error"); + if(tag->property_foreground_set()) + new_tag->property_foreground_rgba() = tag->property_foreground_rgba().get_value(); + if(tag->property_background_set()) + new_tag->property_background_rgba() = tag->property_background_rgba().get_value(); } - set_buffer(text_buffer); + link_tag = buffer->create_tag("link"); + link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE; + link_tag->property_foreground_rgba() = window->get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK); + + set_buffer(*this); wrap_lines(); - auto tooltip_text_view = Gtk::manage(new Gtk::TextView(text_buffer)); + auto tooltip_text_view = Gtk::manage(new Gtk::TextView(buffer)); tooltip_text_view->get_style_context()->add_class("juci_tooltip_text_view"); tooltip_text_view->set_editable(false); @@ -159,7 +170,7 @@ void Tooltip::show(bool disregard_drawn, const std::function &on_motion) #endif auto layout = Pango::Layout::create(tooltip_text_view->get_pango_context()); - layout->set_text(text_buffer->get_text()); + layout->set_text(buffer->get_text()); layout->get_pixel_size(size.first, size.second); size.first += 6; // 2xpadding size.second += 8; // 2xpadding + 2 @@ -181,7 +192,7 @@ void Tooltip::show(bool disregard_drawn, const std::function &on_motion) }); } - if(text_buffer->size() == 0) + if(buffer->size() == 0) return; // Do not show empty tooltips int root_x = 0, root_y = 0; @@ -259,13 +270,13 @@ void Tooltip::hide(const std::pair &last_mouse_pos, const std::pairbegin(); + auto iter = buffer->begin(); while(iter) { - auto last_space = text_buffer->end(); + auto last_space = buffer->end(); bool end = false; for(unsigned c = 0; c <= 80; c++) { if(!iter) { @@ -288,21 +299,38 @@ void Tooltip::wrap_lines() { last_space = iter; } if(iter && last_space) { - auto mark = text_buffer->create_mark(last_space); + auto mark = buffer->create_mark(last_space); auto last_space_p = last_space; last_space.forward_char(); - text_buffer->erase(last_space_p, last_space); - text_buffer->insert(mark->get_iter(), "\n"); + buffer->erase(last_space_p, last_space); + buffer->insert(mark->get_iter(), "\n"); iter = mark->get_iter(); iter.forward_char(); - text_buffer->delete_mark(mark); + buffer->delete_mark(mark); } } } } +void Tooltip::insert_with_links_tagged(const std::string &text) { + static std::regex http_regex("(https?://[a-zA-Z0-9\\-._~:/?#\\[\\]@!$&'()*+,;=]+[a-zA-Z0-9\\-_~/@$*+;=])"); + std::smatch sm; + std::sregex_iterator it(text.begin(), text.end(), http_regex); + std::sregex_iterator end; + size_t start_pos = 0; + if(it != end) { + auto link_tag = buffer->get_tag_table()->lookup("link"); + for(; it != end; ++it) { + buffer->insert(buffer->get_insert()->get_iter(), &text[start_pos], &text[it->position()]); + buffer->insert_with_tag(buffer->get_insert()->get_iter(), &text[it->position()], &text[it->position() + it->length()], link_tag); + start_pos = it->position() + it->length(); + } + } + buffer->insert(buffer->get_insert()->get_iter(), &text[start_pos], &text[text.size()]); +} + void Tooltips::show(const Gdk::Rectangle &rectangle, bool disregard_drawn) { for(auto &tooltip : tooltip_list) { tooltip.update(); diff --git a/src/tooltips.h b/src/tooltips.h index 5d7dab4..7afb40a 100644 --- a/src/tooltips.h +++ b/src/tooltips.h @@ -7,8 +7,8 @@ class Tooltip { public: - Tooltip(Gtk::TextView *text_view, Glib::RefPtr start_mark_, Glib::RefPtr end_mark_, std::function &)> set_buffer_); - Tooltip(std::function &)> set_buffer_) : Tooltip(nullptr, Glib::RefPtr(), Glib::RefPtr(), std::move(set_buffer_)) {} + Tooltip(Gtk::TextView *text_view, Glib::RefPtr start_mark_, Glib::RefPtr end_mark_, std::function set_buffer_); + Tooltip(std::function set_buffer_) : Tooltip(nullptr, Glib::RefPtr(), Glib::RefPtr(), std::move(set_buffer_)) {} ~Tooltip(); void update(); @@ -19,14 +19,16 @@ public: Glib::RefPtr start_mark; Glib::RefPtr end_mark; - Glib::RefPtr text_buffer; + Glib::RefPtr buffer; + + void insert_with_links_tagged(const std::string &text); private: std::unique_ptr window; void wrap_lines(); Gtk::TextView *text_view; - std::function &)> set_buffer; + std::function set_buffer; std::pair size; Gdk::Rectangle rectangle; diff --git a/src/window.cc b/src/window.cc index 891ee37..ef9180b 100644 --- a/src/window.cc +++ b/src/window.cc @@ -521,7 +521,7 @@ void Window::set_menu_actions() { menu.add_action("edit_cut", [this]() { // Return if a shown tooltip has selected text for(auto tooltip : Tooltips::shown_tooltips) { - auto buffer = tooltip->text_buffer; + auto buffer = tooltip->buffer; if(buffer && buffer->get_has_selection()) return; } @@ -549,7 +549,7 @@ void Window::set_menu_actions() { menu.add_action("edit_cut_lines", [this]() { // Return if a shown tooltip has selected text for(auto tooltip : Tooltips::shown_tooltips) { - auto buffer = tooltip->text_buffer; + auto buffer = tooltip->buffer; if(buffer && buffer->get_has_selection()) return; } @@ -572,7 +572,7 @@ void Window::set_menu_actions() { menu.add_action("edit_copy", [this]() { // Copy from a tooltip if it has selected text for(auto tooltip : Tooltips::shown_tooltips) { - auto buffer = tooltip->text_buffer; + auto buffer = tooltip->buffer; if(buffer && buffer->get_has_selection()) { buffer->copy_clipboard(Gtk::Clipboard::get()); return; @@ -603,7 +603,7 @@ void Window::set_menu_actions() { menu.add_action("edit_copy_lines", [this]() { // Copy from a tooltip if it has selected text for(auto tooltip : Tooltips::shown_tooltips) { - auto buffer = tooltip->text_buffer; + auto buffer = tooltip->buffer; if(buffer && buffer->get_has_selection()) { Gtk::TextIter start, end; buffer->get_selection_bounds(start, end); diff --git a/tests/stubs/tooltips.cc b/tests/stubs/tooltips.cc index 41525d2..719dac2 100644 --- a/tests/stubs/tooltips.cc +++ b/tests/stubs/tooltips.cc @@ -4,10 +4,12 @@ Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle(); Tooltip::Tooltip(Gtk::TextView *text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark, - std::function &)> create_tooltip_buffer) : text_view(text_view) {} + std::function create_tooltip_buffer) : text_view(text_view) {} Tooltip::~Tooltip() {} +void Tooltip::insert_with_links_tagged(const std::string &) {} + void Tooltips::show(Gdk::Rectangle const &, bool) {} void Tooltips::show(bool) {}