/* This file is part of KOffice Copyright (C) 2004 Zack Rusin <zack@kde.org> Original version written by David Sweet <dsweet@kde.org> and Wolfram Diestel <wolfram@steloj.de> 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 "config.h" #include "KoSpell.h" #include "KoTextObject.h" #include "KoTextParag.h" #include "KoTextIterator.h" #include <tdespell2/broker.h> #include <tdespell2/filter.h> #include <tdeglobal.h> #include <tdelocale.h> #include <kdebug.h> #include <tqtimer.h> //#define DEBUG_SPELL using namespace KSpell2; class KoSpell::Private { public: KoTextIterator *itr; KoTextParag *parag; bool dialog; bool needsIncrement; KoTextDocument *lastTxtDocument; }; KoSpell::KoSpell( const Broker::Ptr& broker, TQObject *parent, const char *name ) : BackgroundChecker( broker, parent, name ) { d = new Private; d->parag = 0; d->itr = 0; d->dialog = false; d->needsIncrement = false; d->lastTxtDocument = 0; } KoSpell::~KoSpell() { delete d; } bool KoSpell::check( KoTextIterator *itr, bool dialog ) { bool ret = false; if ( !itr ) return ret; d->itr = itr; connect( d->itr, TQT_SIGNAL( currentParagraphDeleted() ), TQT_SLOT( slotCurrentParagraphDeleted() ) ); d->lastTxtDocument = d->itr->currentTextObject()->textDocument(); d->needsIncrement = false; ret = !d->itr->atEnd(); d->dialog = dialog; return ret; } bool KoSpell::check( KoTextParag *parag ) { if ( checking() || !parag ) return false; d->parag = parag; d->lastTxtDocument = d->parag->textDocument(); start(); return true; } bool KoSpell::checkWordInParagraph( KoTextParag *parag, int pos, TQString& foundWord, int& start ) { if ( !parag ) { start = -1; return false; } d->parag = parag; d->lastTxtDocument = d->parag->textDocument(); TQString str = parag->string()->stringToSpellCheck(); /// ##### do we really need to create a Filter every time? Filter filter; filter.setBuffer( str ); filter.setSettings( broker()->settings() ); Word w = filter.wordAtPosition( pos ); foundWord = w.word; start = w.start; #ifdef DEBUG_SPELL kdDebug()<<"KoSpell: WORD IS " << w.word << ", pos = "<< pos << ", start = "<< w.start <<endl; #endif return checkWord( w.word ); } TQString KoSpell::getMoreText() { #ifdef DEBUG_SPELL kdDebug()<<"getMoreText: dialog = " << d->dialog << ", itr = " << d->itr << ", atEnd = " << ( ( d->itr ) ? d->itr->atEnd() : true ) << " d->parag=" << d->parag << endl; #endif if ( d->needsIncrement && d->itr && !d->itr->atEnd() ) { ++( *d->itr ); if ( !d->itr->atEnd() ) d->lastTxtDocument = d->itr->currentTextObject()->textDocument(); } if ( d->itr && d->itr->atEnd() ) return TQString(); if ( !d->dialog && !d->itr ) { TQString str = d->parag ? d->parag->string()->stringToSpellCheck() : TQString(); if ( !str.isEmpty() ) emit aboutToFeedText(); return str; } d->needsIncrement = true; TQString text = d->itr->currentText(); d->parag = d->itr->currentParag(); emit aboutToFeedText(); //kdDebug()<<"here 2"<<endl; while ( !d->dialog && d->parag ) { if ( d->parag->string()->needsSpellCheck() && d->parag->length() > 1 ) break; ++(*d->itr); if ( d->itr->atEnd() ) { d->needsIncrement = false; return TQString(); } d->parag = d->itr->currentParag(); d->lastTxtDocument = d->parag->textDocument(); text = d->itr->currentText(); } d->parag->string()->setNeedsSpellCheck( false ); return text; } void KoSpell::finishedCurrentFeed() { emit paragraphChecked( d->parag ); } KoTextParag *KoSpell::currentParag() const { return d->parag; } KoTextObject *KoSpell::currentTextObject() const { if ( d->itr && !d->itr->atEnd() ) return d->itr->currentTextObject(); return 0; } int KoSpell::currentStartIndex() const { if ( d->itr && !d->itr->atEnd() ) return d->itr->currentStartIndex(); return 0; } void KoSpell::slotCurrentParagraphDeleted() { #ifdef DEBUG_SPELL kdDebug() << "KoSpell::slotCurrentParagraphDeleted itr=" << d->itr << endl; #endif stop(); if ( d->itr ) { d->needsIncrement = false; d->parag = d->itr->currentParag(); #ifdef DEBUG_SPELL kdDebug() << "KoSpell::slotCurrentParagraphDeleted d->parag=" << d->parag << endl; #endif start(); } else { d->parag = 0; } } bool KoSpell::checking() const { #ifdef DEBUG_SPELL kdDebug()<< "KoSpell::checking: itr=" << d->itr << ", atEnd=" << ( ( d->itr ) ? d->itr->atEnd() : false ) << ", filter()->atEnd()=" << filter()->atEnd() << endl; #endif if ( d->itr ) { if ( d->itr->atEnd() && filter()->atEnd() ) return false; else return true; } else return !filter()->atEnd(); } KoTextDocument * KoSpell::textDocument() const { return d->lastTxtDocument; } KSpell2::Settings * KoSpell::settings() const { return broker()->settings(); } #include "KoSpell.moc"