1/* This file is part of the KDE libraries
2
3 SPDX-FileCopyrightText: 2009 Jakub Stachowski <qbast@go2.pl>
4
5 SPDX-License-Identifier: LGPL-2.0-or-later
6*/
7
8#include <QString>
9
10#include "guesslanguage.h"
11#include "languagefilter_p.h"
12#include "loader_p.h"
13#include "settingsimpl_p.h"
14#include "speller.h"
15
16namespace Sonnet
17{
18#define MIN_RELIABILITY 0.1
19#define MAX_ITEMS 5
20
21class LanguageFilterPrivate
22{
23public:
24 LanguageFilterPrivate(AbstractTokenizer *s)
25 : source(s)
26 {
27 gl.setLimits(MAX_ITEMS, MIN_RELIABILITY);
28 }
29
30 ~LanguageFilterPrivate()
31 {
32 delete source;
33 }
34
35 QString mainLanguage() const;
36
37 AbstractTokenizer *source = nullptr;
38 Token lastToken;
39
40 mutable QString lastLanguage;
41 mutable QString cachedMainLanguage;
42 QString prevLanguage;
43
44 GuessLanguage gl;
45 Speller sp;
46};
47
48QString LanguageFilterPrivate::mainLanguage() const
49{
50 if (cachedMainLanguage.isNull()) {
51 cachedMainLanguage = gl.identify(text: source->buffer(), suggestions: QStringList(Loader::openLoader()->settings()->defaultLanguage()));
52 }
53 return cachedMainLanguage;
54}
55
56/* -----------------------------------------------------------------*/
57
58LanguageFilter::LanguageFilter(AbstractTokenizer *source)
59 : d(new LanguageFilterPrivate(source))
60{
61 d->prevLanguage = Loader::openLoader()->settings()->defaultLanguage();
62}
63
64LanguageFilter::LanguageFilter(const LanguageFilter &other)
65 : d(new LanguageFilterPrivate(other.d->source))
66{
67 d->lastToken = other.d->lastToken;
68 d->lastLanguage = other.d->lastLanguage;
69 d->cachedMainLanguage = other.d->cachedMainLanguage;
70 d->prevLanguage = other.d->prevLanguage;
71}
72
73LanguageFilter::~LanguageFilter() = default;
74
75bool LanguageFilter::hasNext() const
76{
77 return d->source->hasNext();
78}
79
80void LanguageFilter::setBuffer(const QString &buffer)
81{
82 d->cachedMainLanguage = QString();
83 d->source->setBuffer(buffer);
84}
85
86Token LanguageFilter::next()
87{
88 d->lastToken = d->source->next();
89 d->prevLanguage = d->lastLanguage;
90 d->lastLanguage = QString();
91 return d->lastToken;
92}
93
94QString LanguageFilter::language() const
95{
96 if (d->lastLanguage.isNull()) {
97 d->lastLanguage = d->gl.identify(text: d->lastToken.toString(), suggestions: QStringList() << d->prevLanguage << Loader::openLoader()->settings()->defaultLanguage());
98 }
99 const QStringList available = d->sp.availableLanguages();
100
101 // FIXME: do something a little more smart here
102 if (!available.contains(str: d->lastLanguage)) {
103 for (const QString &lang : available) {
104 if (lang.startsWith(s: d->lastLanguage)) {
105 d->lastLanguage = lang;
106 break;
107 }
108 }
109 }
110
111 return d->lastLanguage;
112}
113
114bool LanguageFilter::isSpellcheckable() const
115{
116 const QString &lastlang = language();
117 if (lastlang.isEmpty()) {
118 return false;
119 }
120
121 if (d->sp.availableLanguages().contains(str: lastlang)) {
122 return true;
123 }
124
125 return false;
126}
127
128QString LanguageFilter::buffer() const
129{
130 return d->source->buffer();
131}
132
133void LanguageFilter::replace(int position, int len, const QString &newWord)
134{
135 d->source->replace(position, len, newWord);
136 // FIXME: fix lastToken
137 // uncache language for current token - it may have changed
138 d->lastLanguage = QString();
139}
140}
141

source code of sonnet/src/core/languagefilter.cpp