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();
|
emit updateExtraArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
|
void TextDocumentLayout::doFoldOrUnfold(const QTextBlock &block, bool unfold, bool recursive)
|
||||||
{
|
{
|
||||||
if (!canFold(block))
|
if (!canFold(block))
|
||||||
return;
|
return;
|
||||||
@@ -643,7 +643,10 @@ void TextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
|
|||||||
while (b.isValid() && foldingIndent(b) > indent && (unfold || b.next().isValid())) {
|
while (b.isValid() && foldingIndent(b) > indent && (unfold || b.next().isValid())) {
|
||||||
b.setVisible(unfold);
|
b.setVisible(unfold);
|
||||||
b.setLineCount(unfold? qMax(1, b.layout()->lineCount()) : 0);
|
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()) {
|
if (isFolded(b) && b.next().isValid()) {
|
||||||
int jndent = foldingIndent(b);
|
int jndent = foldingIndent(b);
|
||||||
b = b.next();
|
b = b.next();
|
||||||
|
@@ -199,7 +199,7 @@ public:
|
|||||||
static int lexerState(const QTextBlock &block);
|
static int lexerState(const QTextBlock &block);
|
||||||
static void changeFoldingIndent(QTextBlock &block, int delta);
|
static void changeFoldingIndent(QTextBlock &block, int delta);
|
||||||
static bool canFold(const QTextBlock &block);
|
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 bool isFolded(const QTextBlock &block);
|
||||||
static void setFolded(const QTextBlock &block, bool folded);
|
static void setFolded(const QTextBlock &block, bool folded);
|
||||||
static void setExpectedRawStringSuffix(const QTextBlock &block, const QByteArray &suffix);
|
static void setExpectedRawStringSuffix(const QTextBlock &block, const QByteArray &suffix);
|
||||||
|
@@ -4235,7 +4235,7 @@ void TextEditorWidgetPrivate::registerActions()
|
|||||||
.setScriptable(true);
|
.setScriptable(true);
|
||||||
m_unfoldAllAction = ActionBuilder(this, UNFOLD_ALL)
|
m_unfoldAllAction = ActionBuilder(this, UNFOLD_ALL)
|
||||||
.setContext(m_editorContext)
|
.setContext(m_editorContext)
|
||||||
.addOnTriggered([this] { q->unfoldAll(); })
|
.addOnTriggered([this] { q->toggleFoldAll(); })
|
||||||
.setScriptable(true)
|
.setScriptable(true)
|
||||||
.contextAction();
|
.contextAction();
|
||||||
ActionBuilder(this, INCREASE_FONT_SIZE).setContext(m_editorContext).addOnTriggered([this] {
|
ActionBuilder(this, INCREASE_FONT_SIZE).setContext(m_editorContext).addOnTriggered([this] {
|
||||||
@@ -7097,8 +7097,38 @@ void TextEditorWidget::extraAreaLeaveEvent(QEvent *)
|
|||||||
extraAreaMouseEvent(&me);
|
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)
|
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) {
|
if (d->m_marksVisible) {
|
||||||
QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
|
QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
|
||||||
auto contextMenu = new QMenu(this);
|
auto contextMenu = new QMenu(this);
|
||||||
@@ -7119,14 +7149,8 @@ void TextEditorWidget::updateFoldingHighlight(const QPoint &pos)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Update which folder marker is highlighted
|
// Update which folder marker is highlighted
|
||||||
int boxWidth = 0;
|
|
||||||
if (TextEditorSettings::fontSettings().relativeLineSpacing() == 100)
|
|
||||||
boxWidth = foldBoxWidth(fontMetrics());
|
|
||||||
else
|
|
||||||
boxWidth = foldBoxWidth();
|
|
||||||
|
|
||||||
QTextCursor cursor;
|
QTextCursor cursor;
|
||||||
if (pos.x() > extraArea()->width() - boxWidth)
|
if (xIsInsideFoldingRegion(pos.x(), extraArea()->width(), fontMetrics()))
|
||||||
cursor = cursorForPosition(QPoint(0, pos.y()));
|
cursor = cursorForPosition(QPoint(0, pos.y()));
|
||||||
else if (d->m_displaySettings.m_highlightBlocks)
|
else if (d->m_displaySettings.m_highlightBlocks)
|
||||||
cursor = textCursor();
|
cursor = textCursor();
|
||||||
@@ -8907,7 +8931,7 @@ void TextEditorWidget::foldCurrentBlock()
|
|||||||
fold(textCursor().block());
|
fold(textCursor().block());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::fold(const QTextBlock &block)
|
void TextEditorWidget::fold(const QTextBlock &block, bool recursive)
|
||||||
{
|
{
|
||||||
if (singleShotAfterHighlightingDone([this, block] { fold(block); }))
|
if (singleShotAfterHighlightingDone([this, block] { fold(block); }))
|
||||||
return;
|
return;
|
||||||
@@ -8923,14 +8947,14 @@ void TextEditorWidget::fold(const QTextBlock &block)
|
|||||||
b = b.previous();
|
b = b.previous();
|
||||||
}
|
}
|
||||||
if (b.isValid()) {
|
if (b.isValid()) {
|
||||||
TextDocumentLayout::doFoldOrUnfold(b, false);
|
TextDocumentLayout::doFoldOrUnfold(b, false, recursive);
|
||||||
d->moveCursorVisible();
|
d->moveCursorVisible();
|
||||||
documentLayout->requestUpdate();
|
documentLayout->requestUpdate();
|
||||||
documentLayout->emitDocumentSizeChanged();
|
documentLayout->emitDocumentSizeChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::unfold(const QTextBlock &block)
|
void TextEditorWidget::unfold(const QTextBlock &block, bool recursive)
|
||||||
{
|
{
|
||||||
if (singleShotAfterHighlightingDone([this, block] { unfold(block); }))
|
if (singleShotAfterHighlightingDone([this, block] { unfold(block); }))
|
||||||
return;
|
return;
|
||||||
@@ -8941,7 +8965,7 @@ void TextEditorWidget::unfold(const QTextBlock &block)
|
|||||||
QTextBlock b = block;
|
QTextBlock b = block;
|
||||||
while (b.isValid() && !b.isVisible())
|
while (b.isValid() && !b.isVisible())
|
||||||
b = b.previous();
|
b = b.previous();
|
||||||
TextDocumentLayout::doFoldOrUnfold(b, true);
|
TextDocumentLayout::doFoldOrUnfold(b, true, recursive);
|
||||||
d->moveCursorVisible();
|
d->moveCursorVisible();
|
||||||
documentLayout->requestUpdate();
|
documentLayout->requestUpdate();
|
||||||
documentLayout->emitDocumentSizeChanged();
|
documentLayout->emitDocumentSizeChanged();
|
||||||
@@ -8952,16 +8976,14 @@ void TextEditorWidget::unfoldCurrentBlock()
|
|||||||
unfold(textCursor().block());
|
unfold(textCursor().block());
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::unfoldAll()
|
void TextEditorWidget::toggleFoldAll()
|
||||||
{
|
{
|
||||||
if (singleShotAfterHighlightingDone([this] { unfoldAll(); }))
|
if (singleShotAfterHighlightingDone([this] { toggleFoldAll(); }))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QTextDocument *doc = document();
|
QTextDocument *doc = document();
|
||||||
auto documentLayout = qobject_cast<TextDocumentLayout*>(doc->documentLayout());
|
|
||||||
QTC_ASSERT(documentLayout, return);
|
|
||||||
|
|
||||||
QTextBlock block = doc->firstBlock();
|
QTextBlock block = doc->firstBlock();
|
||||||
|
|
||||||
bool makeVisible = true;
|
bool makeVisible = true;
|
||||||
while (block.isValid()) {
|
while (block.isValid()) {
|
||||||
if (block.isVisible() && TextDocumentLayout::canFold(block) && block.next().isVisible()) {
|
if (block.isVisible() && TextDocumentLayout::canFold(block) && block.next().isVisible()) {
|
||||||
@@ -8971,11 +8993,23 @@ void TextEditorWidget::unfoldAll()
|
|||||||
block = block.next();
|
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()) {
|
while (block.isValid()) {
|
||||||
if (TextDocumentLayout::canFold(block))
|
if (TextDocumentLayout::canFold(block))
|
||||||
TextDocumentLayout::doFoldOrUnfold(block, makeVisible);
|
TextDocumentLayout::doFoldOrUnfold(block, unfold);
|
||||||
block = block.next();
|
block = block.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -387,10 +387,11 @@ public:
|
|||||||
void deleteStartOfLine();
|
void deleteStartOfLine();
|
||||||
void deleteStartOfWord();
|
void deleteStartOfWord();
|
||||||
void deleteStartOfWordCamelCase();
|
void deleteStartOfWordCamelCase();
|
||||||
void unfoldAll();
|
void toggleFoldAll();
|
||||||
void fold(const QTextBlock &block);
|
void unfoldAll(bool unfold);
|
||||||
|
void fold(const QTextBlock &block, bool recursive = false);
|
||||||
void foldCurrentBlock();
|
void foldCurrentBlock();
|
||||||
void unfold(const QTextBlock &block);
|
void unfold(const QTextBlock &block, bool recursive = false);
|
||||||
void unfoldCurrentBlock();
|
void unfoldCurrentBlock();
|
||||||
void selectEncoding();
|
void selectEncoding();
|
||||||
void updateTextCodecLabel();
|
void updateTextCodecLabel();
|
||||||
|
Reference in New Issue
Block a user