1/*
2 *  Copyright (C) 2011 Igalia S.L.
3 *
4 *  This library is free software; you can redistribute it and/or
5 *  modify it under the terms of the GNU Lesser General Public
6 *  License as published by the Free Software Foundation; either
7 *  version 2 of the License, or (at your option) any later version.
8 *
9 *  This library is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 *  Lesser General Public License for more details.
13 *
14 *  You should have received a copy of the GNU Lesser General Public
15 *  License along with this library; if not, write to the Free Software
16 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include "config.h"
20#include "webkitspellcheckerenchant.h"
21
22#if ENABLE(SPELLCHECK)
23
24#include "TextCheckerEnchant.h"
25#include "webkitspellchecker.h"
26#include <gtk/gtk.h>
27#include <wtf/OwnPtr.h>
28#include <wtf/gobject/GOwnPtr.h>
29#include <wtf/text/CString.h>
30
31using namespace WebCore;
32
33/**
34 * SECTION:webkitspellcheckerenchant
35 * @short_description: the default spell checking implementation for WebKitGTK+.
36 *
37 * #WebKitSpellCheckerEnchant is the default spell checking implementation for
38 * WebKitGTK+. It uses the Enchant dictionaries installed on the system to
39 * correct spelling.
40 */
41
42struct _WebKitSpellCheckerEnchantPrivate {
43    OwnPtr<TextCheckerEnchant> textCheckerEnchant;
44};
45
46static void webkit_spell_checker_enchant_spell_checker_interface_init(WebKitSpellCheckerInterface* checkerInterface);
47
48G_DEFINE_TYPE_WITH_CODE(WebKitSpellCheckerEnchant, webkit_spell_checker_enchant, G_TYPE_OBJECT,
49                        G_IMPLEMENT_INTERFACE(WEBKIT_TYPE_SPELL_CHECKER,
50                                              webkit_spell_checker_enchant_spell_checker_interface_init))
51
52static void webkit_spell_checker_enchant_finalize(GObject* object)
53{
54    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(object)->priv;
55    priv->~WebKitSpellCheckerEnchantPrivate();
56}
57
58static void webkit_spell_checker_enchant_class_init(WebKitSpellCheckerEnchantClass* klass)
59{
60    GObjectClass* objectClass = G_OBJECT_CLASS(klass);
61    objectClass->finalize = webkit_spell_checker_enchant_finalize;
62    g_type_class_add_private(klass, sizeof(WebKitSpellCheckerEnchantPrivate));
63}
64
65static void webkit_spell_checker_enchant_init(WebKitSpellCheckerEnchant* checker)
66{
67    WebKitSpellCheckerEnchantPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(checker, WEBKIT_TYPE_SPELL_CHECKER_ENCHANT, WebKitSpellCheckerEnchantPrivate);
68    checker->priv = priv;
69    new (priv) WebKitSpellCheckerEnchantPrivate();
70
71    priv->textCheckerEnchant = TextCheckerEnchant::create();
72}
73
74static void checkSpellingOfString(WebKitSpellChecker* checker, const char* string, int* misspellingLocation, int* misspellingLength)
75{
76    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(checker)->priv;
77    priv->textCheckerEnchant->checkSpellingOfString(String::fromUTF8(string), *misspellingLocation, *misspellingLength);
78}
79
80static char** getGuessesForWord(WebKitSpellChecker* checker, const char* word, const char* context)
81{
82    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(checker)->priv;
83
84    Vector<String> guesses = priv->textCheckerEnchant->getGuessesForWord(String::fromUTF8(word));
85
86    if (guesses.isEmpty())
87        return 0;
88
89    int i = 0;
90    int numberOfGuesses = guesses.size();
91    char** guessesArray = static_cast<char**>(g_malloc0((numberOfGuesses + 1) * sizeof(char*)));
92    for (Vector<String>::const_iterator iter = guesses.begin(); iter != guesses.end(); ++iter)
93        guessesArray[i++] = g_strdup(iter->utf8().data());
94    guessesArray[i] = 0;
95
96    return guessesArray;
97}
98
99static void updateSpellCheckingLanguages(WebKitSpellChecker* checker, const char* languages)
100{
101    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(checker)->priv;
102
103    Vector<String> languagesVector;
104    String::fromUTF8(languages).split(static_cast<UChar>(','), languagesVector);
105    priv->textCheckerEnchant->updateSpellCheckingLanguages(languagesVector);
106}
107
108static char* getAutocorrectSuggestionsForMisspelledWord(WebKitSpellChecker* checker, const char* word)
109{
110    return 0;
111}
112
113static void learnWord(WebKitSpellChecker* checker, const char* word)
114{
115    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(checker)->priv;
116    priv->textCheckerEnchant->learnWord(String::fromUTF8(word));
117}
118
119static void ignoreWord(WebKitSpellChecker* checker, const char* word)
120{
121    WebKitSpellCheckerEnchantPrivate* priv = WEBKIT_SPELL_CHECKER_ENCHANT(checker)->priv;
122    priv->textCheckerEnchant->ignoreWord(String::fromUTF8(word));
123}
124
125static void webkit_spell_checker_enchant_spell_checker_interface_init(WebKitSpellCheckerInterface* checkerInterface)
126{
127    checkerInterface->check_spelling_of_string = checkSpellingOfString;
128    checkerInterface->get_guesses_for_word = getGuessesForWord;
129    checkerInterface->update_spell_checking_languages = updateSpellCheckingLanguages;
130    checkerInterface->get_autocorrect_suggestions_for_misspelled_word = getAutocorrectSuggestionsForMisspelledWord;
131    checkerInterface->learn_word = learnWord;
132    checkerInterface->ignore_word = ignoreWord;
133}
134
135#endif /* ENABLE(SPELLCHECK) */
136
137