• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • sonnet
filter.cpp
Go to the documentation of this file.
1// -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*-
24#include "filter_p.h"
25
26#include "settings_p.h"
27
28#include <kglobal.h>
29#include <kdebug.h>
30
31namespace Sonnet
32{
33
34static Word endWord;
35
36class Filter::Private
37{
38public:
39 // The reason it's not in the class directly is that
40 // I'm not 100% sure that having the settings() here is
41 // the way i want to be doing this.
42 Settings *settings;
43};
44
45Filter* Filter::defaultFilter()
46{
47 return new Filter();
48}
49
50Word Filter::end()
51{
52 return endWord;
53}
54
55Filter::Filter()
56 : d(new Private)
57{
58 d->settings = 0;
59}
60
61Filter::~Filter()
62{
63 delete d;
64}
65
66void Filter::setSettings( Settings *conf )
67{
68 d->settings = conf;
69}
70
71Settings *Filter::settings() const
72{
73 return d->settings;
74}
75
76void Filter::restart()
77{
78 m_finder.toStart();
79}
80
81void Filter::setBuffer( const QString& buffer )
82{
83 m_buffer = buffer;
84 m_finder = QTextBoundaryFinder(QTextBoundaryFinder::Word, m_buffer);
85}
86
87QString Filter::buffer() const
88{
89 return m_buffer;
90}
91
92bool Filter::atEnd() const
93{
94 return m_finder.position() >= m_buffer.length() || m_finder.position() < 0;
95}
96
97// we don't want to spell check empty words, or single-char words of the form
98// '<', '=', etc.
99static bool
100isValidWord(const QString &str)
101{
102 if(str.isEmpty() || (str.length() == 1 && !str[0].isLetter())) {
103 return false;
104 }
105 const int length = str.length();
106 for(int i = 0; i < length; ++i) {
107 if(!str[i].isNumber()) {
108 return true;
109 }
110 }
111 // 'str' only contains numbers
112 return false;
113}
114
115static bool
116finderNextWord(QTextBoundaryFinder &finder, QString &word, int &bufferStart)
117{
118 QTextBoundaryFinder::BoundaryReasons boundary = finder.boundaryReasons();
119 int start = finder.position(), end = finder.position();
120 bool inWord = (boundary & QTextBoundaryFinder::StartWord) != 0;
121 while (finder.toNextBoundary() > 0) {
122 boundary = finder.boundaryReasons();
123 if ((boundary & QTextBoundaryFinder::EndWord) && inWord) {
124 end = finder.position();
125 QString str = finder.string().mid(start, end - start);
126 if (isValidWord(str)) {
127 word = str;
128 bufferStart = start;
129#if 0
130 kDebug() << "Word at " << start << " word = '"
131 << str << "', len = " << str.length();
132#endif
133 return true;
134 }
135 inWord = false;
136 }
137 if ((boundary & QTextBoundaryFinder::StartWord)) {
138 start = finder.position();
139 inWord = true;
140 }
141 }
142 return false;
143}
144
145static bool finderWordAt(QTextBoundaryFinder &finder,
146 int at,
147 QString &word, int &bufferStart)
148{
149 int oldPosition = finder.position();
150
151 finder.setPosition(at);
152 if (!finder.isAtBoundary() || (finder.boundaryReasons() & QTextBoundaryFinder::EndWord)) {
153 if (finder.toPreviousBoundary() <= 0) {
154 /* QTextBoundaryIterator doesn't consider start of the string
155 * a boundary so we need to rewind to the beginning to catch
156 * the first word */
157 if (at > 0 && finder.string().length() > 0) {
158 finder.toStart();
159 } else
160 return false;
161 }
162 }
163 bool ret = finderNextWord(finder, word, bufferStart);
164 finder.setPosition(oldPosition);
165 return ret;
166}
167
168Word Filter::nextWord() const
169{
170 QString foundWord;
171 int start;
172 bool allUppercase = false;
173 bool runTogether = false;
174
175 if (!finderNextWord(m_finder, foundWord, start))
176 return Filter::end();
177
178 allUppercase = ( foundWord == foundWord.toUpper() );
179
180 //TODO implement runtogether correctly.
181 //We must ask to sonnet plugins to do it and not directly here.
182
183 if ( shouldBeSkipped( allUppercase, runTogether, foundWord ) )
184 return nextWord();
185 return Word( foundWord, start );
186}
187
188Word Filter::wordAtPosition( unsigned int pos ) const
189{
190 QString foundWord;
191 int start;
192 if (!finderWordAt(m_finder, pos, foundWord, start))
193 return Filter::end();
194 return Word( foundWord, start );
195}
196
197
198void Filter::setCurrentPosition( int i )
199{
200 QString word;
201 int pos;
202
203 //to make sure we're at an reasonable word boundary
204 if (!finderWordAt(m_finder, i, word, pos)) {
205 return;
206 }
207 m_finder.setPosition(pos);
208}
209
210int Filter::currentPosition() const
211{
212 return m_finder.position();
213}
214
215void Filter::replace( const Word& w, const QString& newWord)
216{
217 int oldLen = w.word.length();
218
219 //start spell checkin from the just correct word
220 m_buffer = m_buffer.replace( w.start, oldLen, newWord );
221 m_finder = QTextBoundaryFinder(QTextBoundaryFinder::Word,
222 m_buffer);
223 m_finder.setPosition(w.start);
224}
225
226QString Filter::context() const
227{
228 int len = 60;
229 //we don't want the expression underneath casted to an unsigned int
230 //which would cause it to always evaluate to false
231 int signedPosition = m_finder.position();
232 bool begin = (signedPosition - len/2)<=0;
233
234
235 QString buffer = m_buffer;
236 Word word = wordAtPosition( m_finder.position() );
237 buffer = buffer.replace( word.start, word.word.length(),
238 QString::fromLatin1( "<b>%1</b>" ).arg( word.word ) );
239
240 QString context;
241 if ( begin )
242 context = QString::fromLatin1("%1...")
243 .arg( buffer.mid( 0, len ) );
244 else
245 context = QString::fromLatin1("...%1...")
246 .arg( buffer.mid( m_finder.position() - 20, len ) );
247
248 context.replace( QLatin1Char('\n'), QLatin1Char(' ') );
249
250 return context;
251}
252
253bool Filter::trySkipLinks() const
254{
255 QChar currentChar;
256 int currentPosition = m_finder.position();
257
258 if (currentPosition < 0 || currentPosition >= m_buffer.length())
259 return false;
260 currentChar = m_buffer.at( currentPosition );
261
262 int length = m_buffer.length();
263 //URL - if so skip
264 if ( currentChar == QLatin1Char(':')
265 && (currentPosition+1 < length)
266 && (m_buffer.at( ++currentPosition ) == QLatin1Char('/') || ( currentPosition + 1 ) >= length ) ) {
267 //in both cases url is considered finished at the first whitespace occurrence
268 //TODO hey, "http://en.wikipedia.org/wiki/Main Page" --Nick Shaforostoff
269 while ( !m_buffer.at( currentPosition++ ).isSpace() && currentPosition < length )
270 ;
271 m_finder.setPosition(currentPosition);
272 return true;
273 }
274
275 //Email - if so skip
276 if ( currentChar == QLatin1Char('@')) {
277 while ( ++currentPosition < length && !m_buffer.at( currentPosition ).isSpace() )
278 ;
279 m_finder.setPosition(currentPosition);
280 return true;
281 }
282
283 return false;
284}
285
286bool Filter::ignore( const QString& word ) const
287{
288 return d->settings && d->settings->ignore( word );
289}
290
291bool Filter::shouldBeSkipped( bool wordWasUppercase, bool wordWasRunTogether,
292 const QString& foundWord ) const
293{
294 bool checkUpper = ( d->settings ) ?
295 d->settings->checkUppercase () : true;
296
297 bool skipRunTogether = ( d->settings ) ?
298 d->settings->skipRunTogether() : true;
299
300 if ( trySkipLinks() )
301 return true;
302
303 if ( wordWasUppercase && !checkUpper )
304 return true;
305
306 if ( wordWasRunTogether && skipRunTogether )
307 return true;
308
309 return ignore( foundWord );
310}
311
312}
QString
Sonnet::Filter
Filter is used to split text into words which will be spell checked.
Definition: filter_p.h:66
Sonnet::Filter::trySkipLinks
bool trySkipLinks() const
Definition: filter.cpp:253
Sonnet::Filter::wordAtPosition
virtual Word wordAtPosition(unsigned int pos) const
Definition: filter.cpp:188
Sonnet::Filter::setBuffer
void setBuffer(const QString &buffer)
Definition: filter.cpp:81
Sonnet::Filter::m_buffer
QString m_buffer
Definition: filter_p.h:110
Sonnet::Filter::setCurrentPosition
virtual void setCurrentPosition(int)
Definition: filter.cpp:198
Sonnet::Filter::restart
void restart()
Definition: filter.cpp:76
Sonnet::Filter::context
virtual QString context() const
Should return the sentence containing the current word.
Definition: filter.cpp:226
Sonnet::Filter::currentPosition
virtual int currentPosition() const
Definition: filter.cpp:210
Sonnet::Filter::end
static Word end()
Definition: filter.cpp:50
Sonnet::Filter::defaultFilter
static Filter * defaultFilter()
Definition: filter.cpp:45
Sonnet::Filter::ignore
bool ignore(const QString &word) const
Definition: filter.cpp:286
Sonnet::Filter::buffer
QString buffer() const
Definition: filter.cpp:87
Sonnet::Filter::replace
virtual void replace(const Word &w, const QString &newWord)
Definition: filter.cpp:215
Sonnet::Filter::setSettings
void setSettings(Settings *)
Sets the Settings object for this Filter.
Definition: filter.cpp:66
Sonnet::Filter::m_finder
QTextBoundaryFinder m_finder
Definition: filter_p.h:111
Sonnet::Filter::atEnd
bool atEnd() const
Definition: filter.cpp:92
Sonnet::Filter::nextWord
virtual Word nextWord() const
Definition: filter.cpp:168
Sonnet::Filter::shouldBeSkipped
bool shouldBeSkipped(bool wordWasUppercase, bool wordWasRunTogether, const QString &foundWord) const
Definition: filter.cpp:291
Sonnet::Filter::settings
Settings * settings() const
Returns currently used Settings object.
Definition: filter.cpp:71
Sonnet::Filter::~Filter
virtual ~Filter()
Definition: filter.cpp:61
Sonnet::Filter::Filter
Filter()
Definition: filter.cpp:55
Sonnet::Settings
Settings class.
Definition: settings_p.h:38
filter_p.h
kDebug
#define kDebug
Definition: kdebug.h:316
kdebug.h
kglobal.h
Sonnet
The sonnet namespace.
Definition: backgroundchecker.h:34
Sonnet::endWord
static Word endWord
Definition: filter.cpp:34
Sonnet::finderWordAt
static bool finderWordAt(QTextBoundaryFinder &finder, int at, QString &word, int &bufferStart)
Definition: filter.cpp:145
Sonnet::isValidWord
static bool isValidWord(const QString &str)
Definition: filter.cpp:100
Sonnet::finderNextWord
static bool finderNextWord(QTextBoundaryFinder &finder, QString &word, int &bufferStart)
Definition: filter.cpp:116
settings_p.h
Sonnet::Word
Structure abstracts the word and its position in the parent text.
Definition: filter_p.h:41
Sonnet::Word::word
QString word
Definition: filter_p.h:53
Sonnet::Word::start
int start
Definition: filter_p.h:54
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal