KDE3Support
k3syntaxhighlighter.cpp
Go to the documentation of this file.
00001 /* 00002 Copyright (c) 2003 Trolltech AS 00003 Copyright (c) 2003 Scott Wheeler <wheeler@kde.org> 00004 00005 This file is part of the KDE libraries 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License version 2 as published by the Free Software Foundation. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include "k3syntaxhighlighter.h" 00023 00024 #include <QtGui/QColor> 00025 #include <QtCore/QRegExp> 00026 #include <Qt3Support/Q3SyntaxHighlighter> 00027 #include <QtCore/QTimer> 00028 00029 #include <klocale.h> 00030 #include <kconfig.h> 00031 #include <kdebug.h> 00032 #include <kglobal.h> 00033 #include <k3sconfig.h> 00034 #include <k3spell.h> 00035 #include <Qt3Support/Q3Dict> 00036 #include <QKeyEvent> 00037 00038 #include <kconfiggroup.h> 00039 #include <fixx11h.h> 00040 00041 static int dummy, dummy2, dummy3, dummy4; 00042 static int *Okay = &dummy; 00043 static int *NotOkay = &dummy2; 00044 static int *Ignore = &dummy3; 00045 static int *Unknown = &dummy4; 00046 static const int tenSeconds = 10*1000; 00047 00048 class K3SyntaxHighlighter::K3SyntaxHighlighterPrivate 00049 { 00050 public: 00051 QColor col1, col2, col3, col4, col5; 00052 SyntaxMode mode; 00053 bool enabled; 00054 }; 00055 00056 class K3SpellingHighlighter::K3SpellingHighlighterPrivate 00057 { 00058 public: 00059 00060 K3SpellingHighlighterPrivate() : 00061 alwaysEndsWithSpace( true ), 00062 intraWordEditing( false ) {} 00063 00064 QString currentWord; 00065 int currentPos; 00066 bool alwaysEndsWithSpace; 00067 QColor color; 00068 bool intraWordEditing; 00069 }; 00070 00071 class K3DictSpellingHighlighter::K3DictSpellingHighlighterPrivate 00072 { 00073 public: 00074 K3DictSpellingHighlighterPrivate() : 00075 mDict( 0 ), 00076 spell( 0 ), 00077 mSpellConfig( 0 ), 00078 rehighlightRequest( 0 ), 00079 wordCount( 0 ), 00080 errorCount( 0 ), 00081 autoReady( false ), 00082 globalConfig( true ), 00083 spellReady( false ) {} 00084 00085 ~K3DictSpellingHighlighterPrivate() { 00086 delete rehighlightRequest; 00087 delete spell; 00088 } 00089 00090 static Q3Dict<int>* sDict() 00091 { 00092 if (!statDict) 00093 statDict = new Q3Dict<int>(50021); 00094 return statDict; 00095 } 00096 00097 Q3Dict<int>* mDict; 00098 Q3Dict<int> autoDict; 00099 Q3Dict<int> autoIgnoreDict; 00100 static QObject *sDictionaryMonitor; 00101 K3Spell *spell; 00102 K3SpellConfig *mSpellConfig; 00103 QTimer *rehighlightRequest, *spellTimeout; 00104 QString spellKey; 00105 int wordCount, errorCount; 00106 int checksRequested, checksDone; 00107 int disablePercentage; 00108 int disableWordCount; 00109 bool completeRehighlightRequired; 00110 bool active, automatic, autoReady; 00111 bool globalConfig, spellReady; 00112 private: 00113 static Q3Dict<int>* statDict; 00114 00115 }; 00116 00117 Q3Dict<int>* K3DictSpellingHighlighter::K3DictSpellingHighlighterPrivate::statDict = 0; 00118 00119 00120 K3SyntaxHighlighter::K3SyntaxHighlighter( Q3TextEdit *textEdit, 00121 bool colorQuoting, 00122 const QColor& depth0, 00123 const QColor& depth1, 00124 const QColor& depth2, 00125 const QColor& depth3, 00126 SyntaxMode mode ) 00127 : Q3SyntaxHighlighter( textEdit ),d(new K3SyntaxHighlighterPrivate()) 00128 { 00129 00130 d->enabled = colorQuoting; 00131 d->col1 = depth0; 00132 d->col2 = depth1; 00133 d->col3 = depth2; 00134 d->col4 = depth3; 00135 d->col5 = depth0; 00136 00137 d->mode = mode; 00138 } 00139 00140 K3SyntaxHighlighter::~K3SyntaxHighlighter() 00141 { 00142 delete d; 00143 } 00144 00145 int K3SyntaxHighlighter::highlightParagraph( const QString &text, int ) 00146 { 00147 if (!d->enabled) { 00148 setFormat( 0, text.length(), textEdit()->viewport()->paletteForegroundColor() ); 00149 return 0; 00150 } 00151 00152 QString simplified = text; 00153 simplified = simplified.replace( QRegExp( "\\s" ), QString() ).replace( '|', QLatin1String(">") ); 00154 while ( simplified.startsWith( QLatin1String(">>>>") ) ) 00155 simplified = simplified.mid(3); 00156 if ( simplified.startsWith( QLatin1String(">>>") ) || simplified.startsWith( QString::fromLatin1("> > >") ) ) 00157 setFormat( 0, text.length(), d->col2 ); 00158 else if ( simplified.startsWith( QLatin1String(">>") ) || simplified.startsWith( QString::fromLatin1("> >") ) ) 00159 setFormat( 0, text.length(), d->col3 ); 00160 else if ( simplified.startsWith( QLatin1String(">") ) ) 00161 setFormat( 0, text.length(), d->col4 ); 00162 else 00163 setFormat( 0, text.length(), d->col5 ); 00164 return 0; 00165 } 00166 00167 K3SpellingHighlighter::K3SpellingHighlighter( Q3TextEdit *textEdit, 00168 const QColor& spellColor, 00169 bool colorQuoting, 00170 const QColor& depth0, 00171 const QColor& depth1, 00172 const QColor& depth2, 00173 const QColor& depth3 ) 00174 : K3SyntaxHighlighter( textEdit, colorQuoting, depth0, depth1, depth2, depth3 ),d(new K3SpellingHighlighterPrivate()) 00175 { 00176 00177 d->color = spellColor; 00178 } 00179 00180 K3SpellingHighlighter::~K3SpellingHighlighter() 00181 { 00182 delete d; 00183 } 00184 00185 int K3SpellingHighlighter::highlightParagraph( const QString &text, 00186 int paraNo ) 00187 { 00188 if ( paraNo == -2 ) 00189 paraNo = 0; 00190 // leave #includes, diffs, and quoted replies alone 00191 QString diffAndCo( ">|" ); 00192 00193 bool isCode = diffAndCo.contains(text[0]); 00194 00195 if ( !text.endsWith(' ') ) 00196 d->alwaysEndsWithSpace = false; 00197 00198 K3SyntaxHighlighter::highlightParagraph( text, -2 ); 00199 00200 if ( !isCode ) { 00201 int para, index; 00202 textEdit()->getCursorPosition( ¶, &index ); 00203 int len = text.length(); 00204 if ( d->alwaysEndsWithSpace ) 00205 len--; 00206 00207 d->currentPos = 0; 00208 d->currentWord = ""; 00209 for ( int i = 0; i < len; i++ ) { 00210 if ( !text[i].isLetter() && (!(text[i] == '\'')) ) { 00211 if ( ( para != paraNo ) || 00212 !intraWordEditing() || 00213 ( i - d->currentWord.length() > index ) || 00214 ( i < index ) ) { 00215 flushCurrentWord(); 00216 } else { 00217 d->currentWord = ""; 00218 } 00219 d->currentPos = i + 1; 00220 } else { 00221 d->currentWord += text[i]; 00222 } 00223 } 00224 if ( ( len > 0 && !text[len - 1].isLetter() ) || 00225 ( index + 1 ) != text.length() || 00226 para != paraNo ) 00227 flushCurrentWord(); 00228 } 00229 return ++paraNo; 00230 } 00231 00232 QStringList K3SpellingHighlighter::personalWords() 00233 { 00234 QStringList l; 00235 l.append( "KMail" ); 00236 l.append( "KOrganizer" ); 00237 l.append( "KAddressBook" ); 00238 l.append( "KHTML" ); 00239 l.append( "KIO" ); 00240 l.append( "KJS" ); 00241 l.append( "Konqueror" ); 00242 l.append( "K3Spell" ); 00243 l.append( "Kontact" ); 00244 l.append( "Qt" ); 00245 return l; 00246 } 00247 00248 void K3SpellingHighlighter::flushCurrentWord() 00249 { 00250 while ( d->currentWord[0].isPunct() ) { 00251 d->currentWord = d->currentWord.mid( 1 ); 00252 d->currentPos++; 00253 } 00254 00255 QChar ch; 00256 while ( !d->currentWord.isEmpty() && ( ch = d->currentWord[(int) d->currentWord.length() - 1] ).isPunct() && 00257 ch != '(' && ch != '@' ) 00258 d->currentWord.truncate( d->currentWord.length() - 1 ); 00259 00260 if ( !d->currentWord.isEmpty() ) { 00261 if ( isMisspelled( d->currentWord ) ) { 00262 setFormat( d->currentPos, d->currentWord.length(), d->color ); 00263 // setMisspelled( d->currentPos, d->currentWord.length(), true ); 00264 } 00265 } 00266 d->currentWord = ""; 00267 } 00268 00269 QObject *K3DictSpellingHighlighter::K3DictSpellingHighlighterPrivate::sDictionaryMonitor = 0; 00270 00271 K3DictSpellingHighlighter::K3DictSpellingHighlighter( Q3TextEdit *textEdit, 00272 bool spellCheckingActive , 00273 bool autoEnable, 00274 const QColor& spellColor, 00275 bool colorQuoting, 00276 const QColor& depth0, 00277 const QColor& depth1, 00278 const QColor& depth2, 00279 const QColor& depth3, 00280 K3SpellConfig *spellConfig ) 00281 : K3SpellingHighlighter( textEdit, spellColor, 00282 colorQuoting, depth0, depth1, depth2, depth3 ),d(new K3DictSpellingHighlighterPrivate()) 00283 { 00284 00285 d->mSpellConfig = spellConfig; 00286 d->globalConfig = ( !spellConfig ); 00287 d->automatic = autoEnable; 00288 d->active = spellCheckingActive; 00289 d->checksRequested = 0; 00290 d->checksDone = 0; 00291 d->completeRehighlightRequired = false; 00292 00293 KConfigGroup cg( KGlobal::config(), "K3Spell" ); 00294 d->disablePercentage = cg.readEntry( "K3Spell_AsYouTypeDisablePercentage", QVariant(42 )).toInt(); 00295 d->disablePercentage = qMin( d->disablePercentage, 101 ); 00296 d->disableWordCount = cg.readEntry( "K3Spell_AsYouTypeDisableWordCount", QVariant(100 )).toInt(); 00297 00298 textEdit->installEventFilter( this ); 00299 textEdit->viewport()->installEventFilter( this ); 00300 00301 d->rehighlightRequest = new QTimer(this); 00302 connect( d->rehighlightRequest, SIGNAL( timeout() ), 00303 this, SLOT( slotRehighlight() )); 00304 d->spellTimeout = new QTimer(this); 00305 connect( d->spellTimeout, SIGNAL( timeout() ), 00306 this, SLOT( slotK3SpellNotResponding() )); 00307 00308 if ( d->globalConfig ) { 00309 d->spellKey = spellKey(); 00310 00311 if ( !d->sDictionaryMonitor ) 00312 d->sDictionaryMonitor = new QObject(); 00313 } 00314 else { 00315 d->mDict = new Q3Dict<int>(4001); 00316 connect( d->mSpellConfig, SIGNAL( configChanged() ), 00317 this, SLOT( slotLocalSpellConfigChanged() ) ); 00318 } 00319 00320 slotDictionaryChanged(); 00321 } 00322 00323 K3DictSpellingHighlighter::~K3DictSpellingHighlighter() 00324 { 00325 delete d->spell; 00326 d->spell = 0; 00327 delete d->mDict; 00328 d->mDict = 0; 00329 delete d; 00330 } 00331 00332 void K3DictSpellingHighlighter::slotSpellReady( K3Spell *spell ) 00333 { 00334 kDebug(0) << "KDictSpellingHighlighter::slotSpellReady( " << spell << " )"; 00335 if ( d->globalConfig ) { 00336 connect( d->sDictionaryMonitor, SIGNAL( destroyed()), 00337 this, SLOT( slotDictionaryChanged() )); 00338 } 00339 if ( spell != d->spell ) 00340 { 00341 delete d->spell; 00342 d->spell = spell; 00343 } 00344 d->spellReady = true; 00345 const QStringList l = K3SpellingHighlighter::personalWords(); 00346 for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { 00347 d->spell->addPersonal( *it ); 00348 } 00349 connect( spell, SIGNAL( misspelling( const QString &, const QStringList &, unsigned int )), 00350 this, SLOT( slotMisspelling( const QString &, const QStringList &, unsigned int ))); 00351 connect( spell, SIGNAL( corrected( const QString &, const QString &, unsigned int )), 00352 this, SLOT( slotCorrected( const QString &, const QString &, unsigned int ))); 00353 d->checksRequested = 0; 00354 d->checksDone = 0; 00355 d->completeRehighlightRequired = true; 00356 d->rehighlightRequest->start( 0, true ); 00357 } 00358 00359 bool K3DictSpellingHighlighter::isMisspelled( const QString &word ) 00360 { 00361 if (!d->spellReady) 00362 return false; 00363 00364 // This debug is expensive, only enable it locally 00365 //kDebug(0) << "KDictSpellingHighlighter::isMisspelled( \"" << word << "\" )"; 00366 // Normally isMisspelled would look up a dictionary and return 00367 // true or false, but kspell is asynchronous and slow so things 00368 // get tricky... 00369 // For auto detection ignore signature and reply prefix 00370 if ( !d->autoReady ) 00371 d->autoIgnoreDict.replace( word, Ignore ); 00372 00373 // "dict" is used as a cache to store the results of K3Spell 00374 Q3Dict<int>* dict = ( d->globalConfig ? d->sDict() : d->mDict ); 00375 if ( !dict->isEmpty() && (*dict)[word] == NotOkay ) { 00376 if ( d->autoReady && ( d->autoDict[word] != NotOkay )) { 00377 if ( !d->autoIgnoreDict[word] ) 00378 ++d->errorCount; 00379 d->autoDict.replace( word, NotOkay ); 00380 } 00381 00382 return d->active; 00383 } 00384 if ( !dict->isEmpty() && (*dict)[word] == Okay ) { 00385 if ( d->autoReady && !d->autoDict[word] ) { 00386 d->autoDict.replace( word, Okay ); 00387 } 00388 return false; 00389 } 00390 00391 if ((dict->isEmpty() || !((*dict)[word])) && d->spell ) { 00392 int para, index; 00393 textEdit()->getCursorPosition( ¶, &index ); 00394 ++d->wordCount; 00395 dict->replace( word, Unknown ); 00396 ++d->checksRequested; 00397 if (currentParagraph() != para) 00398 d->completeRehighlightRequired = true; 00399 d->spellTimeout->start( tenSeconds, true ); 00400 d->spell->checkWord( word, false ); 00401 } 00402 return false; 00403 } 00404 00405 bool K3SpellingHighlighter::intraWordEditing() const 00406 { 00407 return d->intraWordEditing; 00408 } 00409 00410 void K3SpellingHighlighter::setIntraWordEditing( bool editing ) 00411 { 00412 d->intraWordEditing = editing; 00413 } 00414 00415 void K3DictSpellingHighlighter::slotMisspelling (const QString &originalWord, const QStringList &suggestions, 00416 unsigned int pos) 00417 { 00418 Q_UNUSED( suggestions ); 00419 // kDebug() << suggestions.join( " " ).toLatin1(); 00420 if ( d->globalConfig ) 00421 d->sDict()->replace( originalWord, NotOkay ); 00422 else 00423 d->mDict->replace( originalWord, NotOkay ); 00424 00425 //Emit this baby so that apps that want to have suggestions in a popup over 00426 //the misspelled word can catch them. 00427 emit newSuggestions( originalWord, suggestions, pos ); 00428 } 00429 00430 void K3DictSpellingHighlighter::slotCorrected(const QString &word, 00431 const QString &, 00432 unsigned int) 00433 00434 { 00435 Q3Dict<int>* dict = ( d->globalConfig ? d->sDict() : d->mDict ); 00436 if ( !dict->isEmpty() && (*dict)[word] == Unknown ) { 00437 dict->replace( word, Okay ); 00438 } 00439 ++d->checksDone; 00440 if (d->checksDone == d->checksRequested) { 00441 d->spellTimeout->stop(); 00442 slotRehighlight(); 00443 } else { 00444 d->spellTimeout->start( tenSeconds, true ); 00445 } 00446 } 00447 00448 void K3DictSpellingHighlighter::dictionaryChanged() 00449 { 00450 QObject *oldMonitor = K3DictSpellingHighlighterPrivate::sDictionaryMonitor; 00451 K3DictSpellingHighlighterPrivate::sDictionaryMonitor = new QObject(); 00452 K3DictSpellingHighlighterPrivate::sDict()->clear(); 00453 delete oldMonitor; 00454 } 00455 00456 void K3DictSpellingHighlighter::restartBackgroundSpellCheck() 00457 { 00458 kDebug(0) << "KDictSpellingHighlighter::restartBackgroundSpellCheck()"; 00459 slotDictionaryChanged(); 00460 } 00461 00462 void K3DictSpellingHighlighter::setActive( bool active ) 00463 { 00464 if ( active == d->active ) 00465 return; 00466 00467 d->active = active; 00468 rehighlight(); 00469 if ( d->active ) 00470 emit activeChanged( i18n("As-you-type spell checking enabled.") ); 00471 else 00472 emit activeChanged( i18n("As-you-type spell checking disabled.") ); 00473 } 00474 00475 bool K3DictSpellingHighlighter::isActive() const 00476 { 00477 return d->active; 00478 } 00479 00480 void K3DictSpellingHighlighter::setAutomatic( bool automatic ) 00481 { 00482 if ( automatic == d->automatic ) 00483 return; 00484 00485 d->automatic = automatic; 00486 if ( d->automatic ) 00487 slotAutoDetection(); 00488 } 00489 00490 bool K3DictSpellingHighlighter::automatic() const 00491 { 00492 return d->automatic; 00493 } 00494 00495 void K3DictSpellingHighlighter::slotRehighlight() 00496 { 00497 kDebug(0) << "KDictSpellingHighlighter::slotRehighlight()"; 00498 if (d->completeRehighlightRequired) { 00499 rehighlight(); 00500 } else { 00501 int para, index; 00502 textEdit()->getCursorPosition( ¶, &index ); 00503 //rehighlight the current para only (undo/redo safe) 00504 textEdit()->insertAt( "", para, index ); 00505 } 00506 if (d->checksDone == d->checksRequested) 00507 d->completeRehighlightRequired = false; 00508 QTimer::singleShot( 0, this, SLOT( slotAutoDetection() )); 00509 } 00510 00511 void K3DictSpellingHighlighter::slotDictionaryChanged() 00512 { 00513 delete d->spell; 00514 d->spellReady = false; 00515 d->wordCount = 0; 00516 d->errorCount = 0; 00517 d->autoDict.clear(); 00518 00519 d->spell = new K3Spell( 0, i18n( "Incremental Spellcheck" ), this, 00520 SLOT( slotSpellReady( K3Spell * ) ), d->mSpellConfig ); 00521 } 00522 00523 void K3DictSpellingHighlighter::slotLocalSpellConfigChanged() 00524 { 00525 kDebug(0) << "KDictSpellingHighlighter::slotSpellConfigChanged()"; 00526 // the spell config has been changed, so we have to restart from scratch 00527 d->mDict->clear(); 00528 slotDictionaryChanged(); 00529 } 00530 00531 QString K3DictSpellingHighlighter::spellKey() 00532 { 00533 KGlobal::config()->reparseConfiguration(); 00534 KConfigGroup cg( KGlobal::config(), "K3Spell" ); 00535 QString key; 00536 key += QString::number( cg.readEntry( "K3Spell_NoRootAffix", QVariant(0 )).toInt()); 00537 key += '/'; 00538 key += QString::number( cg.readEntry( "K3Spell_RunTogether", QVariant(0 )).toInt()); 00539 key += '/'; 00540 key += cg.readEntry( "K3Spell_Dictionary", "" ); 00541 key += '/'; 00542 key += QString::number( cg.readEntry( "K3Spell_DictFromList", QVariant(false )).toInt()); 00543 key += '/'; 00544 key += QString::number( cg.readEntry( "K3Spell_Encoding", QVariant(KS_E_ASCII )).toInt()); 00545 key += '/'; 00546 key += QString::number( cg.readEntry( "K3Spell_Client", QVariant(KS_CLIENT_ISPELL )).toInt()); 00547 return key; 00548 } 00549 00550 00551 // Automatic spell checking support 00552 // In auto spell checking mode disable as-you-type spell checking 00553 // iff more than one third of words are spelt incorrectly. 00554 // 00555 // Words in the signature and reply prefix are ignored. 00556 // Only unique words are counted. 00557 00558 void K3DictSpellingHighlighter::slotAutoDetection() 00559 { 00560 if ( !d->autoReady ) 00561 return; 00562 00563 bool savedActive = d->active; 00564 00565 if ( d->automatic ) { 00566 // tme = Too many errors 00567 bool tme = ( d->wordCount >= d->disableWordCount ) && ( d->errorCount * 100 >= d->disablePercentage * d->wordCount ); 00568 if ( d->active && tme ) 00569 d->active = false; 00570 else if ( !d->active && !tme ) 00571 d->active = true; 00572 } 00573 if ( d->active != savedActive ) { 00574 if ( d->wordCount > 1 ) { 00575 if ( d->active ) 00576 emit activeChanged( i18n("As-you-type spell checking enabled.") ); 00577 else 00578 emit activeChanged( i18n( "Too many misspelled words. " 00579 "As-you-type spell checking disabled." ) ); 00580 } 00581 d->completeRehighlightRequired = true; 00582 d->rehighlightRequest->start( 100, true ); 00583 } 00584 } 00585 00586 void K3DictSpellingHighlighter::slotK3SpellNotResponding() 00587 { 00588 static int retries = 0; 00589 if (retries < 10) { 00590 if ( d->globalConfig ) 00591 K3DictSpellingHighlighter::dictionaryChanged(); 00592 else 00593 slotLocalSpellConfigChanged(); 00594 } else { 00595 setAutomatic( false ); 00596 setActive( false ); 00597 } 00598 ++retries; 00599 } 00600 00601 bool K3DictSpellingHighlighter::eventFilter( QObject *o, QEvent *e) 00602 { 00603 if (o == textEdit() && (e->type() == QEvent::FocusIn)) { 00604 if ( d->globalConfig ) { 00605 QString skey = spellKey(); 00606 if ( d->spell && d->spellKey != skey ) { 00607 d->spellKey = skey; 00608 K3DictSpellingHighlighter::dictionaryChanged(); 00609 } 00610 } 00611 } 00612 00613 if (o == textEdit() && (e->type() == QEvent::KeyPress)) { 00614 QKeyEvent *k = static_cast<QKeyEvent *>(e); 00615 d->autoReady = true; 00616 if (d->rehighlightRequest->isActive()) // try to stay out of the users way 00617 d->rehighlightRequest->start( 500 ); 00618 if ( k->key() == Qt::Key_Enter || 00619 k->key() == Qt::Key_Return || 00620 k->key() == Qt::Key_Up || 00621 k->key() == Qt::Key_Down || 00622 k->key() == Qt::Key_Left || 00623 k->key() == Qt::Key_Right || 00624 k->key() == Qt::Key_PageUp || 00625 k->key() == Qt::Key_PageDown || 00626 k->key() == Qt::Key_Home || 00627 k->key() == Qt::Key_End || 00628 (( k->state() & Qt::ControlModifier ) && 00629 ((k->key() == Qt::Key_A) || 00630 (k->key() == Qt::Key_B) || 00631 (k->key() == Qt::Key_E) || 00632 (k->key() == Qt::Key_N) || 00633 (k->key() == Qt::Key_P))) ) { 00634 if ( intraWordEditing() ) { 00635 setIntraWordEditing( false ); 00636 d->completeRehighlightRequired = true; 00637 d->rehighlightRequest->start( 500, true ); 00638 } 00639 if (d->checksDone != d->checksRequested) { 00640 // Handle possible change of paragraph while 00641 // words are pending spell checking 00642 d->completeRehighlightRequired = true; 00643 d->rehighlightRequest->start( 500, true ); 00644 } 00645 } else { 00646 setIntraWordEditing( true ); 00647 } 00648 if ( k->key() == Qt::Key_Space || 00649 k->key() == Qt::Key_Enter || 00650 k->key() == Qt::Key_Return ) { 00651 QTimer::singleShot( 0, this, SLOT( slotAutoDetection() )); 00652 } 00653 } 00654 00655 else if ( o == textEdit()->viewport() && 00656 ( e->type() == QEvent::MouseButtonPress )) { 00657 d->autoReady = true; 00658 if ( intraWordEditing() ) { 00659 setIntraWordEditing( false ); 00660 d->completeRehighlightRequired = true; 00661 d->rehighlightRequest->start( 0, true ); 00662 } 00663 } 00664 00665 return false; 00666 } 00667 00668 #include "k3syntaxhighlighter.moc"
KDE 4.6 API Reference