Browse Source

selectiondialog.* cleanup.

merge-requests/365/head
eidheim 11 years ago
parent
commit
cd28f0cf5c
  1. 217
      juci/selectiondialog.cc
  2. 31
      juci/selectiondialog.h
  3. 102
      juci/source.cc
  4. 5
      juci/source.h

217
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<Gtk::TextBuffer::Mark> 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<Gtk::Window>(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP));
else
window=std::unique_ptr<Gtk::Dialog>(new Gtk::Dialog());
scrolled_window=std::unique_ptr<Gtk::ScrolledWindow>(new Gtk::ScrolledWindow());
list_view_text=std::unique_ptr<Gtk::ListViewText>(new Gtk::ListViewText(1, false, Gtk::SelectionMode::SELECTION_BROWSE));
search_entry=std::unique_ptr<Gtk::Entry>(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<Tooltips>(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<Tooltips>(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<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, true) {}
void SelectionDialog::show() {
SelectionDialogBase::show();
std::shared_ptr<std::string> 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<Gtk::TreeModel>& 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<Gtk::TreeModel>& 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<Gtk::TextBuffer::Mark> 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<std::string, std::string> 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;

31
juci/selectiondialog.h

@ -4,47 +4,44 @@
#include "gtkmm.h"
#include "logging.h"
#include "tooltips.h"
#include <unordered_map>
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<Gtk::TextBuffer::Mark> 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<std::string, std::pair<std::string, std::string> > rows; //TODO: remove, instead add on_select. Also remember to destroy start_mark in destructor
std::function<void()> on_hide;
bool shown=false;
std::function<void(const std::string& selected, bool finished)> on_select;
Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark;
protected:
virtual void resize();
virtual void cursor_changed();
Gtk::TextView& text_view;
std::unique_ptr<Gtk::Window> window;
std::unique_ptr<Gtk::ScrolledWindow> scrolled_window;
std::unique_ptr<Gtk::ListViewText> list_view_text;
std::unique_ptr<Gtk::Entry> search_entry;
Gtk::ScrolledWindow scrolled_window;
Gtk::ListViewText list_view_text;
Gtk::Entry search_entry;
bool show_search_entry;
std::unique_ptr<Tooltips> tooltips;
int last_selected;
private:
bool popup;
std::unordered_map<std::string, std::string> 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<Gtk::TextBuffer::Mark> start_mark);
void show();
std::function<void(std::string selected)> on_select;
};
class CompletionDialog : public SelectionDialogBase {
public:
CompletionDialog(Gtk::TextView& text_view);
void init() {SelectionDialogBase::init();}
CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
void show();
bool on_key_release(GdkEventKey* key);
bool on_key_press(GdkEventKey* key);

102
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<Gtk::TextBuffer::Mark>& 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;c<prefix.size();c++)
start_iter--;
completion_dialog.start_mark=get_buffer()->create_mark(start_iter);
std::map<std::string, std::pair<std::string, std::string> > rows;
completion_dialog.init();
completion_dialog=std::unique_ptr<CompletionDialog>(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<std::unordered_map<std::string, std::string> >();
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<std::string, std::string>(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<std::string, std::string>();
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::map<std::string,
////////////////////////////
Source::ClangViewRefactor::ClangViewRefactor(const std::string& file_path, const std::string& project_path):
Source::ClangViewAutocomplete(file_path, project_path), selection_dialog(*this) {
Source::ClangViewAutocomplete(file_path, project_path) {
similar_tokens_tag=get_buffer()->create_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<std::string, std::pair<std::string, std::string> > rows;
selection_dialog.init();
selection_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter())));
auto rows=std::make_shared<std::unordered_map<std::string, std::string> >();
auto methods=clang_tokens->get_cxx_methods();
if(methods.size()==0)
return;
for(auto &method: methods) {
rows[method.first]=std::pair<std::string, std::string>(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();
}
};
}

5
juci/source.h

@ -120,7 +120,8 @@ public:
private:
void start_autocomplete();
void autocomplete();
CompletionDialog completion_dialog;
std::unique_ptr<CompletionDialog> completion_dialog;
bool completion_dialog_shown=false;
std::vector<Source::AutoCompleteData> get_autocomplete_suggestions(int line_number, int column, std::map<std::string, std::string>& buffer_map);
Glib::Dispatcher autocomplete_done;
sigc::connection autocomplete_done_connection;
@ -137,7 +138,7 @@ public:
private:
Glib::RefPtr<Gtk::TextTag> similar_tokens_tag;
std::string last_similar_tokens_tagged;
SelectionDialog selection_dialog;
std::unique_ptr<SelectionDialog> selection_dialog;
};
class ClangView : public ClangViewRefactor {

Loading…
Cancel
Save