File indexing completed on 2024-03-24 04:03:40
0001 /* This file is part of the KDE libraries 0002 0003 SPDX-FileCopyrightText: 2009 Jakub Stachowski <qbast@go2.pl> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include <QString> 0009 0010 #include "guesslanguage.h" 0011 #include "languagefilter_p.h" 0012 #include "loader_p.h" 0013 #include "settingsimpl_p.h" 0014 #include "speller.h" 0015 0016 namespace Sonnet 0017 { 0018 #define MIN_RELIABILITY 0.1 0019 #define MAX_ITEMS 5 0020 0021 class LanguageFilterPrivate 0022 { 0023 public: 0024 LanguageFilterPrivate(AbstractTokenizer *s) 0025 : source(s) 0026 { 0027 gl.setLimits(MAX_ITEMS, MIN_RELIABILITY); 0028 } 0029 0030 ~LanguageFilterPrivate() 0031 { 0032 delete source; 0033 } 0034 0035 QString mainLanguage() const; 0036 0037 AbstractTokenizer *source = nullptr; 0038 Token lastToken; 0039 0040 mutable QString lastLanguage; 0041 mutable QString cachedMainLanguage; 0042 QString prevLanguage; 0043 0044 GuessLanguage gl; 0045 Speller sp; 0046 }; 0047 0048 QString LanguageFilterPrivate::mainLanguage() const 0049 { 0050 if (cachedMainLanguage.isNull()) { 0051 cachedMainLanguage = gl.identify(source->buffer(), QStringList(Loader::openLoader()->settings()->defaultLanguage())); 0052 } 0053 return cachedMainLanguage; 0054 } 0055 0056 /* -----------------------------------------------------------------*/ 0057 0058 LanguageFilter::LanguageFilter(AbstractTokenizer *source) 0059 : d(new LanguageFilterPrivate(source)) 0060 { 0061 d->prevLanguage = Loader::openLoader()->settings()->defaultLanguage(); 0062 } 0063 0064 LanguageFilter::LanguageFilter(const LanguageFilter &other) 0065 : d(new LanguageFilterPrivate(other.d->source)) 0066 { 0067 d->lastToken = other.d->lastToken; 0068 d->lastLanguage = other.d->lastLanguage; 0069 d->cachedMainLanguage = other.d->cachedMainLanguage; 0070 d->prevLanguage = other.d->prevLanguage; 0071 } 0072 0073 LanguageFilter::~LanguageFilter() = default; 0074 0075 bool LanguageFilter::hasNext() const 0076 { 0077 return d->source->hasNext(); 0078 } 0079 0080 void LanguageFilter::setBuffer(const QString &buffer) 0081 { 0082 d->cachedMainLanguage = QString(); 0083 d->source->setBuffer(buffer); 0084 } 0085 0086 Token LanguageFilter::next() 0087 { 0088 d->lastToken = d->source->next(); 0089 d->prevLanguage = d->lastLanguage; 0090 d->lastLanguage = QString(); 0091 return d->lastToken; 0092 } 0093 0094 QString LanguageFilter::language() const 0095 { 0096 if (d->lastLanguage.isNull()) { 0097 d->lastLanguage = d->gl.identify(d->lastToken.toString(), QStringList() << d->prevLanguage << Loader::openLoader()->settings()->defaultLanguage()); 0098 } 0099 const QStringList available = d->sp.availableLanguages(); 0100 0101 // FIXME: do something a little more smart here 0102 if (!available.contains(d->lastLanguage)) { 0103 for (const QString &lang : available) { 0104 if (lang.startsWith(d->lastLanguage)) { 0105 d->lastLanguage = lang; 0106 break; 0107 } 0108 } 0109 } 0110 0111 return d->lastLanguage; 0112 } 0113 0114 bool LanguageFilter::isSpellcheckable() const 0115 { 0116 const QString &lastlang = language(); 0117 if (lastlang.isEmpty()) { 0118 return false; 0119 } 0120 0121 if (d->sp.availableLanguages().contains(lastlang)) { 0122 return true; 0123 } 0124 0125 return false; 0126 } 0127 0128 QString LanguageFilter::buffer() const 0129 { 0130 return d->source->buffer(); 0131 } 0132 0133 void LanguageFilter::replace(int position, int len, const QString &newWord) 0134 { 0135 d->source->replace(position, len, newWord); 0136 // FIXME: fix lastToken 0137 // uncache language for current token - it may have changed 0138 d->lastLanguage = QString(); 0139 } 0140 }