24#include "KoBgSpellCheck.h"
25#include "KoBgSpellCheck.moc"
26#include "KoTextParag.h"
30#include "KoTextObject.h"
31#include "KoTextDocument.h"
34#include <tdespell2/backgroundchecker.h>
35#include <tdespell2/broker.h>
36#include <tdespell2/dictionary.h>
37#include <tdespell2/settings.h>
38#include <tdespell2/filter.h>
39using namespace KSpell2;
43#include <tdeversion.h>
49class KoBgSpellCheck::Private
54 TQPtrDict<KoTextParag> paragCache;
56 KoTextParag* intraWordParag;
57 int intraWordPosition;
60static const int delayAfterMarked = 10;
62KoBgSpellCheck::KoBgSpellCheck(
const Broker::Ptr& broker, TQObject *parent,
64 : TQObject( parent,
name )
66#ifdef DEBUG_BGSPELLCHECKING
67 kdDebug(32500) <<
"KoBgSpellCheck::KoBgSpellCheck " <<
this << endl;
70 d->startupChecking =
false;
72 d->intraWordParag = 0;
73 d->intraWordPosition = 0;
74 d->backSpeller =
new KoSpell( broker,
this,
"KoSpell" );
76 connect( d->backSpeller, TQ_SIGNAL(misspelling(
const TQString&,
int)),
77 TQ_SLOT(spellCheckerMisspelling(
const TQString &,
int )) );
78 connect( d->backSpeller, TQ_SIGNAL(done()),
79 TQ_SLOT(spellCheckerDone()) );
80 connect( d->backSpeller, TQ_SIGNAL(aboutToFeedText()),
81 TQ_SLOT(slotClearPara()) );
84KoBgSpellCheck::~KoBgSpellCheck()
89void KoBgSpellCheck::registerNewTextObject(
KoTextObject *obj )
93 connect( obj, TQ_SIGNAL(paragraphCreated(KoTextParag*)),
94 TQ_SLOT(slotParagraphCreated(KoTextParag*)) );
95 connect( obj, TQ_SIGNAL(paragraphModified(KoTextParag*,
int,
int,
int)),
96 TQ_SLOT(slotParagraphModified(KoTextParag*,
int,
int,
int)) );
97 connect( obj, TQ_SIGNAL(paragraphDeleted(KoTextParag*)),
98 TQ_SLOT(slotParagraphDeleted(KoTextParag*)) );
101void KoBgSpellCheck::setEnabled(
bool b )
103 d->backSpeller->settings()->setBackgroundCheckerEnabled( b );
110bool KoBgSpellCheck::enabled()
const
112 return d->backSpeller->settings()->backgroundCheckerEnabled();
115void KoBgSpellCheck::start()
120 d->startupChecking =
true;
123 d->backSpeller->check( itr );
124 d->backSpeller->start();
127void KoBgSpellCheck::spellCheckerMisspelling(
const TQString &old,
int pos )
129 KoTextParag* parag = d->backSpeller->currentParag();
130#ifdef DEBUG_BGSPELLCHECKING
131 kdDebug(32500) <<
"KoBgSpellCheck::spellCheckerMisspelling parag=" << parag
132 <<
" (id=" << parag->paragId() <<
", length="
133 << parag->length() <<
") pos=" << pos <<
" length="
134 << old.length() << endl;
136 markWord( parag, pos, old.length(),
true );
139 parag->document()->emitRepaintChanged();
141 if ( d->startupChecking && d->marked > delayAfterMarked ) {
143 TQTimer::singleShot( 1000,
this, TQ_SLOT(checkerContinue()) );
145 if ( d->startupChecking )
151void KoBgSpellCheck::markWord( KoTextParag* parag,
int pos,
int length,
bool misspelled )
153 if ( pos >= parag->length() ) {
154 kdDebug(32500) <<
"markWord: " << pos <<
" is out of parag (length=" << parag->length() <<
")" << endl;
157 if ( misspelled && parag == d->intraWordParag &&
158 d->intraWordPosition >= pos &&
159 d->intraWordPosition < pos+length ) {
160#ifdef DEBUG_BGSPELLCHECKING
161 kdDebug(32500) <<
"markWord: " << parag <<
" " << pos <<
" to " << pos+length <<
" - word being edited" << endl;
166 KoTextStringChar *ch = parag->at( pos );
168 format.setMisspelled( misspelled );
169#ifdef DEBUG_BGSPELLCHECKING
170 kdDebug(32500) <<
"markWord: changing mark from " << pos <<
" length=" << length <<
" misspelled=" << misspelled << endl;
172 parag->setFormat( pos, length, &format,
true, KoTextFormat::Misspelled );
173 parag->setChanged(
true );
177void KoBgSpellCheck::checkerContinue()
180 d->backSpeller->continueChecking();
183void KoBgSpellCheck::spellCheckerDone()
185 d->startupChecking =
false;
187 if ( d->paragCache.isEmpty() )
190 TQPtrDictIterator<KoTextParag> itr( d->paragCache );
191 KoTextParag *parag = d->paragCache.take( itr.currentKey() );
192#ifdef DEBUG_BGSPELLCHECKING
193 kdDebug(32500) <<
"spellCheckerDone : " << parag <<
", cache = "<< d->paragCache.count() <<endl;
195 d->backSpeller->check( parag );
198void KoBgSpellCheck::stop()
200#ifdef DEBUG_BGSPELLCHECKING
201 kdDebug(32500) <<
"KoBgSpellCheck::stopSpellChecking" << endl;
203 d->backSpeller->stop();
206void KoBgSpellCheck::slotParagraphCreated( KoTextParag* parag )
208 parag->string()->setNeedsSpellCheck(
true );
211 if ( !d->backSpeller->check( parag ) ) {
212 d->paragCache.insert( parag, parag );
216void KoBgSpellCheck::slotParagraphModified( KoTextParag* parag,
int ,
217 int pos,
int length )
219 parag->string()->setNeedsSpellCheck(
true );
223 if ( d->backSpeller->checking() ) {
224 d->paragCache.insert( parag, parag );
227#ifdef DEBUG_BGSPELLCHECKING
228 kdDebug(32500) <<
"Para modified " << parag <<
" pos = "<<pos<<
", length = "<< length <<endl;
231#if TDE_VERSION > TDE_MAKE_VERSION(3,3,0)
233 TQString str = parag->string()->stringToSpellCheck();
236 filter.setBuffer( str );
238 filter.setCurrentPosition( TQMAX( 0, pos - 2 ) );
239 int curPos = filter.currentPosition();
241 filter.setSettings( d->backSpeller->settings() );
246 markWord( parag, curPos, parag->length() - curPos,
false );
248 for ( Word w = filter.nextWord(); !w.end; w = filter.nextWord() ) {
249 bool misspelling = !d->backSpeller->checkWord( w.word );
251 markWord( parag, w.start, w.word.length(), misspelling );
253 if ( parag->hasChanged() )
254 parag->document()->emitRepaintChanged();
259 bool misspelled = !d->backSpeller->checkWordInParagraph( parag, pos,
261 markWord( parag, start, word.length(), misspelled );
262 parag->document()->emitRepaintChanged();
266 d->backSpeller->check( parag );
270void KoBgSpellCheck::slotParagraphDeleted( KoTextParag* parag )
272 d->paragCache.take( parag );
273 if ( parag == d->intraWordParag )
274 d->intraWordParag = 0;
281void KoBgSpellCheck::slotClearPara()
283 KoTextParag *parag = d->backSpeller->currentParag();
291 KoTextStringChar *ch = parag->at( 0 );
293 format.setMisspelled(
false );
294#ifdef DEBUG_BGSPELLCHECKING
295 kdDebug(32500) <<
"clearPara: resetting mark on paragraph " << parag->paragId() << endl;
297 parag->setFormat( 0, parag->length()-1, &format,
true,
298 KoTextFormat::Misspelled );
299 parag->setChanged(
true );
300 parag->document()->emitRepaintChanged();
303KSpell2::Settings * KoBgSpellCheck::settings()
const
305 return d->backSpeller->settings();
308void KoBgSpellCheck::setIntraWordEditing( KoTextParag* parag,
int index )
310 KoTextParag* oldIntraWordParag = d->intraWordParag;
311 int oldIntraWordPosition = d->intraWordPosition;
313 d->intraWordParag = parag;
314 d->intraWordPosition = index;
316 if ( oldIntraWordParag && !parag ) {
319 slotParagraphModified( oldIntraWordParag, 0 , oldIntraWordPosition, 1 );
KOffice spell checking object Used for both spell-checking-with-a-dialog (directly) and background sp...
Each character (KoTextStringChar) points to a KoTextFormat that defines the formatting of that charac...
A convenient way to iterate over paragraphs, possibly in multiple textobjects, with many options (fro...
The KoTextObject is the high-level object that contains a KoTextDocument (the list of paragraphs),...
const char * name(StdAction id)