From cd28f0cf5c2ca8e5f2ecdb420488cca404405a05 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 13:11:55 +0200 Subject: [PATCH 01/31] selectiondialog.* cleanup. --- juci/selectiondialog.cc | 217 +++++++++++++++++++--------------------- juci/selectiondialog.h | 31 +++--- juci/source.cc | 102 ++++++++++--------- juci/source.h | 5 +- 4 files changed, 178 insertions(+), 177 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index 6bee4cb..0a34363 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -5,67 +5,63 @@ namespace sigc { SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE } -SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, bool popup): text_view(text_view), popup(popup) {} - -void SelectionDialogBase::init() { - if(popup) +SelectionDialogBase::SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry): text_view(text_view), +start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, false, Gtk::SelectionMode::SELECTION_BROWSE) { + if(!show_search_entry) window=std::unique_ptr(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); else window=std::unique_ptr(new Gtk::Dialog()); - scrolled_window=std::unique_ptr(new Gtk::ScrolledWindow()); - list_view_text=std::unique_ptr(new Gtk::ListViewText(1, false, Gtk::SelectionMode::SELECTION_BROWSE)); - search_entry=std::unique_ptr(new Gtk::Entry()); - list_view_text->set_search_entry(*search_entry); + list_view_text.set_search_entry(search_entry); window->set_default_size(0, 0); window->property_decorated()=false; window->set_skip_taskbar_hint(true); - scrolled_window->set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); - list_view_text->set_enable_search(true); - list_view_text->set_headers_visible(false); - list_view_text->set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); - list_view_text->set_activate_on_single_click(true); - list_view_text->set_hover_selection(false); - list_view_text->set_rules_hint(true); - //list_view_text->set_fixed_height_mode(true); //TODO: This is buggy on OS X, remember to post an issue on GTK+ 3 - - last_selected=-1; + scrolled_window.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC, Gtk::PolicyType::POLICY_AUTOMATIC); + list_view_text.set_enable_search(true); + list_view_text.set_headers_visible(false); + list_view_text.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL); + list_view_text.set_activate_on_single_click(true); + list_view_text.set_hover_selection(false); + list_view_text.set_rules_hint(true); + //list_view_text.set_fixed_height_mode(true); //TODO: This is buggy on OS X, remember to post an issue on GTK+ 3 - list_view_text->signal_cursor_changed().connect(sigc::mem_fun(*this, &SelectionDialog::cursor_changed), true); - list_view_text->signal_realize().connect([this](){ + list_view_text.signal_cursor_changed().connect(sigc::mem_fun(*this, &SelectionDialog::cursor_changed), true); + list_view_text.signal_realize().connect([this](){ resize(); }); - list_view_text->clear_items(); + scrolled_window.add(list_view_text); + if(!show_search_entry) + window->add(scrolled_window); + else { + auto dialog=(Gtk::Dialog*)window.get(); + dialog->get_vbox()->pack_start(search_entry, false, false); + dialog->get_vbox()->pack_start(scrolled_window, true, true); + dialog->set_transient_for((Gtk::Window&)(*text_view.get_toplevel())); + } +} + +SelectionDialogBase::~SelectionDialogBase() { + text_view.get_buffer()->delete_mark(start_mark); } -void SelectionDialogBase::append(const std::string& row) { - list_view_text->append(row); +void SelectionDialogBase::add_row(const std::string& row, const std::string& tooltip) { + list_view_text.append(row); + if(tooltip.size()>0) + tooltip_texts[row]=tooltip; } void SelectionDialogBase::show() { - scrolled_window->add(*list_view_text); - if(popup) - window->add(*scrolled_window); - else { - auto dialog=(Gtk::Dialog*)window.get(); - dialog->get_vbox()->pack_start(*search_entry, false, false); - dialog->get_vbox()->pack_start(*scrolled_window, true, true); - dialog->set_transient_for((Gtk::Window&)(*text_view.get_toplevel())); - } - if(rows.size()>0) { - list_view_text->get_selection()->select(*list_view_text->get_model()->children().begin()); - list_view_text->scroll_to_row(list_view_text->get_selection()->get_selected_rows()[0]); + if(list_view_text.get_model()->children().size()>0) { + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); } move(); window->show_all(); - search_entry->show(); - shown=true; + search_entry.show(); } void SelectionDialogBase::hide() { - shown=false; window->hide(); if(tooltips) tooltips->hide(); @@ -74,23 +70,25 @@ void SelectionDialogBase::hide() { } void SelectionDialogBase::cursor_changed() { - auto selected=list_view_text->get_selected(); + auto selected=list_view_text.get_selected(); if(selected.size()>0) { if(selected[0]!=last_selected || last_selected==-1) { if(tooltips) tooltips->hide(); - auto row = rows.at(list_view_text->get_text(selected[0])); - if(row.second.size()>0) { - tooltips=std::unique_ptr(new Tooltips()); - auto tooltip_text=row.second; - auto get_tooltip_buffer=[this, tooltip_text]() { - auto tooltip_buffer=Gtk::TextBuffer::create(text_view.get_buffer()->get_tag_table()); - //TODO: Insert newlines to tooltip_text (use 80 chars, then newline?) - tooltip_buffer->insert_at_cursor(tooltip_text); - return tooltip_buffer; - }; - tooltips->emplace_back(get_tooltip_buffer, text_view, text_view.get_buffer()->create_mark(start_mark->get_iter()), text_view.get_buffer()->create_mark(text_view.get_buffer()->get_insert()->get_iter())); - tooltips->show(true); + auto it=tooltip_texts.find(list_view_text.get_text(selected[0])); + if(it!=tooltip_texts.end()) { + auto tooltip_text=it->second; + if(tooltip_text.size()>0) { + tooltips=std::unique_ptr(new Tooltips()); + auto get_tooltip_buffer=[this, tooltip_text]() { + auto tooltip_buffer=Gtk::TextBuffer::create(text_view.get_buffer()->get_tag_table()); + //TODO: Insert newlines to tooltip_text (use 80 chars, then newline?) + tooltip_buffer->insert_at_cursor(tooltip_text); + return tooltip_buffer; + }; + tooltips->emplace_back(get_tooltip_buffer, text_view, text_view.get_buffer()->create_mark(start_mark->get_iter()), text_view.get_buffer()->create_mark(text_view.get_buffer()->get_insert()->get_iter())); + tooltips->show(true); + } } } } @@ -118,10 +116,10 @@ void SelectionDialogBase::move() { void SelectionDialogBase::resize() { INFO("SelectionDialog set size"); - if(list_view_text->get_realized()) { + 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); + 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(); @@ -131,21 +129,21 @@ void SelectionDialogBase::resize() { 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); + scrolled_window.set_policy(Gtk::PolicyType::POLICY_NEVER, Gtk::PolicyType::POLICY_AUTOMATIC); - int window_height=std::min(row_height*(int)rows.size(), row_height*10); - if(!popup) - window_height+=search_entry->get_height(); + int window_height=std::min(row_height*(int)list_view_text.get_model()->children().size(), row_height*10); + if(show_search_entry) + window_height+=search_entry.get_height(); window->resize(row_width, window_height); } } -SelectionDialog::SelectionDialog(Gtk::TextView& text_view) : SelectionDialogBase(text_view, false) {} +SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, true) {} void SelectionDialog::show() { SelectionDialogBase::show(); std::shared_ptr search_key(new std::string()); - auto filter_model=Gtk::TreeModelFilter::create(list_view_text->get_model()); + auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model()); filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator& iter){ std::string row_lc; iter->get_value(0, row_lc); @@ -156,83 +154,85 @@ void SelectionDialog::show() { return true; return false; }); - list_view_text->set_model(filter_model); - list_view_text->set_search_equal_func([this](const Glib::RefPtr& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) { + list_view_text.set_model(filter_model); + list_view_text.set_search_equal_func([this](const Glib::RefPtr& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) { return false; }); - search_entry->signal_changed().connect([this, search_key, filter_model](){ - *search_key=search_entry->get_text(); + search_entry.signal_changed().connect([this, search_key, filter_model](){ + *search_key=search_entry.get_text(); filter_model->refilter(); - list_view_text->set_search_entry(*search_entry); //TODO:Report the need of this to GTK's git (bug) + list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug) }); - search_entry->signal_event().connect([this, search_key, filter_model](GdkEvent* event) { + search_entry.signal_event().connect([this, search_key, filter_model](GdkEvent* event) { if(event->type==GDK_KEY_PRESS) { auto key=(GdkEventKey*)event; - if(key->keyval==GDK_KEY_Down) { - auto it=list_view_text->get_selection()->get_selected(); + if(key->keyval==GDK_KEY_Down && list_view_text.get_model()->children().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); if(it) { it++; if(it) { - list_view_text->set_cursor(list_view_text->get_model()->get_path(it)); + list_view_text.set_cursor(list_view_text.get_model()->get_path(it)); } } else - list_view_text->set_cursor(list_view_text->get_model()->get_path(list_view_text->get_model()->children().begin())); + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); return true; } - if(key->keyval==GDK_KEY_Up) { - auto it=list_view_text->get_selection()->get_selected(); + if(key->keyval==GDK_KEY_Up && list_view_text.get_model()->children().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); if(it) { it--; if(it) { - list_view_text->set_cursor(list_view_text->get_model()->get_path(it)); + list_view_text.set_cursor(list_view_text.get_model()->get_path(it)); } } + else { + auto last_it=list_view_text.get_model()->children().end(); + last_it--; + list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); + } return true; } } return false; }); auto activate=[this](){ - if(on_select && list_view_text->get_selected().size()>0) { - auto it=list_view_text->get_selection()->get_selected(); + if(on_select && list_view_text.get_selected().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); std::string row; it->get_value(0, row); - std::string selected = rows.at(row).first; - on_select(selected); + std::string selected = row; + on_select(selected, true); } window->hide(); }; - search_entry->signal_activate().connect([this, activate](){ + search_entry.signal_activate().connect([this, activate](){ activate(); }); - list_view_text->signal_row_activated().connect([this, activate](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { + list_view_text.signal_row_activated().connect([this, activate](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { activate(); }); window->signal_focus_out_event().connect([this](GdkEventFocus*){ window->hide(); return true; }); - list_view_text->set_cursor(list_view_text->get_model()->get_path(list_view_text->get_model()->children().begin())); } -CompletionDialog::CompletionDialog(Gtk::TextView& text_view) : SelectionDialogBase(text_view, true) {} +CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false) {} void CompletionDialog::show() { SelectionDialogBase::show(); show_offset=text_view.get_buffer()->get_insert()->get_iter().get_offset(); - list_view_text->signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { - if(shown) { - select(); - } + list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { + select(); }); 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); + search_entry.set_text(text); + list_view_text.set_search_entry(search_entry); } row_in_entry=false; @@ -240,29 +240,13 @@ void CompletionDialog::show() { void CompletionDialog::select(bool hide_window) { row_in_entry=true; - auto selected=list_view_text->get_selected(); - std::pair select; + auto selected=list_view_text.get_selected(); if(selected.size()>0) { - select = rows.at(list_view_text->get_text(selected[0])); - text_view.get_buffer()->erase(start_mark->get_iter(), text_view.get_buffer()->get_insert()->get_iter()); - text_view.get_buffer()->insert(start_mark->get_iter(), select.first); + if(on_select) + on_select(list_view_text.get_text(selected[0]), hide_window); } if(hide_window) { hide(); - char find_char=select.first.back(); - if(find_char==')' || find_char=='>') { - if(find_char==')') - find_char='('; - else - find_char='<'; - size_t pos=select.first.find(find_char); - if(pos!=std::string::npos) { - auto start_offset=start_mark->get_iter().get_offset()+pos+1; - auto end_offset=start_mark->get_iter().get_offset()+select.first.size()-1; - if(start_offset!=end_offset) - text_view.get_buffer()->select_range(text_view.get_buffer()->get_iter_at_offset(start_offset), text_view.get_buffer()->get_iter_at_offset(end_offset)); - } - } } } @@ -276,8 +260,8 @@ bool CompletionDialog::on_key_release(GdkEventKey* key) { else { 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); + search_entry.set_text(text); + list_view_text.set_search_entry(search_entry); } cursor_changed(); } @@ -300,26 +284,33 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { } if(key->keyval==GDK_KEY_Shift_L || key->keyval==GDK_KEY_Shift_R || key->keyval==GDK_KEY_Alt_L || key->keyval==GDK_KEY_Alt_R || key->keyval==GDK_KEY_Control_L || key->keyval==GDK_KEY_Control_R || key->keyval==GDK_KEY_Meta_L || key->keyval==GDK_KEY_Meta_R) return false; - if(key->keyval==GDK_KEY_Down) { - auto it=list_view_text->get_selection()->get_selected(); + if(key->keyval==GDK_KEY_Down && list_view_text.get_model()->children().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); if(it) { it++; if(it) { - list_view_text->set_cursor(list_view_text->get_model()->get_path(it)); + list_view_text.set_cursor(list_view_text.get_model()->get_path(it)); } } + else + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); select(false); cursor_changed(); return true; } - if(key->keyval==GDK_KEY_Up) { - auto it=list_view_text->get_selection()->get_selected(); + if(key->keyval==GDK_KEY_Up && list_view_text.get_model()->children().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); if(it) { it--; if(it) { - list_view_text->set_cursor(list_view_text->get_model()->get_path(it)); + list_view_text.set_cursor(list_view_text.get_model()->get_path(it)); } } + else { + auto last_it=list_view_text.get_model()->children().end(); + last_it--; + list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); + } select(false); cursor_changed(); return true; diff --git a/juci/selectiondialog.h b/juci/selectiondialog.h index d55d9a3..7d9ec12 100644 --- a/juci/selectiondialog.h +++ b/juci/selectiondialog.h @@ -4,47 +4,44 @@ #include "gtkmm.h" #include "logging.h" #include "tooltips.h" +#include class SelectionDialogBase { public: - SelectionDialogBase(Gtk::TextView& text_view, bool popup); - virtual void init(); //TODO: use constructor instead of init - virtual void append(const std::string& row); + SelectionDialogBase(Gtk::TextView& text_view, Glib::RefPtr start_mark, bool show_search_entry); + ~SelectionDialogBase(); + virtual void add_row(const std::string& row, const std::string& tooltip=""); virtual void show(); virtual void hide(); virtual void move(); - std::map > rows; //TODO: remove, instead add on_select. Also remember to destroy start_mark in destructor std::function on_hide; - bool shown=false; + std::function on_select; Glib::RefPtr start_mark; protected: virtual void resize(); virtual void cursor_changed(); - Gtk::TextView& text_view; + std::unique_ptr window; - std::unique_ptr scrolled_window; - std::unique_ptr list_view_text; - std::unique_ptr search_entry; + Gtk::ScrolledWindow scrolled_window; + Gtk::ListViewText list_view_text; + Gtk::Entry search_entry; + bool show_search_entry; std::unique_ptr tooltips; - int last_selected; -private: - bool popup; + std::unordered_map tooltip_texts; + int last_selected=-1; }; class SelectionDialog : public SelectionDialogBase { public: - SelectionDialog(Gtk::TextView& text_view); - void init() {SelectionDialogBase::init();} + SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark); void show(); - std::function on_select; }; class CompletionDialog : public SelectionDialogBase { public: - CompletionDialog(Gtk::TextView& text_view); - void init() {SelectionDialogBase::init();} + CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark); void show(); bool on_key_release(GdkEventKey* key); bool on_key_press(GdkEventKey* key); diff --git a/juci/source.cc b/juci/source.cc index d2c7804..9aead05 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -547,32 +547,28 @@ bool Source::ClangViewParse::on_key_press_event(GdkEventKey* key) { //// ClangViewAutocomplete /// ////////////////////////////// Source::ClangViewAutocomplete::ClangViewAutocomplete(const std::string& file_path, const std::string& project_path): -Source::ClangViewParse(file_path, project_path), completion_dialog(*this), autocomplete_cancel_starting(false) { - completion_dialog.on_hide=[this](){ - start_reparse(); - }; - +Source::ClangViewParse(file_path, project_path), autocomplete_cancel_starting(false) { get_buffer()->signal_changed().connect([this](){ - if(completion_dialog.shown) + if(completion_dialog_shown) delayed_reparse_connection.disconnect(); start_autocomplete(); }); get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iterator, const Glib::RefPtr& mark){ if(mark->get_name()=="insert") { autocomplete_cancel_starting=true; - if(completion_dialog.shown) { - completion_dialog.hide(); + if(completion_dialog_shown) { + completion_dialog->hide(); } } }); signal_scroll_event().connect([this](GdkEventScroll* event){ - if(completion_dialog.shown) - completion_dialog.hide(); + if(completion_dialog_shown) + completion_dialog->hide(); return false; }, false); signal_key_release_event().connect([this](GdkEventKey* key){ - if(completion_dialog.shown) { - if(completion_dialog.on_key_release(key)) + if(completion_dialog_shown) { + if(completion_dialog->on_key_release(key)) return true; } @@ -582,16 +578,16 @@ Source::ClangViewParse(file_path, project_path), completion_dialog(*this), autoc bool Source::ClangViewAutocomplete::on_key_press_event(GdkEventKey *key) { last_keyval=key->keyval; - if(completion_dialog.shown) { - if(completion_dialog.on_key_press(key)) + if(completion_dialog_shown) { + if(completion_dialog->on_key_press(key)) return true; } return ClangViewParse::on_key_press_event(key); } bool Source::ClangViewAutocomplete::on_focus_out_event(GdkEventFocus* event) { - if(completion_dialog.shown) { - completion_dialog.hide(); + if(completion_dialog_shown) { + completion_dialog->hide(); } return Source::ClangViewParse::on_focus_out_event(event); @@ -613,7 +609,7 @@ void Source::ClangViewAutocomplete::start_autocomplete() { prefix_mutex.lock(); prefix=sm[3].str(); prefix_mutex.unlock(); - if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !completion_dialog.shown) { + if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !completion_dialog_shown) { autocomplete(); } else if(last_keyval=='.' && autocomplete_starting) @@ -623,13 +619,13 @@ void Source::ClangViewAutocomplete::start_autocomplete() { prefix_mutex.lock(); prefix=sm[3].str(); prefix_mutex.unlock(); - if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !completion_dialog.shown) { + if((prefix.size()==0 || prefix[0]<'0' || prefix[0]>'9') && !autocomplete_starting && !completion_dialog_shown) { autocomplete(); } } else autocomplete_cancel_starting=true; - if(autocomplete_starting || completion_dialog.shown) + if(autocomplete_starting || completion_dialog_shown) delayed_reparse_connection.disconnect(); } } @@ -644,15 +640,15 @@ void Source::ClangViewAutocomplete::autocomplete() { autocomplete_done_connection=autocomplete_done.connect([this, ac_data](){ autocomplete_starting=false; if(!autocomplete_cancel_starting) { - if(completion_dialog.start_mark) - get_buffer()->delete_mark(completion_dialog.start_mark); auto start_iter=get_buffer()->get_insert()->get_iter(); for(size_t c=0;ccreate_mark(start_iter); - - std::map > rows; - completion_dialog.init(); + completion_dialog=std::unique_ptr(new CompletionDialog(*this, get_buffer()->create_mark(start_iter))); + completion_dialog->on_hide=[this](){ + start_reparse(); + completion_dialog_shown=false; + }; + auto rows=std::make_shared >(); for (auto &data : *ac_data) { std::stringstream ss; std::string return_value; @@ -667,17 +663,37 @@ void Source::ClangViewAutocomplete::autocomplete() { } auto ss_str=ss.str(); if (ss_str.length() > 0) { // if length is 0 the result is empty - auto pair=std::pair(ss_str, data.brief_comments); - rows[ss.str() + " --> " + return_value] = pair; - completion_dialog.append(ss.str() + " --> " + return_value); + (*rows)[ss.str() + " --> " + return_value] = ss_str; + completion_dialog->add_row(ss.str() + " --> " + return_value, data.brief_comments); } } - if (rows.empty()) { - rows["No suggestions found..."] = std::pair(); - completion_dialog.append("No suggestions found..."); + if (rows->empty()) { + (*rows)["No suggestions found..."] = ""; + completion_dialog->add_row("No suggestions found..."); } - completion_dialog.rows=std::move(rows); - completion_dialog.show(); + completion_dialog->on_select=[this, rows](const std::string& selected, bool finished) { + auto row = rows->at(selected); + get_buffer()->erase(completion_dialog->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); + get_buffer()->insert(completion_dialog->start_mark->get_iter(), row); + if(finished) { + char find_char=row.back(); + if(find_char==')' || find_char=='>') { + if(find_char==')') + find_char='('; + else + find_char='<'; + size_t pos=row.find(find_char); + if(pos!=std::string::npos) { + auto start_offset=completion_dialog->start_mark->get_iter().get_offset()+pos+1; + auto end_offset=completion_dialog->start_mark->get_iter().get_offset()+row.size()-1; + 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)); + } + } + } + }; + completion_dialog_shown=true; + completion_dialog->show(); } else start_autocomplete(); @@ -743,7 +759,7 @@ get_autocomplete_suggestions(int line_number, int column, std::mapcreate_tag(); similar_tokens_tag->property_weight()=Pango::WEIGHT_BOLD; @@ -809,26 +825,22 @@ Source::ClangViewAutocomplete(file_path, project_path), selection_dialog(*this) goto_method=[this](){ if(clang_readable) { - if(selection_dialog.start_mark) - get_buffer()->delete_mark(selection_dialog.start_mark); - selection_dialog.start_mark=get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()); - std::map > rows; - selection_dialog.init(); + selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()))); + auto rows=std::make_shared >(); auto methods=clang_tokens->get_cxx_methods(); if(methods.size()==0) return; for(auto &method: methods) { - rows[method.first]=std::pair(std::to_string(method.second), ""); - selection_dialog.append(method.first); + (*rows)[method.first]=std::to_string(method.second); + selection_dialog->add_row(method.first); } - selection_dialog.rows=std::move(rows); - selection_dialog.on_select=[this](std::string selected) { - auto offset=stoul(selected); + selection_dialog->on_select=[this, rows](const std::string& selected, bool finished) { + auto offset=stoul(rows->at(selected)); get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); delayed_tooltips_connection.disconnect(); }; - selection_dialog.show(); + selection_dialog->show(); } }; } diff --git a/juci/source.h b/juci/source.h index 6a2c75b..f96d245 100644 --- a/juci/source.h +++ b/juci/source.h @@ -120,7 +120,8 @@ public: private: void start_autocomplete(); void autocomplete(); - CompletionDialog completion_dialog; + std::unique_ptr completion_dialog; + bool completion_dialog_shown=false; std::vector get_autocomplete_suggestions(int line_number, int column, std::map& buffer_map); Glib::Dispatcher autocomplete_done; sigc::connection autocomplete_done_connection; @@ -137,7 +138,7 @@ public: private: Glib::RefPtr similar_tokens_tag; std::string last_similar_tokens_tagged; - SelectionDialog selection_dialog; + std::unique_ptr selection_dialog; }; class ClangView : public ClangViewRefactor { From e4cdc8e0c6171f1c6f16b34756b3c3a12b2b0ff5 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 14:01:55 +0200 Subject: [PATCH 02/31] Further cleanup of selectiondialog.*. --- juci/selectiondialog.cc | 4 +--- juci/selectiondialog.h | 4 ++-- juci/source.cc | 53 +++++++++++++++++++++-------------------- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index 0a34363..98c4710 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -163,7 +163,7 @@ void SelectionDialog::show() { filter_model->refilter(); list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug) }); - search_entry.signal_event().connect([this, search_key, filter_model](GdkEvent* event) { + search_entry.signal_event().connect([this](GdkEvent* event) { if(event->type==GDK_KEY_PRESS) { auto key=(GdkEventKey*)event; if(key->keyval==GDK_KEY_Down && list_view_text.get_model()->children().size()>0) { @@ -234,8 +234,6 @@ void CompletionDialog::show() { search_entry.set_text(text); list_view_text.set_search_entry(search_entry); } - - row_in_entry=false; } void CompletionDialog::select(bool hide_window) { diff --git a/juci/selectiondialog.h b/juci/selectiondialog.h index 7d9ec12..5ff32c2 100644 --- a/juci/selectiondialog.h +++ b/juci/selectiondialog.h @@ -16,7 +16,7 @@ public: virtual void move(); std::function on_hide; - std::function on_select; + std::function on_select; Glib::RefPtr start_mark; protected: virtual void resize(); @@ -50,7 +50,7 @@ private: void select(bool hide_window=true); int show_offset; - bool row_in_entry; + bool row_in_entry=false; }; #endif // JUCI_SELECTIONDIALOG_H_ \ No newline at end of file diff --git a/juci/source.cc b/juci/source.cc index 9aead05..a57ac0c 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -644,11 +644,32 @@ void Source::ClangViewAutocomplete::autocomplete() { for(size_t c=0;c(new CompletionDialog(*this, get_buffer()->create_mark(start_iter))); + auto rows=std::make_shared >(); completion_dialog->on_hide=[this](){ start_reparse(); completion_dialog_shown=false; }; - auto rows=std::make_shared >(); + completion_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + auto row = rows->at(selected); + get_buffer()->erase(completion_dialog->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); + get_buffer()->insert(completion_dialog->start_mark->get_iter(), row); + if(hide_window) { + char find_char=row.back(); + if(find_char==')' || find_char=='>') { + if(find_char==')') + find_char='('; + else + find_char='<'; + size_t pos=row.find(find_char); + if(pos!=std::string::npos) { + auto start_offset=completion_dialog->start_mark->get_iter().get_offset()+pos+1; + auto end_offset=completion_dialog->start_mark->get_iter().get_offset()+row.size()-1; + 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)); + } + } + } + }; for (auto &data : *ac_data) { std::stringstream ss; std::string return_value; @@ -671,27 +692,6 @@ void Source::ClangViewAutocomplete::autocomplete() { (*rows)["No suggestions found..."] = ""; completion_dialog->add_row("No suggestions found..."); } - completion_dialog->on_select=[this, rows](const std::string& selected, bool finished) { - auto row = rows->at(selected); - get_buffer()->erase(completion_dialog->start_mark->get_iter(), get_buffer()->get_insert()->get_iter()); - get_buffer()->insert(completion_dialog->start_mark->get_iter(), row); - if(finished) { - char find_char=row.back(); - if(find_char==')' || find_char=='>') { - if(find_char==')') - find_char='('; - else - find_char='<'; - size_t pos=row.find(find_char); - if(pos!=std::string::npos) { - auto start_offset=completion_dialog->start_mark->get_iter().get_offset()+pos+1; - auto end_offset=completion_dialog->start_mark->get_iter().get_offset()+row.size()-1; - 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)); - } - } - } - }; completion_dialog_shown=true; completion_dialog->show(); } @@ -826,16 +826,17 @@ Source::ClangViewAutocomplete(file_path, project_path) { goto_method=[this](){ if(clang_readable) { selection_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()))); - auto rows=std::make_shared >(); + auto rows=std::make_shared >(); auto methods=clang_tokens->get_cxx_methods(); if(methods.size()==0) return; for(auto &method: methods) { - (*rows)[method.first]=std::to_string(method.second); + (*rows)[method.first]=method.second; selection_dialog->add_row(method.first); } - selection_dialog->on_select=[this, rows](const std::string& selected, bool finished) { - auto offset=stoul(rows->at(selected)); + //TODO see if rows gets destroyed when selection_dialog gets destroyed. + selection_dialog->on_select=[this, rows](const std::string& selected, bool hide_window) { + auto offset=rows->at(selected); get_buffer()->place_cursor(get_buffer()->get_iter_at_offset(offset)); scroll_to(get_buffer()->get_insert(), 0.0, 1.0, 0.5); delayed_tooltips_connection.disconnect(); From 7f6d38860285ee92a0e24dbdb2384087fdb3b836 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 15:16:24 +0200 Subject: [PATCH 03/31] Now showing only methods/variables including the string the user writes if the completion window opens right after ->, :: or . Very useful if the user do not know the beginning of the method or variable searched for. --- juci/selectiondialog.cc | 66 ++++++++++++++++++++++++++++------------- juci/selectiondialog.h | 2 +- 2 files changed, 47 insertions(+), 21 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index 98c4710..35e2697 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -25,7 +25,6 @@ start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, list_view_text.set_rules_hint(true); //list_view_text.set_fixed_height_mode(true); //TODO: This is buggy on OS X, remember to post an issue on GTK+ 3 - list_view_text.signal_cursor_changed().connect(sigc::mem_fun(*this, &SelectionDialog::cursor_changed), true); list_view_text.signal_realize().connect([this](){ resize(); }); @@ -69,13 +68,16 @@ void SelectionDialogBase::hide() { on_hide(); } +//TODO: this is not called when selecting row with mouse, but I guess that is ok. void SelectionDialogBase::cursor_changed() { - auto selected=list_view_text.get_selected(); - if(selected.size()>0) { - if(selected[0]!=last_selected || last_selected==-1) { + if(list_view_text.get_selected().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); + std::string row; + it->get_value(0, row); + if(row!=last_row || last_row.size()==0) { if(tooltips) tooltips->hide(); - auto it=tooltip_texts.find(list_view_text.get_text(selected[0])); + auto it=tooltip_texts.find(row); if(it!=tooltip_texts.end()) { auto tooltip_text=it->second; if(tooltip_text.size()>0) { @@ -91,13 +93,13 @@ void SelectionDialogBase::cursor_changed() { } } } + last_row=row; + } + else { + last_row=""; + if(tooltips) + tooltips->hide(); } - else if(tooltips) - tooltips->hide(); - if(selected.size()>0) - last_selected=selected[0]; - else - last_selected=-1; } void SelectionDialogBase::move() { @@ -201,8 +203,7 @@ void SelectionDialog::show() { auto it=list_view_text.get_selection()->get_selected(); std::string row; it->get_value(0, row); - std::string selected = row; - on_select(selected, true); + on_select(row, true); } window->hide(); }; @@ -225,6 +226,27 @@ void CompletionDialog::show() { show_offset=text_view.get_buffer()->get_insert()->get_iter().get_offset(); + if(show_offset==start_mark->get_iter().get_offset()) { + std::shared_ptr search_key(new std::string()); + auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model()); + filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator& iter){ + std::string row_lc; + iter->get_value(0, row_lc); + auto search_key_lc=*search_key; + std::transform(row_lc.begin(), row_lc.end(), row_lc.begin(), ::tolower); + std::transform(search_key_lc.begin(), search_key_lc.end(), search_key_lc.begin(), ::tolower); + if(row_lc.find(search_key_lc)!=std::string::npos) + return true; + return false; + }); + list_view_text.set_model(filter_model); + search_entry.signal_changed().connect([this, search_key, filter_model](){ + *search_key=search_entry.get_text(); + filter_model->refilter(); + list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug) + }); + } + list_view_text.signal_row_activated().connect([this](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { select(); }); @@ -238,11 +260,15 @@ void CompletionDialog::show() { void CompletionDialog::select(bool hide_window) { row_in_entry=true; - auto selected=list_view_text.get_selected(); - if(selected.size()>0) { + + if(list_view_text.get_selected().size()>0) { + auto it=list_view_text.get_selection()->get_selected(); + std::string row; + it->get_value(0, row); if(on_select) - on_select(list_view_text.get_text(selected[0]), hide_window); + on_select(row, hide_window); } + if(hide_window) { hide(); } @@ -257,10 +283,8 @@ bool CompletionDialog::on_key_release(GdkEventKey* key) { } else { 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); - } + search_entry.set_text(text); + list_view_text.set_search_entry(search_entry); cursor_changed(); } return false; @@ -275,9 +299,11 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { 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) { + cursor_changed(); return true; } } + cursor_changed(); return false; } if(key->keyval==GDK_KEY_Shift_L || key->keyval==GDK_KEY_Shift_R || key->keyval==GDK_KEY_Alt_L || key->keyval==GDK_KEY_Alt_R || key->keyval==GDK_KEY_Control_L || key->keyval==GDK_KEY_Control_R || key->keyval==GDK_KEY_Meta_L || key->keyval==GDK_KEY_Meta_R) diff --git a/juci/selectiondialog.h b/juci/selectiondialog.h index 5ff32c2..e2c6067 100644 --- a/juci/selectiondialog.h +++ b/juci/selectiondialog.h @@ -30,7 +30,7 @@ protected: bool show_search_entry; std::unique_ptr tooltips; std::unordered_map tooltip_texts; - int last_selected=-1; + std::string last_row; }; class SelectionDialog : public SelectionDialogBase { From 62ca0c8ffecfa7ab2840a1cc93c19e5bb2616d93 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 17:27:09 +0200 Subject: [PATCH 04/31] Fixes to selectiondialog.*. --- juci/selectiondialog.cc | 59 ++++++++++++++++++++++++++++++----------- juci/selectiondialog.h | 2 +- 2 files changed, 45 insertions(+), 16 deletions(-) diff --git a/juci/selectiondialog.cc b/juci/selectiondialog.cc index 35e2697..256f0b3 100644 --- a/juci/selectiondialog.cc +++ b/juci/selectiondialog.cc @@ -29,6 +29,19 @@ start_mark(start_mark), show_search_entry(show_search_entry), list_view_text(1, resize(); }); + list_view_text.signal_event_after().connect([this](GdkEvent* event){ + if(event->type==GDK_KEY_PRESS || event->type==GDK_BUTTON_PRESS) { + update_tooltips(); + } + }); + if(show_search_entry) { + search_entry.signal_event_after().connect([this](GdkEvent* event){ + if(event->type==GDK_KEY_PRESS || event->type==GDK_BUTTON_PRESS) { + update_tooltips(); + } + }); + } + scrolled_window.add(list_view_text); if(!show_search_entry) window->add(scrolled_window); @@ -51,13 +64,8 @@ void SelectionDialogBase::add_row(const std::string& row, const std::string& too } void SelectionDialogBase::show() { - if(list_view_text.get_model()->children().size()>0) { - list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); - } - move(); window->show_all(); - search_entry.show(); } void SelectionDialogBase::hide() { @@ -68,8 +76,7 @@ void SelectionDialogBase::hide() { on_hide(); } -//TODO: this is not called when selecting row with mouse, but I guess that is ok. -void SelectionDialogBase::cursor_changed() { +void SelectionDialogBase::update_tooltips() { if(list_view_text.get_selected().size()>0) { auto it=list_view_text.get_selection()->get_selected(); std::string row; @@ -146,6 +153,7 @@ void SelectionDialog::show() { SelectionDialogBase::show(); std::shared_ptr search_key(new std::string()); auto filter_model=Gtk::TreeModelFilter::create(list_view_text.get_model()); + filter_model->set_visible_func([this, search_key](const Gtk::TreeModel::const_iterator& iter){ std::string row_lc; iter->get_value(0, row_lc); @@ -156,15 +164,19 @@ void SelectionDialog::show() { return true; return false; }); + list_view_text.set_model(filter_model); + list_view_text.set_search_equal_func([this](const Glib::RefPtr& model, int column, const Glib::ustring& key, const Gtk::TreeModel::iterator& iter) { return false; }); + search_entry.signal_changed().connect([this, search_key, filter_model](){ *search_key=search_entry.get_text(); filter_model->refilter(); list_view_text.set_search_entry(search_entry); //TODO:Report the need of this to GTK's git (bug) }); + search_entry.signal_event().connect([this](GdkEvent* event) { if(event->type==GDK_KEY_PRESS) { auto key=(GdkEventKey*)event; @@ -198,6 +210,7 @@ void SelectionDialog::show() { } return false; }); + auto activate=[this](){ if(on_select && list_view_text.get_selected().size()>0) { auto it=list_view_text.get_selection()->get_selected(); @@ -205,18 +218,24 @@ void SelectionDialog::show() { it->get_value(0, row); on_select(row, true); } - window->hide(); + hide(); }; search_entry.signal_activate().connect([this, activate](){ activate(); }); list_view_text.signal_row_activated().connect([this, activate](const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn*) { activate(); - }); + }); + window->signal_focus_out_event().connect([this](GdkEventFocus*){ - window->hide(); + hide(); return true; }); + + if(list_view_text.get_model()->children().size()>0) { + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); + update_tooltips(); + } } CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr start_mark) : SelectionDialogBase(text_view, start_mark, false) {} @@ -256,6 +275,11 @@ void CompletionDialog::show() { search_entry.set_text(text); list_view_text.set_search_entry(search_entry); } + + if(list_view_text.get_model()->children().size()>0) { + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); + update_tooltips(); + } } void CompletionDialog::select(bool hide_window) { @@ -285,7 +309,12 @@ bool CompletionDialog::on_key_release(GdkEventKey* key) { 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); - cursor_changed(); + if(text=="") { + if(list_view_text.get_model()->children().size()>0) { + list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); + } + } + update_tooltips(); } return false; } @@ -299,11 +328,11 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { 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) { - cursor_changed(); + update_tooltips(); return true; } } - cursor_changed(); + update_tooltips(); return false; } if(key->keyval==GDK_KEY_Shift_L || key->keyval==GDK_KEY_Shift_R || key->keyval==GDK_KEY_Alt_L || key->keyval==GDK_KEY_Alt_R || key->keyval==GDK_KEY_Control_L || key->keyval==GDK_KEY_Control_R || key->keyval==GDK_KEY_Meta_L || key->keyval==GDK_KEY_Meta_R) @@ -319,7 +348,7 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { else list_view_text.set_cursor(list_view_text.get_model()->get_path(list_view_text.get_model()->children().begin())); select(false); - cursor_changed(); + update_tooltips(); return true; } if(key->keyval==GDK_KEY_Up && list_view_text.get_model()->children().size()>0) { @@ -336,7 +365,7 @@ bool CompletionDialog::on_key_press(GdkEventKey* key) { list_view_text.set_cursor(list_view_text.get_model()->get_path(last_it)); } select(false); - cursor_changed(); + update_tooltips(); return true; } if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) { diff --git a/juci/selectiondialog.h b/juci/selectiondialog.h index e2c6067..abdd59b 100644 --- a/juci/selectiondialog.h +++ b/juci/selectiondialog.h @@ -20,7 +20,7 @@ public: Glib::RefPtr start_mark; protected: virtual void resize(); - virtual void cursor_changed(); + virtual void update_tooltips(); Gtk::TextView& text_view; std::unique_ptr window; From 742e22fe525a683fd9c26feb49063239c52a5b8d Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 17:35:50 +0200 Subject: [PATCH 05/31] Abit less eager tooltips and marking of similar tokens. --- juci/source.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/juci/source.cc b/juci/source.cc index a57ac0c..8c6dec0 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -380,7 +380,7 @@ void Source::ClangViewParse::update_diagnostics() { void Source::ClangViewParse::update_types() { type_tooltips.clear(); for(auto &token: *clang_tokens) { - if(token.has_type()) { + if(token.get_kind()==clang::Token_Identifier && token.has_type()) { auto start=get_buffer()->get_iter_at_offset(token.offsets.first); auto end=get_buffer()->get_iter_at_offset(token.offsets.second); auto get_tooltip_buffer=[this, &token]() { @@ -775,7 +775,7 @@ Source::ClangViewAutocomplete(file_path, project_path) { bool found=false; if(clang_readable) { for(auto &token: *clang_tokens) { - if(token.has_type()) { + if(token.get_kind()==clang::Token_Identifier && token.has_type()) { auto insert_offset=(unsigned)get_buffer()->get_insert()->get_iter().get_offset(); if(insert_offset>=token.offsets.first && insert_offset<=token.offsets.second) { found=true; From 52141023436d561cea64bc4f6a8a962107d576ba Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 17:51:02 +0200 Subject: [PATCH 06/31] Small fix with respect to simplified Token::get_brief_comments. --- juci/source.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/juci/source.cc b/juci/source.cc index 8c6dec0..9e829d1 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -388,7 +388,7 @@ void Source::ClangViewParse::update_types() { tooltip_buffer->insert_at_cursor("Type: "+token.get_type()); auto brief_comment=token.get_brief_comments(); if(brief_comment!="") - tooltip_buffer->insert_at_cursor("\n\n"+brief_comment+"."); + tooltip_buffer->insert_at_cursor("\n\n"+brief_comment); return tooltip_buffer; }; From f558a8ad6a6a7959229d1400ee6480eaa2eca5a6 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 22 Jul 2015 18:06:01 +0200 Subject: [PATCH 07/31] Minor fix to: go to declaration. --- juci/source.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/juci/source.cc b/juci/source.cc index 9e829d1..a970acd 100644 --- a/juci/source.cc +++ b/juci/source.cc @@ -807,7 +807,7 @@ Source::ClangViewAutocomplete(file_path, project_path) { std::pair location; if(clang_readable) { for(auto &token: *clang_tokens) { - if(token.has_type()) { + if(token.get_kind()==clang::Token_Identifier && token.has_type()) { auto insert_offset=(unsigned)get_buffer()->get_insert()->get_iter().get_offset(); if(insert_offset>=token.offsets.first && insert_offset<=token.offsets.second) { auto referenced=token.get_cursor().get_referenced(); From bd42aca5b6dc4f85a434833d07955b5aabc48073 Mon Sep 17 00:00:00 2001 From: eidheim Date: Thu, 23 Jul 2015 14:12:54 +0200 Subject: [PATCH 08/31] The entrybox is remade to be more general and easy to use. Search code to new entrybox will be finished next commit. --- juci/CMakeLists.txt | 4 +-- juci/entry.h | 22 ------------ juci/{entry.cc => entrybox.cc} | 47 ++++++++++++++++++++++-- juci/entrybox.h | 42 ++++++++++++++++++++++ juci/notebook.cc | 66 +++++++++++++++++++++++++--------- juci/notebook.h | 4 +-- juci/selectiondialog.cc | 2 ++ juci/window.cc | 13 ++++++- 8 files changed, 154 insertions(+), 46 deletions(-) delete mode 100644 juci/entry.h rename juci/{entry.cc => entrybox.cc} (54%) create mode 100644 juci/entrybox.h diff --git a/juci/CMakeLists.txt b/juci/CMakeLists.txt index b6f672f..694961c 100644 --- a/juci/CMakeLists.txt +++ b/juci/CMakeLists.txt @@ -117,8 +117,8 @@ add_executable(${project_name} api.cc notebook.cc notebook.h - entry.h - entry.cc + entrybox.h + entrybox.cc directories.h directories.cc terminal.h diff --git a/juci/entry.h b/juci/entry.h deleted file mode 100644 index 36a45e2..0000000 --- a/juci/entry.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef JUCI_ENTRY_H_ -#define JUCI_ENTRY_H_ - -#include -#include -#include "gtkmm.h" - -class Entry: public Gtk::Box { -public: - Entry(); - void show_set_filename(); - void show_search(const std::string& current); - void hide(); - std::string operator()(); - Gtk::Entry entry; - Gtk::Button button_apply_set_filename, button_close, button_next, button_prev; -private: - bool on_key_press(GdkEventKey* key); - std::function activate; -}; - -#endif // JUCI_ENTRY_H_ diff --git a/juci/entry.cc b/juci/entrybox.cc similarity index 54% rename from juci/entry.cc rename to juci/entrybox.cc index 429016c..dff6550 100644 --- a/juci/entry.cc +++ b/juci/entrybox.cc @@ -1,6 +1,47 @@ -#include "entry.h" +#include "entrybox.h" -Entry::Entry() : +namespace sigc { + SIGC_FUNCTORS_DEDUCE_RESULT_TYPE_WITH_DECLTYPE +} + +EntryBox::Entry::Entry(const std::string& content, std::function on_activate, unsigned length) : Gtk::Entry(), on_activate(on_activate) { + set_max_length(length); + set_text(content); + signal_activate().connect([this](){ + if(this->on_activate) + this->on_activate(get_text()); + }); +} + +EntryBox::Button::Button(const std::string& label, std::function on_activate) : Gtk::Button(label), on_activate(on_activate) { + signal_clicked().connect([this](){ + if(this->on_activate) + this->on_activate(); + }); +} + +EntryBox::EntryBox() : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) {} + +void EntryBox::clear() { + hide(); + entries.clear(); + buttons.clear(); +} + +void EntryBox::show() { + for(auto& entry: entries) { + pack_start(entry, Gtk::PACK_SHRINK); + } + for(auto& button: buttons) + pack_start(button, Gtk::PACK_SHRINK); + show_all(); + if(entries.size()>0) { + entries.begin()->grab_focus(); + entries.begin()->select_region(0, entries.begin()->get_text_length()); + } +} + +/*Entry::Entry() : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL), button_apply_set_filename(Gtk::Stock::APPLY), button_close(Gtk::Stock::CLOSE), @@ -58,4 +99,4 @@ void Entry::hide() { std::string Entry::operator()() { return entry.get_text(); -} +}*/ diff --git a/juci/entrybox.h b/juci/entrybox.h new file mode 100644 index 0000000..e4b748d --- /dev/null +++ b/juci/entrybox.h @@ -0,0 +1,42 @@ +#ifndef JUCI_ENTRYBOX_H_ +#define JUCI_ENTRYBOX_H_ + +#include +#include +#include "gtkmm.h" + +class EntryBox : public Gtk::Box { +public: + class Entry : public Gtk::Entry { + public: + Entry(const std::string& content="", std::function on_activate=nullptr, unsigned length=50); + std::function on_activate; + }; + class Button : public Gtk::Button { + public: + Button(const std::string& label, std::function on_activate=nullptr); + std::function on_activate; + }; +public: + EntryBox(); + void clear(); + void show(); + std::list entries; + std::list