static void check_range(GtkSpell *spell, GtkTextBuffer *buffer, GtkTextIter start, GtkTextIter end) { /* we need to "split" on word boundaries. * luckily, pango knows what "words" are * so we don't have to figure it out. */ GtkTextIter wstart, wend; if (debug) { g_print("check_range: "); print_iter("s", &start); print_iter("e", &end); g_print(" -> "); } if (gtk_text_iter_inside_word(&end)) gtk_text_iter_forward_word_end(&end); if (!gtk_text_iter_starts_word(&start)) { if (gtk_text_iter_inside_word(&start) || gtk_text_iter_ends_word(&start)) { gtk_text_iter_backward_word_start(&start); } else { /* if we're neither at the beginning nor inside a word, * me must be in some spaces. * skip forward to the beginning of the next word. */ //gtk_text_buffer_remove_tag(buffer, tag_highlight, &start, &end); if (gtk_text_iter_forward_word_end(&start)) gtk_text_iter_backward_word_start(&start); } } gtk_text_buffer_remove_tag(buffer, spell->tag_highlight, &start, &end); if (debug) {print_iter("s", &start); print_iter("e", &end); g_print("\n");} wstart = start; while (gtk_text_iter_compare(&wstart, &end) < 0) { /* move wend to the end of the current word. */ wend = wstart; gtk_text_iter_forward_word_end(&wend); check_word(spell, buffer, &wstart, &wend); /* now move wend to the beginning of the next word, */ gtk_text_iter_forward_word_end(&wend); gtk_text_iter_backward_word_start(&wend); /* make sure we've actually advanced * (we don't advance in some corner cases), */ if (gtk_text_iter_equal(&wstart, &wend)) break; /* we're done in these cases.. */ /* and then pick this as the new next word beginning. */ wstart = wend; } }
/** Kolorowanie słów. Słowa nie znajdujące się w słowniku - potencjalnie błędne - zostają oznaczone na czerwono. */ static void show_errors() { GtkTextIter start, end, text_end; int i, range; char *word; gunichar *wword; gtk_text_buffer_create_tag(editor_buf, "red_fg", "foreground", "red", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_end_iter(editor_buf, &text_end); gtk_text_buffer_get_start_iter(editor_buf, &end); range = gtk_text_buffer_get_char_count(editor_buf); while (!gtk_text_iter_is_end(&end)) { gtk_text_iter_forward_word_end(&end); start = end; gtk_text_iter_backward_word_start(&start); word = gtk_text_iter_get_text(&start, &end); wword = g_utf8_to_ucs4_fast(word, -1, NULL); if (make_lowercase(wword)) { if (!dictionary_find(dict, wword)) gtk_text_buffer_apply_tag_by_name(editor_buf, "red_fg", &start, &end); } g_free(word); g_free(wword); } }
static void update_words (ExampleAppWindow *win) { ExampleAppWindowPrivate *priv; GHashTable *strings; GHashTableIter iter; GtkWidget *tab, *view, *row; GtkTextBuffer *buffer; GtkTextIter start, end; GList *children, *l; gchar *word, *key; priv = example_app_window_get_instance_private (win); tab = gtk_stack_get_visible_child (GTK_STACK (priv->stack)); if (tab == NULL) return; view = gtk_bin_get_child (GTK_BIN (tab)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); strings = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); gtk_text_buffer_get_start_iter (buffer, &start); while (!gtk_text_iter_is_end (&start)) { while (!gtk_text_iter_starts_word (&start)) { if (!gtk_text_iter_forward_char (&start)) goto done; } end = start; if (!gtk_text_iter_forward_word_end (&end)) goto done; word = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); g_hash_table_add (strings, g_utf8_strdown (word, -1)); g_free (word); start = end; } done: children = gtk_container_get_children (GTK_CONTAINER (priv->words)); for (l = children; l; l = l->next) gtk_container_remove (GTK_CONTAINER (priv->words), GTK_WIDGET (l->data)); g_list_free (children); g_hash_table_iter_init (&iter, strings); while (g_hash_table_iter_next (&iter, (gpointer *)&key, NULL)) { row = gtk_button_new_with_label (key); g_signal_connect (row, "clicked", G_CALLBACK (find_word), win); gtk_widget_show (row); gtk_container_add (GTK_CONTAINER (priv->words), row); } g_hash_table_unref (strings); }
static void get_cur_word_extents(GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end) { gtk_text_buffer_get_iter_at_mark(buffer, start, gtk_text_buffer_get_insert(buffer)); if (!gtk_text_iter_starts_word(start)) gtk_text_iter_backward_word_start(start); *end = *start; if (gtk_text_iter_inside_word(end)) gtk_text_iter_forward_word_end(end); }
// Koloruje słowa nie ze słownika na czerwono static void ColorMistakes (GtkMenuItem *item, gpointer data) { GtkTextIter start, end, buffEnd; gtk_text_buffer_get_start_iter(editor_buf, &end); //Teraz sztuczką przesuwamy końcowy iterator na koniec ostatniego słowa gtk_text_buffer_get_end_iter(editor_buf, &buffEnd); gtk_text_iter_backward_word_start(&buffEnd); gtk_text_iter_forward_word_end(&buffEnd); gtk_text_buffer_create_tag(editor_buf, "red_fg", "foreground", "red", "weight", PANGO_WEIGHT_BOLD, NULL); // Aktualizacja słownika if(update_actual_dict() < 0) return; start = end; while (!gtk_text_iter_equal(&end, &buffEnd)) { // Inkrementacja zmiennych gtk_text_iter_forward_word_end(&end); start = end; gtk_text_iter_backward_word_start(&start); // Usuwamy etykietkę ze słowa jeśli jest gtk_text_buffer_remove_tag_by_name(editor_buf, "red_fg", &start, &end); // Separujemy słowo char* word = gtk_text_iter_get_text(&start, &end); gunichar* wword = g_utf8_to_ucs4_fast(word, -1, NULL); // Jeśli znaleziono w słowniku to kolorujemy if(!dictionary_find(dict, (const wchar_t*)wword)) gtk_text_buffer_apply_tag_by_name(editor_buf, "red_fg", &start, &end); g_free(word); } }
static void update_current (GeditDocument *doc, gint current) { CheckRange *range; GtkTextIter iter; GtkTextIter end_iter; gedit_debug (DEBUG_PLUGINS); g_return_if_fail (doc != NULL); g_return_if_fail (current >= 0); range = get_check_range (doc); g_return_if_fail (range != NULL); gtk_text_buffer_get_iter_at_offset (GTK_TEXT_BUFFER (doc), &iter, current); if (!gtk_text_iter_inside_word (&iter)) { /* if we're not inside a word, * we must be in some spaces. * skip forward to the beginning of the next word. */ if (!gtk_text_iter_is_end (&iter)) { gtk_text_iter_forward_word_end (&iter); gtk_text_iter_backward_word_start (&iter); } } else { if (!gtk_text_iter_starts_word (&iter)) gtk_text_iter_backward_word_start (&iter); } gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); if (gtk_text_iter_compare (&end_iter, &iter) < 0) { gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &end_iter); } else { gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->current_mark, &iter); } }
static gboolean gtkspell_text_iter_forward_word_end(GtkTextIter *i) { GtkTextIter iter; /* heuristic: * if we're on an singlequote/apostrophe and * if the next letter is alphanumeric, * this is an apostrophe. */ if (!gtk_text_iter_forward_word_end(i)) return FALSE; if (gtk_text_iter_get_char(i) != '\'') return TRUE; iter = *i; if (gtk_text_iter_forward_char(&iter)) { if (g_unichar_isalpha(gtk_text_iter_get_char(&iter))) { return (gtk_text_iter_forward_word_end(i)); } } return TRUE; }
static void get_word_extents_from_mark (GtkTextBuffer *buffer, GtkTextIter *start, GtkTextIter *end, GtkTextMark *mark) { gtk_text_buffer_get_iter_at_mark(buffer, start, mark); if (!gtk_text_iter_starts_word (start)) gtk_text_iter_backward_word_start (start); *end = *start; if (gtk_text_iter_inside_word (end)) gtk_text_iter_forward_word_end (end); }
static gchar * get_current_word (GeditDocument *doc, gint *start, gint *end) { const CheckRange *range; GtkTextIter end_iter; GtkTextIter current_iter; gint range_end; gedit_debug (DEBUG_PLUGINS); g_return_val_if_fail (doc != NULL, NULL); g_return_val_if_fail (start != NULL, NULL); g_return_val_if_fail (end != NULL, NULL); range = get_check_range (doc); g_return_val_if_fail (range != NULL, NULL); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), &end_iter, range->end_mark); range_end = gtk_text_iter_get_offset (&end_iter); gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (doc), ¤t_iter, range->current_mark); end_iter = current_iter; if (!gtk_text_iter_is_end (&end_iter)) { gedit_debug_message (DEBUG_PLUGINS, "Current is not end"); gtk_text_iter_forward_word_end (&end_iter); } *start = gtk_text_iter_get_offset (¤t_iter); *end = MIN (gtk_text_iter_get_offset (&end_iter), range_end); gedit_debug_message (DEBUG_PLUGINS, "Current word extends [%d, %d]", *start, *end); if (!(*start < *end)) return NULL; return gtk_text_buffer_get_slice (GTK_TEXT_BUFFER (doc), ¤t_iter, &end_iter, TRUE); }
gboolean ide_editor_spell_utils_text_iter_forward_word_end (GtkTextIter *iter) { g_return_val_if_fail (iter != NULL, FALSE); while (gtk_text_iter_forward_word_end (iter)) { GtkTextIter next_char; if (!is__text_iter_apostrophe_or_dash (iter)) return TRUE; next_char = *iter; gtk_text_iter_forward_char (&next_char); if (!gtk_text_iter_starts_word (&next_char)) return TRUE; *iter = next_char; } return FALSE; }
static gint console_complete_word (GtkTextBuffer *buf, GtkTextIter *iter) { GtkTextIter start, end; const char *targ = NULL; gchar *src; start = end = *iter; if (!gtk_text_iter_starts_word(&start)) { gtk_text_iter_backward_word_start(&start); } if (!gtk_text_iter_ends_word(&end)) { gtk_text_iter_forward_word_end(&end); } src = gtk_text_buffer_get_text(buf, &start, &end, FALSE); if (src != NULL && *src != '\0') { if (gtk_text_iter_get_line_offset(&start) == 2) { /* first word on line */ targ = gretl_command_complete(src); } else { targ = console_varname_complete(src); } if (targ != NULL) { gtk_text_buffer_delete(buf, &start, &end); gtk_text_buffer_insert(buf, &start, targ, -1); } else { console_beep(); } } g_free(src); return TRUE; }
ParseWords::ParseWords(const ustring & text) // Parses a line of text in its separate words. // Note: This is comparable to object Parse, but does a better job. { // Load text into buffer. ustring text2(text); text2.append(" "); GtkTextBuffer *textbuffer; textbuffer = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(textbuffer, text2.c_str(), -1); // Iterators. GtkTextIter startiter, enditer; // Parse into separate words. gtk_text_buffer_get_start_iter(textbuffer, &enditer); while (gtk_text_iter_forward_word_end(&enditer)) { startiter = enditer; gtk_text_iter_backward_word_start(&startiter); ustring word = gtk_text_iter_get_text(&startiter, &enditer); words.push_back(word); } // Free memory g_object_unref(textbuffer); }
gboolean xed_spell_utils_skip_no_spell_check (GtkTextIter *start, GtkTextIter *end) { GtkSourceBuffer *buffer = GTK_SOURCE_BUFFER (gtk_text_iter_get_buffer (start)); while (gtk_source_buffer_iter_has_context_class (buffer, start, "no-spell-check")) { GtkTextIter last = *start; if (!gtk_source_buffer_iter_forward_to_context_class_toggle (buffer, start, "no-spell-check")) { return FALSE; } if (gtk_text_iter_compare (start, &last) <= 0) { return FALSE; } gtk_text_iter_forward_word_end (start); gtk_text_iter_backward_word_start (start); if (gtk_text_iter_compare (start, &last) <= 0) { return FALSE; } if (gtk_text_iter_compare (start, end) >= 0) { return FALSE; } } return TRUE; }
static void set_check_range (GeditDocument *doc, GtkTextIter *start, GtkTextIter *end) { CheckRange *range; GtkTextIter iter; gedit_debug (DEBUG_PLUGINS); range = get_check_range (doc); if (range == NULL) { gedit_debug_message (DEBUG_PLUGINS, "There was not a previous check range"); gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (doc), &iter); range = g_new0 (CheckRange, 1); range->start_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_start_mark", &iter, TRUE); range->end_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_end_mark", &iter, FALSE); range->current_mark = gtk_text_buffer_create_mark (GTK_TEXT_BUFFER (doc), "check_range_current_mark", &iter, TRUE); g_object_set_qdata_full (G_OBJECT (doc), check_range_id, range, (GDestroyNotify)g_free); } if (gedit_spell_utils_skip_no_spell_check (start, end)) { if (!gtk_text_iter_inside_word (end)) { /* if we're neither inside a word, * we must be in some spaces. * skip backward to the end of the previous word. */ if (!gtk_text_iter_is_end (end)) { gtk_text_iter_backward_word_start (end); gtk_text_iter_forward_word_end (end); } } else { if (!gtk_text_iter_ends_word (end)) gtk_text_iter_forward_word_end (end); } } else { /* no spell checking in the specified range */ start = end; } gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->start_mark, start); gtk_text_buffer_move_mark (GTK_TEXT_BUFFER (doc), range->end_mark, end); range->mw_start = -1; range->mw_end = -1; update_current (doc, gtk_text_iter_get_offset (start)); }
/** Sprawdzenie słowa, na którym aktualnie znajduje się kursor. Ewentualne dodanie do słownika. @param[in] item element menu. @param[in] data wskaźnik na wartość. */ static void WhatCheck (GtkMenuItem *item, gpointer data) { GtkWidget *dialog; GtkTextIter start, end; char *word; gunichar *wword; //load_dictionary_from_menu(&dict); // Znajdujemy pozycję kursora gtk_text_buffer_get_iter_at_mark(editor_buf, &start, gtk_text_buffer_get_insert(editor_buf)); // Jeśli nie wewnątrz słowa, kończymy if (!gtk_text_iter_inside_word(&start)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Kursor musi być w środku słowa"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } // Znajdujemy początek i koniec słowa, a potem samo słowo end = start; gtk_text_iter_backward_word_start(&start); gtk_text_iter_forward_word_end(&end); word = gtk_text_iter_get_text(&start, &end); // Zamieniamy na wide char (no prawie) wword = g_utf8_to_ucs4_fast(word, -1, NULL); if (!make_lowercase(wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Podane słowo nie jest słowem słownikowym."); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Sprawdzamy if (dictionary_find(dict, (wchar_t *)wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Wszystko w porządku,\nśpij spokojnie"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Czas korekty GtkWidget *vbox, *label, *combo; struct word_list hints; int i; wchar_t **words; dictionary_hints(dict, (wchar_t *)wword, &hints); words = (wchar_t **) word_list_get(&hints); dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_ADD, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Słowo nie znajduje się w słowniku. Wybierz \njedną z propozycji lub dodaj słowa do słownika."); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); // Spuszczane menu combo = gtk_combo_box_text_new(); for (i = 0; i < word_list_size(&hints); i++) { // Combo box lubi mieć Gtk char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL); // Dodajemy kolejny element gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword); g_free(uword); } gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); gint click = gtk_dialog_run(GTK_DIALOG(dialog)); if (click == GTK_RESPONSE_ACCEPT) { char *korekta = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); // Usuwamy stare gtk_text_buffer_delete(editor_buf, &start, &end); // Wstawiamy nowe gtk_text_buffer_insert(editor_buf, &start, korekta, -1); g_free(korekta); } // Proponujemy dodanie słowa do słownika else if (click == GTK_RESPONSE_APPLY) dictionary_insert(dict, wword); gtk_widget_destroy(dialog); } } g_free(word); g_free(wword); }
void CheckCapitalization::check_suspicious_capitalization(ustring & text) /* Checks on suspicious capitalization, like "bOat" or "BOat". There are exceptions to this check. */ { // Load text into buffer. ustring text2(text); text2.append(" "); GtkTextBuffer *textbuffer; textbuffer = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(textbuffer, text2.c_str(), -1); // Iterators. GtkTextIter startiter, enditer; // Check all separate words. gtk_text_buffer_get_start_iter(textbuffer, &enditer); while (gtk_text_iter_forward_word_end(&enditer)) { startiter = enditer; gtk_text_iter_backward_word_start(&startiter); vector < bool > capspattern; unsigned int capscount = 0; GtkTextIter iter = startiter; while (gtk_text_iter_in_range(&iter, &startiter, &enditer)) { bool upper = g_unichar_isupper(gtk_text_iter_get_char(&iter)); capspattern.push_back(upper); if (upper) capscount++; gtk_text_iter_forward_char(&iter); } // No further checking if words are too short. if (capspattern.size() < 2) continue; // No further checking if only small letters. if (capscount == 0) continue; // No further checking if all capitals. if (capscount == capspattern.size()) continue; // No further checking if first letter capitalized only. if ((capspattern[0]) && (capscount == 1)) continue; // Ok, there could be a problem of mixed capitalization. // Get the prefix before the first capital, and the suffix after it. ustring word = gtk_text_iter_get_text(&startiter, &enditer); ustring uncapitalized_prefix; ustring capitalized_suffix; for (unsigned int i = 1; i < capspattern.size(); i++) { if (capspattern[i]) { uncapitalized_prefix = word.substr(0, i); capitalized_suffix = word.substr(i, word.length() - i); break; } } // See whether the suffix is properly capitalized. unsigned int suffix_capital_count = 0; for (unsigned int i = 0; i < capitalized_suffix.length(); i++) { if (g_unichar_isupper(g_utf8_get_char(capitalized_suffix.substr(i, 1).c_str()))) suffix_capital_count++; } bool suffix_properly_capitalized = false; if (suffix_capital_count == 1) suffix_properly_capitalized = true; if (suffix_capital_count == capitalized_suffix.length()) suffix_properly_capitalized = true; // Give message and continue if capitalization error in suffix, but only // if this so-called wrongly capitalized suffix has not been approved af. if (!suffix_properly_capitalized) { if (capitalized_suffixes.find(capitalized_suffix) == capitalized_suffixes.end()) { mixed_capitalization_message(word); continue; } } // No further checking if this uncapitalized prefix is in the list, // or any is allowed. if (uncapitalized_prefixes.find(uncapitalized_prefix) != uncapitalized_prefixes.end()) continue; if (allow_any_uncapitalized_prefixes) continue; // Ok, not in the list. Try again with lower case initial. ustring initial = uncapitalized_prefix.substr(0, 1); initial = initial.casefold(); uncapitalized_prefix.replace(0, 1, initial); if (uncapitalized_prefixes.find(uncapitalized_prefix) != uncapitalized_prefixes.end()) continue; // No further checking if the suffix is in the list of approved suffixes. if (capitalized_suffixes.find(capitalized_suffix) != capitalized_suffixes.end()) continue; // Ok, not found, but it could be this suffix is in all capitals. Handle that. initial = capitalized_suffix.substr(0, 1); capitalized_suffix.erase(0, 1); capitalized_suffix = capitalized_suffix.casefold(); capitalized_suffix.insert(0, initial); if (capitalized_suffixes.find(capitalized_suffix) != capitalized_suffixes.end()) continue; // Ok, it appears we've got an error here -> give message. mixed_capitalization_message(word); } // Free memory g_object_unref(textbuffer); }
static void check_range (GeditAutomaticSpellChecker *spell, GtkTextIter start, GtkTextIter end, gboolean force_all) { /* we need to "split" on word boundaries. * luckily, Pango knows what "words" are * so we don't have to figure it out. */ GtkTextIter wstart; GtkTextIter wend; GtkTextIter cursor; GtkTextIter precursor; gboolean highlight; /* g_print ("Check range: [%d - %d]\n", gtk_text_iter_get_offset (&start), gtk_text_iter_get_offset (&end)); */ if (gtk_text_iter_inside_word (&end)) gtk_text_iter_forward_word_end (&end); if (!gtk_text_iter_starts_word (&start)) { if (gtk_text_iter_inside_word (&start) || gtk_text_iter_ends_word (&start)) { gtk_text_iter_backward_word_start (&start); } else { /* if we're neither at the beginning nor inside a word, * me must be in some spaces. * skip forward to the beginning of the next word. */ if (gtk_text_iter_forward_word_end (&start)) gtk_text_iter_backward_word_start (&start); } } gtk_text_buffer_get_iter_at_mark (GTK_TEXT_BUFFER (spell->doc), &cursor, gtk_text_buffer_get_insert (GTK_TEXT_BUFFER (spell->doc))); precursor = cursor; gtk_text_iter_backward_char (&precursor); highlight = gtk_text_iter_has_tag (&cursor, spell->tag_highlight) || gtk_text_iter_has_tag (&precursor, spell->tag_highlight); gtk_text_buffer_remove_tag (GTK_TEXT_BUFFER (spell->doc), spell->tag_highlight, &start, &end); /* Fix a corner case when replacement occurs at beginning of buffer: * An iter at offset 0 seems to always be inside a word, * even if it's not. Possibly a pango bug. */ if (gtk_text_iter_get_offset (&start) == 0) { gtk_text_iter_forward_word_end(&start); gtk_text_iter_backward_word_start(&start); } wstart = start; while (gedit_spell_utils_skip_no_spell_check (&wstart, &end) && gtk_text_iter_compare (&wstart, &end) < 0) { gboolean inword; /* move wend to the end of the current word. */ wend = wstart; gtk_text_iter_forward_word_end (&wend); inword = (gtk_text_iter_compare (&wstart, &cursor) < 0) && (gtk_text_iter_compare (&cursor, &wend) <= 0); if (inword && !force_all) { /* this word is being actively edited, * only check if it's already highligted, * otherwise defer this check until later. */ if (highlight) check_word (spell, &wstart, &wend); else spell->deferred_check = TRUE; } else { check_word (spell, &wstart, &wend); spell->deferred_check = FALSE; } /* now move wend to the beginning of the next word, */ gtk_text_iter_forward_word_end (&wend); gtk_text_iter_backward_word_start (&wend); /* make sure we've actually advanced * (we don't advance in some corner cases), */ if (gtk_text_iter_equal (&wstart, &wend)) break; /* we're done in these cases.. */ /* and then pick this as the new next word beginning. */ wstart = wend; } }
static void WhatCheck (GtkMenuItem *item, gpointer data) { GtkWidget *dialog; GtkTextIter start, end; char *word; gunichar *wword; // Znajdujemy pozycję kursora gtk_text_buffer_get_iter_at_mark(editor_buf, &start, gtk_text_buffer_get_insert(editor_buf)); // Jeśli nie wewnątrz słowa, kończymy if (!gtk_text_iter_inside_word(&start)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "Kursor musi być w środku słowa"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); return; } // Znajdujemy początek i koniec słowa, a potem samo słowo end = start; gtk_text_iter_backward_word_start(&start); gtk_text_iter_forward_word_end(&end); word = gtk_text_iter_get_text(&start, &end); // Zamieniamy na wide char (no prawie) wword = g_utf8_to_ucs4_fast(word, -1, NULL); if(update_actual_dict() < 0) return; // Sprawdzamy if (dictionary_find(dict, (wchar_t *)wword)) { dialog = gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Wszystko w porządku,\nśpij spokojnie"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } else { // Czas korekty GtkWidget *vbox, *label, *combo; struct word_list hints; int i; wchar_t **words; dictionary_hints(dict, (wchar_t *)wword, &hints); words = word_list_get(&hints); dialog = gtk_dialog_new_with_buttons("Korekta", NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); // W treści dialogu dwa elementy vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst label = gtk_label_new("Coś nie tak, mam kilka propozycji"); gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 1); // Spuszczane menu combo = gtk_combo_box_text_new(); for (i = 0; i < word_list_size(&hints); i++) { // Combo box lubi mieć Gtk char *uword = g_ucs4_to_utf8((gunichar *)words[i], -1, NULL, NULL, NULL); // Dodajemy kolejny element gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), uword); g_free(uword); } //gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo),"<inne...>"); gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); gtk_box_pack_start(GTK_BOX(vbox), combo, FALSE, FALSE, 1); gtk_widget_show(combo); char *korekta, *question; GtkWidget *ask_dialog, *ask_vbox, *ask_label; switch (gtk_dialog_run(GTK_DIALOG(dialog))) { case GTK_RESPONSE_ACCEPT: korekta = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); // Usuwamy stare gtk_text_buffer_delete(editor_buf, &start, &end); // Wstawiamy nowe gtk_text_buffer_insert(editor_buf, &start, korekta, -1); g_free(korekta); break; case GTK_RESPONSE_REJECT: question = "Czy chcesz dodać to słowo do słownika?"; ask_dialog = gtk_dialog_new_with_buttons(question, NULL, 0, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL); ask_vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); // Tekst ask_label = gtk_label_new("Coś nie tak, mam kilka propozycji"); gtk_widget_show(ask_label); gtk_box_pack_start(GTK_BOX(ask_vbox), ask_label, FALSE, FALSE, 1); // Jeśli chiciał dodać nowe słowo do słownika to dodamy i zapiszemy if (gtk_dialog_run(GTK_DIALOG(ask_dialog)) == GTK_RESPONSE_ACCEPT) { dictionary_insert(dict, (wchar_t *)wword); dictionary_save_lang(dict, dict_location); } gtk_widget_destroy(ask_dialog); break; } gtk_widget_destroy(dialog); } }
static void add_chat_msg(GtTwitchChatView* self, const gchar* sender, const gchar* colour, const gchar* msg, GList* emotes, gint user_modes) { GtTwitchChatViewPrivate* priv = gt_twitch_chat_view_get_instance_private(self); GtkTextTag* sender_colour_tag = NULL; gint offset = 0; gtk_text_buffer_get_end_iter(priv->chat_buffer, &priv->bottom_iter); if (!colour || strlen(colour) < 1) //TODO: Set random colour instead of just black colour = get_default_chat_colour(sender); sender_colour_tag = gtk_text_tag_table_lookup(priv->tag_table, colour); if (!sender_colour_tag) { sender_colour_tag = gtk_text_tag_new(colour); g_object_set(sender_colour_tag, "foreground", colour, "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_tag_table_add(priv->tag_table, sender_colour_tag); } offset = strlen(sender) + 2; //TODO: Cleanup? #define INSERT_USER_MOD_PIXBUF(mode, name) \ if (user_modes & mode) \ { \ gtk_text_buffer_insert_pixbuf(priv->chat_buffer, &priv->bottom_iter, priv->chat_badges->name); \ gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, " ", -1); \ gtk_text_iter_forward_chars(&priv->bottom_iter, 2); \ offset += 2; \ } \ INSERT_USER_MOD_PIXBUF(USER_MODE_SUBSCRIBER, subscriber); INSERT_USER_MOD_PIXBUF(USER_MODE_TURBO, turbo); INSERT_USER_MOD_PIXBUF(USER_MODE_GLOBAL_MOD, global_mod); INSERT_USER_MOD_PIXBUF(USER_MODE_BROADCASTER, broadcaster); INSERT_USER_MOD_PIXBUF(USER_MODE_STAFF, staff); INSERT_USER_MOD_PIXBUF(USER_MODE_ADMIN, admin); INSERT_USER_MOD_PIXBUF(USER_MODE_MOD, mod); #undef INSERT_USER_MOD_PIXBUF gtk_text_buffer_insert_with_tags(priv->chat_buffer, &priv->bottom_iter, sender, -1, sender_colour_tag, NULL); gtk_text_iter_forward_word_end(&priv->bottom_iter); gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, ": ", -1); gtk_text_iter_forward_chars(&priv->bottom_iter, 2); insert_message_with_emotes(priv->chat_buffer, &priv->bottom_iter, emotes, msg, offset); gtk_text_iter_forward_to_line_end(&priv->bottom_iter); gtk_text_buffer_insert(priv->chat_buffer, &priv->bottom_iter, "\n", -1); gtk_text_buffer_move_mark(priv->chat_buffer, priv->bottom_mark, &priv->bottom_iter); gtk_text_view_scroll_mark_onscreen(GTK_TEXT_VIEW(priv->chat_view), priv->bottom_mark); }
bool search_in_bibledit_word_boundaries_match(const ustring & text, const ustring & searchword, bool matchbeginning, bool matchending, bool globbing) // Does the word boundary matching. { /* Deal with matching the start of a word and/or of the end. There are four cases here. 1. Match word start only. 2. Match word end only. 3. Both match start end end of a word, which implies "whole word". 4. No matching at all. Boundary resolution is handled by pango_break(). Textual boundaries such as word boundaries and line boundaries are determined for each item. In most cases a general algorithm suffices for this process, but in some cases a language module will override the generic algorithm with a more specific one. It seems to be easier programming to use GtkTextIter and GtkTextBuffer, rather than pango_break() directly. */ // Whether the word matches. bool match = false; // Textbuffer for determining word boundaries. GtkTextBuffer *textbuffer = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(textbuffer, text.c_str(), -1); // Iterators needed. GtkTextIter startiter; GtkTextIter enditer; // Store segments of text to compare against. vector < ustring > segments; // Deal with case one: Match word start only. if (matchbeginning && !matchending) { // Create a patternword for the glob-style pattern matching. ustring patternword = searchword + "*"; // Collect all strings starting with a word. gtk_text_buffer_get_start_iter(textbuffer, &startiter); gtk_text_buffer_get_end_iter(textbuffer, &enditer); while (gtk_text_iter_forward_word_end(&startiter)) { gtk_text_iter_backward_word_start(&startiter); segments.push_back(gtk_text_iter_get_text(&startiter, &enditer)); gtk_text_iter_forward_word_end(&startiter); } // See whether the word is in it. for (unsigned int i2 = 0; i2 < segments.size(); i2++) { if (globbing) { // Glob-style pattern matching. if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) { match = true; break; } } else { // Straight compare. if (segments[i2].find(searchword) == 0) { match = true; break; } } } } // Deal with case two: Match word end only. if (!matchbeginning && matchending) { // Create a patternword for the glob-style pattern matching. ustring patternword = "*" + searchword; // Collect all strings ending with a word. gtk_text_buffer_get_start_iter(textbuffer, &startiter); gtk_text_buffer_get_start_iter(textbuffer, &enditer); while (gtk_text_iter_forward_word_end(&enditer)) { segments.push_back(gtk_text_iter_get_text(&startiter, &enditer)); } // See whether the word is in it. for (unsigned int i2 = 0; i2 < segments.size(); i2++) { if (globbing) { // Glob-style pattern matching. if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) { match = true; break; } } else { // Straight compare. size_t matchposition; matchposition = segments[i2].length() - searchword.length(); // Negative match positions cause a false match. Solve that here. matchposition = CLAMP(matchposition, 0, 99999999); if (segments[i2].find(searchword) == matchposition) { match = true; break; } } } } // Deal with case three: Match both word start and end. // Interpreted as "match whole word". if (matchbeginning && matchending) { // Create a patternword for the glob-style pattern matching. ustring patternword = searchword; // Collect all whole words. gtk_text_buffer_get_start_iter(textbuffer, &enditer); while (gtk_text_iter_forward_word_end(&enditer)) { startiter = enditer; gtk_text_iter_backward_word_start(&startiter); segments.push_back(gtk_text_iter_get_text(&startiter, &enditer)); } // See whether the word is in it. for (unsigned int i2 = 0; i2 < segments.size(); i2++) { if (globbing) { // Glob-style pattern matching. if (g_pattern_match_simple(patternword.c_str(), segments[i2].c_str())) { match = true; break; } } else { // Straight compare. if (segments[i2] == searchword) { match = true; break; } } } } // Case four: Nothing to test, so set found to true. if (!matchbeginning && !matchending) match = true; // Free memory. g_object_unref(textbuffer); // Return whether match. return match; }
void load_file (const gchar *demoname, const gchar *filename) { GtkTextBuffer *info_buffer, *source_buffer; GtkTextIter start, end; char *resource_filename; GError *err = NULL; int state = 0; gboolean in_para = 0; gchar **lines; GBytes *bytes; gint i; if (!g_strcmp0 (current_file, filename)) return; remove_data_tabs (); add_data_tab (demoname); g_free (current_file); current_file = g_strdup (filename); info_buffer = gtk_text_buffer_new (NULL); gtk_text_buffer_create_tag (info_buffer, "title", "font", "Sans 18", "pixels-below-lines", 10, NULL); source_buffer = gtk_text_buffer_new (NULL); gtk_text_buffer_create_tag (source_buffer, "source", "font", "monospace", NULL); gtk_text_buffer_create_tag (source_buffer, "comment", "foreground", "DodgerBlue", NULL); gtk_text_buffer_create_tag (source_buffer, "type", "foreground", "ForestGreen", NULL); gtk_text_buffer_create_tag (source_buffer, "string", "foreground", "RosyBrown", "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_create_tag (source_buffer, "control", "foreground", "purple", NULL); gtk_text_buffer_create_tag (source_buffer, "preprocessor", "style", PANGO_STYLE_OBLIQUE, "foreground", "burlywood4", NULL); gtk_text_buffer_create_tag (source_buffer, "function", "weight", PANGO_WEIGHT_BOLD, "foreground", "DarkGoldenrod4", NULL); resource_filename = g_strconcat ("/sources/", filename, NULL); bytes = g_resources_lookup_data (resource_filename, 0, &err); g_free (resource_filename); if (bytes == NULL) { g_warning ("Cannot open source for %s: %s\n", filename, err->message); g_error_free (err); return; } lines = g_strsplit (g_bytes_get_data (bytes, NULL), "\n", -1); g_bytes_unref (bytes); gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0); for (i = 0; lines[i] != NULL; i++) { gchar *p; gchar *q; gchar *r; /* Make sure \r is stripped at the end for the poor windows people */ lines[i] = g_strchomp (lines[i]); p = lines[i]; switch (state) { case 0: /* Reading title */ while (*p == '/' || *p == '*' || g_ascii_isspace (*p)) p++; r = p; while (*r != '\0') { while (*r != '/' && *r != ':' && *r != '\0') r++; if (*r == '/') { r++; p = r; } if (r[0] == ':' && r[1] == ':') *r = '\0'; } q = p + strlen (p); while (q > p && g_ascii_isspace (*(q - 1))) q--; if (q > p) { int len_chars = g_utf8_pointer_to_offset (p, q); end = start; g_assert (strlen (p) >= q - p); gtk_text_buffer_insert (info_buffer, &end, p, q - p); start = end; gtk_text_iter_backward_chars (&start, len_chars); gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end); start = end; while (*p && *p != '\n') p++; state++; } break; case 1: /* Reading body of info section */ while (g_ascii_isspace (*p)) p++; if (*p == '*' && *(p + 1) == '/') { gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0); state++; } else { int len; while (*p == '*' || g_ascii_isspace (*p)) p++; len = strlen (p); while (g_ascii_isspace (*(p + len - 1))) len--; if (len > 0) { if (in_para) gtk_text_buffer_insert (info_buffer, &start, " ", 1); g_assert (strlen (p) >= len); gtk_text_buffer_insert (info_buffer, &start, p, len); in_para = 1; } else { gtk_text_buffer_insert (info_buffer, &start, "\n", 1); in_para = 0; } } break; case 2: /* Skipping blank lines */ while (g_ascii_isspace (*p)) p++; if (*p) { p = lines[i]; state++; /* Fall through */ } else break; case 3: /* Reading program body */ gtk_text_buffer_insert (source_buffer, &start, p, -1); if (lines[i+1] != NULL) gtk_text_buffer_insert (source_buffer, &start, "\n", 1); break; } } g_strfreev (lines); fontify (source_buffer); gtk_text_buffer_create_tag (source_buffer, "top-margin", "pixels-above-lines", 20, NULL); gtk_text_buffer_get_start_iter (source_buffer, &start); end = start; gtk_text_iter_forward_word_end (&end); gtk_text_buffer_apply_tag_by_name (source_buffer, "top-margin", &start, &end); gtk_text_buffer_create_tag (source_buffer, "bottom-margin", "pixels-below-lines", 20, NULL); gtk_text_buffer_get_end_iter (source_buffer, &end); start = end; gtk_text_iter_backward_word_start (&start); gtk_text_buffer_apply_tag_by_name (source_buffer, "bottom-margin", &start, &end); gtk_text_view_set_buffer (GTK_TEXT_VIEW (source_view), source_buffer); g_object_unref (source_buffer); gtk_text_buffer_create_tag (info_buffer, "top-margin", "pixels-above-lines", 20, NULL); gtk_text_buffer_get_start_iter (info_buffer, &start); end = start; gtk_text_iter_forward_word_end (&end); gtk_text_buffer_apply_tag_by_name (info_buffer, "top-margin", &start, &end); gtk_text_buffer_create_tag (info_buffer, "bottom-margin", "pixels-below-lines", 20, NULL); gtk_text_buffer_get_end_iter (info_buffer, &end); start = end; gtk_text_iter_backward_word_start (&start); gtk_text_buffer_apply_tag_by_name (info_buffer, "bottom-margin", &start, &end); gtk_text_view_set_buffer (GTK_TEXT_VIEW (info_view), info_buffer); g_object_unref (info_buffer); }
void CheckCapitalization::check_capitalization(vector < int >&chapters, vector < ustring > &verses, ustring & text, vector < size_t > &pointers, bool end_check) /* Check capitalization in text. If "end_check" is true, it also check for final sentence closing. */ { /* Note that this at first used gtk_text_iter_starts_sentence (&iter) and gtk_text_iter_ends_sentence (&iter), but these functions are not good enough, because do not work in several cases, like e.g. in the following line, it does not indicate the end of the sentence: As soon as the leaders of the tribes of Israel took their places, the Israelites said, “How could such a horrible thing happen?" Therefore we use other means to check sentences. */ // No check if there's no text. if (trim(text).empty()) return; // Some variables needed. bool expect_capital_now = false; bool expect_capital_caused_by_reference = false; gunichar previous_char = 0; int localchapter = 0; ustring localverse = "0"; GtkTextBuffer *textbuffer; textbuffer = gtk_text_buffer_new(NULL); gtk_text_buffer_set_text(textbuffer, text.c_str(), -1); GtkTextIter iter; gtk_text_buffer_get_start_iter(textbuffer, &iter); bool going = true; while (going) { // Get the unicode character. gunichar unichar = gtk_text_iter_get_char(&iter); // See whether to expect a capital now. if (punctuation_followed_by_capitals_set.find(unichar) != punctuation_followed_by_capitals_set.end()) { // Ok, expect capital. expect_capital_now = true; expect_capital_caused_by_reference = false; // Was this expectation caused by a reference? if (is_reference(iter)) expect_capital_caused_by_reference = true; } // If we expect a capital, and we find one, no longer look for one. if (expect_capital_now) { if (g_unichar_isupper(unichar)) { expect_capital_now = false; } } // If we expect a capital, and we get lower case, that might be trouble. if (expect_capital_now) { if (g_unichar_islower(unichar)) { // There is no trouble if it follows a character after which to ignore lower case. if (ignore_lower_case_following_set.find(previous_char) != ignore_lower_case_following_set.end()) { expect_capital_now = false; } // If the lowercase character follows an abbreviation, there is no trouble either. GtkTextIter iter2 = iter; gtk_text_iter_backward_word_start(&iter2); GtkTextIter iter3 = iter2; gtk_text_iter_forward_word_end(&iter3); gtk_text_iter_forward_char(&iter3); ustring abbreviation = gtk_text_iter_get_text(&iter2, &iter3); if (abbreviations.find(abbreviation) != abbreviations.end()) { expect_capital_now = false; } // If it follows a reference, there is no trouble. if (expect_capital_caused_by_reference) expect_capital_now = false; // Ok, give message. if (expect_capital_now) { // Determine chapter and verse. get_chapter_and_verse(chapters, verses, pointers, iter, localchapter, localverse); message(book, localchapter, localverse, _("Capital expected: ") + get_context(iter)); } // Only give one message about missing capitals in this context. expect_capital_now = false; } } // Store this characters as the previous characters for the next round. if (g_unichar_isgraph(unichar)) previous_char = unichar; // Next round. going = gtk_text_iter_forward_char(&iter); } // The sentence should be ended with proper punctuation. if (end_check) { if (expect_capital_now) if (g_unichar_isdigit(previous_char)) expect_capital_now = false; if (!expect_capital_now) { message(book, chapter, verse, _("Unended sentence: ") + get_context(iter)); } } // Free memory g_object_unref(textbuffer); }