void SpellCheckerCore::replaceWordsInCurrentEditor(const WordList &wordsToReplace, const QString &replacementWord)
{
    if(wordsToReplace.count() == 0) {
        Q_ASSERT(wordsToReplace.count() != 0);
        return;
    }
    if(d->currentEditor == NULL) {
        Q_ASSERT(d->currentEditor != NULL);
        return;
    }
    TextEditor::TextEditorWidget* editorWidget = qobject_cast<TextEditor::TextEditorWidget*>(d->currentEditor->widget());
    if(editorWidget == NULL) {
        Q_ASSERT(editorWidget != NULL);
        return;
    }

    QTextCursor cursor = editorWidget->textCursor();
    /* Iterate the words and replace all one by one */
    foreach(const Word& wordToReplace, wordsToReplace) {
        editorWidget->gotoLine(wordToReplace.lineNumber, wordToReplace.columnNumber - 1);
        int wordStartPos = editorWidget->textCursor().position();
        editorWidget->gotoLine(wordToReplace.lineNumber, wordToReplace.columnNumber + wordToReplace.length - 1);
        int wordEndPos = editorWidget->textCursor().position();

        cursor.beginEditBlock();
        cursor.setPosition(wordStartPos);
        cursor.setPosition(wordEndPos, QTextCursor::KeepAnchor);
        cursor.removeSelectedText();
        cursor.insertText(replacementWord);
        cursor.endEditBlock();
    }
void SpellCheckerCore::giveSuggestionsForWordUnderCursor()
{
  if( d->currentEditor.isNull() == true ) {
    return;
  }
  Word word;
  WordList wordsToReplace;
  bool wordMistake = isWordUnderCursorMistake( word );
  if( wordMistake == false ) {
    return;
  }

  getAllOccurrencesOfWord( word, wordsToReplace );

  SuggestionsDialog dialog( word.text, word.suggestions, wordsToReplace.count() );
  SuggestionsDialog::ReturnCode code = static_cast<SuggestionsDialog::ReturnCode>( dialog.exec() );
  switch( code ) {
    case SuggestionsDialog::Rejected:
      /* Cancel and exit */
      return;
    case SuggestionsDialog::Accepted:
      /* Clear the list and only add the one to replace */
      wordsToReplace.clear();
      wordsToReplace.append( word );
      break;
    case SuggestionsDialog::AcceptAll:
      /* Do nothing since the list of words is already valid */
      break;
  }

  QString replacement = dialog.replacementWord();
  replaceWordsInCurrentEditor( wordsToReplace, replacement );
}
void SpellCheckerCore::replaceWordsInCurrentEditor( const WordList& wordsToReplace, const QString& replacementWord )
{
  if( wordsToReplace.count() == 0 ) {
    Q_ASSERT( wordsToReplace.count() != 0 );
    return;
  }
  if( d->currentEditor == nullptr ) {
    Q_ASSERT( d->currentEditor != nullptr );
    return;
  }
  TextEditor::TextEditorWidget* editorWidget = qobject_cast<TextEditor::TextEditorWidget*>( d->currentEditor->widget() );
  if( editorWidget == nullptr ) {
    Q_ASSERT( editorWidget != nullptr );
    return;
  }

  QTextCursor cursor = editorWidget->textCursor();
  /* Iterate the words and replace all one by one */
  for( const Word& wordToReplace: wordsToReplace ) {
    editorWidget->gotoLine( int32_t( wordToReplace.lineNumber ), int32_t( wordToReplace.columnNumber ) - 1 );
    int wordStartPos = editorWidget->textCursor().position();
    editorWidget->gotoLine( int32_t( wordToReplace.lineNumber ), int32_t( wordToReplace.columnNumber ) + wordToReplace.length - 1 );
    int wordEndPos = editorWidget->textCursor().position();

    cursor.beginEditBlock();
    cursor.setPosition( wordStartPos );
    cursor.setPosition( wordEndPos, QTextCursor::KeepAnchor );
    cursor.removeSelectedText();
    cursor.insertText( replacementWord );
    cursor.endEditBlock();
  }
  /* If more than one suggestion was replaced, show a notification */
  if( wordsToReplace.count() > 1 ) {
    Utils::FadingIndicator::showText( editorWidget,
                                      tr( "%1 occurrences replaced." ).arg( wordsToReplace.count() ),
                                      Utils::FadingIndicator::SmallText );
  }
}
bool SpellCheckerCore::getAllOccurrencesOfWord(const Word &word, WordList& words)
{
    if(d->currentEditor.isNull() == true) {
        return false;
    }
    WordList wl;
    QString currentFileName = d->currentEditor->document()->filePath().toString();
    wl = d->spellingMistakesModel->mistakesForFile(currentFileName);
    if(wl.isEmpty() == true) {
        return false;
    }
    WordList::ConstIterator iter = wl.constBegin();
    while(iter != wl.constEnd()) {
        const Word& currentWord = iter.value();
        if(currentWord.text == word.text) {
            words.append(currentWord);
        }
        ++iter;
    }
    return (wl.count() > 0);

}
Esempio n. 5
0
void SpellCheckProcessor::process(QFutureInterface<WordList> &future)
{
#ifdef BENCH_TIME
    QElapsedTimer timer;
    timer.start();
#endif /* BENCH_TIME */
    WordListConstIter misspelledIter;
    WordListConstIter prevMisspelledIter;
    Word misspelledWord;
    WordList misspelledWords;
    WordList words = d_wordList;
    WordListConstIter wordIter = words.constBegin();
    bool spellingMistake;
    future.setProgressRange(0, words.count() + 1);
    while(wordIter != d_wordList.constEnd()) {
        /* Get the word at the current iterator position.
         * After this is done, move the iterator to the next position and
         * increment the progress value. This is done so that one can call
         * 'continue' anywhere after this in the loop without having to worry
         * about advancing the iterator since this will already be done and
         * correct for the next iteration. */
        misspelledWord = (*wordIter);
        ++wordIter;
        future.setProgressValue(future.progressValue() + 1);
        /* Check if the future was cancelled */
        if(future.isCanceled() == true) {
            return;
        }
        spellingMistake = d_spellChecker->isSpellingMistake(misspelledWord.text);
        /* Check to see if the char after the word is a period. If it is,
         * add the period to the word an see if it passes the checker. */
        if((spellingMistake == true)
                && (misspelledWord.charAfter == QLatin1Char('.'))) {
            /* Recheck the word with the period added */
            spellingMistake = d_spellChecker->isSpellingMistake(misspelledWord.text + QLatin1Char('.'));
        }

        if(spellingMistake == true) {
            /* The word is a spelling mistake, check if the word was a mistake
             * the previous time that this file was processed. If it was the
             * suggestions can be reused without having to get the suggestions
             * through the spell checker since this is slow compared to the rest
             * of the processing. */
            prevMisspelledIter = d_previousMistakes.find(misspelledWord.text);
            if(prevMisspelledIter != d_previousMistakes.constEnd()) {
                misspelledWord.suggestions = (*prevMisspelledIter).suggestions;
                misspelledWords.append(misspelledWord);
                continue;
            }
            /* The word was not in the previous iteration, search for the word
             * in the list of words that were already checked in this iteration
             * and identified as spelling mistakes. If there are words that are
             * repeated and misspelled, this can reduce the time to process
             * the file since the time to get suggestions is rather slow.
             * If there are no repeating mistakes then this might add unneeded
             * overhead. */
            misspelledIter = misspelledWords.find(misspelledWord.text);
            if(misspelledIter != misspelledWords.constEnd()) {
                misspelledWord.suggestions = (*misspelledIter).suggestions;
                /* Add the word to the local list of misspelled words. */
                misspelledWords.append(misspelledWord);
                continue;
            }
            /* At this point the word is a mistake for the first time. It was neither
             * a mistake in the previous pass of the file nor did the word occur previously
             * in this file, use the spell checker to get the suggestions for the word. */
            d_spellChecker->getSuggestionsForWord(misspelledWord.text, misspelledWord.suggestions);
            /* Add the word to the local list of misspelled words. */
            misspelledWords.append(misspelledWord);
        }
    }
#ifdef BENCH_TIME
    qDebug() << "File: " << d_fileName
             << "\n  - time : " << timer.elapsed()
             << "\n  - count: " << misspelledWords.size();
#endif /* BENCH_TIME */
    future.reportResult(misspelledWords);
}