void ClangFormat::disableFormattingSelectedText() { TextEditor::TextEditorWidget *widget = TextEditor::TextEditorWidget::currentTextEditorWidget(); if (!widget) return; const QTextCursor tc = widget->textCursor(); if (!tc.hasSelection()) return; // Insert start marker const QTextBlock selectionStartBlock = tc.document()->findBlock(tc.selectionStart()); QTextCursor insertCursor(tc.document()); insertCursor.beginEditBlock(); insertCursor.setPosition(selectionStartBlock.position()); insertCursor.insertText("// clang-format off\n"); const int positionToRestore = tc.position(); // Insert end marker QTextBlock selectionEndBlock = tc.document()->findBlock(tc.selectionEnd()); insertCursor.setPosition(selectionEndBlock.position() + selectionEndBlock.length() - 1); insertCursor.insertText("\n// clang-format on"); insertCursor.endEditBlock(); // Reset the cursor position in order to clear the selection. QTextCursor restoreCursor(tc.document()); restoreCursor.setPosition(positionToRestore); widget->setTextCursor(restoreCursor); // The indentation of these markers might be undesired, so reformat. // This is not optimal because two undo steps will be needed to remove the markers. const int reformatTextLength = insertCursor.position() - selectionStartBlock.position(); BeautifierPlugin::formatCurrentFile(command(selectionStartBlock.position(), reformatTextLength)); }
void moveToPosition(Editor *editor, int newPos, bool visualMode) { QTextBlock targetBlock = editor->document()->findBlock(newPos); if (!targetBlock.isValid()) targetBlock = editor->document()->lastBlock(); bool overwriteMode = editor->overwriteMode(); TextEditor::TextEditorWidget *baseEditor = qobject_cast<TextEditor::TextEditorWidget*>(editor); bool visualBlockMode = baseEditor && baseEditor->hasBlockSelection(); bool selectNextCharacter = (overwriteMode || visualMode) && !visualBlockMode; bool keepSelection = visualMode || visualBlockMode; QTextCursor textCursor = editor->textCursor(); textCursor.setPosition(selectNextCharacter ? newPos : newPos + 1, keepSelection ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor); if (baseEditor) baseEditor->setTextCursor(textCursor); else editor->setTextCursor(textCursor); if (visualBlockMode) { baseEditor->setBlockSelection(false); baseEditor->setBlockSelection(true); } }
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 == NULL) { return; } TextEditor::TextEditorWidget* editorWidget = baseEditor->editorWidget(); if(editorWidget == NULL) { return; } QList<QTextEdit::ExtraSelection> selections; foreach(const Word& word, words.values()) { QTextCursor cursor(editorWidget->document()); /* Walk to the correct position using the line and column number since the * absolute position is not available and I do not know of a way to get/ * calculate the absolute position from that information. * * One would think that the position from the CppDocumentParser::tokenizeWords() * function can be used if stored in the Word, but it is not the correct position. */ cursor.setPosition(0); cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, word.lineNumber - 1); cursor.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, 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); format.setUnderlineColor(QColor(Qt::red)); format.setUnderlineStyle(QTextCharFormat::WaveUnderline); format.setToolTip(word.suggestions.isEmpty() ? QLatin1String("Incorrect spelling") : QString(QLatin1String("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); }
void CoolScrollPlugin::onEditorCreated(Core::IEditor *editor, const QString &fileName) { Q_UNUSED(fileName); TextEditor::TextEditorWidget* baseEditor = qobject_cast<TextEditor::TextEditorWidget*>(editor->widget()); baseEditor->setVerticalScrollBar(new CoolScrollBar(baseEditor, m_settings)); }
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::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 ); } }
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 ); }
CoolScrollBar * CoolScrollPlugin::getEditorScrollBar(Core::IEditor *editor) { TextEditor::TextEditorWidget* baseEditor = qobject_cast<TextEditor::TextEditorWidget*>(editor->widget()); return qobject_cast<CoolScrollBar*>(baseEditor->verticalScrollBar()); }