forked from qt-creator/qt-creator
TextEditor: Add folding actions to the extra area context menu
Fixes: QTCREATORBUG-7461 Change-Id: I83c48433781a33af7ea603a08e0c2727f0481cef Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
@@ -633,7 +633,7 @@ void TextDocumentLayout::requestExtraAreaUpdate()
|
||||
emit updateExtraArea();
|
||||
}
|
||||
|
||||
void TextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
|
||||
void TextDocumentLayout::doFoldOrUnfold(const QTextBlock &block, bool unfold, bool recursive)
|
||||
{
|
||||
if (!canFold(block))
|
||||
return;
|
||||
@@ -643,7 +643,10 @@ void TextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
|
||||
while (b.isValid() && foldingIndent(b) > indent && (unfold || b.next().isValid())) {
|
||||
b.setVisible(unfold);
|
||||
b.setLineCount(unfold? qMax(1, b.layout()->lineCount()) : 0);
|
||||
if (unfold) { // do not unfold folded sub-blocks
|
||||
if (recursive) {
|
||||
if ((unfold && isFolded(b)) || (!unfold && canFold(b)))
|
||||
setFolded(b, !unfold);
|
||||
} else if (unfold) { // do not unfold folded sub-blocks
|
||||
if (isFolded(b) && b.next().isValid()) {
|
||||
int jndent = foldingIndent(b);
|
||||
b = b.next();
|
||||
|
@@ -199,7 +199,7 @@ public:
|
||||
static int lexerState(const QTextBlock &block);
|
||||
static void changeFoldingIndent(QTextBlock &block, int delta);
|
||||
static bool canFold(const QTextBlock &block);
|
||||
static void doFoldOrUnfold(const QTextBlock& block, bool unfold);
|
||||
static void doFoldOrUnfold(const QTextBlock &block, bool unfold, bool recursive = false);
|
||||
static bool isFolded(const QTextBlock &block);
|
||||
static void setFolded(const QTextBlock &block, bool folded);
|
||||
static void setExpectedRawStringSuffix(const QTextBlock &block, const QByteArray &suffix);
|
||||
|
@@ -4235,7 +4235,7 @@ void TextEditorWidgetPrivate::registerActions()
|
||||
.setScriptable(true);
|
||||
m_unfoldAllAction = ActionBuilder(this, UNFOLD_ALL)
|
||||
.setContext(m_editorContext)
|
||||
.addOnTriggered([this] { q->unfoldAll(); })
|
||||
.addOnTriggered([this] { q->toggleFoldAll(); })
|
||||
.setScriptable(true)
|
||||
.contextAction();
|
||||
ActionBuilder(this, INCREASE_FONT_SIZE).setContext(m_editorContext).addOnTriggered([this] {
|
||||
@@ -7097,8 +7097,38 @@ void TextEditorWidget::extraAreaLeaveEvent(QEvent *)
|
||||
extraAreaMouseEvent(&me);
|
||||
}
|
||||
|
||||
static bool xIsInsideFoldingRegion(int x, int extraAreaWidth, const QFontMetrics &fm)
|
||||
{
|
||||
int boxWidth = 0;
|
||||
if (TextEditorSettings::fontSettings().relativeLineSpacing() == 100)
|
||||
boxWidth = foldBoxWidth(fm);
|
||||
else
|
||||
boxWidth = foldBoxWidth();
|
||||
|
||||
return x > extraAreaWidth - boxWidth && x <= extraAreaWidth;
|
||||
}
|
||||
|
||||
void TextEditorWidget::extraAreaContextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
if (d->m_codeFoldingVisible
|
||||
&& xIsInsideFoldingRegion(e->pos().x(), extraArea()->width(), fontMetrics())) {
|
||||
const QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
|
||||
const QTextBlock block = cursor.block();
|
||||
auto menu = new QMenu(this);
|
||||
|
||||
menu->addAction(Tr::tr("Fold"), this, [&] { fold(block); });
|
||||
menu->addAction(Tr::tr("Fold recursively"), this, [&] { fold(block, true); });
|
||||
menu->addAction(Tr::tr("Fold all"), this, [this] { unfoldAll(/* unfold = */ false); });
|
||||
menu->addAction(Tr::tr("Unfold"), this, [&] { unfold(block); });
|
||||
menu->addAction(Tr::tr("Unfold recursively"), this, [&] { unfold(block, true); });
|
||||
menu->addAction(Tr::tr("Unfold all"), this, [this] { unfoldAll(/* fold = */ true); });
|
||||
menu->exec(e->globalPos());
|
||||
|
||||
delete menu;
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->m_marksVisible) {
|
||||
QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
|
||||
auto contextMenu = new QMenu(this);
|
||||
@@ -7119,14 +7149,8 @@ void TextEditorWidget::updateFoldingHighlight(const QPoint &pos)
|
||||
return;
|
||||
|
||||
// Update which folder marker is highlighted
|
||||
int boxWidth = 0;
|
||||
if (TextEditorSettings::fontSettings().relativeLineSpacing() == 100)
|
||||
boxWidth = foldBoxWidth(fontMetrics());
|
||||
else
|
||||
boxWidth = foldBoxWidth();
|
||||
|
||||
QTextCursor cursor;
|
||||
if (pos.x() > extraArea()->width() - boxWidth)
|
||||
if (xIsInsideFoldingRegion(pos.x(), extraArea()->width(), fontMetrics()))
|
||||
cursor = cursorForPosition(QPoint(0, pos.y()));
|
||||
else if (d->m_displaySettings.m_highlightBlocks)
|
||||
cursor = textCursor();
|
||||
@@ -8907,7 +8931,7 @@ void TextEditorWidget::foldCurrentBlock()
|
||||
fold(textCursor().block());
|
||||
}
|
||||
|
||||
void TextEditorWidget::fold(const QTextBlock &block)
|
||||
void TextEditorWidget::fold(const QTextBlock &block, bool recursive)
|
||||
{
|
||||
if (singleShotAfterHighlightingDone([this, block] { fold(block); }))
|
||||
return;
|
||||
@@ -8923,14 +8947,14 @@ void TextEditorWidget::fold(const QTextBlock &block)
|
||||
b = b.previous();
|
||||
}
|
||||
if (b.isValid()) {
|
||||
TextDocumentLayout::doFoldOrUnfold(b, false);
|
||||
TextDocumentLayout::doFoldOrUnfold(b, false, recursive);
|
||||
d->moveCursorVisible();
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditorWidget::unfold(const QTextBlock &block)
|
||||
void TextEditorWidget::unfold(const QTextBlock &block, bool recursive)
|
||||
{
|
||||
if (singleShotAfterHighlightingDone([this, block] { unfold(block); }))
|
||||
return;
|
||||
@@ -8941,7 +8965,7 @@ void TextEditorWidget::unfold(const QTextBlock &block)
|
||||
QTextBlock b = block;
|
||||
while (b.isValid() && !b.isVisible())
|
||||
b = b.previous();
|
||||
TextDocumentLayout::doFoldOrUnfold(b, true);
|
||||
TextDocumentLayout::doFoldOrUnfold(b, true, recursive);
|
||||
d->moveCursorVisible();
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
@@ -8952,16 +8976,14 @@ void TextEditorWidget::unfoldCurrentBlock()
|
||||
unfold(textCursor().block());
|
||||
}
|
||||
|
||||
void TextEditorWidget::unfoldAll()
|
||||
void TextEditorWidget::toggleFoldAll()
|
||||
{
|
||||
if (singleShotAfterHighlightingDone([this] { unfoldAll(); }))
|
||||
if (singleShotAfterHighlightingDone([this] { toggleFoldAll(); }))
|
||||
return;
|
||||
|
||||
QTextDocument *doc = document();
|
||||
auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
|
||||
QTC_ASSERT(documentLayout, return);
|
||||
|
||||
QTextBlock block = doc->firstBlock();
|
||||
|
||||
bool makeVisible = true;
|
||||
while (block.isValid()) {
|
||||
if (block.isVisible() && TextDocumentLayout::canFold(block) && block.next().isVisible()) {
|
||||
@@ -8971,11 +8993,23 @@ void TextEditorWidget::unfoldAll()
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
block = doc->firstBlock();
|
||||
unfoldAll(makeVisible);
|
||||
}
|
||||
|
||||
void TextEditorWidget::unfoldAll(bool unfold)
|
||||
{
|
||||
if (singleShotAfterHighlightingDone([this, unfold] { unfoldAll(unfold); }))
|
||||
return;
|
||||
|
||||
QTextDocument *doc = document();
|
||||
auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
|
||||
QTC_ASSERT(documentLayout, return);
|
||||
|
||||
QTextBlock block = doc->firstBlock();
|
||||
|
||||
while (block.isValid()) {
|
||||
if (TextDocumentLayout::canFold(block))
|
||||
TextDocumentLayout::doFoldOrUnfold(block, makeVisible);
|
||||
TextDocumentLayout::doFoldOrUnfold(block, unfold);
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
|
@@ -387,10 +387,11 @@ public:
|
||||
void deleteStartOfLine();
|
||||
void deleteStartOfWord();
|
||||
void deleteStartOfWordCamelCase();
|
||||
void unfoldAll();
|
||||
void fold(const QTextBlock &block);
|
||||
void toggleFoldAll();
|
||||
void unfoldAll(bool unfold);
|
||||
void fold(const QTextBlock &block, bool recursive = false);
|
||||
void foldCurrentBlock();
|
||||
void unfold(const QTextBlock &block);
|
||||
void unfold(const QTextBlock &block, bool recursive = false);
|
||||
void unfoldCurrentBlock();
|
||||
void selectEncoding();
|
||||
void updateTextCodecLabel();
|
||||
|
Reference in New Issue
Block a user