Browse Source

Replaced spellcheck tooltips with selectiondialog where one can select a correct word.

merge-requests/365/head
eidheim 10 years ago
parent
commit
2ed5b6f12b
  1. 42
      src/selectiondialog.cc
  2. 3
      src/selectiondialog.h
  3. 122
      src/source.cc
  4. 10
      src/source.h

42
src/selectiondialog.cc

@ -148,7 +148,7 @@ void SelectionDialogBase::resize() {
}
}
SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, true) {}
SelectionDialog::SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry) : SelectionDialogBase(text_view, start_mark, show_search_entry) {}
void SelectionDialog::show() {
SelectionDialogBase::show();
@ -239,6 +239,46 @@ void SelectionDialog::show() {
}
}
bool SelectionDialog::on_key_press(GdkEventKey* key) {
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));
}
}
else
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 && 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));
}
}
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;
}
if(key->keyval==GDK_KEY_Return || key->keyval==GDK_KEY_ISO_Left_Tab || key->keyval==GDK_KEY_Tab) {
auto it=list_view_text.get_selection()->get_selected();
auto column=list_view_text.get_column(0);
list_view_text.row_activated(list_view_text.get_model()->get_path(it), *column);
return true;
}
hide();
if(key->keyval==GDK_KEY_Escape)
return true;
return false;
}
CompletionDialog::CompletionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark) : SelectionDialogBase(text_view, start_mark, false) {}
void CompletionDialog::show() {

3
src/selectiondialog.h

@ -37,7 +37,8 @@ private:
class SelectionDialog : public SelectionDialogBase {
public:
SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark);
SelectionDialog(Gtk::TextView& text_view, Glib::RefPtr<Gtk::TextBuffer::Mark> start_mark, bool show_search_entry=true);
bool on_key_press(GdkEventKey* key);
void show();
};

122
src/source.cc

