diff --git a/src/terminal.cc b/src/terminal.cc index 216e19f..909c37d 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -9,6 +9,8 @@ #include Terminal::Terminal() { + set_editable(false); + bold_tag=get_buffer()->create_tag(); bold_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY; diff --git a/src/tooltips.cc b/src/tooltips.cc index 18ef39e..954c97e 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -1,6 +1,7 @@ #include "tooltips.h" #include "selection_dialog.h" +std::set Tooltips::shown_tooltips; Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); Tooltip::Tooltip(std::function()> create_tooltip_buffer, Gtk::TextView *text_view, @@ -8,6 +9,7 @@ Glib::RefPtr start_mark, Glib::RefPtrget_buffer()->delete_mark(start_mark); text_view->get_buffer()->delete_mark(end_mark); @@ -34,6 +36,8 @@ void Tooltip::update() { } void Tooltip::show(bool disregard_drawn) { + Tooltips::shown_tooltips.emplace(this); + if(!window) { //init window window=std::make_unique(Gtk::WindowType::WINDOW_POPUP); @@ -60,9 +64,9 @@ void Tooltip::show(bool disregard_drawn) { box->get_style_context()->add_class("juci_tooltip_box"); window->add(*box); - auto buffer=create_tooltip_buffer(); - wrap_lines(buffer); - auto tooltip_text_view=Gtk::manage(new Gtk::TextView(buffer)); + text_buffer=create_tooltip_buffer(); + wrap_lines(); + auto tooltip_text_view=Gtk::manage(new Gtk::TextView(text_buffer)); tooltip_text_view->set_editable(false); if(text_view) { @@ -75,7 +79,7 @@ void Tooltip::show(bool disregard_drawn) { box->add(*tooltip_text_view); auto layout=Pango::Layout::create(tooltip_text_view->get_pango_context()); - layout->set_text(buffer->get_text()); + layout->set_text(text_buffer->get_text()); layout->get_pixel_size(size.first, size.second); size.first+=6; // 2xpadding size.second+=8; // 2xpadding + 2 @@ -139,11 +143,15 @@ void Tooltip::show(bool disregard_drawn) { } void Tooltip::hide() { + Tooltips::shown_tooltips.erase(this); if(window) window->hide(); } -void Tooltip::wrap_lines(Glib::RefPtr text_buffer) { +void Tooltip::wrap_lines() { + if(!text_buffer) + return; + auto iter=text_buffer->begin(); while(iter) { diff --git a/src/tooltips.h b/src/tooltips.h index eb657a9..07d0563 100644 --- a/src/tooltips.h +++ b/src/tooltips.h @@ -3,6 +3,7 @@ #include #include #include +#include class Tooltip { public: @@ -17,9 +18,11 @@ public: Gdk::Rectangle activation_rectangle; Glib::RefPtr start_mark; Glib::RefPtr end_mark; + + Glib::RefPtr text_buffer; private: std::unique_ptr window; - void wrap_lines(Glib::RefPtr text_buffer); + void wrap_lines(); std::function()> create_tooltip_buffer; Gtk::TextView *text_view; @@ -29,6 +32,7 @@ private: class Tooltips { public: + static std::set shown_tooltips; static void init() {drawn_tooltips_rectangle=Gdk::Rectangle();} void show(const Gdk::Rectangle& rectangle, bool disregard_drawn=false); void show(bool disregard_drawn=false); @@ -40,7 +44,7 @@ public: void emplace_back(Ts&&... params) { tooltip_list.emplace_back(std::forward(params)...); } - + static Gdk::Rectangle drawn_tooltips_rectangle; private: diff --git a/src/window.cc b/src/window.cc index bbd1b37..a384adc 100644 --- a/src/window.cc +++ b/src/window.cc @@ -391,27 +391,73 @@ void Window::set_menu_actions() { auto widget=get_focus(); if(auto entry=dynamic_cast(widget)) entry->cut_clipboard(); - else if(auto view=Notebook::get().get_current_view()) { - view->disable_spellcheck=true; - view->get_buffer()->cut_clipboard(Gtk::Clipboard::get()); - view->disable_spellcheck=false; + else if(auto view=dynamic_cast(widget)) { + auto source_view=dynamic_cast(view); + if(source_view) + source_view->disable_spellcheck=true; + if(!view->get_buffer()->get_has_selection()) { + auto start=view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line()); + auto end=start; + if(!end.ends_line()) + end.forward_to_line_end(); + end.forward_char(); + if(!end.starts_line()) // In case of \r\n + end.forward_char(); + Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end)); + if(view->get_editable()) + view->get_buffer()->erase(start, end); + } + else { + if(view->get_editable()) + view->get_buffer()->cut_clipboard(Gtk::Clipboard::get()); + else + view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); + } + if(source_view) + source_view->disable_spellcheck=false; } }); 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; + if(buffer && buffer->get_has_selection()) { + buffer->copy_clipboard(Gtk::Clipboard::get()); + return; + } + } + auto widget=get_focus(); if(auto entry=dynamic_cast(widget)) entry->copy_clipboard(); - else if(auto text_view=dynamic_cast(widget)) - text_view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); + else if(auto view=dynamic_cast(widget)) { + if(!view->get_buffer()->get_has_selection()) { + auto start=view->get_buffer()->get_iter_at_line(view->get_buffer()->get_insert()->get_iter().get_line()); + auto end=start; + if(!end.ends_line()) + end.forward_to_line_end(); + end.forward_char(); + if(!end.starts_line()) // In case of \r\n + end.forward_char(); + Gtk::Clipboard::get()->set_text(view->get_buffer()->get_text(start, end)); + } + else + view->get_buffer()->copy_clipboard(Gtk::Clipboard::get()); + } }); menu.add_action("edit_paste", [this]() { auto widget=get_focus(); if(auto entry=dynamic_cast(widget)) entry->paste_clipboard(); - else if(auto view=Notebook::get().get_current_view()) { - view->disable_spellcheck=true; - view->paste(); - view->disable_spellcheck=false; + else if(auto view=dynamic_cast(widget)) { + auto source_view=dynamic_cast(view); + if(source_view) { + source_view->disable_spellcheck=true; + source_view->paste(); + source_view->disable_spellcheck=false; + } + else if(view->get_editable()) + view->get_buffer()->paste_clipboard(Gtk::Clipboard::get()); } });