diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2023-08-03 17:15:08 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2023-08-08 08:52:55 +0000 |
commit | 099fe7d5d1cfddec3e5ace152da671942a68e813 (patch) | |
tree | 93af1de737eb978db5bf20c73bc79ee3f0de6add | |
parent | f93836b25d57fed5888b1376e1e1b2d084fcb98d (diff) |
CppEditor: Let users fold/unfold all comment blocks
Fixes: QTCREATORBUG-2449
Change-Id: Ib090f1bb0d0866f14ddb6dfb10bf2ff2563585e0
Reviewed-by: David Schulz <david.schulz@qt.io>
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.cpp | 13 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppmodelmanager.cpp | 49 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppmodelmanager.h | 3 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 36 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.h | 6 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditoractionhandler.cpp | 4 |
6 files changed, 93 insertions, 18 deletions
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index e47c939d28..b1f69fbacf 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -396,6 +396,19 @@ void CppEditorPlugin::initialize() connect(showPreprocessedInSplitAction, &QAction::triggered, this, [] { CppModelManager::showPreprocessedFile(true); }); + QAction * const foldCommentsAction = new QAction(Tr::tr("Fold All Comment Blocks"), this); + command = ActionManager::registerAction(foldCommentsAction, + "CppTools.FoldCommentBlocks", context); + mcpptools->addAction(command); + contextMenu->addAction(command, Constants::G_CONTEXT_FIRST); + connect(foldCommentsAction, &QAction::triggered, this, [] { CppModelManager::foldComments(); }); + QAction * const unfoldCommentsAction = new QAction(Tr::tr("Unfold All Comment Blocks"), this); + command = ActionManager::registerAction(unfoldCommentsAction, + "CppTools.UnfoldCommentBlocks", context); + mcpptools->addAction(command); + contextMenu->addAction(command, Constants::G_CONTEXT_FIRST); + connect(unfoldCommentsAction, &QAction::triggered, this, [] { CppModelManager::unfoldComments(); }); + QAction *const findUnusedFunctionsAction = new QAction(Tr::tr("Find Unused Functions"), this); command = ActionManager::registerAction(findUnusedFunctionsAction, "CppTools.FindUnusedFunctions"); diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index c95567eb3b..d24a30d226 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -12,6 +12,7 @@ #include "cppcodemodelsettings.h" #include "cppeditorconstants.h" #include "cppeditortr.h" +#include "cppeditorwidget.h" #include "cppfindreferences.h" #include "cppincludesfilter.h" #include "cppindexingsupport.h" @@ -59,6 +60,7 @@ #include <projectexplorer/target.h> #include <texteditor/textdocument.h> +#include <texteditor/textdocumentlayout.h> #include <utils/algorithm.h> #include <utils/environment.h> @@ -469,6 +471,53 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) compiler->start(); } +static void foldOrUnfoldComments(bool unfold) +{ + IEditor * const currentEditor = EditorManager::currentEditor(); + if (!currentEditor) + return; + const auto editorWidget = qobject_cast<CppEditorWidget*>(currentEditor->widget()); + if (!editorWidget) + return; + TextEditor::TextDocument * const textDoc = editorWidget->textDocument(); + QTC_ASSERT(textDoc, return); + + const Document::Ptr cppDoc = CppModelManager::snapshot().preprocessedDocument( + textDoc->contents(), textDoc->filePath()); + QTC_ASSERT(cppDoc, return); + cppDoc->tokenize(); + TranslationUnit * const tu = cppDoc->translationUnit(); + if (!tu || !tu->isTokenized()) + return; + + for (int commentTokIndex = 0; commentTokIndex < tu->commentCount(); ++commentTokIndex) { + const Token &tok = tu->commentAt(commentTokIndex); + if (tok.kind() != T_COMMENT && tok.kind() != T_DOXY_COMMENT) + continue; + const int tokenPos = tu->getTokenPositionInDocument(tok, textDoc->document()); + const int tokenEndPos = tu->getTokenEndPositionInDocument(tok, textDoc->document()); + const QTextBlock tokenBlock = textDoc->document()->findBlock(tokenPos); + if (!tokenBlock.isValid()) + continue; + const QTextBlock nextBlock = tokenBlock.next(); + if (!nextBlock.isValid()) + continue; + if (tokenEndPos < nextBlock.position()) + continue; + if (TextEditor::TextDocumentLayout::foldingIndent(tokenBlock) + >= TextEditor::TextDocumentLayout::foldingIndent(nextBlock)) { + continue; + } + if (unfold) + editorWidget->unfold(tokenBlock); + else + editorWidget->fold(tokenBlock); + } +} + +void CppModelManager::foldComments() { foldOrUnfoldComments(false); } +void CppModelManager::unfoldComments() { foldOrUnfoldComments(true); } + class FindUnusedActionsEnabledSwitcher { public: diff --git a/src/plugins/cppeditor/cppmodelmanager.h b/src/plugins/cppeditor/cppmodelmanager.h index 2e78042eb7..bdda63ee55 100644 --- a/src/plugins/cppeditor/cppmodelmanager.h +++ b/src/plugins/cppeditor/cppmodelmanager.h @@ -190,12 +190,13 @@ public: static void findUsages(const CursorInEditor &data, Backend backend = Backend::Best); static void switchHeaderSource(bool inNextSplit, Backend backend = Backend::Best); static void showPreprocessedFile(bool inNextSplit); + static void foldComments(); + static void unfoldComments(); static void findUnusedFunctions(const Utils::FilePath &folder); static void checkForUnusedSymbol(Core::SearchResult *search, const Utils::Link &link, CPlusPlus::Symbol *symbol, const CPlusPlus::LookupContext &context, const Utils::LinkHandler &callback); - static CppIndexingSupport *indexingSupport(); static Utils::FilePaths projectFiles(); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 8d16d57922..9cee311e6d 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -7881,40 +7881,50 @@ void TextEditorWidget::setExtraEncodingSettings(const ExtraEncodingSettings &ext d->m_document->setExtraEncodingSettings(extraEncodingSettings); } -void TextEditorWidget::fold() +void TextEditorWidget::foldCurrentBlock() +{ + fold(textCursor().block()); +} + +void TextEditorWidget::fold(const QTextBlock &block) { QTextDocument *doc = document(); auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout()); QTC_ASSERT(documentLayout, return); - QTextBlock block = textCursor().block(); - if (!(TextDocumentLayout::canFold(block) && block.next().isVisible())) { + QTextBlock b = block; + if (!(TextDocumentLayout::canFold(b) && b.next().isVisible())) { // find the closest previous block which can fold - int indent = TextDocumentLayout::foldingIndent(block); - while (block.isValid() && (TextDocumentLayout::foldingIndent(block) >= indent || !block.isVisible())) - block = block.previous(); + int indent = TextDocumentLayout::foldingIndent(b); + while (b.isValid() && (TextDocumentLayout::foldingIndent(b) >= indent || !b.isVisible())) + b = b.previous(); } - if (block.isValid()) { - TextDocumentLayout::doFoldOrUnfold(block, false); + if (b.isValid()) { + TextDocumentLayout::doFoldOrUnfold(b, false); d->moveCursorVisible(); documentLayout->requestUpdate(); documentLayout->emitDocumentSizeChanged(); } } -void TextEditorWidget::unfold() +void TextEditorWidget::unfold(const QTextBlock &block) { QTextDocument *doc = document(); auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout()); QTC_ASSERT(documentLayout, return); - QTextBlock block = textCursor().block(); - while (block.isValid() && !block.isVisible()) - block = block.previous(); - TextDocumentLayout::doFoldOrUnfold(block, true); + QTextBlock b = block; + while (b.isValid() && !b.isVisible()) + b = b.previous(); + TextDocumentLayout::doFoldOrUnfold(b, true); d->moveCursorVisible(); documentLayout->requestUpdate(); documentLayout->emitDocumentSizeChanged(); } +void TextEditorWidget::unfoldCurrentBlock() +{ + unfold(textCursor().block()); +} + void TextEditorWidget::unfoldAll() { QTextDocument *doc = document(); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index c05425a5b0..0540c86be5 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -363,8 +363,10 @@ public: void deleteStartOfWord(); void deleteStartOfWordCamelCase(); void unfoldAll(); - void fold(); - void unfold(); + void fold(const QTextBlock &block); + void foldCurrentBlock(); + void unfold(const QTextBlock &block); + void unfoldCurrentBlock(); void selectEncoding(); void updateTextCodecLabel(); void selectLineEnding(int index); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 00ed94a5ee..4224b50443 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -344,11 +344,11 @@ void TextEditorActionHandlerPrivate::createActions() QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+Shift+S") : Tr::tr("Alt+Shift+S")), G_EDIT_TEXT, advancedEditMenu); registerAction(FOLD, - [] (TextEditorWidget *w) { w->fold(); }, true, Tr::tr("Fold"), + [] (TextEditorWidget *w) { w->foldCurrentBlock(); }, true, Tr::tr("Fold"), QKeySequence(Tr::tr("Ctrl+<")), G_EDIT_COLLAPSING, advancedEditMenu); registerAction(UNFOLD, - [] (TextEditorWidget *w) { w->unfold(); }, true, Tr::tr("Unfold"), + [] (TextEditorWidget *w) { w->unfoldCurrentBlock(); }, true, Tr::tr("Unfold"), QKeySequence(Tr::tr("Ctrl+>")), G_EDIT_COLLAPSING, advancedEditMenu); m_unfoldAllAction = registerAction(UNFOLD_ALL, |