Subversion Repositories Scribus

Rev

Rev 22723 | Rev 24041 | 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 <QComboBox>
#include <QListWidget>
#include <QTextEdit>

#include "hunspelldialog.h"
#include "langmgr.h"

HunspellDialog::HunspellDialog(QWidget *parent, ScribusDoc *doc, StoryText *iText)
{
        setupUi( this );
        setModal( true );

        connect (ignoreOncePushButton, SIGNAL(clicked()), this, SLOT(goToNextWord()));
        connect (ignoreAllPushButton, SIGNAL(clicked()), this, SLOT(ignoreAllWords()));
        connect (changePushButton, SIGNAL(clicked()), this, SLOT(changeWord()));
        connect (changeAllPushButton, SIGNAL(clicked()), this, SLOT(changeAllWords()));
        connect (languagesComboBox, SIGNAL(currentIndexChanged(const QString &)), this, SLOT(languageComboChanged(const QString &)));

        m_doc = doc;
        m_docChanged = false;
        m_iText = iText;
        m_returnToDefaultLang = false;
        m_primaryLangIndex = 0;

        m_dictionaryMap = nullptr;
        m_hspellerMap = nullptr;
        m_wfList = nullptr;
        m_wfListIndex = 0;
}

void HunspellDialog::set(QMap<QString, QString>* dictionaryMap, QMap<QString, HunspellDict*> *hspellerMap, QList<WordsFound> *wfList)
{
        m_dictionaryMap = dictionaryMap;
        m_hspellerMap = hspellerMap;
        m_wfList = wfList;
        bool b = languagesComboBox->blockSignals(true);
        languagesComboBox->clear();

        QStringList langsToAdd;
        auto it = m_dictionaryMap->cbegin();
        while (it != m_dictionaryMap->cend())
        {
                QString lang = LanguageManager::instance()->getLangFromAbbrev(it.key(), true);
                if (!langsToAdd.contains(lang))
                        langsToAdd << (!lang.isEmpty() ? lang : it.key());
                ++it;
        }
        languagesComboBox->addItems(langsToAdd);
        languagesComboBox->setCurrentIndex(0);
        m_primaryLangIndex = 0;
        languagesComboBox->blockSignals(b);
        m_wfListIndex = 0;
        goToNextWord(0);
}

void HunspellDialog::updateSuggestions(QStringList &newSuggestions)
{
        suggestionsListWidget->clear();
        suggestionsListWidget->addItems(newSuggestions);
        suggestionsListWidget->setCurrentRow(0);
}

void HunspellDialog::goToNextWord(int i)
{
        if (m_returnToDefaultLang)
        {
                bool b = languagesComboBox->blockSignals(true);
                languagesComboBox->setCurrentIndex(m_primaryLangIndex);
                languagesComboBox->blockSignals(b);
        }
        if (i >= 0)
                m_wfListIndex = i;
        else
        {
                do {
                        ++m_wfListIndex;
                } while (m_wfListIndex<m_wfList->count() && (m_wfList->at(m_wfListIndex).changed || m_wfList->at(m_wfListIndex).ignore));
                //qDebug()<<"selected word index"<<m_wfListIndex;
        }
        if (m_wfListIndex>=m_wfList->count())
        {
                statusLabel->setText(tr("Spelling check complete"));
                suggestionsListWidget->clear();
                sentenceTextEdit->clear();
                changePushButton->setEnabled(false);
                changeAllPushButton->setEnabled(false);
                ignoreOncePushButton->setEnabled(false);
                ignoreAllPushButton->setEnabled(false);
                return;
        }
        statusLabel->setText("");
        currWF=m_wfList->at(m_wfListIndex);
        setLanguageCombo(currWF.lang);
        updateSuggestions(currWF.replacements);

        int sentencePos = 0;
        QString sentence(m_iText->sentence(currWF.start, sentencePos));
        sentence.insert(currWF.end-sentencePos+currWF.changeOffset,"</b></font>");
        sentence.insert(currWF.start-sentencePos+currWF.changeOffset,"<font color=red><b>");
        sentenceTextEdit->setText(sentence);
}

void HunspellDialog::ignoreAllWords()
{
        if (m_wfListIndex < 0 || m_wfListIndex >= m_wfList->count())
                return;
        QString wordToIgnore = m_wfList->at(m_wfListIndex).w;
        //Do we start from 0 or from the instance of the word where we are... 0 for now
        for (int i = 0; i < m_wfList->count(); ++i)
                if (m_wfList->at(i).w == wordToIgnore)
                        (*m_wfList)[i].ignore = true;
        goToNextWord();
}

void HunspellDialog::changeWord()
{
        //If we have ignored a word or its already changed, skip to the next.
        if (m_wfList->at(m_wfListIndex).ignore || m_wfList->at(m_wfListIndex).changed)
                goToNextWord();
        replaceWord(m_wfListIndex);
        goToNextWord();
}

void HunspellDialog::changeAllWords()
{
        if (m_wfList->at(m_wfListIndex).ignore && !m_wfList->at(m_wfListIndex).changed)
                return;
        QString wordToChange = m_wfList->at(m_wfListIndex).w;
        //Do we start from 0 or from the instance of the word where we are... 0 for now
        for (int i = 0; i <m_wfList->count(); ++i)
                if (m_wfList->at(i).w == wordToChange)
                        replaceWord(i);
        goToNextWord();
}

void HunspellDialog::replaceWord(int i)
{
        //TODO: rehyphenate after the replacement
        QString newText(suggestionsListWidget->currentItem()->text());
        int lengthDiff = m_iText->replaceWord(m_wfList->at(i).start + m_wfList->at(i).changeOffset, newText);
        if (lengthDiff != 0)
        {
                for (int k = i; k<m_wfList->count(); ++k)
                        (*m_wfList)[k].changeOffset += lengthDiff;
        }
        (*m_wfList)[i].changed = true;
        m_docChanged = true;
}

void HunspellDialog::languageComboChanged(const QString &newLanguage)
{
        m_returnToDefaultLang = true;
        QString wordLang = LanguageManager::instance()->getAbbrevFromLang(newLanguage, false);
        if (!m_hspellerMap->contains(wordLang) )
        {
                //qDebug() << "hspeller"<<wordLang<<"does not exist";
                return;
        }
        //qDebug() << wordLang << newLanguage;
        if (m_wfList->count() == 0)
                return;
        if (m_wfListIndex >= m_wfList->count())
                m_wfListIndex = 0;
        QString word = m_wfList->at(m_wfListIndex).w;
        if ((*m_hspellerMap)[wordLang]->spell(word) == 0)
        {
                QStringList replacements = (*m_hspellerMap)[wordLang]->suggest(word);
                updateSuggestions(replacements);
        }
        else
        {
                (*m_wfList)[m_wfListIndex].changed = true;
                m_docChanged = true;
                goToNextWord();
        }
}

void HunspellDialog::setLanguageCombo(const QString &newLangAbbrev)
{
        bool found = false;

        auto it = m_dictionaryMap->cbegin();
        while (it != m_dictionaryMap->cend())
        {
                if (it.key() == newLangAbbrev)
                {
                        found = true;
                        break;
                }
                ++it;
        }
        int i = 0;
        if (found)
                i = languagesComboBox->findText(LanguageManager::instance()->getLangFromAbbrev(newLangAbbrev,true));
        bool b = languagesComboBox->blockSignals(true);
        languagesComboBox->setCurrentIndex(i);
        languagesComboBox->blockSignals(b);
}