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; }
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 ); }