Browse Source

Cleanup of textbuffer tags and tooltips

pipelines/143601543
eidheim 6 years ago
parent
commit
43f2043be1
  1. 4
      src/autocomplete.cc
  2. 4
      src/project.cc
  3. 33
      src/source.cc
  4. 5
      src/source.h
  5. 18
      src/source_clang.cc
  6. 53
      src/source_language_protocol.cc
  7. 68
      src/tooltips.cc
  8. 10
      src/tooltips.h
  9. 8
      src/window.cc
  10. 4
      tests/stubs/tooltips.cc

4
src/autocomplete.cc

@ -162,8 +162,8 @@ void Autocomplete::setup_dialog() {
else { else {
tooltips.clear(); tooltips.clear();
auto iter = CompletionDialog::get()->start_mark->get_iter(); 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<Gtk::TextBuffer> &buffer) { tooltips.emplace_back(view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter), [tooltip_text = std::move(tooltip)](Tooltip &tooltip) {
buffer->insert(buffer->get_insert()->get_iter(), tooltip); tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), tooltip_text);
}); });
tooltips.show(true); tooltips.show(true);

4
src/project.cc

@ -623,7 +623,7 @@ void Project::LLDB::debug_show_variables() {
} }
self->debug_variable_tooltips.clear(); self->debug_variable_tooltips.clear();
auto set_tooltip_buffer = [rows, index](const Glib::RefPtr<Gtk::TextBuffer> &buffer) { auto set_tooltip_buffer = [rows, index](Tooltip &tooltip) {
auto variable = (*rows)[index]; auto variable = (*rows)[index];
Glib::ustring value = variable.value; Glib::ustring value = variable.value;
@ -634,7 +634,7 @@ void Project::LLDB::debug_show_variables() {
next_char_iter++; next_char_iter++;
value.replace(iter, 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) { if(view) {

33
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); mark_attr_debug_breakpoint_and_stop->set_background(rgba);
set_mark_attributes("debug_breakpoint_and_stop", mark_attr_debug_breakpoint_and_stop, 102); 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 = get_buffer()->create_tag();
hide_tag->property_scale() = 0.25; hide_tag->property_scale() = 0.25;
@ -433,9 +431,6 @@ void Source::View::configure() {
} }
//TODO: clear tag_class and param_spec? //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()) { if(Config::get().menu.keys["source_show_completion"].empty()) {
get_completion()->unblock_interactive(); get_completion()->unblock_interactive();
interactive_completion = true; interactive_completion = true;
@ -735,8 +730,8 @@ void Source::View::setup_format_style(bool is_generic_view) {
if(start == end) if(start == end)
start.backward_char(); start.backward_char();
add_diagnostic_tooltip(start, end, true, [error_message = sm[1].str()](const Glib::RefPtr<Gtk::TextBuffer> &buffer) { add_diagnostic_tooltip(start, end, true, [error_message = sm[1].str()](Tooltip &tooltip) {
buffer->insert_at_cursor(error_message); tooltip.buffer->insert_at_cursor(error_message);
}); });
} }
catch(...) { catch(...) {
@ -1544,29 +1539,15 @@ void Source::View::show_or_hide() {
get_buffer()->apply_tag(hide_tag, start, end); get_buffer()->apply_tag(hide_tag, start, end);
} }
void Source::View::insert_with_links_tagged(const Glib::RefPtr<Gtk::TextBuffer> &buffer, const std::string &text) { void Source::View::add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function<void(Tooltip &)> &&set_buffer) {
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<void(const Glib::RefPtr<Gtk::TextBuffer> &)> &&set_buffer) {
diagnostic_offsets.emplace(start.get_offset()); diagnostic_offsets.emplace(start.get_offset());
std::string severity_tag_name = error ? "def:error" : "def:warning"; 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<Gtk::TextBuffer> &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) {
buffer->insert_with_tag(buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name); tooltip.buffer->insert_with_tag(tooltip.buffer->get_insert()->get_iter(), error ? "Error" : "Warning", severity_tag_name);
buffer->insert(buffer->get_insert()->get_iter(), ":\n"); tooltip.buffer->insert(tooltip.buffer->get_insert()->get_iter(), ":\n");
set_buffer(buffer); set_buffer(tooltip);
}); });
get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end); get_buffer()->apply_tag_by_name(severity_tag_name + "_underline", start, end);

