Subversion Repositories Scribus

Rev

Rev 11088 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/

#include "aspellpluginimpl.h"
#include "pageitem_textframe.h"
#include <QMessageBox>
const char* AspellPluginImpl::kDEF_CONTEXT = "AspellPlugin";
const QString AspellPluginImpl::kDEF_ASPELL_ENTRY =
        QString( "en" ) + Speller::Aspell::Suggest::kDICT_DELIM +
        QString( "en" ) + Speller::Aspell::Suggest::kDICT_DELIM +
        QString( "*" ) + Speller::Aspell::Suggest::kDICT_DELIM +
        QString( "60" );  // I.e., en/en/*/60 corresponding to default English dictionary

// Initialize members here, if any
AspellPluginImpl::AspellPluginImpl(ScribusDoc* doc, QWidget* parent) :
        QDialog( parent ), fdoc( doc ), fpos(0), fidx(0)
{
        // Constructor.
        setupUi( this );
        setModal( true );

        rememberedWords.clear();
        // Fill in choices in combo box for text to be spell-checked.
//      ftextSelect->insertItem( 0, "None" );
//      ftextSelect->insertItem( 1, "Selected frame" );
//      ftextSelect->insertItem( 2, "Active page" );
//      ftextSelect->insertItem( 3, "All items" );

        // Clear out default suggestions listbox entry: "New item"

        // Get stored language, jargon, encoding settings
        fprefs = PrefsManager::instance()->prefsFile->getPluginContext( kDEF_CONTEXT );
        getPreferences();

        // Start with settings tab, if dictionary had not been selected
        // earlier.
        fmainTab->setCurrentIndex( 0 );
        QString text = tr( "Loaded " ) + (fentry == kDEF_ASPELL_ENTRY ? tr( "default " ) : "") + fentry + tr( " aspell dictionary." );
        doc->scMW()->setStatusBarInfoText( text );

        ftextDictDetails->setText( fentry );

        try
        {
                // Deactivate GUI elements in spell-checking tab until an
                // aspell dictionary is chosen.
                deactivateSpellGUI();

                // Create speller, and get list of available aspell
                // dictionaries.
                fsuggest = new Speller::Aspell::Suggest( flang.toUtf8().data(), fjargon.toUtf8().data(), fencoding.toUtf8().data() );
                Q_CHECK_PTR( fsuggest );

                // Get list of available aspell dictionaries
                std::vector<std::string> entries;
                fsuggest->listDicts( entries );
                unsigned int idx = 0;
                for( std::vector<std::string>::const_iterator i = entries.begin(); i != entries.end(); ++i )
                {
                        // FIXME: Handle encodings other than UTF-8.
                        flistDicts->insertItem( idx, i->c_str() );
                        idx++;
                }
        }
        catch( const std::invalid_argument& err )
        {
                QString warn = tr( "aspellplugin (AspellPluginImpl::"
                                   "AspellPluginImpl): Error in aspell "
                                   "speller configuration." );
                qWarning( "%s", warn.toUtf8().data() );
        }
        catch( const std::runtime_error& err )
        {
                QString warn = tr( "aspellplugin (AspellPluginImpl::"
                                   "AspellPluginImpl): Error in creating "
                                   "aspell speller." );
                qWarning( "%s", warn.toUtf8().data() );
        }
        activateSpellGUI();
        parseSelection();
}
//__________________________________________________________________________
AspellPluginImpl::~AspellPluginImpl()
{
        // Destructor
        try
        {
                fsuggest->saveLists();
        }
        catch( const std::runtime_error& err )
        {
                qWarning( "aspellplugin (AspellPluginImpl::~AspellPlugin"
                          "Impl): Error in saving aspell word lists." );
        }

        delete fsuggest;
}
//__________________________________________________________________________
void AspellPluginImpl::activateAll()
{
        // Activates all GUI elements in spell-checking tab. Called once an
        // aspell dictionary has been selected.
        fmainTab->widget(0)->setEnabled( true );
}
//__________________________________________________________________________
void AspellPluginImpl::activateSpellGUI()
{
        // Activates spell-checking GUI elements in spell-checking
        // tab, i.e., everything except combo box at top
        fcurrWord->setEnabled( true );
        flistReplacements->setEnabled( true );
        fchangeBtn->setEnabled( true );
        fchangeAllBtn->setEnabled( true );
        fskipAllBtn->setEnabled( true );
        fskipBtn->setEnabled( true );
        faddWordBtn->setEnabled( true );
        ftextLabel1->setEnabled( true );
        ftextLabel2->setEnabled( true );
        ftextLabel3->setEnabled( true );
        ftextLabel4->setEnabled( true );
        fmisSpelling->setEnabled( true );
        ftextDictDetails->setEnabled( true );
}
//__________________________________________________________________________
void AspellPluginImpl::activateTextSelect()
{
        // Activates text select combo box at top of spell-checking tab.
//      fgroupSelect->setEnabled( true );
//      ftextSelect->setEnabled( true );
}
//__________________________________________________________________________
void AspellPluginImpl::deactivateAll()
{
        // Deactivates all GUI elements in spell-checking tab,
        fmainTab->widget(0)->setEnabled( false );
}
//__________________________________________________________________________
void AspellPluginImpl::deactivateSpellGUI()
{
        // Deactivates spell-checking GUI elements in spell-checking tab,
        // i.e., everything except combo box at top
        fcurrWord->setEnabled( false );
        flistReplacements->setEnabled( false );
        fchangeBtn->setEnabled( false );
        fchangeAllBtn->setEnabled( false );
        fskipAllBtn->setEnabled( false );
        fskipBtn->setEnabled( false );
        faddWordBtn->setEnabled( false );
        ftextLabel1->setEnabled( false );
        ftextLabel2->setEnabled( false );
        ftextLabel3->setEnabled( false );
        ftextLabel4->setEnabled( false );
        fmisSpelling->setEnabled( false );
        ftextDictDetails->setEnabled( false );
}
//__________________________________________________________________________
void AspellPluginImpl::deactivateTextSelect()
{
        // Deactivates text select combo box at top of spell-checking tab.
//      fgroupSelect->setEnabled( false );
//      ftextSelect->setEnabled( false );
}
//__________________________________________________________________________
void AspellPluginImpl::nextWord()
{
        QString wordBoundaries = QString(" .,:;\"'!?\n");
        uint len = fFrame->itemText.length();
        while (fpos < len && wordBoundaries.indexOf(fFrame->itemText.text(fpos)) >= 0)
        {
                ++fpos;
        }
        int pa = fpos;
        int pe = 0;
        while (fpos < len && wordBoundaries.indexOf(fFrame->itemText.text(fpos)) < 0)
        {
                ++fpos;
        }
        pe = fpos;
        fcontent = fFrame->itemText.text(pa, pe - pa);
        fpos = pa;
        // Called to skip to the beginning of the next word. 'fpos' is
        // set to the position in 'fcontent' of the beginning of this
        // word, and 'fidx' is set to the index of this word in 'fwordlist'.
//#if 0
//      std::cerr << "nextWord: before, pos = " << fpos << ", length = "
//                << fwordlist[fidx].length() << "\n";
//#endif
        // FIXME: Regexp searches are probably expensive. So, we should
        // replace these with something else. Certainly the first find()
        // can be replaced by adding the length of the word just replaced
        // to 'fpos'.
        // Skip to next whitespace character, i.e., end of last word.
//      fpos = fcontent.indexOf( QRegExp( "\\s|\\W|\\d|\\n|\\r|\\t" ), fpos );
        // Skip to next non-whitespace character, i.e., beginning of
        // next word.
//      fpos = fcontent.indexOf( QRegExp( "\\w" ), fpos );
//#if 0
//      std::cerr << "nextWord: after, pos = " << fpos << "\n";
//#endif
//      fidx++;  // Increment index in 'fcontent'
}
//__________________________________________________________________________
void AspellPluginImpl::checkText()
{
        // Called from parseXXX(), after filling in the currently
        // relevant text into 'fcontent'. Handles spell-checking of
        // the text.
        while (fpos < static_cast<uint>(fFrame->itemText.length()))
        {
                std::vector<std::string> replacement;
                bool status = fsuggest->checkWord(fcontent.toUtf8().data(), replacement);
                if (!status)
                {
                        fmisSpelling->setText( fcontent );
                        fcurrWord->setText( "" );
                        flistReplacements->clear();
                        unsigned int idx = 0;
                        for( std::vector<std::string>::const_iterator i = replacement.begin(); i != replacement.end(); ++i )
                        {
                        // FIXME: Handle encodings other than UTF-8.
                                QString dict = QString::fromUtf8(i->c_str());
                                flistReplacements->insertItem( idx, dict );
                                idx++;
                        }
                        if( flistReplacements->count() > 0 )
                        {
                                // FIXME: Is this the correct substitute for
                                // setSelected()?
                                flistReplacements->setCurrentRow( 0 );
                                fcurrWord->setText( flistReplacements->currentItem()->text() );
                        }
                        if (rememberedWords.contains(fcontent))
                        {
                                QString repl = rememberedWords.value(fcontent);
                                int cs, cx;
                                if (fcontent.length() == repl.length())
                                {
                                        for (cs = 0; cs < fcontent.length(); ++cs)
                                                fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                                }
                                else
                                {
                                        if (fcontent.length() < repl.length())
                                        {
                                                for (cs = 0; cs < fcontent.length(); ++cs)
                                                        fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                                                for (cx = cs; cx < repl.length(); ++cx)
                                                        fFrame->itemText.insertChars(fpos+cx, repl.mid(cx,1), true);
                                        }
                                        else
                                        {
                                                for (cs = 0; cs < repl.length(); ++cs)
                                                        fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                                                fFrame->itemText.removeChars(fpos+cs, fcontent.length() - cs);
                                        }
                                }
                        }
                        else
                                break;
                }
                fpos += fcontent.length();
                nextWord();
        }
}
//__________________________________________________________________________
void AspellPluginImpl::spellCheckDone()
{
        // Called once all words in the current text, i.e., in 'fcontent'
        // have been spell-checked. Pops up an information dialog.
        QMessageBox::information(fdoc->scMW(), tr("Spell-Checker"), tr("Spell-checking completed."));
        if( fFrame && fFrame->asTextFrame() )
                fFrame->asTextFrame()->invalidateLayout();
        if( fnchanges.fntot > 0 )
        {
                fdoc->changed();
        }
        // Redraw document
        fdoc->view()->DrawNew();
        QApplication::restoreOverrideCursor();
        fdoc->scMW()->setStatusBarInfoText(tr("Spell-checking done." ));
        fdoc->scMW()->mainWindowProgressBar->reset();
        close();
}
//__________________________________________________________________________
void AspellPluginImpl::checkWord(const QString& word)
{
        // Called when "Spell-check" button is clicked, or return pressed in
        // text entry box.  Spell-checks current word (in the text entry box).
        std::vector<std::string> replacement;
        bool status = fsuggest->checkWord(word.toUtf8().data(), replacement);
#if 0
        std::cerr << "checkWord: checked \"" << word << "\". "
          "Status = " << (status ? 1 : 0) << '\n';
#endif
        if( status )
        {
                // FIXME: Recursive calls
                nextWord();
                checkText();
        }
        else
        {
                fmisSpelling->setText( fwordlist[fidx] );
                fcurrWord->setText( "" );
                flistReplacements->clear();
                unsigned int idx = 0;
                for( std::vector<std::string>::const_iterator i =
                             replacement.begin();
                     i != replacement.end();
                     ++i )
                {
                        // FIXME: Handle encodings other than UTF-8.
                        QString dict = QString::fromUtf8(i->c_str());
                        flistReplacements->insertItem( idx, dict );
                        idx++;
                }

                if( flistReplacements->count() > 0 )
                {
                        // FIXME: Is this the correct substitute for
                        // setSelected()?
                        flistReplacements->setCurrentRow( 0 );
                        fcurrWord->setText( flistReplacements->currentItem()->text() );
                }
        }
}
//__________________________________________________________________________
void AspellPluginImpl::on_fcloseBtn_clicked()
{
        // Called when the "Close" button is clicked. Makes any pending
        // replacements and closes the spell-checking window.
#if 0
        std::cerr << "on_fcloseBtn_clicked: Making replacements.\n";
#endif
        spellCheckDone();  // Also closes spell-checking window.
}
//__________________________________________________________________________
void AspellPluginImpl::on_fchangeBtn_clicked()
{
        // Called when the "Change" button is clicked. Replaces the word
        // being spell-checked with the current word in text edit box.
        // FIXME: Handle encodings other than UTF-8.
        QString repl = fcurrWord->toPlainText();
        int cs, cx;
        if (fcontent.length() == repl.length())
        {
                for (cs = 0; cs < fcontent.length(); ++cs)
                        fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
        }
        else
        {
                if (fcontent.length() < repl.length())
                {
                        for (cs = 0; cs < fcontent.length(); ++cs)
                                fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                        for (cx = cs; cx < repl.length(); ++cx)
                                fFrame->itemText.insertChars(fpos+cx, repl.mid(cx,1), true);
                }
                else
                {
                        for (cs = 0; cs < repl.length(); ++cs)
                                fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                        fFrame->itemText.removeChars(fpos+cs, fcontent.length() - cs);
                }
        }
        fpos += fcontent.length();
        nextWord();
        checkText();
}
//__________________________________________________________________________
void AspellPluginImpl::on_fchangeAllBtn_clicked()
{
        // Called when the "Change All" button is clicked. Replaces all
        // instances of the word being spell-checked with the current word in
        // text edit box.
        // FIXME: Change commented-out statement below
        // fnchanges.fnwords += fcontent.contains( fwordlist[fidx] );
        // FIXME: Is this the right replacement for fcurrWord->text()?
        QString repl = fcurrWord->toPlainText();
        int cs, cx;
        if (fcontent.length() == repl.length())
        {
                for (cs = 0; cs < fcontent.length(); ++cs)
                        fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
        }
        else
        {
                if (fcontent.length() < repl.length())
                {
                        for (cs = 0; cs < fcontent.length(); ++cs)
                                fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                        for (cx = cs; cx < repl.length(); ++cx)
                                fFrame->itemText.insertChars(fpos+cx, repl.mid(cx,1), true);
                }
                else
                {
                        for (cs = 0; cs < repl.length(); ++cs)
                                fFrame->itemText.replaceChar(fpos+cs, repl[cs]);
                        fFrame->itemText.removeChars(fpos+cs, fcontent.length() - cs);
                }
        }
        if (!rememberedWords.contains(fcontent))
                rememberedWords.insert(fcontent, repl);
        fpos += fcontent.length();
        nextWord();  // Go to next word
        checkText();
}
//__________________________________________________________________________
void AspellPluginImpl::on_fskipBtn_clicked()
{
        // Called when the "Skip" button is clicked. Skips the word currently
        // being spell-checked.
        fpos += fcontent.length();
        nextWord();  // Go to next word
        checkText();
}
//__________________________________________________________________________
void AspellPluginImpl::on_fskipAllBtn_clicked()
{
        // Called when the "Skip All" button is clicked. Puts the word
        // currently being spell-checked into the list of words to be ignored
        // for this session.
        try
        {
#if 0
                std::cerr << "on_fskipAllBtn_clicked: Ignoring \"" <<
                  fwordlist[fidx] << "\"\n";
#endif
                fsuggest->ignoreWord( fcontent.toUtf8().data() );
        }
        catch( const std::runtime_error& err )
        {
               
                QString warn =
                  tr( "AspellPluginImpl::on_fskipAllBtn_clicked(): Unable "
                      "to skip all instances of \"" ) + fcontent +
                  tr(" by adding it to the session list.");
                qWarning( "%s", warn.toUtf8().data() );
        }
        fpos += fcontent.length();
        nextWord();  // Go to next word
        checkText();
}
//__________________________________________________________________________
void AspellPluginImpl::on_faddWordBtn_clicked()
{
        // Called when the "Add word" button is clicked. Adds word to personal
        // word list.
        try
        {
                // FIXME: Handle encodings other than UTF-8.
                // FIXME: Is this the right replacement for fcurrWord->text()?
                fsuggest->addPersonalList( fcurrWord->toPlainText().toUtf8().data() );
        }
        catch( const std::runtime_error& err )
        {
                QString warn =
                        tr( "AspellPluginImpl::on_faddWordBtn_clicked(): "
                            "Unable to add word to personal list." );
                qWarning( "%s", warn.toUtf8().data() );
        }
}
//__________________________________________________________________________
void AspellPluginImpl::on_flistReplacements_itemActivated()
{
        // Called when an item in the list of replacements is
        // selected. Replaces current word in text edit box with the text
        // of the selected item.
        fcurrWord->setText( flistReplacements->currentItem()->text() );
}
//__________________________________________________________________________
void AspellPluginImpl::on_flistDicts_itemActivated()
{
        // Called when an item in the list of available aspell dictionaries is
        // selected, i.e., by double-clicking, or pressing enter. Resets
        // aspell configuration to use the selected dictionary.
        QString entry = flistDicts->currentItem()->text();
        QStringList fields = entry.split( Speller::Aspell::Suggest::kDICT_DELIM );
        // Ensure that we have at least the right no.of fields.
        if( fields.size() == 4 )
        {
                QString value =
                        fields[0] + Speller::Aspell::Suggest::kDICT_DELIM +
                        fields[1] + Speller::Aspell::Suggest::kDICT_DELIM +
                        fields[2] + Speller::Aspell::Suggest::kDICT_DELIM +
                        fields[3];
                ftextDictDetails->setText( value );
                fsuggest->resetConfig( fields[1].toAscii().data(),
                                       fields[2].toAscii().data() );
                // FIXME: Handle encodings other than UTF-8.
                setPreferences( fields[1], fields[2], Speller::Aspell::Suggest::kDEF_ENCODING, value );
        }

        // Activate text select combo box at top of spell-checking tab.
//      activateTextSelect();
        fmainTab->setCurrentIndex( 0 );  // Switch to spell-checking tab.
}
//__________________________________________________________________________
void AspellPluginImpl::getPreferences()
{
        // Retrieves user preferences from saved settings. Defaults are
        // supplied
        flang = fprefs->get( "lang", Speller::Aspell::Suggest::kDEF_LANG );
        fjargon = fprefs->get( "jargon",
                               Speller::Aspell::Suggest::kDEF_JARGON );
        // FIXME: Handle encodings other than UTF-8.
        fencoding = fprefs->get( "encoding",
                                 Speller::Aspell::Suggest::kDEF_ENCODING );
        fentry = fprefs->get( "entry", kDEF_ASPELL_ENTRY );
}
//__________________________________________________________________________
void AspellPluginImpl::setPreferences(const QString& lang,
                                      const QString& jargon,
                                      const QString& encoding,
                                      const QString& entry)
{
        // Saves user preferences using Scribus preferences manager.
        fprefs->set( "lang", lang );
        QString val = jargon == Speller::Aspell::Suggest::kEMPTY ? "" :
                jargon;
        fprefs->set( "jargon", val );
        fprefs->set( "encoding", encoding );
        fprefs->set( "entry", entry );
}
//__________________________________________________________________________
void AspellPluginImpl::languageChange()
{
        qWarning( "AspellPluginImpl::languageChange(): Not implemented yet" );
}
//__________________________________________________________________________
void AspellPluginImpl::on_ftextSelect_activated(int key)
{
        // Called when item is chosen from combo box at top, selecting what
        // items to applyspell-scheking to.
        QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
        fdoc->scMW()->setStatusBarInfoText( tr( "Spell-checking in "
                                               "progress. Please "
                                               "wait..." ) );
        // Activate spell-checking GUI elements, and deactivate top combo
        // box.
        activateSpellGUI();
//      deactivateTextSelect();

        // Initialise counters for no. of changes. */
        fnchanges.fntot = fnchanges.fnframes = 0;

        // The numbering of the keys follows the order in which they were
        // inserted into the combo box. 0 is "None", the default choice.
        if( key == 1 )
        {
                parseSelection();
        }
        else if( key == 2 )
        {
                parsePage();

        }
        else if( key == 3 )
        {
                parseAll();
        }

        // Enable "Save" icon
        if( fnchanges.fntot > 0 )
        {
                fdoc->changed();
        }

        // Redraw document
        fdoc->view()->DrawNew();

        QApplication::restoreOverrideCursor();
        fdoc->scMW()->setStatusBarInfoText(tr("Spell-checking done." ));
        fdoc->scMW()->mainWindowProgressBar->reset();
}
//__________________________________________________________________________
void AspellPluginImpl::makeReplacements()
{
//      if( fnchanges.fnwords > 0 && fFrame && fFrame->asTextFrame() )
//      {
#if 0
                std::cerr << "makeReplacements: Replacing\n\"" <<
                        fFrame->itemText.text( 0, fFrame->itemText.length() )
                          << "\"\nwith\n\"" << fcontent << "\"\n";
#endif
                // Remove all text, and replace it with the modified text.
                // FIXME: What does fFrame->frameDisplays() do? Should we be
                // concerned about it.
//              fFrame->itemText.removeChars( 0, fFrame->itemText.length() );
//              fFrame->itemText.insertChars( 0, fcontent );
//              fnchanges.fnframes++;
#if 0
                std::cerr << "makeReplacements: made replacements\n";
#endif
//      }

        // Done with spell-checking at this point.
#if 0
        if( ftextSelect->currentItem() == 1 )
        {
                std::cerr << "makeReplacements: Spell-checking finished\n";
#endif
                spellCheckDone();
#if 0
        }
#endif
}
//__________________________________________________________________________
void AspellPluginImpl::parseItem()
{
        // Parse text in a frame, and spell-check it.

        // Process only text frames
        if( fFrame && fFrame->asTextFrame() )
        {
                nextWord();
                checkText();
                // Process text from
                // frame.
                // FIXME: There must be a smarter method to get individual
                // words from Scribus text, than pulling out characters into a
                // string, and then parsing that.
                // FIXME: Should we worry about inordinately long strings of
                // text?
//              int i;
//              for( i = 0; i < fFrame->itemText.length() &&
//                           ! fFrame->frameDisplays( i ); ++i )
//              {
                        ;  // Do nothing.
//              }
//              for( ; i < fFrame->itemText.length() && fFrame->frameDisplays(i); ++i  )
//              {
//                      fcontent += fFrame->itemText.text( i, 1 );
//              }

//              fnchanges.fnframes++;
//#if 0
//              std::cerr << "parseItem: fcontent = \"" << fcontent <<
//                "\"\n";
//#endif
//              fwordlist = fcontent.split( QRegExp( "\\s|\\W|\\d|\\n|\\r|\\t" ) );
//#if 0
//              for( size_t i = 0; i < fwordlist.size(); i++ )
//              {
//                      std::cerr << "parseItem: fwordlist[" << i << "] = \""
//                                << fwordlist[i] << "\"\n";
//              }
//#endif
//              fpos = fidx = 0;
//              checkText();
        }
}
//__________________________________________________________________________
void AspellPluginImpl::parseSelection()
{
        fcontent.truncate( 0 );  // Start with empty string
        uint ndocs = fdoc->m_Selection->count();
        //fdoc->scMW()->mainWindowProgressBar->setTotalSteps( ndocs );
        for( uint i = 0; i < ndocs; ++i )
        {
//              fnchanges.fnwords = 0;
                //fdoc->scMW()->mainWindowProgressBar->setProgress( i );
                fFrame = fdoc->m_Selection->itemAt( i );
                parseItem();
//              fnchanges.fntot += fnchanges.fnwords;
        }
        //fdoc->scMW()->mainWindowProgressBar->setProgress( ndocs );
}
//__________________________________________________________________________
void AspellPluginImpl::parsePage()
{
        parsePage( fdoc->currentPageNumber() );
        //spellCheckDone();
}
//__________________________________________________________________________
void AspellPluginImpl::parsePage(int page)
{
        fcontent.truncate( 0 );  // Start with empty string
        uint nproc = 0;
        uint ndocs = fdoc->Items->count();
        for( uint i = 0; i < ndocs; ++i )
        {
                if( fdoc->Items->at( i )->OwnPage == page )
                {
                        ++nproc;
                }
        }

        //fdoc->scMW()->mainWindowProgressBar->setTotalSteps( nproc );
        fdoc->view()->GotoPage( page );
        //uint n = 0;
        for( uint i = 0; i < ndocs; ++i )
        {
                PageItem* b = fdoc->Items->at( i );
                if( b->OwnPage == page )
                {
                        //fdoc->scMW()->mainWindowProgressBar->setProgress(++n);
                        fFrame = b;
                        parseItem();
                        fnchanges.fntot += fnchanges.fnwords;
                }
        }
        //fdoc->scMW()->mainWindowProgressBar->setProgress( n );
}
//__________________________________________________________________________
void AspellPluginImpl::parseAll()
{
        fcontent.truncate( 0 );  // Start with empty string
        for( int i = 0; i < fdoc->Pages->count(); ++i )
        {
                parsePage( i );
        }
        //spellCheckDone();
}
//__________________________________________________________________________
//@@@@@@@@@@@@@@@@@@@@@@@@@ END OF FILE @@@@@@@@@@@@@@@@@@@@@@@@@