예제 #1
0
bool SpellCheckerCore::isWordUnderCursorMistake(Word& word) const
{
    if(d->currentEditor.isNull() == true) {
        return false;
    }

    unsigned int column = d->currentEditor->currentColumn();
    unsigned int line = d->currentEditor->currentLine();
    QString currentFileName = d->currentEditor->document()->filePath().toString();
    WordList wl;
    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.lineNumber == line)
                && ((currentWord.columnNumber <= column)
                    && (currentWord.columnNumber + currentWord.length) >= column)) {
            word = currentWord;
            return true;
        }
        ++iter;
    }
    return false;
}
예제 #2
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);

}
void SpellCheckerCore::addMisspelledWords( const QString& fileName, const WordList& words )
{
  d->spellingMistakesModel->insertSpellingMistakes( fileName, words, d->filesInStartupProject.contains( fileName ) );
  if( d->currentFilePath == fileName ) {
    d->mistakesModel->setCurrentSpellingMistakes( words );
  }

  /* Only apply the underlines to the current file. This is done so that if the
   * whole project is scanned, it does not add selections to pages that might
   * potentially never be opened. This can especially be a problem in large
   * projects.
   */
  if( d->currentFilePath != fileName ) {
    return;
  }
  TextEditor::BaseTextEditor* baseEditor = qobject_cast<TextEditor::BaseTextEditor*>( d->currentEditor );
  if( baseEditor == nullptr ) {
    return;
  }
  TextEditor::TextEditorWidget* editorWidget = baseEditor->editorWidget();
  if( editorWidget == nullptr ) {
    return;
  }
  QTextDocument* document = editorWidget->document();
  if( document == nullptr ) {
    return;
  }
  QList<QTextEdit::ExtraSelection> selections;
  selections.reserve( words.size() );
  const WordList::ConstIterator wordsEnd = words.constEnd();
  for( WordList::ConstIterator wordIter = words.constBegin(); wordIter != wordsEnd; ++wordIter ) {
    const Word& word = wordIter.value();
    /* Get the QTextBlock for the line that the misspelled word is on.
     * The QTextDocument manages lines as blocks (in most cases).
     * The lineNumber of the misspelled word is 1 based (seen in the editor)
     * but the blocks on the QTextDocument are 0 based, thus minus one
     * from the line number to get the correct line.
     * If the block is valid, and the word is not longer than the number of
     * characters in the block (which should normally not be the case)
     * then the cursor is moved to the correct column, and the word is
     * underlined.
     * Again the Columns on the misspelled word is 1 based but
     * the blocks and cursor are 0 based. */
    const QTextBlock& block = document->findBlockByNumber( int32_t( word.lineNumber ) - 1 );
    if( ( block.isValid() == false )
        || ( uint32_t( block.length() ) < ( word.columnNumber - 1 + uint32_t( word.length ) ) ) ) {
      continue;
    }

    QTextCursor cursor( block );
    cursor.setPosition( cursor.position() + int32_t( word.columnNumber ) - 1 );
    cursor.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor, word.length );
    /* Get the current format from the cursor, this is to make sure that the text font
     * and color stays the same, we just want to underline the mistake. */
    QTextCharFormat format = cursor.charFormat();
    format.setFontUnderline( true );
    static const QColor underLineColor = QColor( Qt::red );
    format.setUnderlineColor( underLineColor );
    format.setUnderlineStyle( QTextCharFormat::WaveUnderline );
    format.setToolTip( word.suggestions.isEmpty()
                       ? QStringLiteral( "Incorrect spelling" )
                       : QStringLiteral( "Incorrect spelling, did you mean '%1' ?" ).arg( word.suggestions.first() ) );
    QTextEdit::ExtraSelection selection;
    selection.cursor = cursor;
    selection.format = format;
    selections.append( selection );
  }
  editorWidget->setExtraSelections( Core::Id( SpellChecker::Constants::SPELLCHECK_MISTAKE_ID ), selections );

  /* The model updated, check if the word under the cursor is now a mistake
   * and notify the rest of the checker with this information. */
  Word word;
  bool wordIsMisspelled = isWordUnderCursorMistake( word );
  emit wordUnderCursorMistake( wordIsMisspelled, word );
}