forked from qt-creator/qt-creator
block navigation and selection (bound to Ctrl+[]{}
This commit is contained in:
@@ -162,7 +162,10 @@ int BaseTextFind::replaceAll(const QString &before, const QString &after,
|
||||
QTextDocument::FindFlags findFlags)
|
||||
{
|
||||
QTextCursor editCursor = textCursor();
|
||||
editCursor.movePosition(QTextCursor::Start);
|
||||
if (!m_findScope.isNull())
|
||||
editCursor.setPosition(m_findScope.selectionStart());
|
||||
else
|
||||
editCursor.movePosition(QTextCursor::Start);
|
||||
editCursor.beginEditBlock();
|
||||
int count = 0;
|
||||
QTextCursor found;
|
||||
|
||||
@@ -531,7 +531,6 @@ void BaseTextEditor::selectEncoding()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DocumentMarker::updateMark(ITextMark *mark)
|
||||
{
|
||||
TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(document->documentLayout());
|
||||
@@ -600,6 +599,36 @@ void BaseTextEditor::slotSelectionChanged()
|
||||
d->m_blockSelectionExtraX = 0;
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockStart()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, false))
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockEnd()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, false))
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockStartWithSelection()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findPreviousOpenParenthesis(&cursor, true))
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoBlockEndWithSelection()
|
||||
{
|
||||
QTextCursor cursor = textCursor();
|
||||
if (TextBlockUserData::findNextClosingParenthesis(&cursor, true))
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BaseTextEditor::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
|
||||
@@ -633,6 +662,11 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
|
||||
e->accept();
|
||||
return;
|
||||
}
|
||||
} else if (e == QKeySequence::Paste) {
|
||||
if (!ro) {
|
||||
d->removeBlockSelection();
|
||||
// continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,6 +727,8 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
|
||||
break;
|
||||
case Qt::Key_Home:
|
||||
if (!(e == QKeySequence::MoveToStartOfDocument) && !(e == QKeySequence::SelectStartOfDocument)) {
|
||||
if ((e->modifiers() & (Qt::AltModifier | Qt::ShiftModifier)) == (Qt::AltModifier | Qt::ShiftModifier))
|
||||
d->m_lastEventWasBlockSelectionEvent = true;
|
||||
handleHomeKey(e->modifiers() & Qt::ShiftModifier);
|
||||
e->accept();
|
||||
return;
|
||||
@@ -708,6 +744,7 @@ void BaseTextEditor::keyPressEvent(QKeyEvent *e)
|
||||
return;
|
||||
}
|
||||
// fall through
|
||||
case Qt::Key_End:
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_Left:
|
||||
#ifndef Q_OS_MAC
|
||||
@@ -795,6 +832,15 @@ skip_event:
|
||||
delete e;
|
||||
}
|
||||
|
||||
void BaseTextEditor::setTextCursor(const QTextCursor &cursor)
|
||||
{
|
||||
// workaround for QTextControl bug
|
||||
bool selectionChange = cursor.hasSelection() || textCursor().hasSelection();
|
||||
QPlainTextEdit::setTextCursor(cursor);
|
||||
if (selectionChange)
|
||||
slotSelectionChanged();
|
||||
}
|
||||
|
||||
void BaseTextEditor::gotoLine(int line, int column)
|
||||
{
|
||||
const int blockNumber = line - 1;
|
||||
@@ -2908,6 +2954,61 @@ TextBlockUserData::MatchType TextBlockUserData::checkClosedParenthesis(QTextCurs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TextBlockUserData::findPreviousOpenParenthesis(QTextCursor *cursor, bool select)
|
||||
{
|
||||
QTextBlock block = cursor->block();
|
||||
int position = cursor->position();
|
||||
int ignore = 0;
|
||||
while (block.isValid()) {
|
||||
Parentheses parenList = TextEditDocumentLayout::parentheses(block);
|
||||
if (!parenList.isEmpty()) {
|
||||
for (int i = parenList.count()-1; i >= 0; --i) {
|
||||
Parenthesis paren = parenList.at(i);
|
||||
if (block == cursor->block() && position - block.position() <= paren.pos + 1)
|
||||
continue;
|
||||
if (paren.type == Parenthesis::Closed) {
|
||||
++ignore;
|
||||
} else if (ignore > 0) {
|
||||
--ignore;
|
||||
} else {
|
||||
cursor->setPosition(block.position() + paren.pos, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
block = block.previous();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextBlockUserData::findNextClosingParenthesis(QTextCursor *cursor, bool select)
|
||||
{
|
||||
QTextBlock block = cursor->block();
|
||||
int position = cursor->position();
|
||||
int ignore = 0;
|
||||
while (block.isValid()) {
|
||||
Parentheses parenList = TextEditDocumentLayout::parentheses(block);
|
||||
if (!parenList.isEmpty()) {
|
||||
for (int i = 0; i < parenList.count(); ++i) {
|
||||
Parenthesis paren = parenList.at(i);
|
||||
if (block == cursor->block() && position - block.position() >= paren.pos)
|
||||
continue;
|
||||
if (paren.type == Parenthesis::Opened) {
|
||||
++ignore;
|
||||
} else if (ignore > 0) {
|
||||
--ignore;
|
||||
} else {
|
||||
cursor->setPosition(block.position() + paren.pos+1, select ? QTextCursor::KeepAnchor : QTextCursor::MoveAnchor);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
block = block.next();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TextBlockUserData::MatchType TextBlockUserData::matchCursorBackward(QTextCursor *cursor)
|
||||
{
|
||||
cursor->clearSelection();
|
||||
@@ -3152,13 +3253,16 @@ void BaseTextEditor::collapse()
|
||||
TextEditDocumentLayout *documentLayout = qobject_cast<TextEditDocumentLayout*>(doc->documentLayout());
|
||||
Q_ASSERT(documentLayout);
|
||||
QTextBlock block = textCursor().block();
|
||||
qDebug() << "collapse at block" << block.blockNumber();
|
||||
while (block.isValid()) {
|
||||
if (TextBlockUserData::canCollapse(block)) {
|
||||
if ((block.next().userState()) >> 8 == (textCursor().block().userState() >> 8))
|
||||
qDebug() << "test block" << block.blockNumber();
|
||||
if (TextBlockUserData::canCollapse(block) && block.next().isVisible()) {
|
||||
if ((block.next().userState()) >> 8 <= (textCursor().block().userState() >> 8))
|
||||
break;
|
||||
}
|
||||
block = block.previous();
|
||||
}
|
||||
qDebug() << "found" << block.blockNumber();
|
||||
if (block.isValid()) {
|
||||
TextBlockUserData::doCollapse(block, false);
|
||||
d->moveCursorVisible();
|
||||
@@ -3238,6 +3342,14 @@ void BaseTextEditor::cut()
|
||||
QPlainTextEdit::cut();
|
||||
}
|
||||
|
||||
void BaseTextEditor::paste()
|
||||
{
|
||||
if (d->m_inBlockSelectionMode) {
|
||||
d->removeBlockSelection();
|
||||
}
|
||||
QPlainTextEdit::paste();
|
||||
}
|
||||
|
||||
QMimeData *BaseTextEditor::createMimeDataFromSelection() const
|
||||
{
|
||||
if (d->m_inBlockSelectionMode) {
|
||||
|
||||
@@ -169,6 +169,8 @@ public:
|
||||
static MatchType checkClosedParenthesis(QTextCursor *cursor, QChar c);
|
||||
static MatchType matchCursorBackward(QTextCursor *cursor);
|
||||
static MatchType matchCursorForward(QTextCursor *cursor);
|
||||
static bool findPreviousOpenParenthesis(QTextCursor *cursor, bool select = false);
|
||||
static bool findNextClosingParenthesis(QTextCursor *cursor, bool select = false);
|
||||
|
||||
|
||||
private:
|
||||
@@ -298,6 +300,8 @@ public:
|
||||
|
||||
void setReadOnly(bool b);
|
||||
|
||||
void setTextCursor(const QTextCursor &cursor);
|
||||
|
||||
public slots:
|
||||
void setDisplayName(const QString &title);
|
||||
virtual void setFontSettings(const TextEditor::FontSettings &);
|
||||
@@ -305,6 +309,7 @@ public slots:
|
||||
virtual void unCommentSelection();
|
||||
virtual void setStorageSettings(const TextEditor::StorageSettings &);
|
||||
|
||||
void paste();
|
||||
void cut();
|
||||
|
||||
void zoomIn(int range = 1);
|
||||
@@ -316,6 +321,11 @@ public slots:
|
||||
void expand();
|
||||
void selectEncoding();
|
||||
|
||||
void gotoBlockStart();
|
||||
void gotoBlockEnd();
|
||||
void gotoBlockStartWithSelection();
|
||||
void gotoBlockEndWithSelection();
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ TextEditorActionHandler::TextEditorActionHandler(Core::ICore *core,
|
||||
= m_collapseAction = m_expandAction
|
||||
= m_deleteLineAction = m_selectEncodingAction
|
||||
= m_increaseFontSizeAction = m_decreaseFontSizeAction
|
||||
= m_gotoBlockStartAction = m_gotoBlockStartWithSelectionAction
|
||||
= m_gotoBlockEndAction = m_gotoBlockEndWithSelectionAction
|
||||
= 0;
|
||||
|
||||
m_contextId << m_core->uniqueIDManager()->uniqueIdentifier(context);
|
||||
@@ -185,6 +187,27 @@ void TextEditorActionHandler::createActions()
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+-")));
|
||||
connect(m_decreaseFontSizeAction, SIGNAL(triggered()), this, SLOT(decreaseFontSize()));
|
||||
advancedMenu->addAction(command);
|
||||
|
||||
m_gotoBlockStartAction = new QAction(tr("Goto Block Start"), this);
|
||||
command = am->registerAction(m_gotoBlockStartAction, Constants::GOTO_BLOCK_START, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+[")));
|
||||
connect(m_gotoBlockStartAction, SIGNAL(triggered()), this, SLOT(gotoBlockStart()));
|
||||
|
||||
m_gotoBlockEndAction = new QAction(tr("Goto Block End"), this);
|
||||
command = am->registerAction(m_gotoBlockEndAction, Constants::GOTO_BLOCK_END, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+]")));
|
||||
connect(m_gotoBlockEndAction, SIGNAL(triggered()), this, SLOT(gotoBlockEnd()));
|
||||
|
||||
m_gotoBlockStartWithSelectionAction = new QAction(tr("Goto Block Start With Selection"), this);
|
||||
command = am->registerAction(m_gotoBlockStartWithSelectionAction, Constants::GOTO_BLOCK_START_WITH_SELECTION, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+{")));
|
||||
connect(m_gotoBlockStartWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockStartWithSelection()));
|
||||
|
||||
m_gotoBlockEndWithSelectionAction = new QAction(tr("Goto Block End With Selection"), this);
|
||||
command = am->registerAction(m_gotoBlockEndWithSelectionAction, Constants::GOTO_BLOCK_END_WITH_SELECTION, m_contextId);
|
||||
command->setDefaultKeySequence(QKeySequence(tr("Ctrl+}")));
|
||||
connect(m_gotoBlockEndWithSelectionAction, SIGNAL(triggered()), this, SLOT(gotoBlockEndWithSelection()));
|
||||
|
||||
}
|
||||
|
||||
bool TextEditorActionHandler::supportsAction(const QString & /*id */) const
|
||||
@@ -365,54 +388,29 @@ void TextEditorActionHandler::setTextWrapping(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::unCommentSelection()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->unCommentSelection();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::deleteLine()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->deleteLine();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::unCollapseAll()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->unCollapseAll();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::collapse()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->collapse();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::expand()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->expand();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::selectEncoding()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->selectEncoding();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::increaseFontSize()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->zoomIn();
|
||||
}
|
||||
|
||||
void TextEditorActionHandler::decreaseFontSize()
|
||||
{
|
||||
if (m_currentEditor)
|
||||
m_currentEditor->zoomOut();
|
||||
#define FUNCTION(funcname) void TextEditorActionHandler::funcname ()\
|
||||
{\
|
||||
if (m_currentEditor)\
|
||||
m_currentEditor->funcname ();\
|
||||
}
|
||||
#define FUNCTION2(funcname, funcname2) void TextEditorActionHandler::funcname ()\
|
||||
{\
|
||||
if (m_currentEditor)\
|
||||
m_currentEditor->funcname2 ();\
|
||||
}
|
||||
|
||||
FUNCTION(unCommentSelection)
|
||||
FUNCTION(deleteLine)
|
||||
FUNCTION(unCollapseAll)
|
||||
FUNCTION(collapse)
|
||||
FUNCTION(expand)
|
||||
FUNCTION2(increaseFontSize, zoomIn)
|
||||
FUNCTION2(decreaseFontSize, zoomOut)
|
||||
FUNCTION(selectEncoding)
|
||||
FUNCTION(gotoBlockStart)
|
||||
FUNCTION(gotoBlockEnd)
|
||||
FUNCTION(gotoBlockStartWithSelection)
|
||||
FUNCTION(gotoBlockEndWithSelection)
|
||||
|
||||
void TextEditorActionHandler::updateCurrentEditor(Core::IContext *object)
|
||||
{
|
||||
|
||||
@@ -109,6 +109,10 @@ private slots:
|
||||
void selectEncoding();
|
||||
void increaseFontSize();
|
||||
void decreaseFontSize();
|
||||
void gotoBlockStart();
|
||||
void gotoBlockEnd();
|
||||
void gotoBlockStartWithSelection();
|
||||
void gotoBlockEndWithSelection();
|
||||
void updateCurrentEditor(Core::IContext *object);
|
||||
|
||||
private:
|
||||
@@ -131,6 +135,10 @@ private:
|
||||
QAction *m_selectEncodingAction;
|
||||
QAction *m_increaseFontSizeAction;
|
||||
QAction *m_decreaseFontSizeAction;
|
||||
QAction *m_gotoBlockStartAction;
|
||||
QAction *m_gotoBlockEndAction;
|
||||
QAction *m_gotoBlockStartWithSelectionAction;
|
||||
QAction *m_gotoBlockEndWithSelectionAction;
|
||||
|
||||
uint m_optionalActions;
|
||||
QPointer<BaseTextEditor> m_currentEditor;
|
||||
|
||||
@@ -48,9 +48,15 @@ const char * const UN_COLLAPSE_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";
|
||||
const char * const GOTO_BLOCK_START = "TextEditor.GotoBlockStart";
|
||||
const char * const GOTO_BLOCK_START_WITH_SELECTION = "TextEditor.GotoBlockStartWithSelection";
|
||||
const char * const GOTO_BLOCK_END = "TextEditor.GotoBlockEnd";
|
||||
const char * const GOTO_BLOCK_END_WITH_SELECTION = "TextEditor.GotoBlockEndWithSelection";
|
||||
const char * const DELETE_LINE = "TextEditor.DeleteLine";
|
||||
const char * const DELETE_WORD = "TextEditor.DeleteWord";
|
||||
const char * const SELECT_ENCODING = "TextEditor.SelectEncoding";
|
||||
const char * const GOTO_OPENING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
|
||||
const char * const GOTO_CLOSING_PARENTHESIS = "TextEditor.GotoOpeningParenthesis";
|
||||
const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain";
|
||||
const char * const C_TEXTEDITOR_MIMETYPE_XML = "application/xml";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user