27 #include <kstaticdeleter.h>
36 static KStaticDeleter<Filter> sd;
37 static Filter* defFilter = 0;
48 Filter* Filter::defaultFilter()
51 sd.setObject( defFilter,
new Filter() );
61 : m_currentPosition( 0 )
82 void Filter::restart()
84 m_currentPosition = 0;
87 void Filter::setBuffer(
const TQString& buffer )
90 m_currentPosition = 0;
93 TQString Filter::buffer()
const
98 bool Filter::atEnd()
const
100 if ( m_currentPosition >= m_buffer.length() ) {
106 Word Filter::nextWord()
const
108 TQChar currentChar = skipToLetter( m_currentPosition );
110 if ( m_currentPosition >= m_buffer.length() ) {
111 return Filter::end();
114 bool allUppercase = currentChar.category() & TQChar::Letter_Uppercase;
115 bool runTogether =
false;
118 int start = m_currentPosition;
119 while ( currentChar.isLetter() ) {
120 if ( currentChar.category() & TQChar::Letter_Lowercase )
121 allUppercase =
false;
130 foundWord += currentChar;
132 currentChar = m_buffer[ m_currentPosition ];
135 if ( shouldBeSkipped( allUppercase, runTogether, foundWord ) )
138 return Word( foundWord, start );
141 Word Filter::previousWord()
const
143 while ( !m_buffer[ m_currentPosition ].isLetter() &&
144 m_currentPosition != 0) {
148 if ( m_currentPosition == 0 ) {
149 return Filter::end();
153 int start = m_currentPosition;
154 while ( m_buffer[ start ].isLetter() ) {
155 foundWord.prepend( m_buffer[ m_currentPosition ] );
159 return Word( foundWord, start );
162 Word Filter::wordAtPosition(
unsigned int pos )
const
164 if ( pos > m_buffer.length() )
165 return Filter::end();
167 int currentPosition = pos - 1;
169 while ( currentPosition >= 0 &&
170 m_buffer[ currentPosition ].isLetter() ) {
171 foundWord.prepend( m_buffer[ currentPosition ] );
177 int start = (currentPosition < 0) ? 0 : ++currentPosition;
178 currentPosition = pos ;
179 if ( m_buffer[ currentPosition ].isLetter() ) {
180 while ( m_buffer[ currentPosition ].isLetter() ) {
181 foundWord.append( m_buffer[ currentPosition ] );
186 return Word( foundWord, start );
190 void Filter::setCurrentPosition(
int i )
192 m_currentPosition = i;
196 while ( m_buffer[m_currentPosition].isLetter() && m_currentPosition > 0 )
200 int Filter::currentPosition()
const
202 return m_currentPosition;
205 void Filter::replace(
const Word& w,
const TQString& newWord)
207 int oldLen = w.word.length();
208 int newLen = newWord.length();
210 if ( oldLen != newLen && m_currentPosition > w.start ) {
211 if ( m_currentPosition > w.start ) {
212 int len = newLen - oldLen;
213 m_currentPosition += len;
216 m_buffer = m_buffer.replace( w.start, oldLen, newWord );
224 int signedPosition = m_currentPosition;
225 bool begin = ( (signedPosition - len/2)<=0 ) ?
true :
false;
228 TQString buffer = m_buffer;
229 Word word = wordAtPosition( m_currentPosition );
230 buffer = buffer.replace( word.start, word.word.length(),
231 TQString(
"<b>%1</b>" ).arg( word.word ) );
235 context = TQString(
"%1...")
236 .arg( buffer.mid( 0, len ) );
238 context = TQString(
"...%1..." )
239 .arg( buffer.mid( m_currentPosition - 20, len ) );
241 context = context.replace(
'\n',
' ' );
246 bool Filter::trySkipLinks()
const
248 TQChar currentChar = m_buffer[ m_currentPosition ];
250 uint length = m_buffer.length();
252 if ( currentChar ==
':' &&
253 ( m_buffer[ ++m_currentPosition] ==
'/' || ( m_currentPosition + 1 ) >= length ) ) {
255 while ( !m_buffer[ m_currentPosition++ ].isSpace() && m_currentPosition < length )
261 if ( currentChar ==
'@' ) {
262 while ( !m_buffer[ ++m_currentPosition ].isSpace() && m_currentPosition < length )
270 bool Filter::ignore(
const TQString& word )
const
273 return d->settings->ignore( word );
278 TQChar Filter::skipToLetter( uint &fromPosition )
const
281 TQChar currentChar = m_buffer[ fromPosition ];
282 while ( !currentChar.isLetter() &&
283 ++fromPosition < m_buffer.length() ) {
284 currentChar = m_buffer[ fromPosition ];
289 bool Filter::shouldBeSkipped(
bool wordWasUppercase,
bool wordWasRunTogether,
290 const TQString& foundWord )
const
292 bool checkUpper = ( d->settings ) ?
293 d->settings->checkUppercase () :
true;
294 bool skipRunTogether = ( d->settings ) ?
295 d->settings->skipRunTogether() :
true;
297 if ( trySkipLinks() )
300 if ( wordWasUppercase && !checkUpper )
303 if ( wordWasRunTogether && skipRunTogether )
306 return ignore( foundWord );