forked from qt-creator/qt-creator
Rework code folding
The new and cleaner foldingIndent in the block user data will make it easier to support other kinds of indentation for various other programming languages (like Python).
This commit is contained in:
@@ -65,15 +65,19 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
const QList<SimpleToken> tokens = tokenize(text, initialState);
|
||||
state = tokenize.state(); // refresh the state
|
||||
|
||||
int foldingIndent = initialBraceDepth;
|
||||
if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(currentBlock())) {
|
||||
userData->setFoldingIndent(0);
|
||||
userData->setFoldingStartIncluded(false);
|
||||
userData->setFoldingEndIncluded(false);
|
||||
}
|
||||
|
||||
if (tokens.isEmpty()) {
|
||||
setCurrentBlockState(previousState);
|
||||
if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(currentBlock())) {
|
||||
userData->setClosingCollapseMode(TextBlockUserData::NoClosingCollapse);
|
||||
userData->setCollapseMode(TextBlockUserData::NoCollapse);
|
||||
}
|
||||
BaseTextDocumentLayout::clearParentheses(currentBlock());
|
||||
if (text.length()) // the empty line can still contain whitespace
|
||||
setFormat(0, text.length(), m_formats[CppVisualWhitespace]);
|
||||
BaseTextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -102,13 +106,29 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
if (tk.is(T_LPAREN) || tk.is(T_LBRACE) || tk.is(T_LBRACKET)) {
|
||||
const QChar c(tk.text().at(0));
|
||||
parentheses.append(Parenthesis(Parenthesis::Opened, c, tk.position()));
|
||||
if (tk.is(T_LBRACE))
|
||||
if (tk.is(T_LBRACE)) {
|
||||
++braceDepth;
|
||||
|
||||
// if a folding block opens at the beginning of a line, treat the entire line
|
||||
// as if it were inside the folding block
|
||||
if (tk.position() == firstNonSpace) {
|
||||
++foldingIndent;
|
||||
BaseTextDocumentLayout::userData(currentBlock())->setFoldingStartIncluded(true);
|
||||
}
|
||||
}
|
||||
} else if (tk.is(T_RPAREN) || tk.is(T_RBRACE) || tk.is(T_RBRACKET)) {
|
||||
const QChar c(tk.text().at(0));
|
||||
parentheses.append(Parenthesis(Parenthesis::Closed, c, tk.position()));
|
||||
if (tk.is(T_RBRACE))
|
||||
if (tk.is(T_RBRACE)) {
|
||||
--braceDepth;
|
||||
if (braceDepth < foldingIndent) {
|
||||
// unless we are at the end of the block, we reduce the folding indent
|
||||
if (i == tokens.size()-1 || tokens.at(i+1).is(T_SEMICOLON))
|
||||
BaseTextDocumentLayout::userData(currentBlock())->setFoldingEndIncluded(true);
|
||||
else
|
||||
foldingIndent = qMin(braceDepth, foldingIndent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool highlightCurrentWordAsPreprocessor = highlightAsPreprocessor;
|
||||
@@ -148,7 +168,11 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
// - is not a continuation line (tokens.size() > 1 || ! state)
|
||||
if (initialState && i == 0 && (tokens.size() > 1 || ! state)) {
|
||||
--braceDepth;
|
||||
|
||||
// unless we are at the end of the block, we reduce the folding indent
|
||||
if (i == tokens.size()-1)
|
||||
BaseTextDocumentLayout::userData(currentBlock())->setFoldingEndIncluded(true);
|
||||
else
|
||||
foldingIndent = qMin(braceDepth, foldingIndent);
|
||||
const int tokenEnd = tk.position() + tk.length() - 1;
|
||||
parentheses.append(Parenthesis(Parenthesis::Closed, QLatin1Char('-'), tokenEnd));
|
||||
|
||||
@@ -167,6 +191,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
|
||||
else if (tk.is(T_IDENTIFIER))
|
||||
highlightWord(tk.text(), tk.position(), tk.length());
|
||||
|
||||
}
|
||||
|
||||
// mark the trailing white spaces
|
||||
@@ -177,43 +202,23 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
highlightLine(text, lastTokenEnd, text.length() - lastTokenEnd, QTextCharFormat());
|
||||
}
|
||||
|
||||
if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(currentBlock())) {
|
||||
userData->setClosingCollapseMode(TextBlockUserData::NoClosingCollapse);
|
||||
userData->setCollapseMode(TextBlockUserData::NoCollapse);
|
||||
}
|
||||
|
||||
if (! initialState && state && ! tokens.isEmpty()) {
|
||||
parentheses.append(Parenthesis(Parenthesis::Opened, QLatin1Char('+'),
|
||||
tokens.last().position()));
|
||||
++braceDepth;
|
||||
}
|
||||
|
||||
QChar c;
|
||||
int collapse = Parenthesis::collapseAtPos(parentheses, &c);
|
||||
if (collapse >= 0) {
|
||||
TextBlockUserData::CollapseMode collapseMode = TextBlockUserData::CollapseAfter;
|
||||
if (collapse == firstNonSpace && c != QLatin1Char('+'))
|
||||
collapseMode = TextBlockUserData::CollapseThis;
|
||||
BaseTextDocumentLayout::userData(currentBlock())->setCollapseMode(collapseMode);
|
||||
}
|
||||
|
||||
|
||||
int cc = Parenthesis::closeCollapseAtPos(parentheses);
|
||||
if (cc >= 0) {
|
||||
TextBlockUserData *userData = BaseTextDocumentLayout::userData(currentBlock());
|
||||
userData->setClosingCollapseMode(TextBlockUserData::ClosingCollapse);
|
||||
QString trailingText = text.mid(cc+1).simplified();
|
||||
if (trailingText.isEmpty() || trailingText == QLatin1String(";")) {
|
||||
userData->setClosingCollapseMode(TextBlockUserData::ClosingCollapseAtEnd);
|
||||
}
|
||||
}
|
||||
|
||||
BaseTextDocumentLayout::setParentheses(currentBlock(), parentheses);
|
||||
|
||||
// if the block is ifdefed out, we only store the parentheses, but
|
||||
|
||||
// do not adjust the brace depth.
|
||||
if (BaseTextDocumentLayout::ifdefedOut(currentBlock()))
|
||||
if (BaseTextDocumentLayout::ifdefedOut(currentBlock())) {
|
||||
braceDepth = initialBraceDepth;
|
||||
foldingIndent = initialBraceDepth;
|
||||
}
|
||||
|
||||
BaseTextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent);
|
||||
|
||||
// optimization: if only the brace depth changes, we adjust subsequent blocks
|
||||
// to have QSyntaxHighlighter stop the rehighlighting
|
||||
@@ -226,6 +231,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
QTextBlock block = currentBlock().next();
|
||||
while (block.isValid() && block.userState() != -1) {
|
||||
BaseTextDocumentLayout::changeBraceDepth(block, delta);
|
||||
BaseTextDocumentLayout::changeFoldingIndent(block, delta);
|
||||
block = block.next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ Highlighter::Highlighter(QTextDocument *parent)
|
||||
{
|
||||
m_currentBlockParentheses.reserve(20);
|
||||
m_braceDepth = 0;
|
||||
m_foldingIndent = 0;
|
||||
}
|
||||
|
||||
Highlighter::~Highlighter()
|
||||
@@ -102,27 +103,27 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
break;
|
||||
|
||||
case Token::LeftParenthesis:
|
||||
onOpeningParenthesis('(', token.offset);
|
||||
onOpeningParenthesis('(', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightParenthesis:
|
||||
onClosingParenthesis(')', token.offset);
|
||||
onClosingParenthesis(')', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::LeftBrace:
|
||||
onOpeningParenthesis('{', token.offset);
|
||||
onOpeningParenthesis('{', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightBrace:
|
||||
onClosingParenthesis('}', token.offset);
|
||||
onClosingParenthesis('}', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::LeftBracket:
|
||||
onOpeningParenthesis('[', token.offset);
|
||||
onOpeningParenthesis('[', token.offset, index == 0);
|
||||
break;
|
||||
|
||||
case Token::RightBracket:
|
||||
onClosingParenthesis(']', token.offset);
|
||||
onClosingParenthesis(']', token.offset, index == tokens.size()-1);
|
||||
break;
|
||||
|
||||
case Token::Identifier: {
|
||||
@@ -232,12 +233,8 @@ void Highlighter::highlightBlock(const QString &text)
|
||||
|
||||
setFormat(previousTokenEnd, text.length() - previousTokenEnd, m_formats[VisualWhitespace]);
|
||||
|
||||
int firstNonSpace = 0;
|
||||
if (! tokens.isEmpty())
|
||||
firstNonSpace = tokens.first().offset;
|
||||
|
||||
setCurrentBlockState(m_scanner.state());
|
||||
onBlockEnd(m_scanner.state(), firstNonSpace);
|
||||
onBlockEnd(m_scanner.state());
|
||||
}
|
||||
|
||||
bool Highlighter::maybeQmlKeyword(const QStringRef &text) const
|
||||
@@ -301,6 +298,12 @@ int Highlighter::onBlockStart()
|
||||
{
|
||||
m_currentBlockParentheses.clear();
|
||||
m_braceDepth = 0;
|
||||
m_foldingIndent = 0;
|
||||
if (TextEditor::TextBlockUserData *userData = TextEditor::BaseTextDocumentLayout::testUserData(currentBlock())) {
|
||||
userData->setFoldingIndent(0);
|
||||
userData->setFoldingStartIncluded(false);
|
||||
userData->setFoldingEndIncluded(false);
|
||||
}
|
||||
|
||||
int state = 0;
|
||||
int previousState = previousBlockState();
|
||||
@@ -308,56 +311,41 @@ int Highlighter::onBlockStart()
|
||||
state = previousState & 0xff;
|
||||
m_braceDepth = previousState >> 8;
|
||||
}
|
||||
m_foldingIndent = m_braceDepth;
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
void Highlighter::onBlockEnd(int state, int firstNonSpace)
|
||||
void Highlighter::onBlockEnd(int state)
|
||||
{
|
||||
typedef TextEditor::TextBlockUserData TextEditorBlockData;
|
||||
|
||||
setCurrentBlockState((m_braceDepth << 8) | state);
|
||||
|
||||
// Set block data parentheses. Force creation of block data unless empty
|
||||
TextEditorBlockData *blockData = 0;
|
||||
|
||||
if (QTextBlockUserData *userData = currentBlockUserData())
|
||||
blockData = static_cast<TextEditorBlockData *>(userData);
|
||||
|
||||
if (!blockData && !m_currentBlockParentheses.empty()) {
|
||||
blockData = new TextEditorBlockData;
|
||||
setCurrentBlockUserData(blockData);
|
||||
}
|
||||
if (blockData) {
|
||||
blockData->setParentheses(m_currentBlockParentheses);
|
||||
blockData->setClosingCollapseMode(TextEditor::TextBlockUserData::NoClosingCollapse);
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::NoCollapse);
|
||||
}
|
||||
if (!m_currentBlockParentheses.isEmpty()) {
|
||||
QTC_ASSERT(blockData, return);
|
||||
int collapse = Parenthesis::collapseAtPos(m_currentBlockParentheses);
|
||||
if (collapse >= 0) {
|
||||
if (collapse == firstNonSpace)
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::CollapseThis);
|
||||
else
|
||||
blockData->setCollapseMode(TextEditor::TextBlockUserData::CollapseAfter);
|
||||
}
|
||||
if (Parenthesis::hasClosingCollapse(m_currentBlockParentheses))
|
||||
blockData->setClosingCollapseMode(TextEditor::TextBlockUserData::NoClosingCollapse);
|
||||
}
|
||||
TextEditor::BaseTextDocumentLayout::setParentheses(currentBlock(), m_currentBlockParentheses);
|
||||
TextEditor::BaseTextDocumentLayout::setFoldingIndent(currentBlock(), m_foldingIndent);
|
||||
}
|
||||
|
||||
void Highlighter::onOpeningParenthesis(QChar parenthesis, int pos)
|
||||
void Highlighter::onOpeningParenthesis(QChar parenthesis, int pos, bool atStart)
|
||||
{
|
||||
if (parenthesis == QLatin1Char('{') || parenthesis == QLatin1Char('['))
|
||||
if (parenthesis == QLatin1Char('{') || parenthesis == QLatin1Char('[')) {
|
||||
++m_braceDepth;
|
||||
// if a folding block opens at the beginning of a line, treat the entire line
|
||||
// as if it were inside the folding block
|
||||
if (atStart)
|
||||
TextEditor::BaseTextDocumentLayout::userData(currentBlock())->setFoldingStartIncluded(true);
|
||||
}
|
||||
m_currentBlockParentheses.push_back(Parenthesis(Parenthesis::Opened, parenthesis, pos));
|
||||
}
|
||||
|
||||
void Highlighter::onClosingParenthesis(QChar parenthesis, int pos)
|
||||
void Highlighter::onClosingParenthesis(QChar parenthesis, int pos, bool atEnd)
|
||||
{
|
||||
if (parenthesis == QLatin1Char('}') || parenthesis == QLatin1Char(']'))
|
||||
if (parenthesis == QLatin1Char('}') || parenthesis == QLatin1Char(']')) {
|
||||
--m_braceDepth;
|
||||
if (atEnd)
|
||||
TextEditor::BaseTextDocumentLayout::userData(currentBlock())->setFoldingEndIncluded(true);
|
||||
else
|
||||
m_foldingIndent = qMin(m_braceDepth, m_foldingIndent); // folding indent is the minimum brace depth of a block
|
||||
}
|
||||
m_currentBlockParentheses.push_back(Parenthesis(Parenthesis::Closed, parenthesis, pos));
|
||||
}
|
||||
|
||||
|
||||
@@ -78,12 +78,12 @@ protected:
|
||||
virtual void highlightBlock(const QString &text);
|
||||
|
||||
int onBlockStart();
|
||||
void onBlockEnd(int state, int firstNonSpace);
|
||||
void onBlockEnd(int state);
|
||||
|
||||
// The functions are notified whenever parentheses are encountered.
|
||||
// Custom behaviour can be added, for example storing info for indenting.
|
||||
void onOpeningParenthesis(QChar parenthesis, int pos);
|
||||
void onClosingParenthesis(QChar parenthesis, int pos);
|
||||
void onOpeningParenthesis(QChar parenthesis, int pos, bool atStart);
|
||||
void onClosingParenthesis(QChar parenthesis, int pos, bool atEnd);
|
||||
|
||||
bool maybeQmlKeyword(const QStringRef &text) const;
|
||||
bool maybeQmlBuiltinType(const QStringRef &text) const;
|
||||
@@ -94,6 +94,7 @@ private:
|
||||
|
||||
bool m_qmlEnabled;
|
||||
int m_braceDepth;
|
||||
int m_foldingIndent;
|
||||
|
||||
QmlJS::Scanner m_scanner;
|
||||
Parentheses m_currentBlockParentheses;
|
||||
|
||||
@@ -31,60 +31,6 @@
|
||||
|
||||
using namespace TextEditor;
|
||||
|
||||
bool Parenthesis::hasClosingCollapse(const Parentheses &parentheses)
|
||||
{
|
||||
return closeCollapseAtPos(parentheses) >= 0;
|
||||
}
|
||||
|
||||
int Parenthesis::closeCollapseAtPos(const Parentheses &parentheses)
|
||||
{
|
||||
int depth = 0;
|
||||
for (int i = 0; i < parentheses.size(); ++i) {
|
||||
const Parenthesis &p = parentheses.at(i);
|
||||
if (p.chr == QLatin1Char('{')
|
||||
|| p.chr == QLatin1Char('+')
|
||||
|| p.chr == QLatin1Char('[')) {
|
||||
++depth;
|
||||
} else if (p.chr == QLatin1Char('}')
|
||||
|| p.chr == QLatin1Char('-')
|
||||
|| p.chr == QLatin1Char(']')) {
|
||||
if (--depth < 0)
|
||||
return p.pos;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Parenthesis::collapseAtPos(const Parentheses &parentheses, QChar *character)
|
||||
{
|
||||
int result = -1;
|
||||
QChar c;
|
||||
|
||||
int depth = 0;
|
||||
for (int i = 0; i < parentheses.size(); ++i) {
|
||||
const Parenthesis &p = parentheses.at(i);
|
||||
if (p.chr == QLatin1Char('{')
|
||||
|| p.chr == QLatin1Char('+')
|
||||
|| p.chr == QLatin1Char('[')) {
|
||||
if (depth == 0) {
|
||||
result = p.pos;
|
||||
c = p.chr;
|
||||
}
|
||||
++depth;
|
||||
} else if (p.chr == QLatin1Char('}')
|
||||
|| p.chr == QLatin1Char('-')
|
||||
|| p.chr == QLatin1Char(']')) {
|
||||
if (--depth < 0)
|
||||
depth = 0;
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
if (result >= 0 && character)
|
||||
*character = c;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
TextBlockUserData::~TextBlockUserData()
|
||||
{
|
||||
TextMarks marks = m_marks;
|
||||
@@ -94,11 +40,6 @@ TextBlockUserData::~TextBlockUserData()
|
||||
}
|
||||
}
|
||||
|
||||
int TextBlockUserData::collapseAtPos(QChar *character) const
|
||||
{
|
||||
return Parenthesis::collapseAtPos(m_parentheses, character);
|
||||
}
|
||||
|
||||
int TextBlockUserData::braceDepthDelta() const
|
||||
{
|
||||
int delta = 0;
|
||||
@@ -112,96 +53,6 @@ int TextBlockUserData::braceDepthDelta() const
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
QTextBlock TextBlockUserData::testCollapse(const QTextBlock& block)
|
||||
{
|
||||
QTextBlock info = block;
|
||||
if (block.userData() && static_cast<TextBlockUserData*>(block.userData())->collapseMode() == CollapseAfter)
|
||||
;
|
||||
else if (block.next().userData()
|
||||
&& static_cast<TextBlockUserData*>(block.next().userData())->collapseMode()
|
||||
== TextBlockUserData::CollapseThis)
|
||||
info = block.next();
|
||||
else
|
||||
return QTextBlock();
|
||||
int pos = static_cast<TextBlockUserData*>(info.userData())->collapseAtPos();
|
||||
if (pos < 0)
|
||||
return QTextBlock();
|
||||
QTextCursor cursor(info);
|
||||
cursor.setPosition(cursor.position() + pos);
|
||||
matchCursorForward(&cursor);
|
||||
return cursor.block();
|
||||
}
|
||||
|
||||
void TextBlockUserData::doCollapse(const QTextBlock& block, bool visible)
|
||||
{
|
||||
QTextBlock info = block;
|
||||
if (block.userData() && static_cast<TextBlockUserData*>(block.userData())->collapseMode() == CollapseAfter)
|
||||
;
|
||||
else if (block.next().userData()
|
||||
&& static_cast<TextBlockUserData*>(block.next().userData())->collapseMode()
|
||||
== TextBlockUserData::CollapseThis)
|
||||
info = block.next();
|
||||
else {
|
||||
if (visible && !block.next().isVisible()) {
|
||||
// no match, at least unfold!
|
||||
QTextBlock b = block.next();
|
||||
while (b.isValid() && !b.isVisible()) {
|
||||
b.setVisible(true);
|
||||
b.setLineCount(visible ? qMax(1, b.layout()->lineCount()) : 0);
|
||||
b = b.next();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
int pos = static_cast<TextBlockUserData*>(info.userData())->collapseAtPos();
|
||||
if (pos < 0)
|
||||
return;
|
||||
QTextCursor cursor(info);
|
||||
cursor.setPosition(cursor.position() + pos);
|
||||
if (matchCursorForward(&cursor) != Match) {
|
||||
if (visible) {
|
||||
// no match, at least unfold!
|
||||
QTextBlock b = block.next();
|
||||
while (b.isValid() && !b.isVisible()) {
|
||||
b.setVisible(true);
|
||||
b.setLineCount(visible ? qMax(1, b.layout()->lineCount()) : 0);
|
||||
b = b.next();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
QTextBlock b = block.next();
|
||||
while (b < cursor.block()) {
|
||||
b.setVisible(visible);
|
||||
b.setLineCount(visible ? qMax(1, b.layout()->lineCount()) : 0);
|
||||
if (visible) {
|
||||
TextBlockUserData *data = canCollapse(b);
|
||||
if (data && data->collapsed()) {
|
||||
QTextBlock end = testCollapse(b);
|
||||
if (data->collapseIncludesClosure())
|
||||
end = end.next();
|
||||
if (end.isValid()) {
|
||||
b = end;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
b = b.next();
|
||||
}
|
||||
|
||||
bool collapseIncludesClosure = hasClosingCollapseAtEnd(b);
|
||||
if (collapseIncludesClosure) {
|
||||
b.setVisible(visible);
|
||||
b.setLineCount(visible ? qMax(1, b.layout()->lineCount()) : 0);
|
||||
}
|
||||
static_cast<TextBlockUserData*>(info.userData())->setCollapseIncludesClosure(collapseIncludesClosure);
|
||||
static_cast<TextBlockUserData*>(info.userData())->setCollapsed(!block.next().isVisible());
|
||||
|
||||
}
|
||||
|
||||
|
||||
TextBlockUserData::MatchType TextBlockUserData::checkOpenParenthesis(QTextCursor *cursor, QChar c)
|
||||
{
|
||||
QTextBlock block = cursor->block();
|
||||
@@ -591,3 +442,76 @@ void BaseTextDocumentLayout::changeBraceDepth(QTextBlock &block, int delta)
|
||||
if (delta)
|
||||
setBraceDepth(block, braceDepth(block) + delta);
|
||||
}
|
||||
|
||||
void BaseTextDocumentLayout::setFoldingIndent(const QTextBlock &block, int indent)
|
||||
{
|
||||
if (indent == 0) {
|
||||
if (TextBlockUserData *userData = testUserData(block))
|
||||
userData->setFoldingIndent(0);
|
||||
} else {
|
||||
userData(block)->setFoldingIndent(qMax(0,indent));
|
||||
}
|
||||
}
|
||||
|
||||
int BaseTextDocumentLayout::foldingIndent(const QTextBlock &block)
|
||||
{
|
||||
if (TextBlockUserData *userData = testUserData(block))
|
||||
return userData->foldingIndent();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BaseTextDocumentLayout::changeFoldingIndent(QTextBlock &block, int delta)
|
||||
{
|
||||
if (delta)
|
||||
setFoldingIndent(block, foldingIndent(block) + delta);
|
||||
}
|
||||
|
||||
bool BaseTextDocumentLayout::canFold(const QTextBlock &block)
|
||||
{
|
||||
return (block.next().isValid() && foldingIndent(block.next()) > foldingIndent(block));
|
||||
}
|
||||
|
||||
bool BaseTextDocumentLayout::isFolded(const QTextBlock &block)
|
||||
{
|
||||
if (TextBlockUserData *userData = testUserData(block))
|
||||
return userData->folded();
|
||||
return false;
|
||||
}
|
||||
|
||||
void BaseTextDocumentLayout::setFolded(const QTextBlock &block, bool folded)
|
||||
{
|
||||
if (folded)
|
||||
userData(block)->setFolded(true);
|
||||
else {
|
||||
if (TextBlockUserData *userData = testUserData(block))
|
||||
return userData->setFolded(false);
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextDocumentLayout::doFoldOrUnfold(const QTextBlock& block, bool unfold)
|
||||
{
|
||||
if (!canFold(block))
|
||||
return;
|
||||
QTextBlock b = block.next();
|
||||
if (b.isVisible() == unfold)
|
||||
return;
|
||||
|
||||
int indent = foldingIndent(block);
|
||||
while (b.isValid() && foldingIndent(b) > indent && b.next().isValid()) {
|
||||
b.setVisible(unfold);
|
||||
b.setLineCount(unfold? qMax(1, b.layout()->lineCount()) : 0);
|
||||
if (unfold) { // do not unfold folded sub-blocks
|
||||
if (isFolded(b) && b.next().isValid()) {
|
||||
int jndent = foldingIndent(b);
|
||||
b = b.next();
|
||||
while (b.isValid() && foldingIndent(b) > jndent)
|
||||
b = b.next();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
b = b.next();
|
||||
}
|
||||
setFolded(block, !unfold);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@ struct TEXTEDITOR_EXPORT Parenthesis
|
||||
Type type;
|
||||
QChar chr;
|
||||
int pos;
|
||||
static int collapseAtPos(const Parentheses &parentheses, QChar *character = 0);
|
||||
static int closeCollapseAtPos(const Parentheses &parentheses);
|
||||
static bool hasClosingCollapse(const Parentheses &parentheses);
|
||||
};
|
||||
|
||||
|
||||
@@ -62,15 +59,12 @@ class TEXTEDITOR_EXPORT TextBlockUserData : public QTextBlockUserData
|
||||
{
|
||||
public:
|
||||
|
||||
enum CollapseMode { NoCollapse , CollapseThis, CollapseAfter };
|
||||
enum ClosingCollapseMode { NoClosingCollapse, ClosingCollapse, ClosingCollapseAtEnd };
|
||||
|
||||
inline TextBlockUserData()
|
||||
: m_collapseIncludesClosure(false),
|
||||
m_collapseMode(NoCollapse),
|
||||
m_closingCollapseMode(NoClosingCollapse),
|
||||
m_collapsed(false),
|
||||
m_ifdefedOut(false) {}
|
||||
: m_folded(false),
|
||||
m_ifdefedOut(false),
|
||||
m_foldingIndent(0),
|
||||
m_foldingStartIncluded(false),
|
||||
m_foldingEndIncluded(false){}
|
||||
~TextBlockUserData();
|
||||
|
||||
inline TextMarks marks() const { return m_marks; }
|
||||
@@ -80,21 +74,8 @@ public:
|
||||
inline void clearMarks() { m_marks.clear(); }
|
||||
inline void documentClosing() { Q_FOREACH(ITextMark *tm, m_marks) { tm->documentClosing(); } m_marks.clear();}
|
||||
|
||||
inline CollapseMode collapseMode() const { return (CollapseMode)m_collapseMode; }
|
||||
inline void setCollapseMode(CollapseMode c) { m_collapseMode = c; }
|
||||
|
||||
inline void setClosingCollapseMode(ClosingCollapseMode c) { m_closingCollapseMode = c; }
|
||||
inline ClosingCollapseMode closingCollapseMode() const { return (ClosingCollapseMode) m_closingCollapseMode; }
|
||||
|
||||
inline bool hasClosingCollapse() const { return closingCollapseMode() != NoClosingCollapse; }
|
||||
inline bool hasClosingCollapseAtEnd() const { return closingCollapseMode() == ClosingCollapseAtEnd; }
|
||||
inline bool hasClosingCollapseInside() const { return closingCollapseMode() == ClosingCollapse; }
|
||||
|
||||
inline void setCollapsed(bool b) { m_collapsed = b; }
|
||||
inline bool collapsed() const { return m_collapsed; }
|
||||
|
||||
inline void setCollapseIncludesClosure(bool b) { m_collapseIncludesClosure = b; }
|
||||
inline bool collapseIncludesClosure() const { return m_collapseIncludesClosure; }
|
||||
inline void setFolded(bool b) { m_folded = b; }
|
||||
inline bool folded() const { return m_folded; }
|
||||
|
||||
inline void setParentheses(const Parentheses &parentheses) { m_parentheses = parentheses; }
|
||||
inline void clearParentheses() { m_parentheses.clear(); }
|
||||
@@ -106,49 +87,6 @@ public:
|
||||
inline bool clearIfdefedOut() { bool result = m_ifdefedOut; m_ifdefedOut = false; return result;}
|
||||
inline bool ifdefedOut() const { return m_ifdefedOut; }
|
||||
|
||||
inline static TextBlockUserData *canCollapse(const QTextBlock &block) {
|
||||
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData());
|
||||
if (!data || data->collapseMode() != CollapseAfter) {
|
||||
data = static_cast<TextBlockUserData*>(block.next().userData());
|
||||
if (!data || data->collapseMode() != TextBlockUserData::CollapseThis)
|
||||
data = 0;
|
||||
}
|
||||
if (data && data->m_ifdefedOut)
|
||||
data = 0;
|
||||
return data;
|
||||
}
|
||||
|
||||
inline static bool hasCollapseAfter(const QTextBlock & block)
|
||||
{
|
||||
if (!block.isValid()) {
|
||||
return false;
|
||||
} else if (block.next().isValid()) {
|
||||
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.next().userData());
|
||||
if (data && data->collapseMode() == TextBlockUserData::CollapseThis && !data->m_ifdefedOut)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static bool hasClosingCollapse(const QTextBlock &block) {
|
||||
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData());
|
||||
return (data && data->hasClosingCollapse());
|
||||
}
|
||||
|
||||
inline static bool hasClosingCollapseAtEnd(const QTextBlock &block) {
|
||||
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData());
|
||||
return (data && data->hasClosingCollapseAtEnd());
|
||||
}
|
||||
|
||||
inline static bool hasClosingCollapseInside(const QTextBlock &block) {
|
||||
TextBlockUserData *data = static_cast<TextBlockUserData*>(block.userData());
|
||||
return (data && data->hasClosingCollapseInside());
|
||||
}
|
||||
|
||||
static QTextBlock testCollapse(const QTextBlock& block);
|
||||
static void doCollapse(const QTextBlock& block, bool visible);
|
||||
|
||||
int collapseAtPos(QChar *character = 0) const;
|
||||
|
||||
enum MatchType { NoMatch, Match, Mismatch };
|
||||
static MatchType checkOpenParenthesis(QTextCursor *cursor, QChar c);
|
||||
@@ -161,14 +99,21 @@ public:
|
||||
static bool findPreviousBlockOpenParenthesis(QTextCursor *cursor, bool checkStartPosition = false);
|
||||
static bool findNextBlockClosingParenthesis(QTextCursor *cursor);
|
||||
|
||||
int foldingIndent() const { return m_foldingIndent; }
|
||||
void setFoldingIndent(int indent) { m_foldingIndent = indent; }
|
||||
void setFoldingStartIncluded(bool included) { m_foldingStartIncluded = included; }
|
||||
bool foldingStartIncluded() const { return m_foldingStartIncluded; }
|
||||
void setFoldingEndIncluded(bool included) { m_foldingEndIncluded = included; }
|
||||
bool foldingEndIncluded() const { return m_foldingEndIncluded; }
|
||||
|
||||
|
||||
private:
|
||||
TextMarks m_marks;
|
||||
uint m_collapseIncludesClosure : 1;
|
||||
uint m_collapseMode : 4;
|
||||
uint m_closingCollapseMode : 4;
|
||||
uint m_collapsed : 1;
|
||||
uint m_folded : 1;
|
||||
uint m_ifdefedOut : 1;
|
||||
uint m_foldingIndent : 16;
|
||||
uint m_foldingStartIncluded : 1;
|
||||
uint m_foldingEndIncluded : 1;
|
||||
Parentheses m_parentheses;
|
||||
};
|
||||
|
||||
@@ -192,6 +137,13 @@ public:
|
||||
static int braceDepth(const QTextBlock &block);
|
||||
static void setBraceDepth(QTextBlock &block, int depth);
|
||||
static void changeBraceDepth(QTextBlock &block, int delta);
|
||||
static void setFoldingIndent(const QTextBlock &block, int indent);
|
||||
static int foldingIndent(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 bool isFolded(const QTextBlock &block);
|
||||
static void setFolded(const QTextBlock &block, bool folded);
|
||||
|
||||
static TextBlockUserData *testUserData(const QTextBlock &block) {
|
||||
return static_cast<TextBlockUserData*>(block.userData());
|
||||
|
||||
@@ -202,11 +202,10 @@ BaseTextEditor::BaseTextEditor(QWidget *parent)
|
||||
viewport()->setMouseTracking(true);
|
||||
d->extraAreaSelectionAnchorBlockNumber
|
||||
= d->extraAreaToggleMarkBlockNumber
|
||||
= d->extraAreaHighlightCollapseBlockNumber
|
||||
= d->extraAreaHighlightCollapseColumn
|
||||
= d->extraAreaHighlightFoldedBlockNumber
|
||||
= -1;
|
||||
|
||||
d->visibleCollapsedBlockNumber = d->suggestedVisibleCollapsedBlockNumber = -1;
|
||||
d->visibleFoldedBlockNumber = d->suggestedVisibleFoldedBlockNumber = -1;
|
||||
|
||||
connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(slotUpdateExtraAreaWidth()));
|
||||
connect(this, SIGNAL(modificationChanged(bool)), this, SLOT(slotModificationChanged(bool)));
|
||||
@@ -280,7 +279,7 @@ void BaseTextEditor::print(QPrinter *printer)
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
static int collapseBoxWidth(const QFontMetrics &fm)
|
||||
static int foldBoxWidth(const QFontMetrics &fm)
|
||||
{
|
||||
const int lineSpacing = fm.lineSpacing();
|
||||
return lineSpacing + lineSpacing%2 + 1;
|
||||
@@ -585,7 +584,7 @@ bool BaseTextEditor::open(const QString &fileName)
|
||||
/*
|
||||
Collapses the first comment in a file, if there is only whitespace above
|
||||
*/
|
||||
void BaseTextEditorPrivate::collapseLicenseHeader()
|
||||
void BaseTextEditorPrivate::foldLicenseHeader()
|
||||
{
|
||||
QTextDocument *doc = q->document();
|
||||
BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout());
|
||||
@@ -593,19 +592,16 @@ void BaseTextEditorPrivate::collapseLicenseHeader()
|
||||
QTextBlock block = doc->firstBlock();
|
||||
const TabSettings &ts = m_document->tabSettings();
|
||||
while (block.isValid() && block.isVisible()) {
|
||||
TextBlockUserData *data = TextBlockUserData::canCollapse(block);
|
||||
if (data && block.next().isVisible()) {
|
||||
QChar character;
|
||||
static_cast<TextBlockUserData*>(data)->collapseAtPos(&character);
|
||||
if (character != QLatin1Char('+'))
|
||||
break; // not a comment
|
||||
TextBlockUserData::doCollapse(block, false);
|
||||
QString text = block.text();
|
||||
if (BaseTextDocumentLayout::canFold(block) && block.next().isVisible()) {
|
||||
if (text.trimmed().startsWith(QLatin1String("/*"))) {
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, false);
|
||||
moveCursorVisible();
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
break;
|
||||
}
|
||||
QString text = block.text();
|
||||
}
|
||||
if (ts.firstNonSpace(text) < text.size())
|
||||
break;
|
||||
block = block.next();
|
||||
@@ -1001,7 +997,7 @@ void BaseTextEditor::moveLineUpDown(bool up)
|
||||
QTextCursor cursor = textCursor();
|
||||
QTextCursor move = cursor;
|
||||
|
||||
move.setVisualNavigation(false); // this opens collapsed items instead of destroying them
|
||||
move.setVisualNavigation(false); // this opens folded items instead of destroying them
|
||||
|
||||
if (d->m_moveLineUndoHack)
|
||||
move.joinPreviousEditBlock();
|
||||
@@ -1068,7 +1064,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
|
||||
QToolTip::hideText();
|
||||
|
||||
d->m_moveLineUndoHack = false;
|
||||
d->clearVisibleCollapsedBlock();
|
||||
d->clearVisibleFoldedBlock();
|
||||
|
||||
QKeyEvent *original_e = e;
|
||||
d->m_lastEventWasBlockSelectionEvent = false;
|
||||
@@ -1629,19 +1625,16 @@ QByteArray BaseTextEditor::saveState() const
|
||||
stream << column;
|
||||
|
||||
// store code folding state
|
||||
QList<int> collapsedBlocks;
|
||||
QList<int> foldedBlocks;
|
||||
QTextBlock block = document()->firstBlock();
|
||||
while (block.isValid()) {
|
||||
if (block.userData() && static_cast<TextBlockUserData*>(block.userData())->collapsed()) {
|
||||
if (block.userData() && static_cast<TextBlockUserData*>(block.userData())->folded()) {
|
||||
int number = block.blockNumber();
|
||||
if (static_cast<TextBlockUserData*>(block.userData())->collapseMode()
|
||||
== TextBlockUserData::CollapseThis)
|
||||
number--;
|
||||
collapsedBlocks += number;
|
||||
foldedBlocks += number;
|
||||
}
|
||||
block = block.next();
|
||||
}
|
||||
stream << collapsedBlocks;
|
||||
stream << foldedBlocks;
|
||||
|
||||
return state;
|
||||
}
|
||||
@@ -1650,7 +1643,7 @@ bool BaseTextEditor::restoreState(const QByteArray &state)
|
||||
{
|
||||
if (state.isEmpty()) {
|
||||
if (d->m_displaySettings.m_autoFoldFirstComment)
|
||||
d->collapseLicenseHeader();
|
||||
d->foldLicenseHeader();
|
||||
return false;
|
||||
}
|
||||
int version;
|
||||
@@ -1672,11 +1665,11 @@ bool BaseTextEditor::restoreState(const QByteArray &state)
|
||||
foreach(int blockNumber, collapsedBlocks) {
|
||||
QTextBlock block = doc->findBlockByNumber(qMax(0, blockNumber));
|
||||
if (block.isValid())
|
||||
TextBlockUserData::doCollapse(block, false);
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, false);
|
||||
}
|
||||
} else {
|
||||
if (d->m_displaySettings.m_autoFoldFirstComment)
|
||||
d->collapseLicenseHeader();
|
||||
d->foldLicenseHeader();
|
||||
}
|
||||
|
||||
d->m_lastCursorChangeWasInteresting = false; // avoid adding last position to history
|
||||
@@ -1850,7 +1843,7 @@ BaseTextEditorPrivate::BaseTextEditorPrivate()
|
||||
m_parenthesesMatchingEnabled(false),
|
||||
m_autoParenthesesEnabled(true),
|
||||
m_extraArea(0),
|
||||
m_mouseOnCollapsedMarker(false),
|
||||
m_mouseOnFoldedMarker(false),
|
||||
m_marksVisible(false),
|
||||
m_codeFoldingVisible(false),
|
||||
m_codeFoldingSupported(false),
|
||||
@@ -1999,29 +1992,26 @@ void BaseTextEditor::resizeEvent(QResizeEvent *e)
|
||||
QRect(cr.left(), cr.top(), extraAreaWidth(), cr.height())));
|
||||
}
|
||||
|
||||
QRect BaseTextEditor::collapseBox()
|
||||
QRect BaseTextEditor::foldBox()
|
||||
{
|
||||
if (d->m_highlightBlocksInfo.isEmpty() || d->extraAreaHighlightCollapseBlockNumber < 0)
|
||||
if (d->m_highlightBlocksInfo.isEmpty() || d->extraAreaHighlightFoldedBlockNumber < 0)
|
||||
return QRect();
|
||||
|
||||
QTextBlock begin = document()->findBlockByNumber(d->m_highlightBlocksInfo.open.last());
|
||||
|
||||
if (TextBlockUserData::hasCollapseAfter(begin.previous()))
|
||||
begin = begin.previous();
|
||||
|
||||
QTextBlock end = document()->findBlockByNumber(d->m_highlightBlocksInfo.close.first());
|
||||
if (!begin.isValid() || !end.isValid())
|
||||
return QRect();
|
||||
QRectF br = blockBoundingGeometry(begin).translated(contentOffset());
|
||||
QRectF er = blockBoundingGeometry(end).translated(contentOffset());
|
||||
|
||||
return QRect(d->m_extraArea->width() - collapseBoxWidth(fontMetrics()),
|
||||
return QRect(d->m_extraArea->width() - foldBoxWidth(fontMetrics()),
|
||||
int(br.top()),
|
||||
collapseBoxWidth(fontMetrics()),
|
||||
foldBoxWidth(fontMetrics()),
|
||||
er.bottom() - br.top());
|
||||
}
|
||||
|
||||
QTextBlock BaseTextEditor::collapsedBlockAt(const QPoint &pos, QRect *box) const
|
||||
QTextBlock BaseTextEditor::foldedBlockAt(const QPoint &pos, QRect *box) const
|
||||
{
|
||||
QPointF offset(contentOffset());
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
@@ -2621,7 +2611,7 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
|
||||
block = block.next();
|
||||
|
||||
if (!block.isVisible()) {
|
||||
if (block.blockNumber() == d->visibleCollapsedBlockNumber) {
|
||||
if (block.blockNumber() == d->visibleFoldedBlockNumber) {
|
||||
visibleCollapsedBlock = block;
|
||||
visibleCollapsedBlockOffset = offset + QPointF(0,1);
|
||||
}
|
||||
@@ -2725,24 +2715,17 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
|
||||
|
||||
QString replacement = QLatin1String("...");
|
||||
|
||||
QTextBlock info = block;
|
||||
if (block.userData()
|
||||
&& static_cast<TextBlockUserData*>(block.userData())->collapseMode() == TextBlockUserData::CollapseAfter)
|
||||
;
|
||||
else if (block.next().userData()
|
||||
&& static_cast<TextBlockUserData*>(block.next().userData())->collapseMode()
|
||||
== TextBlockUserData::CollapseThis) {
|
||||
if (TextBlockUserData *nextBlockUserData = BaseTextDocumentLayout::testUserData(nextBlock)) {
|
||||
if (nextBlockUserData->foldingStartIncluded())
|
||||
replacement.prepend(nextBlock.text().trimmed().left(1));
|
||||
info = nextBlock;
|
||||
}
|
||||
|
||||
|
||||
block = nextVisibleBlock.previous();
|
||||
if (!block.isValid())
|
||||
block = doc->lastBlock();
|
||||
|
||||
if (info.userData()
|
||||
&& static_cast<TextBlockUserData*>(info.userData())->collapseIncludesClosure()) {
|
||||
if (TextBlockUserData *blockUserData = BaseTextDocumentLayout::testUserData(block)) {
|
||||
if (blockUserData->foldingEndIncluded()) {
|
||||
QString right = block.text().trimmed();
|
||||
if (right.endsWith(QLatin1Char(';'))) {
|
||||
right.chop(1);
|
||||
@@ -2753,6 +2736,8 @@ void BaseTextEditor::paintEvent(QPaintEvent *e)
|
||||
replacement.append(right.right(right.endsWith(QLatin1Char('/')) ? 2 : 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectThis)
|
||||
painter.setPen(palette().highlightedText().color());
|
||||
painter.drawText(collapseRect, Qt::AlignCenter, replacement);
|
||||
@@ -2888,7 +2873,7 @@ int BaseTextEditor::extraAreaWidth(int *markWidthPtr) const
|
||||
space += 4;
|
||||
|
||||
if (d->m_codeFoldingVisible)
|
||||
space += collapseBoxWidth(fm);
|
||||
space += foldBoxWidth(fm);
|
||||
return space;
|
||||
}
|
||||
|
||||
@@ -2948,7 +2933,7 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
|
||||
if (d->m_marksVisible)
|
||||
markWidth += fm.lineSpacing();
|
||||
|
||||
const int collapseColumnWidth = d->m_codeFoldingVisible ? collapseBoxWidth(fm): 0;
|
||||
const int collapseColumnWidth = d->m_codeFoldingVisible ? foldBoxWidth(fm): 0;
|
||||
const int extraAreaWidth = d->m_extraArea->width() - collapseColumnWidth;
|
||||
|
||||
painter.fillRect(e->rect(), pal.color(QPalette::Base));
|
||||
@@ -3020,50 +3005,35 @@ void BaseTextEditor::extraAreaPaintEvent(QPaintEvent *e)
|
||||
|
||||
if (d->m_codeFoldingVisible) {
|
||||
|
||||
bool collapseThis = false;
|
||||
bool collapseAfter = false;
|
||||
bool hasClosingCollapse = false;
|
||||
|
||||
if (TextBlockUserData *userData = static_cast<TextBlockUserData*>(block.userData())) {
|
||||
if (!userData->ifdefedOut()) {
|
||||
collapseAfter = (userData->collapseMode() == TextBlockUserData::CollapseAfter);
|
||||
collapseThis = (userData->collapseMode() == TextBlockUserData::CollapseThis);
|
||||
hasClosingCollapse = userData->hasClosingCollapse() && (previousBraceDepth > 0);
|
||||
}
|
||||
}
|
||||
|
||||
int extraAreaHighlightCollapseBlockNumber = -1;
|
||||
int extraAreaHighlightCollapseEndBlockNumber = -1;
|
||||
int extraAreaHighlightFoldBlockNumber = -1;
|
||||
int extraAreaHighlightFoldEndBlockNumber = -1;
|
||||
bool endIsVisible = false;
|
||||
if (!d->m_highlightBlocksInfo.isEmpty()) {
|
||||
extraAreaHighlightCollapseBlockNumber = d->m_highlightBlocksInfo.open.last();
|
||||
extraAreaHighlightCollapseEndBlockNumber = d->m_highlightBlocksInfo.close.first();
|
||||
endIsVisible = doc->findBlockByNumber(extraAreaHighlightCollapseEndBlockNumber).isVisible();
|
||||
extraAreaHighlightFoldBlockNumber = d->m_highlightBlocksInfo.open.last();
|
||||
extraAreaHighlightFoldEndBlockNumber = d->m_highlightBlocksInfo.close.first();
|
||||
endIsVisible = doc->findBlockByNumber(extraAreaHighlightFoldEndBlockNumber).isVisible();
|
||||
|
||||
QTextBlock before = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1);
|
||||
if (TextBlockUserData::hasCollapseAfter(before)) {
|
||||
extraAreaHighlightCollapseBlockNumber--;
|
||||
}
|
||||
// QTextBlock before = doc->findBlockByNumber(extraAreaHighlightCollapseBlockNumber-1);
|
||||
// if (TextBlockUserData::hasCollapseAfter(before)) {
|
||||
// extraAreaHighlightCollapseBlockNumber--;
|
||||
// }
|
||||
}
|
||||
|
||||
TextBlockUserData *nextBlockUserData = BaseTextDocumentLayout::testUserData(nextBlock);
|
||||
|
||||
bool collapseNext = nextBlockUserData
|
||||
&& nextBlockUserData->collapseMode() == TextBlockUserData::CollapseThis
|
||||
&& !nextBlockUserData->ifdefedOut();
|
||||
bool drawBox = nextBlockUserData
|
||||
&& BaseTextDocumentLayout::foldingIndent(block) < nextBlockUserData->foldingIndent();
|
||||
|
||||
bool nextHasClosingCollapse = nextBlockUserData
|
||||
&& nextBlockUserData->hasClosingCollapseInside()
|
||||
&& nextBlockUserData->ifdefedOut();
|
||||
|
||||
bool drawBox = ((collapseAfter || collapseNext) && !nextHasClosingCollapse);
|
||||
bool active = blockNumber == extraAreaHighlightCollapseBlockNumber;
|
||||
bool drawStart = drawBox && active;
|
||||
bool drawEnd = blockNumber == extraAreaHighlightCollapseEndBlockNumber || (drawStart && !endIsVisible);
|
||||
bool hovered = blockNumber >= extraAreaHighlightCollapseBlockNumber
|
||||
&& blockNumber <= extraAreaHighlightCollapseEndBlockNumber;
|
||||
|
||||
int boxWidth = collapseBoxWidth(fm);
|
||||
bool active = blockNumber == extraAreaHighlightFoldBlockNumber;
|
||||
|
||||
bool drawStart = active;
|
||||
bool drawEnd = blockNumber == extraAreaHighlightFoldEndBlockNumber || (drawStart && !endIsVisible);
|
||||
bool hovered = blockNumber >= extraAreaHighlightFoldBlockNumber
|
||||
&& blockNumber <= extraAreaHighlightFoldEndBlockNumber;
|
||||
|
||||
int boxWidth = foldBoxWidth(fm);
|
||||
if (hovered) {
|
||||
int itop = qRound(top);
|
||||
int ibottom = qRound(bottom);
|
||||
@@ -3264,8 +3234,8 @@ void BaseTextEditor::slotCursorPositionChanged()
|
||||
{
|
||||
#if 0
|
||||
qDebug() << "block" << textCursor().blockNumber()+1
|
||||
<< "depth:" << BaseTextDocumentLayout::braceDepth(textCursor().block())
|
||||
<< '/' << BaseTextDocumentLayout::braceDepth(document()->lastBlock());
|
||||
<< "brace depth:" << BaseTextDocumentLayout::braceDepth(textCursor().block())
|
||||
<< "indent:" << BaseTextDocumentLayout::userData(textCursor().block())->foldingIndent();
|
||||
#endif
|
||||
if (!d->m_contentsChanged && d->m_lastCursorChangeWasInteresting) {
|
||||
Core::EditorManager::instance()->addCurrentPositionToNavigationHistory(editableInterface(), d->m_tempNavigationState);
|
||||
@@ -3294,8 +3264,7 @@ void BaseTextEditor::updateHighlights()
|
||||
|
||||
if (d->m_displaySettings.m_highlightBlocks) {
|
||||
QTextCursor cursor = textCursor();
|
||||
d->extraAreaHighlightCollapseBlockNumber = cursor.blockNumber();
|
||||
d->extraAreaHighlightCollapseColumn = cursor.position() - cursor.block().position();
|
||||
d->extraAreaHighlightFoldedBlockNumber = cursor.blockNumber();
|
||||
d->m_highlightBlocksTimer->start(100);
|
||||
}
|
||||
}
|
||||
@@ -3315,7 +3284,7 @@ void BaseTextEditor::slotUpdateBlockNotify(const QTextBlock &block)
|
||||
/* The syntax highlighting state changes. This opens up for
|
||||
the possibility that the paragraph has braces that support
|
||||
code folding. In this case, do the save thing and also
|
||||
update the previous block, which might contain a collapse
|
||||
update the previous block, which might contain a fold
|
||||
box which now is invalid.*/
|
||||
emit requestBlockUpdate(block.previous());
|
||||
}
|
||||
@@ -3350,24 +3319,24 @@ void BaseTextEditor::timerEvent(QTimerEvent *e)
|
||||
int timeout = 4900 / (delta * delta);
|
||||
d->autoScrollTimer.start(timeout, this);
|
||||
|
||||
} else if (e->timerId() == d->collapsedBlockTimer.timerId()) {
|
||||
d->visibleCollapsedBlockNumber = d->suggestedVisibleCollapsedBlockNumber;
|
||||
d->suggestedVisibleCollapsedBlockNumber = -1;
|
||||
d->collapsedBlockTimer.stop();
|
||||
} else if (e->timerId() == d->foldedBlockTimer.timerId()) {
|
||||
d->visibleFoldedBlockNumber = d->suggestedVisibleFoldedBlockNumber;
|
||||
d->suggestedVisibleFoldedBlockNumber = -1;
|
||||
d->foldedBlockTimer.stop();
|
||||
viewport()->update();
|
||||
}
|
||||
QPlainTextEdit::timerEvent(e);
|
||||
}
|
||||
|
||||
|
||||
void BaseTextEditorPrivate::clearVisibleCollapsedBlock()
|
||||
void BaseTextEditorPrivate::clearVisibleFoldedBlock()
|
||||
{
|
||||
if (suggestedVisibleCollapsedBlockNumber) {
|
||||
suggestedVisibleCollapsedBlockNumber = -1;
|
||||
collapsedBlockTimer.stop();
|
||||
if (suggestedVisibleFoldedBlockNumber) {
|
||||
suggestedVisibleFoldedBlockNumber = -1;
|
||||
foldedBlockTimer.stop();
|
||||
}
|
||||
if (visibleCollapsedBlockNumber >= 0) {
|
||||
visibleCollapsedBlockNumber = -1;
|
||||
if (visibleFoldedBlockNumber >= 0) {
|
||||
visibleFoldedBlockNumber = -1;
|
||||
q->viewport()->update();
|
||||
}
|
||||
}
|
||||
@@ -3379,21 +3348,21 @@ void BaseTextEditor::mouseMoveEvent(QMouseEvent *e)
|
||||
updateLink(e);
|
||||
|
||||
if (e->buttons() == Qt::NoButton) {
|
||||
const QTextBlock collapsedBlock = collapsedBlockAt(e->pos());
|
||||
const QTextBlock collapsedBlock = foldedBlockAt(e->pos());
|
||||
const int blockNumber = collapsedBlock.next().blockNumber();
|
||||
if (blockNumber < 0) {
|
||||
d->clearVisibleCollapsedBlock();
|
||||
} else if (blockNumber != d->visibleCollapsedBlockNumber) {
|
||||
d->suggestedVisibleCollapsedBlockNumber = blockNumber;
|
||||
d->collapsedBlockTimer.start(40, this);
|
||||
d->clearVisibleFoldedBlock();
|
||||
} else if (blockNumber != d->visibleFoldedBlockNumber) {
|
||||
d->suggestedVisibleFoldedBlockNumber = blockNumber;
|
||||
d->foldedBlockTimer.start(40, this);
|
||||
}
|
||||
|
||||
// Update the mouse cursor
|
||||
if (collapsedBlock.isValid() && !d->m_mouseOnCollapsedMarker) {
|
||||
d->m_mouseOnCollapsedMarker = true;
|
||||
if (collapsedBlock.isValid() && !d->m_mouseOnFoldedMarker) {
|
||||
d->m_mouseOnFoldedMarker = true;
|
||||
viewport()->setCursor(Qt::PointingHandCursor);
|
||||
} else if (!collapsedBlock.isValid() && d->m_mouseOnCollapsedMarker) {
|
||||
d->m_mouseOnCollapsedMarker = false;
|
||||
} else if (!collapsedBlock.isValid() && d->m_mouseOnFoldedMarker) {
|
||||
d->m_mouseOnFoldedMarker = false;
|
||||
viewport()->setCursor(Qt::IBeamCursor);
|
||||
}
|
||||
} else {
|
||||
@@ -3429,9 +3398,9 @@ void BaseTextEditor::mousePressEvent(QMouseEvent *e)
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
d->clearBlockSelection(); // just in case, otherwise we might get strange drag and drop
|
||||
|
||||
QTextBlock collapsedBlock = collapsedBlockAt(e->pos());
|
||||
if (collapsedBlock.isValid()) {
|
||||
toggleBlockVisible(collapsedBlock);
|
||||
QTextBlock foldedBlock = foldedBlockAt(e->pos());
|
||||
if (foldedBlock.isValid()) {
|
||||
toggleBlockVisible(foldedBlock);
|
||||
viewport()->setCursor(Qt::IBeamCursor);
|
||||
}
|
||||
|
||||
@@ -3509,7 +3478,6 @@ void BaseTextEditor::extraAreaLeaveEvent(QEvent *)
|
||||
void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
|
||||
{
|
||||
QTextCursor cursor = cursorForPosition(QPoint(0, e->pos().y()));
|
||||
cursor.setPosition(cursor.block().position());
|
||||
|
||||
int markWidth;
|
||||
extraAreaWidth(&markWidth);
|
||||
@@ -3517,34 +3485,19 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
|
||||
if (d->m_codeFoldingVisible
|
||||
&& e->type() == QEvent::MouseMove && e->buttons() == 0) { // mouse tracking
|
||||
// Update which folder marker is highlighted
|
||||
const int highlightBlockNumber = d->extraAreaHighlightCollapseBlockNumber;
|
||||
const int highlightColumn = d->extraAreaHighlightCollapseColumn;
|
||||
d->extraAreaHighlightCollapseBlockNumber = -1;
|
||||
d->extraAreaHighlightCollapseColumn = -1;
|
||||
const int highlightBlockNumber = d->extraAreaHighlightFoldedBlockNumber;
|
||||
d->extraAreaHighlightFoldedBlockNumber = -1;
|
||||
|
||||
if (e->pos().x() > extraArea()->width() - collapseBoxWidth(fontMetrics())) {
|
||||
d->extraAreaHighlightCollapseBlockNumber = cursor.blockNumber();
|
||||
if (TextBlockUserData::canCollapse(cursor.block())
|
||||
|| !TextBlockUserData::hasClosingCollapse(cursor.block()))
|
||||
d->extraAreaHighlightCollapseColumn = cursor.block().length()-1;
|
||||
if (TextBlockUserData::hasCollapseAfter(cursor.block())) {
|
||||
d->extraAreaHighlightCollapseBlockNumber++;
|
||||
d->extraAreaHighlightCollapseColumn = -1;
|
||||
if (TextBlockUserData::canCollapse(cursor.block().next())
|
||||
|| !TextBlockUserData::hasClosingCollapse(cursor.block().next()))
|
||||
d->extraAreaHighlightCollapseColumn = cursor.block().next().length()-1;
|
||||
}
|
||||
if (e->pos().x() > extraArea()->width() - foldBoxWidth(fontMetrics())) {
|
||||
d->extraAreaHighlightFoldedBlockNumber = cursor.blockNumber();
|
||||
} else if (d->m_displaySettings.m_highlightBlocks) {
|
||||
QTextCursor cursor = textCursor();
|
||||
d->extraAreaHighlightCollapseBlockNumber = cursor.blockNumber();
|
||||
d->extraAreaHighlightCollapseColumn = cursor.position() - cursor.block().position();
|
||||
d->extraAreaHighlightFoldedBlockNumber = cursor.blockNumber();
|
||||
}
|
||||
|
||||
if (highlightBlockNumber != d->extraAreaHighlightCollapseBlockNumber
|
||||
|| highlightColumn != d->extraAreaHighlightCollapseColumn) {
|
||||
if (highlightBlockNumber != d->extraAreaHighlightFoldedBlockNumber)
|
||||
d->m_highlightBlocksTimer->start(d->m_highlightBlocksInfo.isEmpty() ? 120 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Set whether the mouse cursor is a hand or normal arrow
|
||||
if (e->type() == QEvent::MouseMove) {
|
||||
@@ -3555,18 +3508,16 @@ void BaseTextEditor::extraAreaMouseEvent(QMouseEvent *e)
|
||||
|
||||
if (e->type() == QEvent::MouseButtonPress || e->type() == QEvent::MouseButtonDblClick) {
|
||||
if (e->button() == Qt::LeftButton) {
|
||||
int boxWidth = collapseBoxWidth(fontMetrics());
|
||||
int boxWidth = foldBoxWidth(fontMetrics());
|
||||
if (d->m_codeFoldingVisible && e->pos().x() > extraArea()->width() - boxWidth) {
|
||||
if (!cursor.block().next().isVisible()) {
|
||||
toggleBlockVisible(cursor.block());
|
||||
d->moveCursorVisible(false);
|
||||
} else if (collapseBox().contains(e->pos())) {
|
||||
} else if (foldBox().contains(e->pos())) {
|
||||
cursor.setPosition(
|
||||
document()->findBlockByNumber(d->m_highlightBlocksInfo.open.last()).position()
|
||||
);
|
||||
QTextBlock c = cursor.block();
|
||||
if (TextBlockUserData::hasCollapseAfter(c.previous()))
|
||||
c = c.previous();
|
||||
toggleBlockVisible(c);
|
||||
d->moveCursorVisible(false);
|
||||
}
|
||||
@@ -3643,7 +3594,7 @@ void BaseTextEditor::toggleBlockVisible(const QTextBlock &block)
|
||||
QTC_ASSERT(documentLayout, return);
|
||||
|
||||
bool visible = block.next().isVisible();
|
||||
TextBlockUserData::doCollapse(block, !visible);
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, !visible);
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
}
|
||||
@@ -3790,7 +3741,7 @@ void BaseTextEditor::handleBackspaceKey()
|
||||
|
||||
void BaseTextEditor::wheelEvent(QWheelEvent *e)
|
||||
{
|
||||
d->clearVisibleCollapsedBlock();
|
||||
d->clearVisibleFoldedBlock();
|
||||
if (scrollWheelZoomingEnabled() && e->modifiers() & Qt::ControlModifier) {
|
||||
const int delta = e->delta();
|
||||
if (delta < 0)
|
||||
@@ -3804,7 +3755,7 @@ void BaseTextEditor::wheelEvent(QWheelEvent *e)
|
||||
|
||||
void BaseTextEditor::zoomIn(int range)
|
||||
{
|
||||
d->clearVisibleCollapsedBlock();
|
||||
d->clearVisibleFoldedBlock();
|
||||
emit requestFontZoom(range*10);
|
||||
}
|
||||
|
||||
@@ -4457,8 +4408,35 @@ void BaseTextEditor::_q_highlightBlocks()
|
||||
{
|
||||
BaseTextEditorPrivateHighlightBlocks highlightBlocksInfo;
|
||||
|
||||
if (d->extraAreaHighlightCollapseBlockNumber >= 0) {
|
||||
QTextBlock block = document()->findBlockByNumber(d->extraAreaHighlightCollapseBlockNumber);
|
||||
QTextBlock block;
|
||||
if (d->extraAreaHighlightFoldedBlockNumber >= 0) {
|
||||
block = document()->findBlockByNumber(d->extraAreaHighlightFoldedBlockNumber);
|
||||
if (block.isValid()
|
||||
&& block.next().isValid()
|
||||
&& BaseTextDocumentLayout::foldingIndent(block.next())
|
||||
> BaseTextDocumentLayout::foldingIndent(block))
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
QTextBlock closeBlock = block;
|
||||
while (block.isValid()) {
|
||||
int foldingIndent = BaseTextDocumentLayout::foldingIndent(block);
|
||||
|
||||
while (block.previous().isValid() && BaseTextDocumentLayout::foldingIndent(block) >= foldingIndent)
|
||||
block = block.previous();
|
||||
int nextIndent = BaseTextDocumentLayout::foldingIndent(block);
|
||||
if (nextIndent == foldingIndent)
|
||||
break;
|
||||
highlightBlocksInfo.open.prepend(block.blockNumber());
|
||||
while (closeBlock.next().isValid()
|
||||
&& BaseTextDocumentLayout::foldingIndent(closeBlock.next()) >= foldingIndent )
|
||||
closeBlock = closeBlock.next();
|
||||
highlightBlocksInfo.close.append(closeBlock.blockNumber());
|
||||
int visualIndent = qMin(d->visualIndent(block), d->visualIndent(closeBlock));
|
||||
highlightBlocksInfo.visualIndent.prepend(visualIndent);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (block.isValid()) {
|
||||
QTextCursor cursor(block);
|
||||
if (d->extraAreaHighlightCollapseColumn >= 0)
|
||||
@@ -4479,8 +4457,7 @@ void BaseTextEditor::_q_highlightBlocks()
|
||||
highlightBlocksInfo.visualIndent.prepend(visualIndent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
if (d->m_highlightBlocksInfo != highlightBlocksInfo) {
|
||||
d->m_highlightBlocksInfo = highlightBlocksInfo;
|
||||
viewport()->update();
|
||||
@@ -4651,8 +4628,10 @@ void BaseTextEditor::setIfdefedOutBlocks(const QList<BaseTextEditor::BlockRange>
|
||||
braceDepthDelta -= delta;
|
||||
}
|
||||
|
||||
if (braceDepthDelta)
|
||||
if (braceDepthDelta) {
|
||||
BaseTextDocumentLayout::changeBraceDepth(block,braceDepthDelta);
|
||||
BaseTextDocumentLayout::changeFoldingIndent(block, braceDepthDelta); // ### C++ only, refactor!
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
}
|
||||
@@ -4903,7 +4882,7 @@ void BaseTextEditor::setDisplaySettings(const DisplaySettings &ds)
|
||||
|
||||
d->m_displaySettings = ds;
|
||||
if (!ds.m_highlightBlocks) {
|
||||
d->extraAreaHighlightCollapseBlockNumber = d->extraAreaHighlightCollapseColumn = -1;
|
||||
d->extraAreaHighlightFoldedBlockNumber = -1;
|
||||
d->m_highlightBlocksInfo = BaseTextEditorPrivateHighlightBlocks();
|
||||
}
|
||||
|
||||
@@ -4928,31 +4907,27 @@ void BaseTextEditor::setCompletionSettings(const TextEditor::CompletionSettings
|
||||
setAutoParenthesesEnabled(completionSettings.m_autoInsertBrackets);
|
||||
}
|
||||
|
||||
void BaseTextEditor::collapse()
|
||||
void BaseTextEditor::fold()
|
||||
{
|
||||
QTextDocument *doc = document();
|
||||
BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout());
|
||||
QTC_ASSERT(documentLayout, return);
|
||||
QTextBlock block = textCursor().block();
|
||||
QTextBlock curBlock = block;
|
||||
while (block.isValid()) {
|
||||
if (TextBlockUserData::canCollapse(block) && block.next().isVisible()) {
|
||||
if (block == curBlock || block.next() == curBlock)
|
||||
break;
|
||||
if ((block.next().userState()) >> 8 <= (curBlock.previous().userState() >> 8))
|
||||
break;
|
||||
}
|
||||
if (!(BaseTextDocumentLayout::canFold(block) && block.next().isVisible())) {
|
||||
// find the closest previous block which can fold
|
||||
int indent = BaseTextDocumentLayout::foldingIndent(block);
|
||||
while (block.isValid() && (BaseTextDocumentLayout::foldingIndent(block) >= indent || !block.isVisible()))
|
||||
block = block.previous();
|
||||
}
|
||||
if (block.isValid()) {
|
||||
TextBlockUserData::doCollapse(block, false);
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, false);
|
||||
d->moveCursorVisible();
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseTextEditor::expand()
|
||||
void BaseTextEditor::unfold()
|
||||
{
|
||||
QTextDocument *doc = document();
|
||||
BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout());
|
||||
@@ -4960,13 +4935,13 @@ void BaseTextEditor::expand()
|
||||
QTextBlock block = textCursor().block();
|
||||
while (block.isValid() && !block.isVisible())
|
||||
block = block.previous();
|
||||
TextBlockUserData::doCollapse(block, true);
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, true);
|
||||
d->moveCursorVisible();
|
||||
documentLayout->requestUpdate();
|
||||
documentLayout->emitDocumentSizeChanged();
|
||||
}
|
||||
|
||||
void BaseTextEditor::unCollapseAll()
|
||||
void BaseTextEditor::unfoldAll()
|
||||
{
|
||||
QTextDocument *doc = document();
|
||||
BaseTextDocumentLayout *documentLayout = qobject_cast<BaseTextDocumentLayout*>(doc->documentLayout());
|
||||
@@ -4975,7 +4950,7 @@ void BaseTextEditor::unCollapseAll()
|
||||
QTextBlock block = doc->firstBlock();
|
||||
bool makeVisible = true;
|
||||
while (block.isValid()) {
|
||||
if (block.isVisible() && TextBlockUserData::canCollapse(block) && block.next().isVisible()) {
|
||||
if (block.isVisible() && BaseTextDocumentLayout::canFold(block) && block.next().isVisible()) {
|
||||
makeVisible = false;
|
||||
break;
|
||||
}
|
||||
@@ -4985,8 +4960,8 @@ void BaseTextEditor::unCollapseAll()
|
||||
block = doc->firstBlock();
|
||||
|
||||
while (block.isValid()) {
|
||||
if (TextBlockUserData::canCollapse(block))
|
||||
TextBlockUserData::doCollapse(block, makeVisible);
|
||||
if (BaseTextDocumentLayout::canFold(block))
|
||||
BaseTextDocumentLayout::doFoldOrUnfold(block, makeVisible);
|
||||
block = block.next();
|
||||
}
|
||||
|
||||
|
||||
@@ -224,9 +224,9 @@ public slots:
|
||||
|
||||
void cutLine();
|
||||
void deleteLine();
|
||||
void unCollapseAll();
|
||||
void collapse();
|
||||
void expand();
|
||||
void unfoldAll();
|
||||
void fold();
|
||||
void unfold();
|
||||
void selectEncoding();
|
||||
|
||||
void gotoBlockStart();
|
||||
@@ -491,9 +491,9 @@ private:
|
||||
bool hovered) const;
|
||||
|
||||
void toggleBlockVisible(const QTextBlock &block);
|
||||
QRect collapseBox();
|
||||
QRect foldBox();
|
||||
|
||||
QTextBlock collapsedBlockAt(const QPoint &pos, QRect *box = 0) const;
|
||||
QTextBlock foldedBlockAt(const QPoint &pos, QRect *box = 0) const;
|
||||
|
||||
void updateLink(QMouseEvent *e);
|
||||
void showLink(const Link &);
|
||||
|
||||
@@ -189,8 +189,7 @@ public:
|
||||
|
||||
int extraAreaSelectionAnchorBlockNumber;
|
||||
int extraAreaToggleMarkBlockNumber;
|
||||
int extraAreaHighlightCollapseBlockNumber;
|
||||
int extraAreaHighlightCollapseColumn;
|
||||
int extraAreaHighlightFoldedBlockNumber;
|
||||
|
||||
TextEditorOverlay *m_overlay;
|
||||
TextEditorOverlay *m_snippetOverlay;
|
||||
@@ -200,12 +199,12 @@ public:
|
||||
QTextCharFormat m_occurrencesFormat;
|
||||
QTextCharFormat m_occurrenceRenameFormat;
|
||||
|
||||
QBasicTimer collapsedBlockTimer;
|
||||
int visibleCollapsedBlockNumber;
|
||||
int suggestedVisibleCollapsedBlockNumber;
|
||||
void clearVisibleCollapsedBlock();
|
||||
bool m_mouseOnCollapsedMarker;
|
||||
void collapseLicenseHeader();
|
||||
QBasicTimer foldedBlockTimer;
|
||||
int visibleFoldedBlockNumber;
|
||||
int suggestedVisibleFoldedBlockNumber;
|
||||
void clearVisibleFoldedBlock();
|
||||
bool m_mouseOnFoldedMarker;
|
||||
void foldLicenseHeader();
|
||||
|
||||
QBasicTimer autoScrollTimer;
|
||||
void updateMarksLineNumber();
|
||||
|
||||
@@ -69,9 +69,9 @@ TextEditorActionHandler::TextEditorActionHandler(const QString &context,
|
||||
m_cleanWhitespaceAction(0),
|
||||
m_textWrappingAction(0),
|
||||
m_unCommentSelectionAction(0),
|
||||
m_unCollapseAllAction(0),
|
||||
m_collapseAction(0),
|
||||
m_expandAction(0),
|
||||
m_unfoldAllAction(0),
|
||||
m_foldAction(0),
|
||||
m_unfoldAction(0),
|
||||
m_cutLineAction(0),
|
||||
m_deleteLineAction(0),
|
||||
m_selectEncodingAction(0),
|
||||
@@ -198,21 +198,21 @@ void TextEditorActionHandler::createActions()
|
||||
command = am->registerAction(m_deleteLineAction, Constants::DELETE_LINE, m_contextId);
|
||||
connect(m_deleteLineAction, SIGNAL(triggered()), this, SLOT(deleteLine()));
|
||||
|
||||
m_collapseAction = new QAction(tr("Collapse"), this);
|
||||
command = am->registerAction(m_collapseAction, Constants::COLLAPSE, m_contextId);
|
||||
m_foldAction = new QAction(tr("Fold"), this);
|
||||
command = am->registerAction(m_foldAction, Constants::FOLD, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+<")));
|
||||
connect(m_collapseAction, SIGNAL(triggered()), this, SLOT(collapse()));
|
||||
connect(m_foldAction, SIGNAL(triggered()), this, SLOT(fold()));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_COLLAPSING);
|
||||
|
||||
m_expandAction = new QAction(tr("Expand"), this);
|
||||
command = am->registerAction(m_expandAction, Constants::EXPAND, m_contextId);
|
||||
m_unfoldAction = new QAction(tr("Unfold"), this);
|
||||
command = am->registerAction(m_unfoldAction, Constants::UNFOLD, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+>")));
|
||||
connect(m_expandAction, SIGNAL(triggered()), this, SLOT(expand()));
|
||||
connect(m_unfoldAction, SIGNAL(triggered()), this, SLOT(unfold()));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_COLLAPSING);
|
||||
|
||||
m_unCollapseAllAction = new QAction(tr("(Un)&Collapse All"), this);
|
||||
command = am->registerAction(m_unCollapseAllAction, Constants::UN_COLLAPSE_ALL, m_contextId);
|
||||
connect(m_unCollapseAllAction, SIGNAL(triggered()), this, SLOT(unCollapseAll()));
|
||||
m_unfoldAllAction = new QAction(tr("(Un)&Collapse All"), this);
|
||||
command = am->registerAction(m_unfoldAllAction, Constants::UNFOLD_ALL, m_contextId);
|
||||
connect(m_unfoldAllAction, SIGNAL(triggered()), this, SLOT(unfoldAll()));
|
||||
advancedMenu->addAction(command, Core::Constants::G_EDIT_COLLAPSING);
|
||||
|
||||
m_increaseFontSizeAction = new QAction(tr("Increase Font Size"), this);
|
||||
@@ -406,7 +406,7 @@ void TextEditorActionHandler::updateActions(UpdateMode um)
|
||||
m_moveLineDownAction->setEnabled(um != ReadOnlyMode);
|
||||
|
||||
m_formatAction->setEnabled((m_optionalActions & Format));
|
||||
m_unCollapseAllAction->setEnabled((m_optionalActions & UnCollapseAll));
|
||||
m_unfoldAllAction->setEnabled((m_optionalActions & UnCollapseAll));
|
||||
m_visualizeWhitespaceAction->setChecked(m_currentEditor->displaySettings().m_visualizeWhitespace);
|
||||
if (m_textWrappingAction) {
|
||||
m_textWrappingAction->setChecked(m_currentEditor->displaySettings().m_textWrapping);
|
||||
@@ -498,9 +498,9 @@ FUNCTION(cleanWhitespace)
|
||||
FUNCTION(unCommentSelection)
|
||||
FUNCTION(cutLine)
|
||||
FUNCTION(deleteLine)
|
||||
FUNCTION(unCollapseAll)
|
||||
FUNCTION(collapse)
|
||||
FUNCTION(expand)
|
||||
FUNCTION(unfoldAll)
|
||||
FUNCTION(fold)
|
||||
FUNCTION(unfold)
|
||||
FUNCTION2(increaseFontSize, zoomIn)
|
||||
FUNCTION2(decreaseFontSize, zoomOut)
|
||||
FUNCTION2(resetFontSize, zoomReset)
|
||||
|
||||
@@ -96,9 +96,9 @@ private slots:
|
||||
void cleanWhitespace();
|
||||
void setTextWrapping(bool);
|
||||
void unCommentSelection();
|
||||
void unCollapseAll();
|
||||
void collapse();
|
||||
void expand();
|
||||
void unfoldAll();
|
||||
void fold();
|
||||
void unfold();
|
||||
void cutLine();
|
||||
void deleteLine();
|
||||
void selectEncoding();
|
||||
@@ -153,9 +153,9 @@ private:
|
||||
QAction *m_cleanWhitespaceAction;
|
||||
QAction *m_textWrappingAction;
|
||||
QAction *m_unCommentSelectionAction;
|
||||
QAction *m_unCollapseAllAction;
|
||||
QAction *m_collapseAction;
|
||||
QAction *m_expandAction;
|
||||
QAction *m_unfoldAllAction;
|
||||
QAction *m_foldAction;
|
||||
QAction *m_unfoldAction;
|
||||
QAction *m_cutLineAction;
|
||||
QAction *m_deleteLineAction;
|
||||
QAction *m_selectEncodingAction;
|
||||
|
||||
@@ -43,9 +43,9 @@ const char * const CLEAN_WHITESPACE = "TextEditor.CleanWhitespace";
|
||||
const char * const TEXT_WRAPPING = "TextEditor.TextWrapping";
|
||||
const char * const UN_COMMENT_SELECTION = "TextEditor.UnCommentSelection";
|
||||
const char * const REFORMAT = "TextEditor.Reformat";
|
||||
const char * const COLLAPSE = "TextEditor.Collapse";
|
||||
const char * const EXPAND = "TextEditor.Expand";
|
||||
const char * const UN_COLLAPSE_ALL = "TextEditor.UnCollapseAll";
|
||||
const char * const FOLD = "TextEditor.Fold";
|
||||
const char * const UNFOLD = "TextEditor.Unfold";
|
||||
const char * const UNFOLD_ALL = "TextEditor.UnCollapseAll";
|
||||
const char * const AUTO_INDENT_SELECTION = "TextEditor.AutoIndentSelection";
|
||||
const char * const INCREASE_FONT_SIZE = "TextEditor.IncreaseFontSize";
|
||||
const char * const DECREASE_FONT_SIZE = "TextEditor.DecreaseFontSize";
|
||||
|
||||
Reference in New Issue
Block a user