diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 779a231..38846d4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,7 +12,7 @@ set(project_files juci.cc notebook.cc project.cc - selectiondialog.cc + selection_dialog.cc terminal.cc tooltips.cc window.cc diff --git a/src/notebook.cc b/src/notebook.cc index 4e7833b..48ef5b8 100644 --- a/src/notebook.cc +++ b/src/notebook.cc @@ -5,6 +5,7 @@ #include #include "project.h" #include "filesystem.h" +#include "selection_dialog.h" #if GTKSOURCEVIEWMM_MAJOR_VERSION > 3 || (GTKSOURCEVIEWMM_MAJOR_VERSION == 3 && GTKSOURCEVIEWMM_MINOR_VERSION >= 18) #include "gtksourceview-3.0/gtksourceview/gtksourcemap.h" @@ -522,6 +523,9 @@ bool Notebook::close(size_t index) { delete_cursor_locations(view); + SelectionDialog::get()=nullptr; + CompletionDialog::get()=nullptr; + if(auto clang_view=dynamic_cast(view)) clang_view->async_delete(); else diff --git a/src/project.cc b/src/project.cc index 5016d00..399b83b 100644 --- a/src/project.cc +++ b/src/project.cc @@ -6,6 +6,7 @@ #include #include "menu.h" #include "notebook.h" +#include "selection_dialog.h" #ifdef JUCI_ENABLE_DEBUG #include "debug_lldb.h" #endif @@ -91,10 +92,10 @@ void Project::debug_activate_menu_items() { menu.actions["debug_step_over"]->set_enabled(!debug_status.empty()); menu.actions["debug_step_into"]->set_enabled(!debug_status.empty()); menu.actions["debug_step_out"]->set_enabled(!debug_status.empty()); - menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty() && view); - menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty() && view); + menu.actions["debug_backtrace"]->set_enabled(!debug_status.empty()); + menu.actions["debug_show_variables"]->set_enabled(!debug_status.empty()); menu.actions["debug_run_command"]->set_enabled(!debug_status.empty()); - menu.actions["debug_toggle_breakpoint"]->set_enabled(view && static_cast(view->toggle_breakpoint)); + menu.actions["debug_toggle_breakpoint"]->set_enabled(view && view->toggle_breakpoint); menu.actions["debug_goto_stop"]->set_enabled(!debug_status.empty()); } @@ -493,12 +494,16 @@ void Project::Clang::debug_step_out() { } void Project::Clang::debug_backtrace() { - auto view=Notebook::get().get_current_view(); - if(view && debugging) { + if(debugging) { + auto view=Notebook::get().get_current_view(); auto backtrace=Debug::LLDB::get().get_backtrace(); - auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(iter), true, true); + if(view) { + auto iter=view->get_iter_for_dialog(); + SelectionDialog::create(view, view->get_buffer()->create_mark(iter), true, true); + } + else + SelectionDialog::create(true, true); auto rows=std::make_shared >(); if(backtrace.size()==0) { Info::get().print("No backtrace found"); @@ -520,14 +525,14 @@ void Project::Clang::debug_backtrace() { row+=":"+Glib::Markup::escape_text(file_path)+":"+std::to_string(frame.line_nr)+" - "+Glib::Markup::escape_text(frame.function_name); } (*rows)[row]=frame; - view->selection_dialog->add_row(row); - if(!cursor_set && frame.file_path==view->file_path) { - view->selection_dialog->set_cursor_at_last_row(); + SelectionDialog::get()->add_row(row); + if(!cursor_set && view && frame.file_path==view->file_path) { + SelectionDialog::get()->set_cursor_at_last_row(); cursor_set=true; } } - view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + SelectionDialog::get()->on_select=[this, rows](const std::string& selected, bool hide_window) { auto frame=rows->at(selected); if(!frame.file_path.empty()) { Notebook::get().open(frame.file_path); @@ -539,18 +544,24 @@ void Project::Clang::debug_backtrace() { } } }; - view->hide_tooltips(); - view->selection_dialog->show(); + if(view) + view->hide_tooltips(); + SelectionDialog::get()->show(); } } void Project::Clang::debug_show_variables() { - auto view=Notebook::get().get_current_view(); - if(debugging && view) { + if(debugging) { + auto view=Notebook::get().get_current_view(); auto variables=Debug::LLDB::get().get_variables(); - auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(iter), true, true); + Gtk::TextIter iter; + if(view) { + iter=view->get_iter_for_dialog(); + SelectionDialog::create(view, view->get_buffer()->create_mark(iter), true, true); + } + else + SelectionDialog::create(true, true); auto rows=std::make_shared >(); if(variables.size()==0) { Info::get().print("No variables found"); @@ -561,10 +572,10 @@ void Project::Clang::debug_show_variables() { std::string row="#"+std::to_string(variable.thread_index_id)+":#"+std::to_string(variable.frame_index)+":"+variable.file_path.filename().string()+":"+std::to_string(variable.line_nr)+" - "+Glib::Markup::escape_text(variable.name)+""; (*rows)[row]=variable; - view->selection_dialog->add_row(row); + SelectionDialog::get()->add_row(row); } - view->selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + SelectionDialog::get()->on_select=[this, rows](const std::string& selected, bool hide_window) { auto variable=rows->at(selected); Debug::LLDB::get().select_frame(variable.frame_index, variable.thread_index_id); if(!variable.file_path.empty()) { @@ -578,44 +589,49 @@ void Project::Clang::debug_show_variables() { Info::get().print("Debugger did not find declaration for the variable: "+variable.name); }; - view->selection_dialog->on_hide=[this]() { + SelectionDialog::get()->on_hide=[this]() { debug_variable_tooltips.hide(); debug_variable_tooltips.clear(); }; - view->selection_dialog->on_changed=[this, rows, iter](const std::string &selected) { + SelectionDialog::get()->on_changed=[this, rows, view, iter](const std::string &selected) { if(selected.empty()) { debug_variable_tooltips.hide(); return; } - if(auto view=Notebook::get().get_current_view()) { - debug_variable_tooltips.clear(); - auto create_tooltip_buffer=[this, rows, view, selected]() { - auto variable=rows->at(selected); - auto tooltip_buffer=Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()); - - Glib::ustring value=variable.value; - if(!value.empty()) { - Glib::ustring::iterator iter; - while(!value.validate(iter)) { - auto next_char_iter=iter; - next_char_iter++; - value.replace(iter, next_char_iter, "?"); - } - tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); + debug_variable_tooltips.clear(); + auto create_tooltip_buffer=[this, rows, view, selected]() { + auto variable=rows->at(selected); + auto tooltip_buffer=view?Gtk::TextBuffer::create(view->get_buffer()->get_tag_table()):Gtk::TextBuffer::create(); + + Glib::ustring value=variable.value; + if(!value.empty()) { + Glib::ustring::iterator iter; + while(!value.validate(iter)) { + auto next_char_iter=iter; + next_char_iter++; + value.replace(iter, next_char_iter, "?"); } - - return tooltip_buffer; - }; + if(view) + tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1), "def:note"); + else + tooltip_buffer->insert(tooltip_buffer->get_insert()->get_iter(), value.substr(0, value.size()-1)); + } - debug_variable_tooltips.emplace_back(create_tooltip_buffer, *view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter)); - - debug_variable_tooltips.show(true); - } + return tooltip_buffer; + }; + + if(view) + debug_variable_tooltips.emplace_back(create_tooltip_buffer, view, view->get_buffer()->create_mark(iter), view->get_buffer()->create_mark(iter)); + else + debug_variable_tooltips.emplace_back(create_tooltip_buffer); + + debug_variable_tooltips.show(true); }; - view->hide_tooltips(); - view->selection_dialog->show(); + if(view) + view->hide_tooltips(); + SelectionDialog::get()->show(); } } diff --git a/src/selectiondialog.cc b/src/selection_dialog.cc similarity index 83% rename from src/selectiondialog.cc rename to src/selection_dialog.cc index 86d941d..95fdf99 100644 --- a/src/selectiondialog.cc +++ b/src/selection_dialog.cc @@ -1,4 +1,4 @@ -#include "selectiondialog.h" +#include "selection_dialog.h" #include namespace sigc { @@ -43,7 +43,7 @@ void SelectionDialogBase::ListViewText::clear() { list_store.reset(); } -SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): +SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): text_view(text_view), window(Gtk::WindowType::WINDOW_POPUP), vbox(Gtk::Orientation::ORIENTATION_VERTICAL), list_view_text(use_markup), start_mark(start_mark), show_search_entry(show_search_entry) { auto g_application=g_application_get_default(); auto gio_application=Glib::wrap(g_application, true); @@ -67,26 +67,63 @@ SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr< window.add(vbox); list_view_text.signal_realize().connect([this](){ - resize(); + auto g_application=g_application_get_default(); + auto gio_application=Glib::wrap(g_application, true); + auto application=Glib::RefPtr::cast_static(gio_application); + auto application_window=application->get_active_window(); + + int row_width=0, row_height; + Gdk::Rectangle rect; + list_view_text.get_cell_area(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()), *(list_view_text.get_column(0)), rect); + row_width=rect.get_width(); + row_height=rect.get_height(); + + row_width+=rect.get_x()*2; //TODO: Add correct margin x and y + row_height+=rect.get_y()*2; + + if(this->text_view && row_width>this->text_view->get_width()*2/3) + row_width=this->text_view->get_width()*2/3; + else if(row_width>application_window->get_width()/2) + row_width=application_window->get_width()/2; + else + scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC); + + int window_height=std::min(row_height*static_cast(list_view_text.get_model()->children().size()), row_height*10); + if(this->show_search_entry) + window_height+=search_entry.get_height(); + int window_width=row_width+1; + window.resize(window_width, window_height); + + if(this->text_view) { + Gdk::Rectangle iter_rect; + this->text_view->get_iter_location(this->start_mark->get_iter(), iter_rect); + Gdk::Rectangle visible_rect; + this->text_view->get_visible_rect(visible_rect); + int buffer_x=std::max(iter_rect.get_x(), visible_rect.get_x()); + int buffer_y=iter_rect.get_y()+iter_rect.get_height(); + int window_x, window_y; + this->text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y); + int root_x, root_y; + this->text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y); + window.move(root_x, root_y+1); //TODO: replace 1 with some margin + } + else { + int root_x, root_y; + application_window->get_position(root_x, root_y); + root_x+=application_window->get_width()/2-window_width/2; + root_y+=application_window->get_height()/2-window_height/2; + window.move(root_x, root_y); + } }); list_view_text.signal_cursor_changed().connect([this] { cursor_changed(); }); - - window.signal_realize().connect([this] { - Gdk::Rectangle iter_rect; - this->text_view.get_iter_location(this->start_mark->get_iter(), iter_rect); - Gdk::Rectangle visible_rect; - this->text_view.get_visible_rect(visible_rect); - int buffer_x=std::max(iter_rect.get_x(), visible_rect.get_x()); - int buffer_y=iter_rect.get_y()+iter_rect.get_height(); - int window_x, window_y; - this->text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, buffer_x, buffer_y, window_x, window_y); - int root_x, root_y; - this->text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(window_x, window_y, root_x, root_y); - window.move(root_x, root_y+1); //TODO: replace 1 with some margin - }); +} + +SelectionDialogBase::~SelectionDialogBase() { + if(text_view) + text_view->get_buffer()->delete_mark(start_mark); } void SelectionDialogBase::cursor_changed() { @@ -102,18 +139,14 @@ void SelectionDialogBase::cursor_changed() { on_changed(row); last_row=row; } - -SelectionDialogBase::~SelectionDialogBase() { - text_view.get_buffer()->delete_mark(start_mark); -} - void SelectionDialogBase::add_row(const std::string& row) { list_view_text.append(row); } void SelectionDialogBase::show() { window.show_all(); - text_view.grab_focus(); + if(text_view) + text_view->grab_focus(); if(list_view_text.get_model()->children().size()>0) { if(!list_view_text.get_selection()->get_selected()) { @@ -146,30 +179,9 @@ void SelectionDialogBase::hide() { list_view_text.clear(); } -void SelectionDialogBase::resize() { - if(list_view_text.get_realized()) { - int row_width=0, row_height; - Gdk::Rectangle rect; - list_view_text.get_cell_area(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin()), *(list_view_text.get_column(0)), rect); - row_width=rect.get_width(); - row_height=rect.get_height(); - - row_width+=rect.get_x()*2; //TODO: Add correct margin x and y - row_height+=rect.get_y()*2; - - if(row_width>text_view.get_width()/2) - row_width=text_view.get_width()/2; - else - scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC); +std::unique_ptr SelectionDialog::instance; - int window_height=std::min(row_height*static_cast(list_view_text.get_model()->children().size()), row_height*10); - if(show_search_entry) - window_height+=search_entry.get_height(); - window.resize(row_width+1, window_height); - } -} - -SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) { +SelectionDialog::SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) { std::shared_ptr search_key(new std::string()); auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model()); @@ -288,8 +300,10 @@ bool SelectionDialog::on_key_press(GdkEventKey* key) { return false; } -CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false, false) { - show_offset=text_view.get_buffer()->get_insert()->get_iter().get_offset(); +std::unique_ptr CompletionDialog::instance; + +CompletionDialog::CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false, false) { + show_offset=text_view->get_buffer()->get_insert()->get_iter().get_offset(); std::shared_ptr search_key(new std::string()); auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model()); @@ -325,7 +339,7 @@ CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtrget_text(start_mark->get_iter(), text_view.get_buffer()->get_insert()->get_iter()); + auto text=text_view->get_buffer()->get_text(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter()); if(text.size()>0) { search_entry.set_text(text); list_view_text.set_search_entry(search_entry); @@ -349,11 +363,11 @@ bool CompletionDialog::on_key_release(GdkEventKey* key) { if(key->keyval==GDK_KEY_Down || key->keyval==GDK_KEY_KP_Down || key->keyval==GDK_KEY_Up || key->keyval==GDK_KEY_KP_Up) return false; - if(show_offset>text_view.get_buffer()->get_insert()->get_iter().get_offset()) { + if(show_offset>text_view->get_buffer()->get_insert()->get_iter().get_offset()) { hide(); } else { - auto text=text_view.get_buffer()->get_text(start_mark->get_iter(), text_view.get_buffer()->get_insert()->get_iter()); + auto text=text_view->get_buffer()->get_text(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter()); search_entry.set_text(text); list_view_text.set_search_entry(search_entry); if(text=="") { @@ -371,7 +385,7 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { (key->keyval>=GDK_KEY_a && key->keyval<=GDK_KEY_z) || key->keyval==GDK_KEY_underscore || key->keyval==GDK_KEY_BackSpace) { if(row_in_entry) { - text_view.get_buffer()->erase(start_mark->get_iter(), text_view.get_buffer()->get_insert()->get_iter()); + text_view->get_buffer()->erase(start_mark->get_iter(), text_view->get_buffer()->get_insert()->get_iter()); row_in_entry=false; if(key->keyval==GDK_KEY_BackSpace) return true; diff --git a/src/selectiondialog.h b/src/selection_dialog.h similarity index 57% rename from src/selectiondialog.h rename to src/selection_dialog.h index 74cd014..28163bf 100644 --- a/src/selectiondialog.h +++ b/src/selection_dialog.h @@ -31,13 +31,15 @@ class SelectionDialogBase { }; public: - SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup); - ~SelectionDialogBase(); + SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup); + virtual ~SelectionDialogBase(); void add_row(const std::string& row); void set_cursor_at_last_row(); void show(); void hide(); + bool is_visible() {return window.is_visible();} + void get_position(int &root_x, int &root_y) {window.get_position(root_x, root_y);} std::function on_hide; std::function on_select; @@ -47,8 +49,7 @@ public: protected: void cursor_changed(); - void resize(); - Gtk::TextView& text_view; + Gtk::TextView *text_view; Gtk::Window window; Gtk::Box vbox; Gtk::ScrolledWindow scrolled_window; @@ -60,17 +61,31 @@ protected: }; class SelectionDialog : public SelectionDialogBase { + SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup); + static std::unique_ptr instance; public: - SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry=true, bool use_markup=false); bool on_key_press(GdkEventKey* key); + + static void create(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry=true, bool use_markup=false) { + instance=std::unique_ptr(new SelectionDialog(text_view, start_mark, show_search_entry, use_markup)); + } + static void create(bool show_search_entry=true, bool use_markup=false) { + instance=std::unique_ptr(new SelectionDialog(nullptr, Glib::RefPtr(), show_search_entry, use_markup)); + } + static std::unique_ptr &get() {return instance;} }; class CompletionDialog : public SelectionDialogBase { + CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark); + static std::unique_ptr instance; public: - CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark); bool on_key_release(GdkEventKey* key); bool on_key_press(GdkEventKey* key); + static void create(Gtk::TextView *text_view, Glib::RefPtr start_mark) { + instance=std::unique_ptr(new CompletionDialog(text_view, start_mark)); + } + static std::unique_ptr &get() {return instance;} private: void select(bool hide_window=true); diff --git a/src/source.cc b/src/source.cc index e1b8971..6c88619 100644 --- a/src/source.cc +++ b/src/source.cc @@ -5,6 +5,7 @@ #include "info.h" #include "directories.h" #include "menu.h" +#include "selection_dialog.h" #include #include #include @@ -647,10 +648,10 @@ void Source::View::set_tooltip_and_dialog_events() { return false; }, 500); - if(autocomplete_dialog) - autocomplete_dialog->hide(); - if(selection_dialog) - selection_dialog->hide(); + if(SelectionDialog::get()) + SelectionDialog::get()->hide(); + if(CompletionDialog::get()) + CompletionDialog::get()->hide(); if(update_status_location) update_status_location(this); @@ -947,10 +948,10 @@ void Source::View::hide_tooltips() { void Source::View::hide_dialogs() { SpellCheckView::hide_dialogs(); - if(selection_dialog) - selection_dialog->hide(); - if(autocomplete_dialog) - autocomplete_dialog->hide(); + if(SelectionDialog::get()) + SelectionDialog::get()->hide(); + if(CompletionDialog::get()) + CompletionDialog::get()->hide(); } std::string Source::View::get_line(const Gtk::TextIter &iter) { @@ -1244,12 +1245,12 @@ std::string Source::View::get_token(Gtk::TextIter iter) { } bool Source::View::on_key_press_event(GdkEventKey* key) { - if(selection_dialog && selection_dialog->is_visible()) { - if(selection_dialog->on_key_press(key)) + if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) { + if(SelectionDialog::get()->on_key_press(key)) return true; } - if(autocomplete_dialog && autocomplete_dialog->is_visible()) { - if(autocomplete_dialog->on_key_press(key)) + if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) { + if(CompletionDialog::get()->on_key_press(key)) return true; } diff --git a/src/source.h b/src/source.h index 3816e1c..f329231 100644 --- a/src/source.h +++ b/src/source.h @@ -80,8 +80,6 @@ namespace Source { std::function add_documentation; std::function toggle_breakpoint; - std::unique_ptr autocomplete_dialog; - std::unique_ptr selection_dialog; Gtk::TextIter get_iter_for_dialog(); std::function scroll_to_cursor_delayed=[](View* view, bool center, bool show_tooltips) {}; diff --git a/src/source_clang.cc b/src/source_clang.cc index 8409d12..69b8968 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -8,6 +8,7 @@ #include "info.h" #include "dialogs.h" #include "ctags.h" +#include "selection_dialog.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -455,7 +456,7 @@ void Source::ClangViewParse::update_diagnostics() { } return tooltip_buffer; }; - diagnostic_tooltips.emplace_back(create_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); + diagnostic_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); get_buffer()->apply_tag_by_name(diagnostic_tag_name+"_underline", start, end); auto iter=get_buffer()->get_insert()->get_iter(); @@ -554,7 +555,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) return tooltip_buffer; }; - type_tooltips.emplace_back(create_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); + type_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(start), get_buffer()->create_mark(end)); type_tooltips.show(); return; } @@ -568,7 +569,7 @@ void Source::ClangViewParse::show_type_tooltips(const Gdk::Rectangle &rectangle) Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::path &file_path, Glib::RefPtr language): Source::ClangViewParse(file_path, language), autocomplete_state(AutocompleteState::IDLE) { get_buffer()->signal_changed().connect([this](){ - if(autocomplete_dialog && autocomplete_dialog->is_visible()) + if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) delayed_reparse_connection.disconnect(); else { if(!has_focus()) @@ -596,8 +597,8 @@ Source::ClangViewAutocomplete::ClangViewAutocomplete(const boost::filesystem::pa }); signal_key_release_event().connect([this](GdkEventKey* key){ - if(autocomplete_dialog && autocomplete_dialog->is_visible()) { - if(autocomplete_dialog->on_key_release(key)) + if(CompletionDialog::get() && CompletionDialog::get()->is_visible()) { + if(CompletionDialog::get()->on_key_release(key)) return true; } return false; @@ -614,19 +615,19 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { auto start_iter=get_buffer()->get_insert()->get_iter(); if(prefix.size()>0 && !start_iter.backward_chars(prefix.size())) return; - autocomplete_dialog=std::make_unique(*this, get_buffer()->create_mark(start_iter)); - autocomplete_dialog_rows.clear(); - autocomplete_dialog->on_hide=[this](){ + CompletionDialog::create(this, get_buffer()->create_mark(start_iter)); + completion_dialog_rows.clear(); + CompletionDialog::get()->on_hide=[this](){ get_buffer()->end_user_action(); autocomplete_tooltips.hide(); autocomplete_tooltips.clear(); parsed=false; soft_reparse(); }; - autocomplete_dialog->on_select=[this](const std::string& selected, bool hide_window) { - auto row = autocomplete_dialog_rows.at(selected).first; + CompletionDialog::get()->on_select=[this](const std::string& selected, bool hide_window) { + auto row = completion_dialog_rows.at(selected).first; //erase existing variable or function before insert iter - get_buffer()->erase(autocomplete_dialog->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); + get_buffer()->erase(CompletionDialog::get()->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); //do not insert template argument or function parameters if they already exist auto iter=get_buffer()->get_insert()->get_iter(); if(*iter=='<' || *iter=='(') { @@ -640,7 +641,7 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { auto it=manipulators_map.find(row); if(it!=manipulators_map.end()) row=it->second; - get_buffer()->insert(autocomplete_dialog->start_mark->get_iter(), row); + get_buffer()->insert(CompletionDialog::get()->start_mark->get_iter(), row); //if selection is finalized, select text inside template arguments or function parameters if(hide_window) { auto para_pos=row.find('('); @@ -668,8 +669,8 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { } } if(start_pos!=std::string::npos && end_pos!=std::string::npos) { - auto start_offset=autocomplete_dialog->start_mark->get_iter().get_offset()+start_pos+1; - auto end_offset=autocomplete_dialog->start_mark->get_iter().get_offset()+end_pos; + auto start_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+start_pos+1; + auto end_offset=CompletionDialog::get()->start_mark->get_iter().get_offset()+end_pos; if(start_offset!=end_offset) get_buffer()->select_range(get_buffer()->get_iter_at_offset(start_offset), get_buffer()->get_iter_at_offset(end_offset)); } @@ -682,12 +683,12 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { } }; - autocomplete_dialog->on_changed=[this](const std::string &selected) { + CompletionDialog::get()->on_changed=[this](const std::string &selected) { if(selected.empty()) { autocomplete_tooltips.hide(); return; } - auto tooltip=std::make_shared(autocomplete_dialog_rows.at(selected).second); + auto tooltip=std::make_shared(completion_dialog_rows.at(selected).second); if(tooltip->empty()) { autocomplete_tooltips.hide(); } @@ -701,8 +702,8 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { return tooltip_buffer; }; - auto iter=autocomplete_dialog->start_mark->get_iter(); - autocomplete_tooltips.emplace_back(create_tooltip_buffer, *this, get_buffer()->create_mark(iter), get_buffer()->create_mark(iter)); + auto iter=CompletionDialog::get()->start_mark->get_iter(); + autocomplete_tooltips.emplace_back(create_tooltip_buffer, this, get_buffer()->create_mark(iter), get_buffer()->create_mark(iter)); autocomplete_tooltips.show(true); } @@ -808,8 +809,8 @@ void Source::ClangViewAutocomplete::autocomplete() { auto row_insert_on_selection=row; if(!return_value.empty()) row+=" --> " + return_value; - autocomplete_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); - autocomplete_dialog->add_row(row); + completion_dialog_rows[row] = std::pair(std::move(row_insert_on_selection), std::move(data.brief_comments)); + CompletionDialog::get()->add_row(row); } } autocomplete_data->clear(); @@ -817,10 +818,10 @@ void Source::ClangViewAutocomplete::autocomplete() { if(update_status_state) update_status_state(this); autocomplete_state=AutocompleteState::IDLE; - if (!autocomplete_dialog_rows.empty()) { + if (!completion_dialog_rows.empty()) { get_buffer()->begin_user_action(); hide_tooltips(); - autocomplete_dialog->show(); + CompletionDialog::get()->show(); } else soft_reparse(); diff --git a/src/source_clang.h b/src/source_clang.h index c2787b2..b08bd48 100644 --- a/src/source_clang.h +++ b/src/source_clang.h @@ -77,7 +77,7 @@ namespace Source { void autocomplete_dialog_setup(); void autocomplete_check(); void autocomplete(); - std::unordered_map > autocomplete_dialog_rows; + std::unordered_map > completion_dialog_rows; std::vector autocomplete_get_suggestions(const std::string &buffer, int line_number, int column); Tooltips autocomplete_tooltips; std::string prefix; diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc index 7dddf06..a5490ee 100644 --- a/src/source_spellcheck.cc +++ b/src/source_spellcheck.cc @@ -1,6 +1,7 @@ #include "source_spellcheck.h" #include "config.h" #include "info.h" +#include "selection_dialog.h" #include namespace sigc { @@ -27,8 +28,8 @@ Source::SpellCheckView::SpellCheckView() : Gsv::View() { spellcheck_error_tag->property_underline()=Pango::Underline::UNDERLINE_ERROR; signal_key_press_event().connect([this](GdkEventKey *event) { - if(spellcheck_suggestions_dialog && spellcheck_suggestions_dialog->is_visible()) { - if(spellcheck_suggestions_dialog->on_key_press(event)) + if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) { + if(SelectionDialog::get()->on_key_press(event)) return true; } @@ -150,26 +151,26 @@ Source::SpellCheckView::SpellCheckView() : Gsv::View() { return; if(mark->get_name()=="insert") { - if(spellcheck_suggestions_dialog) - spellcheck_suggestions_dialog->hide(); + if(SelectionDialog::get()) + SelectionDialog::get()->hide(); delayed_spellcheck_suggestions_connection.disconnect(); delayed_spellcheck_suggestions_connection=Glib::signal_timeout().connect([this]() { if(get_buffer()->get_insert()->get_iter().has_tag(spellcheck_error_tag)) { - spellcheck_suggestions_dialog=std::make_unique(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false); + SelectionDialog::create(this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false); auto word=get_word(get_buffer()->get_insert()->get_iter()); auto suggestions=get_spellcheck_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) { + SelectionDialog::get()->add_row(suggestion); + SelectionDialog::get()->on_select=[this, word](const std::string& selected, bool hide_window) { get_buffer()->begin_user_action(); get_buffer()->erase(word.first, word.second); get_buffer()->insert(get_buffer()->get_insert()->get_iter(), selected); get_buffer()->end_user_action(); }; hide_tooltips(); - spellcheck_suggestions_dialog->show(); + SelectionDialog::get()->show(); } return false; }, 500); @@ -178,8 +179,8 @@ Source::SpellCheckView::SpellCheckView() : Gsv::View() { get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark) { if(mark->get_name()=="insert") { - if(spellcheck_suggestions_dialog) - spellcheck_suggestions_dialog->hide(); + if(SelectionDialog::get()) + SelectionDialog::get()->hide(); } }); @@ -240,8 +241,8 @@ void Source::SpellCheckView::configure() { void Source::SpellCheckView::hide_dialogs() { delayed_spellcheck_suggestions_connection.disconnect(); - if(spellcheck_suggestions_dialog) - spellcheck_suggestions_dialog->hide(); + if(SelectionDialog::get()) + SelectionDialog::get()->hide(); } void Source::SpellCheckView::spellcheck(const Gtk::TextIter& start, const Gtk::TextIter& end) { diff --git a/src/source_spellcheck.h b/src/source_spellcheck.h index b1a26e4..48b77f0 100644 --- a/src/source_spellcheck.h +++ b/src/source_spellcheck.h @@ -2,7 +2,6 @@ #define JUCI_SOURCE_SPELLCHECK_H_ #include #include -#include "selectiondialog.h" namespace Source { class SpellCheckView : virtual public Gsv::View { @@ -24,8 +23,6 @@ namespace Source { bool spellcheck_all=false; guint last_keyval=0; private: - std::unique_ptr spellcheck_suggestions_dialog; - Glib::RefPtr spellcheck_error_tag; Glib::RefPtr comment_tag; diff --git a/src/tooltips.cc b/src/tooltips.cc index 35bc55c..b07ca36 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -1,4 +1,5 @@ #include "tooltips.h" +#include "selection_dialog.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -16,31 +17,35 @@ namespace sigc { Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); -Tooltip::Tooltip(std::function()> create_tooltip_buffer, Gtk::TextView& text_view, +Tooltip::Tooltip(std::function()> create_tooltip_buffer, Gtk::TextView *text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark): create_tooltip_buffer(create_tooltip_buffer), text_view(text_view), start_mark(start_mark), end_mark(end_mark) {} Tooltip::~Tooltip() { - text_view.get_buffer()->delete_mark(start_mark); - text_view.get_buffer()->delete_mark(end_mark); + if(text_view) { + text_view->get_buffer()->delete_mark(start_mark); + text_view->get_buffer()->delete_mark(end_mark); + } } void Tooltip::update() { - auto iter=start_mark->get_iter(); - auto end_iter=end_mark->get_iter(); - text_view.get_iter_location(iter, activation_rectangle); - if(iter.get_offset()get_iter(); + auto end_iter=end_mark->get_iter(); + text_view->get_iter_location(iter, activation_rectangle); + if(iter.get_offset()get_iter_location(iter, rectangle); + activation_rectangle.join(rectangle); + } } + int location_window_x, location_window_y; + text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(), activation_rectangle.get_y(), location_window_x, location_window_y); + activation_rectangle.set_x(location_window_x); + activation_rectangle.set_y(location_window_y); } - int location_window_x, location_window_y; - text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, activation_rectangle.get_x(), activation_rectangle.get_y(), location_window_x, location_window_y); - activation_rectangle.set_x(location_window_x); - activation_rectangle.set_y(location_window_y); } void Tooltip::show(bool disregard_drawn) { @@ -64,8 +69,10 @@ void Tooltip::show(bool disregard_drawn) { tooltip_widget=std::make_unique(create_tooltip_buffer()); wrap_lines(tooltip_widget->get_buffer()); tooltip_widget->set_editable(false); - auto tag=text_view.get_buffer()->get_tag_table()->lookup("def:note_background"); - tooltip_widget->override_background_color(tag->property_background_rgba()); + if(text_view) { + auto tag=text_view->get_buffer()->get_tag_table()->lookup("def:note_background"); + tooltip_widget->override_background_color(tag->property_background_rgba()); + } window->add(*tooltip_widget); auto layout=Pango::Layout::create(tooltip_widget->get_pango_context()); @@ -74,19 +81,32 @@ void Tooltip::show(bool disregard_drawn) { size.second+=2; window->signal_realize().connect([this] { + if(!text_view) { + auto &dialog=SelectionDialog::get(); + if(dialog && dialog->is_visible()) { + int root_x, root_y; + dialog->get_position(root_x, root_y); + position.first=root_x; + position.second=root_y-size.second; + if(position.second<0) + position.second=0; + } + } window->move(position.first, position.second); }); } - //Adjust if tooltip is left of text_view - Gdk::Rectangle visible_rect; - text_view.get_visible_rect(visible_rect); - int visible_x, visible_y; - text_view.buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_x, visible_y); - auto activation_rectangle_x=std::max(activation_rectangle.get_x(), visible_x); - - int root_x, root_y; - text_view.get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y); + int root_x=0, root_y=0; + if(text_view) { + //Adjust if tooltip is left of text_view + Gdk::Rectangle visible_rect; + text_view->get_visible_rect(visible_rect); + int visible_x, visible_y; + text_view->buffer_to_window_coords(Gtk::TextWindowType::TEXT_WINDOW_TEXT, visible_rect.get_x(), visible_rect.get_y(), visible_x, visible_y); + auto activation_rectangle_x=std::max(activation_rectangle.get_x(), visible_x); + + text_view->get_window(Gtk::TextWindowType::TEXT_WINDOW_TEXT)->get_root_coords(activation_rectangle_x, activation_rectangle.get_y(), root_x, root_y); + } Gdk::Rectangle rectangle; rectangle.set_x(root_x); rectangle.set_y(std::max(0, root_y-size.second)); diff --git a/src/tooltips.h b/src/tooltips.h index 36fbce6..918be7f 100644 --- a/src/tooltips.h +++ b/src/tooltips.h @@ -6,7 +6,8 @@ class Tooltip { public: - Tooltip(std::function()> create_tooltip_buffer, Gtk::TextView& text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark); + Tooltip(std::function()> create_tooltip_buffer, Gtk::TextView *text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark); + Tooltip(std::function()> create_tooltip_buffer) : Tooltip(create_tooltip_buffer, nullptr, Glib::RefPtr(), Glib::RefPtr()) {} ~Tooltip(); void update(); @@ -22,7 +23,7 @@ private: std::function()> create_tooltip_buffer; std::unique_ptr tooltip_widget; - Gtk::TextView& text_view; + Gtk::TextView *text_view; std::pair size; std::pair position; }; diff --git a/src/window.cc b/src/window.cc index 71a9e0b..2dc154b 100644 --- a/src/window.cc +++ b/src/window.cc @@ -9,6 +9,7 @@ #include "entrybox.h" #include "info.h" #include "ctags.h" +#include "selection_dialog.h" namespace sigc { #ifndef SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE @@ -573,48 +574,62 @@ void Window::set_menu_actions() { }); menu.add_action("source_find_symbol_ctags", [this]() { - if(auto view=Notebook::get().get_current_view()) { - auto pair=Ctags::get_result(view->file_path.parent_path()); - auto path=std::move(pair.first); - auto stream=std::move(pair.second); - stream->seekg(0, std::ios::end); - if(stream->tellg()==0) { - Info::get().print("No symbols found in current project"); - return; - } - stream->seekg(0, std::ios::beg); - + auto view=Notebook::get().get_current_view(); + + boost::filesystem::path ctags_path; + if(view) + ctags_path=view->file_path.parent_path(); + else if(!Directories::get().path.empty()) + ctags_path=Directories::get().path; + else + ctags_path=boost::filesystem::current_path(); + auto pair=Ctags::get_result(ctags_path); + + auto path=std::move(pair.first); + auto stream=std::move(pair.second); + stream->seekg(0, std::ios::end); + if(stream->tellg()==0) { + Info::get().print("No symbols found in current project"); + return; + } + stream->seekg(0, std::ios::beg); + + if(view) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); - auto rows=std::make_shared >(); - - std::string line; - while(std::getline(*stream, line)) { - auto location=Ctags::get_location(line, true); - - std::string row=location.file_path.string()+":"+std::to_string(location.line+1)+": "+location.source; - (*rows)[row]=Source::Offset(location.line, location.index, location.file_path); - view->selection_dialog->add_row(row); - } - - if(rows->size()==0) + SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true); + } + else + SelectionDialog::create(true, true); + + auto rows=std::make_shared >(); + + std::string line; + while(std::getline(*stream, line)) { + auto location=Ctags::get_location(line, true); + + std::string row=location.file_path.string()+":"+std::to_string(location.line+1)+": "+location.source; + (*rows)[row]=Source::Offset(location.line, location.index, location.file_path); + SelectionDialog::get()->add_row(row); + } + + if(rows->size()==0) + return; + SelectionDialog::get()->on_select=[this, rows, path](const std::string &selected, bool hide_window) { + auto offset=rows->at(selected); + boost::filesystem::path declaration_file; + boost::system::error_code ec; + declaration_file=boost::filesystem::canonical(path/offset.file_path, ec); + if(ec) return; - view->selection_dialog->on_select=[this, rows, path](const std::string &selected, bool hide_window) { - auto offset=rows->at(selected); - boost::filesystem::path declaration_file; - boost::system::error_code ec; - declaration_file=boost::filesystem::canonical(path/offset.file_path, ec); - if(ec) - return; - Notebook::get().open(declaration_file); - auto view=Notebook::get().get_current_view(); - view->place_cursor_at_line_index(offset.line, offset.index); - view->scroll_to_cursor_delayed(view, true, false); - view->hide_tooltips(); - }; + Notebook::get().open(declaration_file); + auto view=Notebook::get().get_current_view(); + view->place_cursor_at_line_index(offset.line, offset.index); + view->scroll_to_cursor_delayed(view, true, false); view->hide_tooltips(); - view->selection_dialog->show(); - } + }; + if(view) + view->hide_tooltips(); + SelectionDialog::get()->show(); }); menu.add_action("source_comments_toggle", [this]() { @@ -698,7 +713,7 @@ void Window::set_menu_actions() { auto locations=view->get_implementation_locations(Notebook::get().get_views()); if(!locations.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); + SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto project_path=Project::Build::create(view->file_path)->project_path; if(project_path.empty()) { @@ -718,7 +733,7 @@ void Window::set_menu_actions() { path=location.file_path.filename(); auto row=path.string()+":"+std::to_string(location.line+1); (*rows)[row]=location; - view->selection_dialog->add_row(row); + SelectionDialog::get()->add_row(row); } } @@ -734,7 +749,7 @@ void Window::set_menu_actions() { view->scroll_to_cursor_delayed(view, true, false); return; } - view->selection_dialog->on_select=[this, rows](const std::string &selected, bool hide_window) { + SelectionDialog::get()->on_select=[this, rows](const std::string &selected, bool hide_window) { auto location=rows->at(selected); Notebook::get().open(location.file_path); auto view=Notebook::get().get_current_view(); @@ -743,7 +758,7 @@ void Window::set_menu_actions() { view->hide_tooltips(); }; view->hide_tooltips(); - view->selection_dialog->show(); + SelectionDialog::get()->show(); } } } @@ -755,7 +770,7 @@ void Window::set_menu_actions() { auto usages=view->get_usages(Notebook::get().get_views()); if(!usages.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); + SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto iter=view->get_buffer()->get_insert()->get_iter(); @@ -769,18 +784,18 @@ void Window::set_menu_actions() { } row+=std::to_string(usage.first.line+1)+": "+usage.second; (*rows)[row]=usage.first; - view->selection_dialog->add_row(row); + SelectionDialog::get()->add_row(row); //Set dialog cursor to the last row if the textview cursor is at the same line if(current_page && iter.get_line()==static_cast(usage.first.line) && iter.get_line_index()>=static_cast(usage.first.index)) { - view->selection_dialog->set_cursor_at_last_row(); + SelectionDialog::get()->set_cursor_at_last_row(); } } if(rows->size()==0) return; - view->selection_dialog->on_select=[this, rows](const std::string &selected, bool hide_window) { + SelectionDialog::get()->on_select=[this, rows](const std::string &selected, bool hide_window) { auto offset=rows->at(selected); boost::filesystem::path declaration_file; boost::system::error_code ec; @@ -794,7 +809,7 @@ void Window::set_menu_actions() { view->hide_tooltips(); }; view->hide_tooltips(); - view->selection_dialog->show(); + SelectionDialog::get()->show(); } } } @@ -805,23 +820,23 @@ void Window::set_menu_actions() { auto methods=Notebook::get().get_current_view()->get_methods(); if(!methods.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); + SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto iter=view->get_buffer()->get_insert()->get_iter(); for(auto &method: methods) { (*rows)[method.second]=method.first; - view->selection_dialog->add_row(method.second); + SelectionDialog::get()->add_row(method.second); if(iter.get_line()>=static_cast(method.first.line)) - view->selection_dialog->set_cursor_at_last_row(); + SelectionDialog::get()->set_cursor_at_last_row(); } - view->selection_dialog->on_select=[view, rows](const std::string& selected, bool hide_window) { + SelectionDialog::get()->on_select=[view, rows](const std::string& selected, bool hide_window) { auto offset=rows->at(selected); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(offset.line, offset.index)); view->scroll_to(view->get_buffer()->get_insert(), 0.0, 1.0, 0.5); view->hide_tooltips(); }; view->hide_tooltips(); - view->selection_dialog->show(); + SelectionDialog::get()->show(); } } } @@ -1150,7 +1165,6 @@ void Window::activate_menu_items() { menu.actions["source_center_cursor"]->set_enabled(view); menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && static_cast(view->format_style)); - menu.actions["source_find_symbol_ctags"]->set_enabled(view); menu.actions["source_comments_toggle"]->set_enabled(view && static_cast(view->toggle_comments)); menu.actions["source_comments_add_documentation"]->set_enabled(view && static_cast(view->add_documentation)); menu.actions["source_find_documentation"]->set_enabled(view && static_cast(view->get_token_data)); @@ -1198,6 +1212,11 @@ bool Window::on_key_press_event(GdkEventKey *event) { } #endif + if(SelectionDialog::get() && SelectionDialog::get()->is_visible()) { + if(SelectionDialog::get()->on_key_press(event)) + return true; + } + return Gtk::ApplicationWindow::on_key_press_event(event); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cd9a390..780bdb2 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,7 +5,7 @@ set(stub_files stubs/dialogs.cc stubs/directories.cc stubs/info.cc - stubs/selectiondialog.cc + stubs/selection_dialog.cc stubs/terminal.cc stubs/tooltips.cc ) diff --git a/tests/stubs/selectiondialog.cc b/tests/stubs/selection_dialog.cc similarity index 72% rename from tests/stubs/selectiondialog.cc rename to tests/stubs/selection_dialog.cc index 61866a0..4d0c4ea 100644 --- a/tests/stubs/selectiondialog.cc +++ b/tests/stubs/selection_dialog.cc @@ -1,8 +1,8 @@ -#include "selectiondialog.h" +#include "selection_dialog.h" SelectionDialogBase::ListViewText::ListViewText(bool use_markup) {} -SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): +SelectionDialogBase::SelectionDialogBase(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup): text_view(text_view), list_view_text(use_markup) {} void SelectionDialogBase::show() {} @@ -11,14 +11,18 @@ void SelectionDialogBase::hide() {} void SelectionDialogBase::add_row(const std::string& row) {} -SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup) : +std::unique_ptr SelectionDialog::instance; + +SelectionDialog::SelectionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark, bool show_search_entry, bool use_markup) : SelectionDialogBase(text_view, start_mark, show_search_entry, use_markup) {} SelectionDialogBase::~SelectionDialogBase() {} bool SelectionDialog::on_key_press(GdkEventKey* key) { return true; } -CompletionDialog::CompletionDialog(Gtk::TextView &text_view, Glib::RefPtr start_mark): +std::unique_ptr CompletionDialog::instance; + +CompletionDialog::CompletionDialog(Gtk::TextView *text_view, Glib::RefPtr start_mark): SelectionDialogBase(text_view, start_mark, false, false) {} bool CompletionDialog::on_key_press(GdkEventKey* key) { return true;} diff --git a/tests/stubs/tooltips.cc b/tests/stubs/tooltips.cc index 909e5d9..228fcce 100644 --- a/tests/stubs/tooltips.cc +++ b/tests/stubs/tooltips.cc @@ -3,7 +3,7 @@ Gdk::Rectangle Tooltips::drawn_tooltips_rectangle=Gdk::Rectangle(); Tooltip::Tooltip(std::function()> create_tooltip_buffer, - Gtk::TextView& text_view, + Gtk::TextView *text_view, Glib::RefPtr start_mark, Glib::RefPtr end_mark): text_view(text_view) {}