5
src/source.h

@ -111,13 +111,10 @@ namespace Source {
virtual void apply_clickable_tag(const Gtk::TextIter &iter) {} virtual void apply_clickable_tag(const Gtk::TextIter &iter) {}
bool clickable_tag_applied = false; bool clickable_tag_applied = false;
Glib::RefPtr<Gtk::TextTag> link_tag; /// Used in tooltips
void insert_with_links_tagged(const Glib::RefPtr<Gtk::TextBuffer> &buffer, const std::string &text);
Glib::RefPtr<Gtk::TextTag> hide_tag; Glib::RefPtr<Gtk::TextTag> hide_tag;
virtual void show_diagnostic_tooltips(const Gdk::Rectangle &rectangle) { diagnostic_tooltips.show(rectangle); } 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<void(const Glib::RefPtr<Gtk::TextBuffer> &)> &&set_buffer); void add_diagnostic_tooltip(const Gtk::TextIter &start, const Gtk::TextIter &end, bool error, std::function<void(Tooltip &)> &&set_buffer);
void clear_diagnostic_tooltips(); void clear_diagnostic_tooltips();
std::set<int> diagnostic_offsets; std::set<int> diagnostic_offsets;
void place_cursor_at_next_diagnostic(); void place_cursor_at_next_diagnostic();

18
src/source_clang.cc

@ -316,13 +316,9 @@ void Source::ClangViewParse::update_diagnostics() {
end = get_buffer()->get_iter_at_line_index(line, index); end = get_buffer()->get_iter_at_line_index(line, index);
bool error = false; bool error = false;
std::string severity_tag_name; if(diagnostic.severity <= clangmm::Diagnostic::Severity::Warning)
if(diagnostic.severity <= clangmm::Diagnostic::Severity::Warning) {
severity_tag_name = "def:warning";
num_warnings++; num_warnings++;
}
else { else {
severity_tag_name = "def:error";
num_errors++; num_errors++;
error = true; error = true;
} }
@ -354,8 +350,8 @@ void Source::ClangViewParse::update_diagnostics() {
if(!fix_its_string.empty()) if(!fix_its_string.empty())
diagnostic.spelling += "\n\n" + fix_its_string; diagnostic.spelling += "\n\n" + fix_its_string;
add_diagnostic_tooltip(start, end, error, [spelling = std::move(diagnostic.spelling)](const Glib::RefPtr<Gtk::TextBuffer> &buffer) { add_diagnostic_tooltip(start, end, error, [spelling = std::move(diagnostic.spelling)](Tooltip &tooltip) {
buffer->insert_at_cursor(spelling); 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 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); 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<Gtk::TextBuffer> &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(); 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(); auto brief_comment = cursor.get_brief_comments();
if(brief_comment != "") 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 #ifdef JUCI_ENABLE_DEBUG
if(Debug::LLDB::get().is_stopped()) { if(Debug::LLDB::get().is_stopped()) {
@ -529,7 +525,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle)
next_char_iter++; next_char_iter++;
debug_value.replace(iter, 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));
} }
} }
} }

53
src/source_language_protocol.cc