@ -173,6 +173,8 @@ Source::View::View(const boost::filesystem::path &file_path): file_path(file_pat
tag->property_underline()=Pango::Underline::UNDERLINE_ERROR;
get_buffer()->signal_changed().connect([this](){
delayed_spellcheck_suggestions_connection.disconnect();
auto iter=get_buffer()->get_insert()->get_iter();
if(iter.backward_char()) {
auto context_iter=iter;
@ -183,16 +185,60 @@ Source::View::View(const boost::filesystem::path &file_path): file_path(file_pat
auto second=iter;
if(first.backward_char() && second.forward_char()) {
get_buffer()->remove_tag_by_name("spellcheck_error", first, second);
spellcheck(first);
spellcheck(second);
auto word=spellcheck_get_word(first);
spellcheck_word(word.first, word.second);
word=spellcheck_get_word(second);
spellcheck_word(word.first, word.second);
}
}
else
spellcheck(iter);
else {
auto word=spellcheck_get_word(iter);
spellcheck_word(word.first, word.second);
}
}
}
}
});
get_buffer()->signal_mark_set().connect([this](const Gtk::TextBuffer::iterator& iter, const Glib::RefPtr<Gtk::TextBuffer::Mark>& mark) {
if(mark->get_name()=="insert") {
if(spellcheck_suggestions_dialog_shown)
spellcheck_suggestions_dialog->hide();
delayed_spellcheck_suggestions_connection.disconnect();
delayed_spellcheck_suggestions_connection=Glib::signal_timeout().connect([this]() {
auto tags=get_buffer()->get_insert()->get_iter().get_tags();
bool need_suggestions=false;
for(auto &tag: tags) {
if(tag->property_name()=="spellcheck_error") {
need_suggestions=true;
break;
}
}
if(need_suggestions) {
spellcheck_suggestions_dialog=std::unique_ptr<SelectionDialog>(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false));
spellcheck_suggestions_dialog->on_hide=[this](){
spellcheck_suggestions_dialog_shown=false;
};
auto word=spellcheck_get_word(get_buffer()->get_insert()->get_iter());
auto suggestions=spellcheck_get_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) {
get_source_buffer()->begin_user_action();
get_buffer()->erase(word.first, word.second);
get_buffer()->insert(get_buffer()->get_insert()->get_iter(), selected);
get_source_buffer()->end_user_action();
delayed_tooltips_connection.disconnect();
};
spellcheck_suggestions_dialog->show();
spellcheck_suggestions_dialog_shown=true;
}
return false;
}, 500);
}
});
}
set_tooltip_events();
@ -212,13 +258,11 @@ void Source::View::set_tooltip_events() {
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle);
}
spellcheck_tooltips.show(rectangle);
return false;
}, 100);
}
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
}
on_motion_last_x=event->x;
on_motion_last_y=event->y;
@ -244,12 +288,10 @@ void Source::View::set_tooltip_events() {
type_tooltips.show(rectangle);
diagnostic_tooltips.show(rectangle);
}
spellcheck_tooltips.show(rectangle);
return false;
}, 500);
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
}
});
@ -257,7 +299,6 @@ void Source::View::set_tooltip_events() {
delayed_tooltips_connection.disconnect();
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
return false;
});
@ -265,7 +306,6 @@ void Source::View::set_tooltip_events() {
delayed_tooltips_connection.disconnect();
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
return false;
});
}
@ -453,6 +493,11 @@ string Source::View::get_line_before_insert() {
//Basic indentation
bool Source::View::on_key_press_event(GdkEventKey* key) {
if(spellcheck_suggestions_dialog_shown) {
if(spellcheck_suggestions_dialog->on_key_press(key))
return true;
}
get_source_buffer()->begin_user_action();
//Indent as in next or previous line
if(key->keyval==GDK_KEY_Return && key->state==0 && !get_buffer()->get_has_selection()) {
@ -637,7 +682,7 @@ std::pair<char, unsigned> Source::View::find_tab_char_and_size() {
return {found_tab_char, found_tab_size};
}
void Source::View::spellcheck(Gtk::TextIter iter) {
std::pair<Gtk::TextIter, Gtk::TextIter> Source::View::spellcheck_get_word(Gtk::TextIter iter) {
auto start=iter;
auto end=iter;
@ -650,46 +695,37 @@ void Source::View::spellcheck(Gtk::TextIter iter) {
if(!end.forward_char())
break;
}
for(auto it=spellcheck_tooltips.begin();it!=spellcheck_tooltips.end();it++) {
if(it->start_mark->get_iter()==start || it->start_mark->get_iter()==it->end_mark->get_iter())
it=spellcheck_tooltips.erase(it);
}
return {start, end};
}
void Source::View::spellcheck_word(const Gtk::TextIter& start, const Gtk::TextIter& end) {
auto word=get_buffer()->get_text(start, end);
std::vector<Glib::ustring> words;
if(word.size()>0) {
auto correct = aspell_speller_check(spellcheck_checker, word.data(), word.bytes());
if(correct==0) {
if(correct==0)
get_buffer()->apply_tag_by_name("spellcheck_error", start, end);
const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word.data(), word.bytes());
AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
auto words=std::make_shared<std::string>();
const char *word;
while ((word = aspell_string_enumeration_next(elements))!= NULL) {
if(words->size()==0) {
*words="Suggestions:\n";
(*words)+=word;
}
else
(*words)+=std::string(", ")+word;
}
delete_aspell_string_enumeration(elements);
if(words->size()>0) {
auto create_tooltip_buffer=[this, words]() {
auto tooltip_buffer=Gtk::TextBuffer::create(get_buffer()->get_tag_table());
tooltip_buffer->insert_with_tag(tooltip_buffer->get_insert()->get_iter(), *words, "def:note");
return tooltip_buffer;
};
spellcheck_tooltips.emplace_back(create_tooltip_buffer, *this, get_buffer()->create_mark(start), get_buffer()->create_mark(end));
}
}
else
get_buffer()->remove_tag_by_name("spellcheck_error", start, end);
}
}
std::vector<std::string> Source::View::spellcheck_get_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end) {
auto word_with_error=get_buffer()->get_text(start, end);
const AspellWordList *suggestions = aspell_speller_suggest(spellcheck_checker, word_with_error.data(), word_with_error.bytes());
AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
std::vector<std::string> words;
const char *word;
while ((word = aspell_string_enumeration_next(elements))!= NULL) {
words.emplace_back(word);
}
delete_aspell_string_enumeration(elements);
return words;
}
/////////////////////
//// GenericView ////
@ -775,7 +811,6 @@ Source::View(file_path), project_path(project_path) {
start_reparse();
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
});
bracket_regex=std::regex(std::string("^(")+tab_char+"*).*\\{ *$");
@ -786,7 +821,6 @@ Source::View(file_path), project_path(project_path) {
void Source::ClangViewParse::init_parse() {
type_tooltips.hide();
diagnostic_tooltips.hide();
spellcheck_tooltips.hide();
get_buffer()->remove_all_tags(get_buffer()->begin(), get_buffer()->end());
source_readable=false;
parse_thread_go=true;

10
src/source.h

@ -80,7 +80,6 @@ namespace Source {
bool source_readable;
Tooltips diagnostic_tooltips;
Tooltips type_tooltips;
Tooltips spellcheck_tooltips;
gdouble on_motion_last_x;
gdouble on_motion_last_y;
sigc::connection delayed_tooltips_connection;
@ -109,8 +108,13 @@ namespace Source {
static AspellConfig* spellcheck_config;
AspellCanHaveError *spellcheck_possible_err;
AspellSpeller *spellcheck_checker;
void spellcheck(Gtk::TextIter iter);
}; // class View
std::pair<Gtk::TextIter, Gtk::TextIter> spellcheck_get_word(Gtk::TextIter iter);
void spellcheck_word(const Gtk::TextIter& start, const Gtk::TextIter& end);
std::vector<std::string> spellcheck_get_suggestions(const Gtk::TextIter& start, const Gtk::TextIter& end);
std::unique_ptr<SelectionDialog> spellcheck_suggestions_dialog;
bool spellcheck_suggestions_dialog_shown=false;
sigc::connection delayed_spellcheck_suggestions_connection;
};
class GenericView : public View {
public:

Loading…
Cancel
Save