00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "KoSpell.h"
00024
00025 #include "KoTextObject.h"
00026 #include "KoTextParag.h"
00027 #include "KoTextIterator.h"
00028
00029 #include <sonnet/loader.h>
00030 #include <sonnet/filter.h>
00031
00032 #include <kglobal.h>
00033 #include <klocale.h>
00034 #include <kdebug.h>
00035
00036 #include <QTimer>
00037
00038
00039
00040 using namespace KSpell2;
00041
00042 class KoSpell::Private
00043 {
00044 public:
00045 KoTextIterator *itr;
00046 KoTextParag *parag;
00047 bool dialog;
00048 bool needsIncrement;
00049 KoTextDocument *lastTxtDocument;
00050 };
00051
00052 KoSpell::KoSpell( const KSpell2::Loader::Ptr& loader, QObject *parent,
00053 const char* )
00054 : BackgroundChecker( loader, parent )
00055 {
00056 d = new Private;
00057 d->parag = 0;
00058 d->itr = 0;
00059 d->dialog = false;
00060 d->needsIncrement = false;
00061 d->lastTxtDocument = 0;
00062 }
00063
00064 KoSpell::~KoSpell()
00065 {
00066 delete d;
00067 }
00068
00069 bool KoSpell::check( KoTextIterator *itr, bool dialog )
00070 {
00071 bool ret = false;
00072
00073 if ( !itr )
00074 return ret;
00075
00076 d->itr = itr;
00077 connect( d->itr, SIGNAL( currentParagraphDeleted() ), SLOT( slotCurrentParagraphDeleted() ) );
00078 d->lastTxtDocument = d->itr->currentTextObject()->textDocument();
00079 d->needsIncrement = false;
00080 ret = !d->itr->atEnd();
00081 d->dialog = dialog;
00082
00083 return ret;
00084 }
00085
00086 bool KoSpell::check( KoTextParag *parag )
00087 {
00088 if ( checking() || !parag )
00089 return false;
00090
00091 d->parag = parag;
00092 d->lastTxtDocument = d->parag->textDocument();
00093
00094 start();
00095
00096 return true;
00097 }
00098
00099 bool KoSpell::checkWordInParagraph( KoTextParag *parag, int pos,
00100 QString& foundWord, int& start )
00101 {
00102 if ( !parag ) {
00103 start = -1;
00104 return false;
00105 }
00106
00107 d->parag = parag;
00108 d->lastTxtDocument = d->parag->textDocument();
00109 QString str = parag->string()->stringToSpellCheck();
00111 Filter filter;
00112 filter.setBuffer( str );
00113 filter.setSettings( loader()->settings() );
00114 Word w = filter.wordAtPosition( pos );
00115 foundWord = w.word;
00116 start = w.start;
00117 #ifdef DEBUG_SPELL
00118 kDebug()<<"KoSpell: WORD IS " << w.word << ", pos = "<< pos
00119 << ", start = "<< w.start <<endl;
00120 #endif
00121 return checkWord( w.word );
00122 }
00123
00124 QString KoSpell::getMoreText()
00125 {
00126 #ifdef DEBUG_SPELL
00127 kDebug()<<"getMoreText: dialog = " << d->dialog << ", itr = "
00128 << d->itr << ", atEnd = "
00129 << ( ( d->itr ) ? d->itr->atEnd() : true )
00130 << " d->parag=" << d->parag
00131 << endl;
00132 #endif
00133
00134 if ( d->needsIncrement && d->itr && !d->itr->atEnd() ) {
00135 ++( *d->itr );
00136 if ( !d->itr->atEnd() )
00137 d->lastTxtDocument = d->itr->currentTextObject()->textDocument();
00138 }
00139
00140 if ( d->itr && d->itr->atEnd() )
00141 return QString::null;
00142
00143 if ( !d->dialog && !d->itr ) {
00144 QString str = d->parag ? d->parag->string()->stringToSpellCheck() : QString::null;
00145 if ( !str.isEmpty() )
00146 emit aboutToFeedText();
00147 return str;
00148 }
00149
00150 d->needsIncrement = true;
00151
00152 QString text = d->itr->currentText();
00153 d->parag = d->itr->currentParag();
00154
00155 emit aboutToFeedText();
00156
00157 while ( !d->dialog && d->parag ) {
00158 if ( d->parag->string()->needsSpellCheck() &&
00159 d->parag->length() > 1 )
00160 break;
00161 ++(*d->itr);
00162 if ( d->itr->atEnd() ) {
00163 d->needsIncrement = false;
00164 return QString::null;
00165 }
00166 d->parag = d->itr->currentParag();
00167 d->lastTxtDocument = d->parag->textDocument();
00168 text = d->itr->currentText();
00169 }
00170
00171 d->parag->string()->setNeedsSpellCheck( false );
00172
00173 return text;
00174 }
00175
00176 void KoSpell::finishedCurrentFeed()
00177 {
00178 emit paragraphChecked( d->parag );
00179 }
00180
00181 KoTextParag *KoSpell::currentParag() const
00182 {
00183 return d->parag;
00184 }
00185
00186 KoTextObject *KoSpell::currentTextObject() const
00187 {
00188 if ( d->itr && !d->itr->atEnd() )
00189 return d->itr->currentTextObject();
00190 return 0;
00191 }
00192
00193 int KoSpell::currentStartIndex() const
00194 {
00195 if ( d->itr && !d->itr->atEnd() )
00196 return d->itr->currentStartIndex();
00197 return 0;
00198 }
00199
00200 void KoSpell::slotCurrentParagraphDeleted()
00201 {
00202 #ifdef DEBUG_SPELL
00203 kDebug() << "KoSpell::slotCurrentParagraphDeleted itr=" << d->itr << endl;
00204 #endif
00205 stop();
00206 if ( d->itr ) {
00207 d->needsIncrement = false;
00208 d->parag = d->itr->currentParag();
00209 #ifdef DEBUG_SPELL
00210 kDebug() << "KoSpell::slotCurrentParagraphDeleted d->parag=" << d->parag << endl;
00211 #endif
00212 start();
00213 } else {
00214 d->parag = 0;
00215 }
00216 }
00217
00218 bool KoSpell::checking() const
00219 {
00220 #ifdef DEBUG_SPELL
00221 kDebug()<< "KoSpell::checking: itr=" << d->itr
00222 << ", atEnd=" << ( ( d->itr ) ? d->itr->atEnd() : false )
00223 << ", filter()->atEnd()=" << filter()->atEnd()
00224 << endl;
00225 #endif
00226 if ( d->itr ) {
00227 if ( d->itr->atEnd() &&
00228 filter()->atEnd() )
00229 return false;
00230 else
00231 return true;
00232 } else
00233 return !filter()->atEnd();
00234 }
00235
00236 KoTextDocument * KoSpell::textDocument() const
00237 {
00238 return d->lastTxtDocument;
00239 }
00240
00241 KSpell2::Settings * KoSpell::settings() const
00242 {
00243 return loader()->settings();
00244 }
00245
00246 #include "KoSpell.moc"