File indexing completed on 2024-05-05 04:01:24

0001 /*
0002  * kspell_aspelldict.cpp
0003  *
0004  * SPDX-FileCopyrightText: 2003 Zack Rusin <zack@kde.org>
0005  *
0006  * SPDX-License-Identifier: LGPL-2.1-or-later
0007  */
0008 #include "aspelldict.h"
0009 
0010 #include "aspell_debug.h"
0011 
0012 #ifdef Q_OS_WIN
0013 #include <QCoreApplication>
0014 #endif
0015 
0016 using namespace Sonnet;
0017 
0018 ASpellDict::ASpellDict(const QString &lang)
0019     : SpellerPlugin(lang)
0020 {
0021     m_config = new_aspell_config();
0022     aspell_config_replace(m_config, "lang", lang.toLatin1().constData());
0023     /* All communication with Aspell is done in UTF-8 */
0024     /* For reference, please look at BR#87250         */
0025     aspell_config_replace(m_config, "encoding", "utf-8");
0026 
0027 #ifdef Q_OS_WIN
0028     aspell_config_replace(m_config, "data-dir", QString::fromLatin1("%1/data/aspell").arg(QCoreApplication::applicationDirPath()).toLatin1().constData());
0029     aspell_config_replace(m_config, "dict-dir", QString::fromLatin1("%1/data/aspell").arg(QCoreApplication::applicationDirPath()).toLatin1().constData());
0030 #endif
0031 
0032     AspellCanHaveError *possible_err = new_aspell_speller(m_config);
0033 
0034     if (aspell_error_number(possible_err) != 0) {
0035         qCWarning(SONNET_LOG_ASPELL) << "aspell error: " << aspell_error_message(possible_err);
0036     } else {
0037         m_speller = to_aspell_speller(possible_err);
0038     }
0039 }
0040 
0041 ASpellDict::~ASpellDict()
0042 {
0043     delete_aspell_speller(m_speller);
0044     delete_aspell_config(m_config);
0045 }
0046 
0047 bool ASpellDict::isCorrect(const QString &word) const
0048 {
0049     /* ASpell is expecting length of a string in char representation */
0050     /* word.length() != word.toUtf8().length() for nonlatin strings    */
0051     if (!m_speller) {
0052         return false;
0053     }
0054     int correct = aspell_speller_check(m_speller, word.toUtf8().constData(), word.toUtf8().length());
0055     return correct;
0056 }
0057 
0058 QStringList ASpellDict::suggest(const QString &word) const
0059 {
0060     if (!m_speller) {
0061         return QStringList();
0062     }
0063 
0064     /* ASpell is expecting length of a string in char representation */
0065     /* word.length() != word.toUtf8().length() for nonlatin strings    */
0066     const AspellWordList *suggestions = aspell_speller_suggest(m_speller, word.toUtf8().constData(), word.toUtf8().length());
0067 
0068     AspellStringEnumeration *elements = aspell_word_list_elements(suggestions);
0069 
0070     QStringList qsug;
0071     const char *cword;
0072 
0073     while ((cword = aspell_string_enumeration_next(elements))) {
0074         /* Since while creating the class ASpellDict the encoding is set */
0075         /* to utf-8, one has to convert output from Aspell to QString's UTF-16 */
0076         qsug.append(QString::fromUtf8(cword));
0077     }
0078 
0079     delete_aspell_string_enumeration(elements);
0080     return qsug;
0081 }
0082 
0083 bool ASpellDict::storeReplacement(const QString &bad, const QString &good)
0084 {
0085     if (!m_speller) {
0086         return false;
0087     }
0088     /* ASpell is expecting length of a string in char representation */
0089     /* word.length() != word.toUtf8().length() for nonlatin strings    */
0090     return aspell_speller_store_replacement(m_speller, bad.toUtf8().constData(), bad.toUtf8().length(), good.toUtf8().constData(), good.toUtf8().length());
0091 }
0092 
0093 bool ASpellDict::addToPersonal(const QString &word)
0094 {
0095     if (!m_speller) {
0096         return false;
0097     }
0098     qCDebug(SONNET_LOG_ASPELL) << "Adding" << word << "to aspell personal dictionary";
0099     /* ASpell is expecting length of a string in char representation */
0100     /* word.length() != word.toUtf8().length() for nonlatin strings    */
0101     aspell_speller_add_to_personal(m_speller, word.toUtf8().constData(), word.toUtf8().length());
0102     /* Add is not enough, one has to save it. This is not documented */
0103     /* in ASpell's API manual. I found it in                         */
0104     /* aspell-0.60.2/example/example-c.c                             */
0105     return aspell_speller_save_all_word_lists(m_speller);
0106 }
0107 
0108 bool ASpellDict::addToSession(const QString &word)
0109 {
0110     if (!m_speller) {
0111         return false;
0112     }
0113     /* ASpell is expecting length of a string in char representation */
0114     /* word.length() != word.toUtf8().length() for nonlatin strings    */
0115     return aspell_speller_add_to_session(m_speller, word.toUtf8().constData(), word.toUtf8().length());
0116 }