static gboolean gbp_spell_navigator_goto_next (GspellNavigator *navigator, gchar **word_p, GspellChecker **spell_checker_p, GError **error_p) { GbpSpellNavigator *self = (GbpSpellNavigator *)navigator; GspellTextBuffer *gspell_buffer; GspellChecker *spell_checker; GtkTextIter word_start; GtkTextIter end; GtkTextTag *no_spell_check_tag; g_assert (GBP_IS_SPELL_NAVIGATOR (self)); g_assert ((self->word_start == NULL && self->word_end == NULL) || (self->word_start != NULL && self->word_end != NULL)); gspell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (self->buffer); spell_checker = gspell_text_buffer_get_spell_checker (gspell_buffer); if (spell_checker == NULL) return FALSE; if (gspell_checker_get_language (spell_checker) == NULL) { if (spell_checker_p != NULL) *spell_checker_p = g_object_ref (spell_checker); g_set_error (error_p, GSPELL_CHECKER_ERROR, GSPELL_CHECKER_ERROR_NO_LANGUAGE_SET, "%s", _("No language set. Check your dictionary installation.")); return FALSE; } gtk_text_buffer_get_iter_at_mark (self->buffer, &end, self->end_boundary); if (self->word_start == NULL) { GtkTextIter start; gtk_text_buffer_get_iter_at_mark (self->buffer, &start, self->start_boundary); self->word_start = gtk_text_buffer_create_mark (self->buffer, NULL, &start, TRUE); self->word_end = gtk_text_buffer_create_mark (self->buffer, NULL, &start, FALSE); word_start = start; } else { GtkTextIter word_end; gtk_text_buffer_get_iter_at_mark (self->buffer, &word_end, self->word_end); if (gtk_text_iter_compare (&end, &word_end) <= 0) return FALSE; word_start = word_end; } no_spell_check_tag = gbp_spell_utils_get_no_spell_check_tag (self->buffer); while (TRUE) { GtkTextIter word_end; g_autofree gchar *word = NULL; gboolean correctly_spelled; GError *error = NULL; if (!gbp_spell_utils_text_iter_starts_word (&word_start)) { GtkTextIter iter; iter = word_start; gbp_spell_utils_text_iter_forward_word_end (&word_start); if (gtk_text_iter_equal (&iter, &word_start)) return FALSE; gbp_spell_utils_text_iter_backward_word_start (&word_start); } if (!gbp_spell_utils_skip_no_spell_check (no_spell_check_tag, &word_start, &end)) return FALSE; g_return_val_if_fail (gbp_spell_utils_text_iter_starts_word (&word_start), FALSE); word_end = word_start; gbp_spell_utils_text_iter_forward_word_end (&word_end); if (gtk_text_iter_compare (&end, &word_end) < 0) return FALSE; word = gtk_text_buffer_get_text (self->buffer, &word_start, &word_end, FALSE); correctly_spelled = gspell_checker_check_word (spell_checker, word, -1, &error); if (error != NULL) { g_propagate_error (error_p, error); return FALSE; } if (!correctly_spelled) { /* Found! */ gtk_text_buffer_move_mark (self->buffer, self->word_start, &word_start); gtk_text_buffer_move_mark (self->buffer, self->word_end, &word_end); gbp_spell_navigator_select_misspelled_word (self); if (spell_checker_p != NULL) *spell_checker_p = g_object_ref (spell_checker); if (word_p != NULL) *word_p = g_steal_pointer (&word); return TRUE; } word_start = word_end; } return FALSE; }
static void ide_editor_spell_widget_constructed (GObject *object) { IdeEditorSpellWidget *self = (IdeEditorSpellWidget *)object; GspellTextBuffer *spell_buffer; g_assert (IDE_IS_SOURCE_VIEW (self->view)); self->buffer = IDE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->view))); ide_buffer_set_spell_checking (self->buffer, TRUE); self->spellchecking_status = TRUE; spell_buffer = gspell_text_buffer_get_from_gtk_text_buffer (GTK_TEXT_BUFFER (self->buffer)); self->checker = gspell_text_buffer_get_spell_checker (spell_buffer); ide_editor_spell_dict_set_checker (self->dict, self->checker); self->spellchecker_language = gspell_checker_get_language (self->checker); gspell_language_chooser_set_language (GSPELL_LANGUAGE_CHOOSER (self->language_chooser_button), self->spellchecker_language); g_signal_connect_swapped (self->navigator, "notify::words-counted", G_CALLBACK (ide_editor_spell_widget__words_counted_cb), self); g_signal_connect_swapped (self->word_entry, "changed", G_CALLBACK (ide_editor_spell_widget__word_entry_changed_cb), self); g_signal_connect_swapped (self->word_entry, "populate-popup", G_CALLBACK (ide_editor_spell_widget__populate_popup_cb), self); g_signal_connect_swapped (self->ignore_button, "clicked", G_CALLBACK (ide_editor_spell_widget__ignore_button_clicked_cb), self); g_signal_connect_swapped (self->ignore_all_button, "clicked", G_CALLBACK (ide_editor_spell_widget__ignore_all_button_clicked_cb), self); g_signal_connect_swapped (self->change_button, "clicked", G_CALLBACK (ide_editor_spell_widget__change_button_clicked_cb), self); g_signal_connect_swapped (self->change_all_button, "clicked", G_CALLBACK (ide_editor_spell_widget__change_all_button_clicked_cb), self); g_signal_connect_swapped (self->suggestions_box, "row-selected", G_CALLBACK (ide_editor_spell_widget__row_selected_cb), self); g_signal_connect_swapped (self->suggestions_box, "row-activated", G_CALLBACK (ide_editor_spell_widget__row_activated_cb), self); g_signal_connect_swapped (self, "key-press-event", G_CALLBACK (ide_editor_spell_widget__key_press_event_cb), self); g_signal_connect_swapped (self->highlight_switch, "state-set", G_CALLBACK (ide_editor_spell_widget__highlight_switch_toggled_cb), self); g_signal_connect_object (self->language_chooser_button, "notify::language", G_CALLBACK (ide_editor_spell_widget__language_notify_cb), self, G_CONNECT_SWAPPED); g_signal_connect_swapped (self->dict_add_button, "clicked", G_CALLBACK (ide_editor_spell_widget__add_button_clicked_cb), self); g_signal_connect_swapped (self->dict_word_entry, "changed", G_CALLBACK (ide_editor_spell_widget__dict_word_entry_changed_cb), self); self->placeholder = gtk_label_new (NULL); gtk_widget_set_visible (self->placeholder, TRUE); gtk_list_box_set_placeholder (self->suggestions_box, self->placeholder); /* Due to the change of focus between the view and the spellchecker widget, * we need to start checking only when the widget is mapped, * so the view can keep the selection on the first word. */ g_signal_connect_object (self, "map", G_CALLBACK (ide_editor_spell__widget_mapped_cb), NULL, G_CONNECT_AFTER); g_signal_connect_swapped (self->dict, "loaded", G_CALLBACK (ide_editor_spell_widget__dict__loaded_cb), self); g_signal_connect_object (self->word_label, "notify::label", G_CALLBACK (ide_editor_spell_widget__word_label_notify_cb), self, G_CONNECT_SWAPPED); }