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::updateContextMenu()
{
  if( d->contextMenuHolderCommands.isEmpty() == true ) {
    /* Populate the internal vector with the holder actions to speed up the process
     * of updating the context menu when requested again. */
    QVector<const char*> holderActionIds { Constants::ACTION_HOLDER1_ID, Constants::ACTION_HOLDER2_ID, Constants::ACTION_HOLDER3_ID, Constants::ACTION_HOLDER4_ID, Constants::ACTION_HOLDER5_ID };
    /* Iterate the commands and */
    for( int count = 0; count < holderActionIds.size(); ++count ) {
      Core::Command* cmd = Core::ActionManager::command( holderActionIds[count] );
      d->contextMenuHolderCommands.push_back( cmd );
    }
  }

  Word word;
  bool isMistake = isWordUnderCursorMistake( word );
  /* Do nothing if the context menu is not a mistake.
   * The context menu will in this case already be disabled so there
   * is no need to update it. */
  if( isMistake == false ) {
    return;
  }
  QStringList list = word.suggestions;
  /* Iterate the commands and */
  for( Core::Command* cmd: qAsConst( d->contextMenuHolderCommands ) ) {
    Q_ASSERT( cmd != nullptr );
    if( list.size() > 0 ) {
      /* Disconnect the previous connection made, otherwise it will also trigger */
      cmd->action()->disconnect();
      /* Set the text on the action for the word to use*/
      QString replacementWord = list.takeFirst();
      cmd->action()->setText( replacementWord );
      /* Show the action */
      cmd->action()->setVisible( true );
      /* Connect to lambda function to call to replace the words if the
       * action is triggered. */
      connect( cmd->action(), &QAction::triggered, this, [this, word, replacementWord]() {
        WordList wordsToReplace;
        if( d->settings->replaceAllFromRightClick == true ) {
          this->getAllOccurrencesOfWord( word, wordsToReplace );
        } else {
          wordsToReplace.append( word );
        }
        this->replaceWordsInCurrentEditor( wordsToReplace, replacementWord );
      } );
    } else {
      /* Hide the action since there are less than 5 suggestions for the word. */
      cmd->action()->setVisible( false );
    }
  }
}
Пример #3
0
void SpellCheckerCore::replaceWordUnderCursorFirstSuggestion() {
    Word word;
    /* Get the word under the cursor. */
    bool wordMistake = isWordUnderCursorMistake(word);
    if(wordMistake == false) {
        Q_ASSERT(wordMistake);
        return;
    }
    if(word.suggestions.isEmpty() == true) {
        /* Word does not have any suggestions */
        return;
    }
    WordList words;
    words.append(word);
    replaceWordsInCurrentEditor(words, word.suggestions.first());
}
Пример #4
0
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);

}
Пример #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);
}