1/*
2 * spellingfilter.cpp
3 *
4 * Copyright (c) 2002 Dave Corrie <kde@davecorrie.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21/**
22 @file
23 This file is part of the KDEPIM Utilities library and provides the
24 SpellingFilter class.
25
26 @brief
27 Filters message text that should not be spellchecked.
28
29 @author Dave Corrie \<kde@davecorrie.com\>
30*/
31
32#include "spellingfilter.h"
33
34using namespace KPIMUtils;
35
36/**
37 Private class that helps to provide binary compatibility between releases.
38 @internal
39*/
40//@cond PRIVATE
41class KPIMUtils::SpellingFilter::Private
42{
43 public:
44 QString mOriginal;
45 QString mFiltered;
46};
47//@endcond
48
49//-----------------------------------------------------------------------------
50// SpellingFilter implementation
51//
52
53SpellingFilter::SpellingFilter( const QString &text,
54 const QString &quotePrefix,
55 UrlFiltering filterUrls,
56 EmailAddressFiltering filterEmailAddresses,
57 const QStringList &filterStrings )
58 : d( new KPIMUtils::SpellingFilter::Private )
59{
60 d->mOriginal = text;
61 TextCensor c( text );
62
63 if ( !quotePrefix.isEmpty() ) {
64 c.censorQuotations( quotePrefix );
65 }
66
67 if ( filterUrls ) {
68 c.censorUrls();
69 }
70
71 if ( filterEmailAddresses ) {
72 c.censorEmailAddresses();
73 }
74
75 QStringList::const_iterator iter = filterStrings.begin();
76 QStringList::const_iterator endIter = filterStrings.end();
77 while ( iter != endIter ) {
78 c.censorString( *iter );
79 ++iter;
80 }
81
82 d->mFiltered = c.censoredText();
83}
84
85SpellingFilter::~SpellingFilter()
86{
87 delete d;
88}
89
90QString SpellingFilter::originalText() const
91{
92 return d->mOriginal;
93}
94
95QString SpellingFilter::filteredText() const
96{
97 return d->mFiltered;
98}
99
100//-----------------------------------------------------------------------------
101// SpellingFilter::TextCensor implementation
102//
103
104SpellingFilter::TextCensor::TextCensor( const QString &s )
105 : LinkLocator( s )
106{
107}
108
109void SpellingFilter::TextCensor::censorQuotations( const QString &quotePrefix )
110{
111 mPos = 0;
112 while ( mPos < mText.length() ) {
113 // Find start of quotation
114 findQuotation( quotePrefix );
115 if ( mPos < mText.length() ) {
116 int start = mPos;
117 skipQuotation( quotePrefix );
118
119 // Replace quotation with spaces
120 int len = mPos - start;
121 QString spaces;
122 spaces.fill( QLatin1Char(' '), len );
123 mText.replace( start, len, spaces );
124 }
125 }
126}
127
128void SpellingFilter::TextCensor::censorUrls()
129{
130 mPos = 0;
131 while ( mPos < mText.length() ) {
132 // Find start of url
133 QString url;
134 while ( mPos < mText.length() && url.isEmpty() ) {
135 url = getUrl();
136 ++mPos;
137 }
138
139 if ( mPos < mText.length() && !url.isEmpty() ) {
140 int start = mPos - url.length();
141
142 // Replace url with spaces
143 url.fill( QLatin1Char(' ') );
144 mText.replace( start, url.length(), url );
145 }
146 }
147}
148
149void SpellingFilter::TextCensor::censorEmailAddresses()
150{
151 mPos = 0;
152 while ( mPos < mText.length() ) {
153 // Find start of email address
154 findEmailAddress();
155 if ( mPos < mText.length() ) {
156 QString address = getEmailAddress();
157 ++mPos;
158 if ( !address.isEmpty() ) {
159 int start = mPos - address.length();
160
161 // Replace address with spaces
162 address.fill( QLatin1Char(' ') );
163 mText.replace( start, address.length(), address );
164 }
165 }
166 }
167}
168
169void SpellingFilter::TextCensor::censorString( const QString &s )
170{
171 mPos = 0;
172 while ( mPos != -1 ) {
173 // Find start of string
174 mPos = mText.indexOf( s, mPos );
175 if ( mPos != -1 ) {
176 // Replace string with spaces
177 QString spaces;
178 spaces.fill( QLatin1Char(' '), s.length() );
179 mText.replace( mPos, s.length(), spaces );
180 mPos += s.length();
181 }
182 }
183}
184
185QString SpellingFilter::TextCensor::censoredText() const
186{
187 return mText;
188}
189
190//-----------------------------------------------------------------------------
191// text censorship helper functions
192//
193
194bool SpellingFilter::TextCensor::atLineStart() const
195{
196 return
197 ( mPos == 0 && mText.length() > 0 ) ||
198 ( mText[mPos - 1] == QLatin1Char('\n') );
199}
200
201void SpellingFilter::TextCensor::skipLine()
202{
203 mPos = mText.indexOf( QLatin1Char('\n'), mPos );
204 if ( mPos == -1 ) {
205 mPos = mText.length();
206 } else {
207 ++mPos;
208 }
209}
210
211bool SpellingFilter::TextCensor::atQuotation( const QString &quotePrefix ) const
212{
213 return atLineStart() &&
214 mText.mid( mPos, quotePrefix.length() ) == quotePrefix;
215}
216
217void SpellingFilter::TextCensor::skipQuotation( const QString &quotePrefix )
218{
219 while ( atQuotation( quotePrefix ) ) {
220 skipLine();
221 }
222}
223
224void SpellingFilter::TextCensor::findQuotation( const QString &quotePrefix )
225{
226 while ( mPos < mText.length() &&
227 !atQuotation( quotePrefix ) ) {
228 skipLine();
229 }
230}
231
232void SpellingFilter::TextCensor::findEmailAddress()
233{
234 while ( mPos < mText.length() && mText[mPos] != QLatin1Char( '@' ) ) {
235 ++mPos;
236 }
237}
238