@ -944,40 +944,39 @@ void Source::LanguageProtocolView::update_diagnostics(const std::vector<Language
} }
bool error = false; bool error = false;
std::string severity_tag_name; if(diagnostic.severity >= 2)
if(diagnostic.severity >= 2) {
severity_tag_name = "def:warning";
num_warnings++; num_warnings++;
}
else { else {
severity_tag_name = "def:error";
num_errors++; num_errors++;
error = true; error = true;
} }
add_diagnostic_tooltip(start, end, error, [this, diagnostic = std::move(diagnostic)](const Glib::RefPtr<Gtk::TextBuffer> &buffer) { add_diagnostic_tooltip(start, end, error, [this, diagnostic = std::move(diagnostic)](Tooltip &tooltip) {
buffer->insert_at_cursor(diagnostic.message); tooltip.buffer->insert_at_cursor(diagnostic.message);
for(size_t i = 0; i < diagnostic.related_informations.size(); ++i) { if(!diagnostic.related_informations.empty()) {
auto link = filesystem::get_relative_path(diagnostic.related_informations[i].location.file, file_path.parent_path()).string(); auto link_tag = tooltip.buffer->get_tag_table()->lookup("link");
link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.line + 1); for(size_t i = 0; i < diagnostic.related_informations.size(); ++i) {
link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.character + 1); 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);
if(i == 0) link += ':' + std::to_string(diagnostic.related_informations[i].location.range.start.character + 1);
buffer->insert_at_cursor("\n\n");
buffer->insert_at_cursor(diagnostic.related_informations[i].message); if(i == 0)
buffer->insert_at_cursor(": "); tooltip.buffer->insert_at_cursor("\n\n");
auto pos = buffer->get_insert()->get_iter(); tooltip.buffer->insert_at_cursor(diagnostic.related_informations[i].message);
buffer->insert_with_tag(pos, link, link_tag); tooltip.buffer->insert_at_cursor(": ");
if(i != diagnostic.related_informations.size() - 1) auto pos = tooltip.buffer->get_insert()->get_iter();
buffer->insert_at_cursor("\n"); 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) { for(auto &mark : type_coverage_marks) {
add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), false, [](const Glib::RefPtr<Gtk::TextBuffer> &buffer) { add_diagnostic_tooltip(mark.first->get_iter(), mark.second->get_iter(), false, [](Tooltip &tooltip) {
buffer->insert_at_cursor(type_coverage_message); tooltip.buffer->insert_at_cursor(type_coverage_message);
}); });
num_warnings++; num_warnings++;
} }
@ -1036,7 +1035,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
while(!tooltip.empty() && tooltip.back() == '\n') { while(!tooltip.empty() && tooltip.back() == '\n') {
tooltip.pop_back(); // Remove unnecessary newlines 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) if(current_request != request_count)
return; return;
if(Notebook::get().get_current_view() != this) 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()) { 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<Gtk::TextBuffer> &buffer) { 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) {
insert_with_links_tagged(buffer, tooltip); tooltip.insert_with_links_tagged(tooltip_text);
#ifdef JUCI_ENABLE_DEBUG #ifdef JUCI_ENABLE_DEBUG
if(language_id == "rust" && capabilities.definition) { if(language_id == "rust" && capabilities.definition) {
@ -1084,7 +1083,7 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect
next_char_iter++; next_char_iter++;
debug_value.replace(iter, 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));
} }
} }
} }

68
src/tooltips.cc

@ -8,7 +8,7 @@ std::set<Tooltip *> Tooltips::shown_tooltips;
Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle(); Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle();
Tooltip::Tooltip(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark_, Tooltip::Tooltip(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark_,
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark_, std::function<void(const Glib::RefPtr<Gtk::TextBuffer> &)> set_buffer_) Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark_, std::function<void(Tooltip &toolip)> set_buffer_)
: start_mark(std::move(start_mark_)), end_mark(std::move(end_mark_)), text_view(text_view), set_buffer(std::move(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() { Tooltip::~Tooltip() {
@ -73,21 +73,32 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
box->get_style_context()->add_class("juci_tooltip_box"); box->get_style_context()->add_class("juci_tooltip_box");
window->add(*box); window->add(*box);
buffer = Gtk::TextBuffer::create();
if(text_view) { if(text_view) {
text_buffer = Gtk::TextBuffer::create(text_view->get_buffer()->get_tag_table()); auto tag = text_view->get_buffer()->get_tag_table()->lookup("def:warning");
link_tag = text_buffer->get_tag_table()->lookup("link"); auto new_tag = buffer->create_tag("def:warning");
} if(tag->property_foreground_set())
else { new_tag->property_foreground_rgba() = tag->property_foreground_rgba().get_value();
text_buffer = Gtk::TextBuffer::create(); if(tag->property_background_set())
link_tag = text_buffer->create_tag("link"); new_tag->property_background_rgba() = tag->property_background_rgba().get_value();
link_tag->property_underline() = Pango::Underline::UNDERLINE_SINGLE;
link_tag->property_foreground_rgba() = window->get_style_context()->get_color(Gtk::StateFlags::STATE_FLAG_LINK); 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(); 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->get_style_context()->add_class("juci_tooltip_text_view");
tooltip_text_view->set_editable(false); tooltip_text_view->set_editable(false);
@ -159,7 +170,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
#endif #endif
auto layout = Pango::Layout::create(tooltip_text_view->get_pango_context()); 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); layout->get_pixel_size(size.first, size.second);
size.first += 6; // 2xpadding size.first += 6; // 2xpadding
size.second += 8; // 2xpadding + 2 size.second += 8; // 2xpadding + 2
@ -181,7 +192,7 @@ void Tooltip::show(bool disregard_drawn, const std::function<void()> &on_motion)
}); });
} }
if(text_buffer->size() == 0) if(buffer->size() == 0)
return; // Do not show empty tooltips return; // Do not show empty tooltips
int root_x = 0, root_y = 0; int root_x = 0, root_y = 0;
@ -259,13 +270,13 @@ void Tooltip::hide(const std::pair<int, int> &last_mouse_pos, const std::pair<in
} }
void Tooltip::wrap_lines() { void Tooltip::wrap_lines() {
if(!text_buffer) if(!buffer)
return; return;
auto iter = text_buffer->begin(); auto iter = buffer->begin();
while(iter) { while(iter) {
auto last_space = text_buffer->end(); auto last_space = buffer->end();
bool end = false; bool end = false;
for(unsigned c = 0; c <= 80; c++) { for(unsigned c = 0; c <= 80; c++) {
if(!iter) { if(!iter) {
@ -288,21 +299,38 @@ void Tooltip::wrap_lines() {
last_space = iter; last_space = iter;
} }
if(iter && last_space) { 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; auto last_space_p = last_space;
last_space.forward_char(); last_space.forward_char();
text_buffer->erase(last_space_p, last_space); buffer->erase(last_space_p, last_space);
text_buffer->insert(mark->get_iter(), "\n"); buffer->insert(mark->get_iter(), "\n");
iter = mark->get_iter(); iter = mark->get_iter();
iter.forward_char(); 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) { void Tooltips::show(const Gdk::Rectangle &rectangle, bool disregard_drawn) {
for(auto &tooltip : tooltip_list) { for(auto &tooltip : tooltip_list) {
tooltip.update(); tooltip.update();

10
src/tooltips.h

@ -7,8 +7,8 @@
class Tooltip { class Tooltip {
public: public:
Tooltip(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark_, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark_, std::function<void(const Glib::RefPtr<Gtk::TextBuffer> &)> set_buffer_); Tooltip(Gtk::TextView *text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark_, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark_, std::function<void(Tooltip &)> set_buffer_);
Tooltip(std::function<void(const Glib::RefPtr<Gtk::TextBuffer> &)> set_buffer_) : Tooltip(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), Glib::RefPtr<Gtk::TextBuffer::Mark>(), std::move(set_buffer_)) {} Tooltip(std::function<void(Tooltip &tooltip)> set_buffer_) : Tooltip(nullptr, Glib::RefPtr<Gtk::TextBuffer::Mark>(), Glib::RefPtr<Gtk::TextBuffer::Mark>(), std::move(set_buffer_)) {}
~Tooltip(); ~Tooltip();
void update(); void update();
@ -19,14 +19,16 @@ public:
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark; Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark;
Glib::RefPtr<Gtk::TextBuffer> text_buffer; Glib::RefPtr<Gtk::TextBuffer> buffer;
void insert_with_links_tagged(const std::string &text);
private: private:
std::unique_ptr<Gtk::Window> window; std::unique_ptr<Gtk::Window> window;
void wrap_lines(); void wrap_lines();
Gtk::TextView *text_view; Gtk::TextView *text_view;
std::function<void(const Glib::RefPtr<Gtk::TextBuffer> &)> set_buffer; std::function<void(Tooltip &)> set_buffer;
std::pair<int, int> size; std::pair<int, int> size;
Gdk::Rectangle rectangle; Gdk::Rectangle rectangle;

8
src/window.cc

@ -521,7 +521,7 @@ void Window::set_menu_actions() {
menu.add_action("edit_cut", [this]() { menu.add_action("edit_cut", [this]() {
// Return if a shown tooltip has selected text // Return if a shown tooltip has selected text
for(auto tooltip : Tooltips::shown_tooltips) { for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer; auto buffer = tooltip->buffer;
if(buffer && buffer->get_has_selection()) if(buffer && buffer->get_has_selection())
return; return;
} }
@ -549,7 +549,7 @@ void Window::set_menu_actions() {
menu.add_action("edit_cut_lines", [this]() { menu.add_action("edit_cut_lines", [this]() {
// Return if a shown tooltip has selected text // Return if a shown tooltip has selected text
for(auto tooltip : Tooltips::shown_tooltips) { for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer; auto buffer = tooltip->buffer;
if(buffer && buffer->get_has_selection()) if(buffer && buffer->get_has_selection())
return; return;
} }
@ -572,7 +572,7 @@ void Window::set_menu_actions() {
menu.add_action("edit_copy", [this]() { menu.add_action("edit_copy", [this]() {
// Copy from a tooltip if it has selected text // Copy from a tooltip if it has selected text
for(auto tooltip : Tooltips::shown_tooltips) { for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer; auto buffer = tooltip->buffer;
if(buffer && buffer->get_has_selection()) { if(buffer && buffer->get_has_selection()) {
buffer->copy_clipboard(Gtk::Clipboard::get()); buffer->copy_clipboard(Gtk::Clipboard::get());
return; return;
@ -603,7 +603,7 @@ void Window::set_menu_actions() {
menu.add_action("edit_copy_lines", [this]() { menu.add_action("edit_copy_lines", [this]() {
// Copy from a tooltip if it has selected text // Copy from a tooltip if it has selected text
for(auto tooltip : Tooltips::shown_tooltips) { for(auto tooltip : Tooltips::shown_tooltips) {
auto buffer = tooltip->text_buffer; auto buffer = tooltip->buffer;
if(buffer && buffer->get_has_selection()) { if(buffer && buffer->get_has_selection()) {
Gtk::TextIter start, end; Gtk::TextIter start, end;
buffer->get_selection_bounds(start, end); buffer->get_selection_bounds(start, end);

4
tests/stubs/tooltips.cc

@ -4,10 +4,12 @@ Gdk::Rectangle Tooltips::drawn_tooltips_rectangle = Gdk::Rectangle();
Tooltip::Tooltip(Gtk::TextView *text_view, Tooltip::Tooltip(Gtk::TextView *text_view,
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, Glib::RefPtr<Gtk::TextBuffer::Mark> end_mark,
std::function<void(const Glib::RefPtr<Gtk::TextBuffer> &)> create_tooltip_buffer) : text_view(text_view) {} std::function<void(Tooltip &)> create_tooltip_buffer) : text_view(text_view) {}
Tooltip::~Tooltip() {} Tooltip::~Tooltip() {}
void Tooltip::insert_with_links_tagged(const std::string &) {}
void Tooltips::show(Gdk::Rectangle const &, bool) {} void Tooltips::show(Gdk::Rectangle const &, bool) {}
void Tooltips::show(bool) {} void Tooltips::show(bool) {}

Loading…
Cancel
Save