Відео: GTK using Code Blocks Tutorial for BEGINNERS!
Дана стаття присвячена використанню движка перевірки правопису в графічному інтерфейсі. «Движок» тут в однині, тому що обидва популярних движка: Aspell і Hunspell - ми вже розглянули і могли переконатися, що вони дуже схожі по набору функцій і підходу до роботи. Тому в прикладах до цієї статті там, де треба викликати функції конкретного движка, буде використаний псевдокод.
До речі, в будь-якому випадку корисно написати свій клас-оболонку або набір функцій-обгорток, уклавши в них виклик коштів конкретного движка. Чому? Якщо ви забажаєте раптом змінити один движок на інший, необхідно буде переписати лише «прошарок», не змінюючи решти код. В ООП взагалі добре б зробити повністю абстрактний клас перевірки правопису, а потім успадкувати від нього втілення якогось движка або движків. Таким чином, «переписування» прошарку перетвориться в «дописування», і з`явиться можливість використовувати навіть кілька двигунів одночасно, задіявши механізм поліморфізму: оголосили змінну типу класу-предка, привласнили їй екземпляр класу-нащадка - і вперед.
Отже, перевірку правопису умовно розділимо на фонову та активну. Фонова - коли користувач набирає текст, а помилкові слова якось оформляються - найчастіше підкреслюються червоною лінією. Активна - коли користувач бачить вікно з інтерфейсом, що дає можливість робити послідовний перебір слів, вибір варіантів заміни тощо.
У першому випадку алгоритм приблизно такий: після будь-якої правки беремо поточний слово і перевіряємо його правопис. Якщо слова в словнику немає - підкреслюємо слово. Коли саме здійснюється перевірка: за таймером через певний проміжок часу або відразу після натискання клавіш - справа стороннє. Активна форма перевірки має на увазі послідовний перебір тексту по словам. Текст надається текстовим віджетом. Для прикладу в цій статті об`єднаємо обидві форми перевірки. У нас буде якийсь віджет з текстом, ми перебираємо в ньому все слова і підкреслюємо помилкові. Так ми проілюструємо обидва важливі механізми: і підкреслення, і перебір. Приклади будуть засновані на бібліотеках GTK + 2 (для мови С) і Qt (звичайно ж, для C ++).
Перевірка в GTK +
Спочатку звернемося до GTK +. Припускаю, що ви маєте деякий досвід роботи з її текстовими віджетами, зокрема з парою GtkTextBuffer і GtkTextView. Викладені нижче алгоритми працюють і з движком GtkSourceView (https://projects.gnome.org/gtksourceview), але з деякими застереженнями (різниця в типах). У GTK + підсвічування як візуальний засіб грунтується на застосуванні тегів. Тому спочатку - таблиця тегів: створюємо тег, призначаємо йому властивості (колір тощо), поміщаємо в таблицю, а таблицю призначаємо буферу GtkTextBuffer. Функція створення такої таблиці:
GtkTextTagTable * create _ tags _ table (void) { // створюємо тег з назвою "spell _ err" GtkTextTag * tag _ spell _ err = gtk _ text _ tag _ new ( "spell _ err") - // призначаємо йому червоний колір g_ object _ set (G_ OBJECT (tag _ spell _ err), "foreground", "# Ff0000", NULL); // ... і спосіб підкреслення (PANGO _ UNDERLINE _ ERROR) g_ object _ set (G_ OBJECT (tag _ spell _ err), "underline", PANGO _ UNDERLINE _ ERROR, NULL); // тепер створюємо таблицю GtkTextTagTable * tags _ table = gtk _ text _ tag _ table _ new () - // і поміщаємо в неї створений тег gtk _text _tag _table _add (tags _table, tag _spell _err); // всі, повертаємо таблицю return tags _ table; }
Тепер створимо пару буфер-віджет GtkTextBuffer / GtkTextView і прив`яжемо до неї таблицю:
GtkTextView * text_view = gtk _ text _ view _ new () - GtkTextBuffer * text _ buffer = gtk _ text _ buffer _ new (create _ tags _ table ()); gtk _text _view _set _buffer (text _view, text _buffer) -
Потім, в ході підготовки до перевірки правопису, нам знадобиться службова функція, що видаляє з буфера всю колірну розмітку, задану тегом під ім`ям «spell_err». Але спочатку напишемо макрос, який підставляє замість себе код, що викликає функції для отримання примірника тега з таблиці (по заданому імені). Робимо його макросом, тому що він ще стане в нагоді.
#define get _ tag _ by _ name (text _ buffer, name)
gtk _text _tag _table _lookup ( gtk _text _ buffer _ get _tag _table (text _ buffer), name) Тепер - вже згадана функція: void hide _ error _ marks (GtkTextBuffer * text _ buffer) { GtkTextIter itstart, itend; gtk _ text _ buffer _ get _ bounds (text _ buffer, Sitstart, Sitend); gtk _text _buffer _remove _tag (text _buffer, get _tag _by _name (text _ buffer, "spell _err"), Sitstart, Sitend); }
У ітератори itstart і itend ми отримуємо початок і кінець буфера. Потім викликаємо gtk_text_buffer_remove_tag, щоб видалити з буфера такий-то тег в межах таких-то ітераторів.
Приступимо до написання самої функції перевірки правопису. Тут буде використана тільки одна функція на псевдокоді - ПРОВЕРІТЬ_ПРАВОПІСАНІЕ (gchar * text) - аналог функції перевірки правопису конкретного движка.
void do _ hl _ spell _ check (GtkTextBuffer * text _ buffer) { GtkTextIter iter- GtkTextIter a- GtkTextIter b; gchar * p = NULL- gchar * text; // видаляємо всю «помилкову» підсвічування, якщо // така вже присутній: hide _ error _ marks (text _ buffer); // отримуємо итератор початку буфера: gtk _ text _ buffer _ get _ iter _ at _ offset (text _ buffer, Siter, 0); // якщо на Ітератор iter починається слово, // присвоюємо Ітератор a положення ітератора iter: if (gtk _ text _ iter _ starts _ word (Siter)) a = iter; // входимо в цикл перевірки, з Послівний перебором // вмісту буфера: do { if (gtk _text _iter _starts _word (Siter)) { b = iter; if (gtk _text _iter _backward _char (Sb)) a = iter; if (gtk _text _iter _forward _word _end (Siter)) if (gtk _text _iter _ends _word (Siter)) { // отримуємо поточний (в переборі) слово: text = gtk _ text _ iter _ get _ slice (Sa, Siter); // якщо воно не NULL if (text) { // і якщо довжина його більше 1 if (g _ utf 8 _ strlen (text, -1) gt; 1) { // то перевіряємо правопис: if (! ПЕРЕВІРИТИ _ ПРАВОПИС (text)) { // при помилковості слова застосовуємо тег // до тексту між поточними ітераторами: gtk _ text _ buffer _ apply _ tag ( text _ buffer, get _ tag _ by _ name (Text _ buffer, "spell _ err"), Sa, Siter) - g _ free (text) - continue; } } g _ free (text); } } } } while (gtk _text _iter _forward _char (Siter)); }
Ви не програміст, а лютий шанувальник сучасних технологій? Що ж, в такому разі я рекомендую Вам Iphone 6 купити (https://trafficcost.ru/541fe9128b30a8f7368b4575/subaccount)! Це найбільш технологічне мобільне електронний пристрій, який Ви тільки можете знайти у вільному продажу!