diff options
Diffstat (limited to 'kdeui/ksyntaxhighlighter.cpp')
-rw-r--r-- | kdeui/ksyntaxhighlighter.cpp | 677 |
1 files changed, 0 insertions, 677 deletions
diff --git a/kdeui/ksyntaxhighlighter.cpp b/kdeui/ksyntaxhighlighter.cpp deleted file mode 100644 index 5e334ac11..000000000 --- a/kdeui/ksyntaxhighlighter.cpp +++ /dev/null @@ -1,677 +0,0 @@ -/* - ksyntaxhighlighter.cpp - - Copyright (c) 2003 Trolltech AS - Copyright (c) 2003 Scott Wheeler <wheeler@kde.org> - - This file is part of the KDE libraries - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqcolor.h> -#include <tqregexp.h> -#include <tqsyntaxhighlighter.h> -#include <tqtimer.h> - -#include <klocale.h> -#include <kconfig.h> -#include <kdebug.h> -#include <kglobal.h> -#include <kspell.h> -#include <kapplication.h> - -#include "ksyntaxhighlighter.h" - -static int dummy, dummy2, dummy3, dummy4; -static int *Okay = &dummy; -static int *NotOkay = &dummy2; -static int *Ignore = &dummy3; -static int *Unknown = &dummy4; -static const int tenSeconds = 10*1000; - -class KSyntaxHighlighter::KSyntaxHighlighterPrivate -{ -public: - TQColor col1, col2, col3, col4, col5; - SyntaxMode mode; - bool enabled; -}; - -class KSpellingHighlighter::KSpellingHighlighterPrivate -{ -public: - - KSpellingHighlighterPrivate() : - alwaysEndsWithSpace( true ), - intraWordEditing( false ) {} - - TQString currentWord; - int currentPos; - bool alwaysEndsWithSpace; - TQColor color; - bool intraWordEditing; -}; - -class KDictSpellingHighlighter::KDictSpellingHighlighterPrivate -{ -public: - KDictSpellingHighlighterPrivate() : - mDict( 0 ), - spell( 0 ), - mSpellConfig( 0 ), - rehighlightRequest( 0 ), - wordCount( 0 ), - errorCount( 0 ), - autoReady( false ), - globalConfig( true ), - spellReady( false ) {} - - ~KDictSpellingHighlighterPrivate() { - delete rehighlightRequest; - delete spell; - } - - static TQDict<int>* sDict() - { - if (!statDict) - statDict = new TQDict<int>(50021); - return statDict; - } - - TQDict<int>* mDict; - TQDict<int> autoDict; - TQDict<int> autoIgnoreDict; - static TQObject *sDictionaryMonitor; - KSpell *spell; - KSpellConfig *mSpellConfig; - TQTimer *rehighlightRequest, *spellTimeout; - TQString spellKey; - int wordCount, errorCount; - int checksRequested, checksDone; - int disablePercentage; - int disableWordCount; - bool completeRehighlightRequired; - bool active, automatic, autoReady; - bool globalConfig, spellReady; -private: - static TQDict<int>* statDict; - -}; - -TQDict<int>* KDictSpellingHighlighter::KDictSpellingHighlighterPrivate::statDict = 0; - - -KSyntaxHighlighter::KSyntaxHighlighter( TQTextEdit *textEdit, - bool colorQuoting, - const TQColor& depth0, - const TQColor& depth1, - const TQColor& depth2, - const TQColor& depth3, - SyntaxMode mode ) - : TQSyntaxHighlighter( textEdit ) -{ - d = new KSyntaxHighlighterPrivate(); - - d->enabled = colorQuoting; - d->col1 = depth0; - d->col2 = depth1; - d->col3 = depth2; - d->col4 = depth3; - d->col5 = depth0; - - d->mode = mode; -} - -KSyntaxHighlighter::~KSyntaxHighlighter() -{ - delete d; -} - -int KSyntaxHighlighter::highlightParagraph( const TQString &text, int ) -{ - if (!d->enabled) { - setFormat( 0, text.length(), textEdit()->viewport()->paletteForegroundColor() ); - return 0; - } - - TQString simplified = text; - simplified = TQString(simplified.replace( TQRegExp( "\\s" ), TQString() )).replace( '|', TQString::tqfromLatin1(">") ); - while ( simplified.startsWith( TQString::tqfromLatin1(">>>>") ) ) - simplified = simplified.mid(3); - if ( simplified.startsWith( TQString::tqfromLatin1(">>>") ) || simplified.startsWith( TQString::tqfromLatin1("> > >") ) ) - setFormat( 0, text.length(), d->col2 ); - else if ( simplified.startsWith( TQString::tqfromLatin1(">>") ) || simplified.startsWith( TQString::tqfromLatin1("> >") ) ) - setFormat( 0, text.length(), d->col3 ); - else if ( simplified.startsWith( TQString::tqfromLatin1(">") ) ) - setFormat( 0, text.length(), d->col4 ); - else - setFormat( 0, text.length(), d->col5 ); - return 0; -} - -KSpellingHighlighter::KSpellingHighlighter( TQTextEdit *textEdit, - const TQColor& spellColor, - bool colorQuoting, - const TQColor& depth0, - const TQColor& depth1, - const TQColor& depth2, - const TQColor& depth3 ) - : KSyntaxHighlighter( textEdit, colorQuoting, depth0, depth1, depth2, depth3 ) -{ - d = new KSpellingHighlighterPrivate(); - - d->color = spellColor; -} - -KSpellingHighlighter::~KSpellingHighlighter() -{ - delete d; -} - -int KSpellingHighlighter::highlightParagraph( const TQString &text, - int paraNo ) -{ - if ( paraNo == -2 ) - paraNo = 0; - // leave #includes, diffs, and quoted replies alone - TQString diffAndCo( ">|" ); - - bool isCode = diffAndCo.find(text[0]) != -1; - - if ( !text.endsWith(" ") ) - d->alwaysEndsWithSpace = false; - - KSyntaxHighlighter::highlightParagraph( text, -2 ); - - if ( !isCode ) { - int para, index; - textEdit()->getCursorPosition( ¶, &index ); - int len = text.length(); - if ( d->alwaysEndsWithSpace ) - len--; - - d->currentPos = 0; - d->currentWord = ""; - for ( int i = 0; i < len; i++ ) { - if ( !text[i].isLetter() && (!(text[i] == '\'')) ) { - if ( ( para != paraNo ) || - !intraWordEditing() || - ( i - d->currentWord.length() > (uint)index ) || - ( i < index ) ) { - flushCurrentWord(); - } else { - d->currentWord = ""; - } - d->currentPos = i + 1; - } else { - d->currentWord += text[i]; - } - } - if ( !text[len - 1].isLetter() || - (uint)( index + 1 ) != text.length() || - para != paraNo ) - flushCurrentWord(); - } - return ++paraNo; -} - -TQStringList KSpellingHighlighter::personalWords() -{ - TQStringList l; - l.append( "KMail" ); - l.append( "KOrganizer" ); - l.append( "KAddressBook" ); - l.append( "KHTML" ); - l.append( "KIO" ); - l.append( "KJS" ); - l.append( "Konqueror" ); - l.append( "KSpell" ); - l.append( "Kontact" ); - l.append( "Qt" ); - return l; -} - -void KSpellingHighlighter::flushCurrentWord() -{ - while ( d->currentWord[0].isPunct() ) { - d->currentWord = d->currentWord.mid( 1 ); - d->currentPos++; - } - - TQChar ch; - while ( ( ch = d->currentWord[(int) d->currentWord.length() - 1] ).isPunct() && - ch != '(' && ch != '@' ) - d->currentWord.truncate( d->currentWord.length() - 1 ); - - if ( !d->currentWord.isEmpty() ) { - if ( isMisspelled( d->currentWord ) ) { - setFormat( d->currentPos, d->currentWord.length(), d->color ); -// setMisspelled( d->currentPos, d->currentWord.length(), true ); - } - } - d->currentWord = ""; -} - -TQObject *KDictSpellingHighlighter::KDictSpellingHighlighterPrivate::sDictionaryMonitor = 0; - -KDictSpellingHighlighter::KDictSpellingHighlighter( TQTextEdit *textEdit, - bool spellCheckingActive , - bool autoEnable, - const TQColor& spellColor, - bool colorQuoting, - const TQColor& depth0, - const TQColor& depth1, - const TQColor& depth2, - const TQColor& depth3, - KSpellConfig *spellConfig ) - : KSpellingHighlighter( textEdit, spellColor, - colorQuoting, depth0, depth1, depth2, depth3 ) -{ - d = new KDictSpellingHighlighterPrivate(); - - d->mSpellConfig = spellConfig; - d->globalConfig = ( !spellConfig ); - d->automatic = autoEnable; - d->active = spellCheckingActive; - d->checksRequested = 0; - d->checksDone = 0; - d->completeRehighlightRequired = false; - - KConfig *config = KGlobal::config(); - KConfigGroupSaver cs( config, "KSpell" ); - d->disablePercentage = config->readNumEntry( "KSpell_AsYouTypeDisablePercentage", 42 ); - d->disablePercentage = QMIN( d->disablePercentage, 101 ); - d->disableWordCount = config->readNumEntry( "KSpell_AsYouTypeDisableWordCount", 100 ); - - textEdit->installEventFilter( this ); - textEdit->viewport()->installEventFilter( this ); - - d->rehighlightRequest = new TQTimer(this); - connect( d->rehighlightRequest, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( slotRehighlight() )); - d->spellTimeout = new TQTimer(this); - connect( d->spellTimeout, TQT_SIGNAL( timeout() ), - this, TQT_SLOT( slotKSpellNotResponding() )); - - if ( d->globalConfig ) { - d->spellKey = spellKey(); - - if ( !d->sDictionaryMonitor ) - d->sDictionaryMonitor = new TQObject(); - } - else { - d->mDict = new TQDict<int>(4001); - connect( d->mSpellConfig, TQT_SIGNAL( configChanged() ), - this, TQT_SLOT( slotLocalSpellConfigChanged() ) ); - } - - slotDictionaryChanged(); - // whats this good for? - //startTimer( 2 * 1000 ); -} - -KDictSpellingHighlighter::~KDictSpellingHighlighter() -{ - delete d->spell; - d->spell = 0; - delete d->mDict; - d->mDict = 0; - delete d; -} - -void KDictSpellingHighlighter::slotSpellReady( KSpell *spell ) -{ - kdDebug(0) << "KDictSpellingHighlighter::slotSpellReady( " << spell << " )" << endl; - KConfigGroup cg( KGlobal::config(),"KSpell" ); - if ( cg.readEntry("KSpell_DoSpellChecking") != "0" ) - { - if ( d->globalConfig ) { - connect( d->sDictionaryMonitor, TQT_SIGNAL( destroyed()), - this, TQT_SLOT( slotDictionaryChanged() )); - } - if ( spell != d->spell ) - { - delete d->spell; - d->spell = spell; - } - d->spellReady = true; - const TQStringList l = KSpellingHighlighter::personalWords(); - for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { - d->spell->addPersonal( *it ); - } - connect( spell, TQT_SIGNAL( misspelling( const TQString &, const TQStringList &, unsigned int )), - this, TQT_SLOT( slotMisspelling( const TQString &, const TQStringList &, unsigned int ))); - connect( spell, TQT_SIGNAL( corrected( const TQString &, const TQString &, unsigned int )), - this, TQT_SLOT( slotCorrected( const TQString &, const TQString &, unsigned int ))); - d->checksRequested = 0; - d->checksDone = 0; - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 0, true ); - } -} - -bool KDictSpellingHighlighter::isMisspelled( const TQString &word ) -{ - if (!d->spellReady) - return false; - - // This debug is expensive, only enable it locally - //kdDebug(0) << "KDictSpellingHighlighter::isMisspelled( \"" << word << "\" )" << endl; - // Normally isMisspelled would look up a dictionary and return - // true or false, but kspell is asynchronous and slow so things - // get tricky... - // For auto detection ignore signature and reply prefix - if ( !d->autoReady ) - d->autoIgnoreDict.replace( word, Ignore ); - - // "dict" is used as a cache to store the results of KSpell - TQDict<int>* dict = ( d->globalConfig ? d->sDict() : d->mDict ); - if ( !dict->isEmpty() && (*dict)[word] == NotOkay ) { - if ( d->autoReady && ( d->autoDict[word] != NotOkay )) { - if ( !d->autoIgnoreDict[word] ) - ++d->errorCount; - d->autoDict.replace( word, NotOkay ); - } - - return d->active; - } - if ( !dict->isEmpty() && (*dict)[word] == Okay ) { - if ( d->autoReady && !d->autoDict[word] ) { - d->autoDict.replace( word, Okay ); - } - return false; - } - - if ((dict->isEmpty() || !((*dict)[word])) && d->spell ) { - int para, index; - textEdit()->getCursorPosition( ¶, &index ); - ++d->wordCount; - dict->replace( word, Unknown ); - ++d->checksRequested; - if (currentParagraph() != para) - d->completeRehighlightRequired = true; - d->spellTimeout->start( tenSeconds, true ); - d->spell->checkWord( word, false ); - } - return false; -} - -bool KSpellingHighlighter::intraWordEditing() const -{ - return d->intraWordEditing; -} - -void KSpellingHighlighter::setIntraWordEditing( bool editing ) -{ - d->intraWordEditing = editing; -} - -void KDictSpellingHighlighter::slotMisspelling (const TQString &originalWord, const TQStringList &suggestions, - unsigned int pos) -{ - Q_UNUSED( suggestions ); - // kdDebug() << suggestions.join( " " ).latin1() << endl; - if ( d->globalConfig ) - d->sDict()->replace( originalWord, NotOkay ); - else - d->mDict->replace( originalWord, NotOkay ); - - //Emit this baby so that apps that want to have suggestions in a popup over - //the misspelled word can catch them. - emit newSuggestions( originalWord, suggestions, pos ); -} - -void KDictSpellingHighlighter::slotCorrected(const TQString &word, - const TQString &, - unsigned int) - -{ - TQDict<int>* dict = ( d->globalConfig ? d->sDict() : d->mDict ); - if ( !dict->isEmpty() && (*dict)[word] == Unknown ) { - dict->replace( word, Okay ); - } - ++d->checksDone; - if (d->checksDone == d->checksRequested) { - d->spellTimeout->stop(); - slotRehighlight(); - } else { - d->spellTimeout->start( tenSeconds, true ); - } -} - -void KDictSpellingHighlighter::dictionaryChanged() -{ - TQObject *oldMonitor = KDictSpellingHighlighterPrivate::sDictionaryMonitor; - KDictSpellingHighlighterPrivate::sDictionaryMonitor = new TQObject(); - KDictSpellingHighlighterPrivate::sDict()->clear(); - delete oldMonitor; -} - -void KDictSpellingHighlighter::restartBackgroundSpellCheck() -{ - kdDebug(0) << "KDictSpellingHighlighter::restartBackgroundSpellCheck()" << endl; - slotDictionaryChanged(); -} - -void KDictSpellingHighlighter::setActive( bool active ) -{ - if ( active == d->active ) - return; - - d->active = active; - rehighlight(); - if ( d->active ) - emit activeChanged( i18n("As-you-type spell checking enabled.") ); - else - emit activeChanged( i18n("As-you-type spell checking disabled.") ); -} - -bool KDictSpellingHighlighter::isActive() const -{ - return d->active; -} - -void KDictSpellingHighlighter::setAutomatic( bool automatic ) -{ - if ( automatic == d->automatic ) - return; - - d->automatic = automatic; - if ( d->automatic ) - slotAutoDetection(); -} - -bool KDictSpellingHighlighter::automatic() const -{ - return d->automatic; -} - -void KDictSpellingHighlighter::slotRehighlight() -{ - kdDebug(0) << "KDictSpellingHighlighter::slotRehighlight()" << endl; - if (d->completeRehighlightRequired) { - rehighlight(); - } else { - int para, index; - textEdit()->getCursorPosition( ¶, &index ); - //rehighlight the current para only (undo/redo safe) - bool modified = textEdit()->isModified(); - textEdit()->insertAt( "", para, index ); - textEdit()->setModified( modified ); - } - if (d->checksDone == d->checksRequested) - d->completeRehighlightRequired = false; - TQTimer::singleShot( 0, this, TQT_SLOT( slotAutoDetection() )); -} - -void KDictSpellingHighlighter::slotDictionaryChanged() -{ - delete d->spell; - d->spellReady = false; - d->wordCount = 0; - d->errorCount = 0; - d->autoDict.clear(); - - d->spell = new KSpell( 0, i18n( "Incremental Spellcheck" ), this, - TQT_SLOT( slotSpellReady( KSpell * ) ), d->mSpellConfig ); -} - -void KDictSpellingHighlighter::slotLocalSpellConfigChanged() -{ - kdDebug(0) << "KDictSpellingHighlighter::slotSpellConfigChanged()" << endl; - // the spell config has been changed, so we have to restart from scratch - d->mDict->clear(); - slotDictionaryChanged(); -} - -TQString KDictSpellingHighlighter::spellKey() -{ - KConfig *config = KGlobal::config(); - KConfigGroupSaver cs( config, "KSpell" ); - config->reparseConfiguration(); - TQString key; - key += TQString::number( config->readNumEntry( "KSpell_NoRootAffix", 0 )); - key += '/'; - key += TQString::number( config->readNumEntry( "KSpell_RunTogether", 0 )); - key += '/'; - key += config->readEntry( "KSpell_Dictionary", "" ); - key += '/'; - key += TQString::number( config->readNumEntry( "KSpell_DictFromList", false )); - key += '/'; - key += TQString::number( config->readNumEntry( "KSpell_Encoding", KS_E_UTF8 )); - key += '/'; - key += TQString::number( config->readNumEntry( "KSpell_Client", KS_CLIENT_ISPELL )); - return key; -} - - -// Automatic spell checking support -// In auto spell checking mode disable as-you-type spell checking -// iff more than one third of words are spelt incorrectly. -// -// Words in the signature and reply prefix are ignored. -// Only unique words are counted. - -void KDictSpellingHighlighter::slotAutoDetection() -{ - if ( !d->autoReady ) - return; - - bool savedActive = d->active; - - if ( d->automatic ) { - // tme = Too many errors - bool tme = d->wordCount >= d->disableWordCount && d->errorCount * 100 >= d->disablePercentage * d->wordCount; - if ( d->active && tme ) - d->active = false; - else if ( !d->active && !tme ) - d->active = true; - } - if ( d->active != savedActive ) { - if ( d->wordCount > 1 ) - if ( d->active ) - emit activeChanged( i18n("As-you-type spell checking enabled.") ); - else - emit activeChanged( i18n( "Too many misspelled words. " - "As-you-type spell checking disabled." ) ); - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 100, true ); - } -} - -void KDictSpellingHighlighter::slotKSpellNotResponding() -{ - static int retries = 0; - if (retries < 10) { - if ( d->globalConfig ) - KDictSpellingHighlighter::dictionaryChanged(); - else - slotLocalSpellConfigChanged(); - } else { - setAutomatic( false ); - setActive( false ); - } - ++retries; -} - -bool KDictSpellingHighlighter::eventFilter( TQObject *o, TQEvent *e) -{ - if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(textEdit()) && (e->type() == TQEvent::FocusIn)) { - if ( d->globalConfig ) { - TQString skey = spellKey(); - if ( d->spell && d->spellKey != skey ) { - d->spellKey = skey; - KDictSpellingHighlighter::dictionaryChanged(); - } - } - } - - if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(textEdit()) && (e->type() == TQEvent::KeyPress)) { - TQKeyEvent *k = TQT_TQKEYEVENT(e); - d->autoReady = true; - if (d->rehighlightRequest->isActive()) // try to stay out of the users way - d->rehighlightRequest->changeInterval( 500 ); - if ( k->key() == Key_Enter || - k->key() == Key_Return || - k->key() == Key_Up || - k->key() == Key_Down || - k->key() == Key_Left || - k->key() == Key_Right || - k->key() == Key_PageUp || - k->key() == Key_PageDown || - k->key() == Key_Home || - k->key() == Key_End || - (( k->state() & ControlButton ) && - ((k->key() == Key_A) || - (k->key() == Key_B) || - (k->key() == Key_E) || - (k->key() == Key_N) || - (k->key() == Key_P))) ) { - if ( intraWordEditing() ) { - setIntraWordEditing( false ); - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 500, true ); - } - if (d->checksDone != d->checksRequested) { - // Handle possible change of paragraph while - // words are pending spell checking - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 500, true ); - } - } else { - setIntraWordEditing( true ); - } - if ( k->key() == Key_Space || - k->key() == Key_Enter || - k->key() == Key_Return ) { - TQTimer::singleShot( 0, this, TQT_SLOT( slotAutoDetection() )); - } - } - - else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(textEdit()->viewport()) && - ( e->type() == TQEvent::MouseButtonPress )) { - d->autoReady = true; - if ( intraWordEditing() ) { - setIntraWordEditing( false ); - d->completeRehighlightRequired = true; - d->rehighlightRequest->start( 0, true ); - } - } - - return false; -} - -#include "ksyntaxhighlighter.moc" |