- enhancement: shift+ctrl+down/up to move currenlt selection lines up / down
This commit is contained in:
parent
5e349ec21e
commit
431f5bbced
1
NEWS.md
1
NEWS.md
|
@ -2,6 +2,7 @@ Red Panda C++ Version 1.0.3
|
||||||
- fix: when oj problem grabbed by competitive companion received,
|
- fix: when oj problem grabbed by competitive companion received,
|
||||||
the app is restored to normal state, no matter it's current state.
|
the app is restored to normal state, no matter it's current state.
|
||||||
- enhancement: input shortcut in the option dialog's general -> shortcut page by pressing keys.
|
- enhancement: input shortcut in the option dialog's general -> shortcut page by pressing keys.
|
||||||
|
- enhancement: shift+ctrl+down/up to move currenlt selection lines up / down
|
||||||
|
|
||||||
Red Panda C++ Version 1.0.2
|
Red Panda C++ Version 1.0.2
|
||||||
- enhancement: press tab in column mode won't exit column mode
|
- enhancement: press tab in column mode won't exit column mode
|
||||||
|
|
|
@ -7523,3 +7523,20 @@ void MainWindow::on_txtProblemCaseInput_cursorPositionChanged()
|
||||||
ui->lblProblemCaseInput->setText(tr("Line %1").arg(cursor.block().firstLineNumber()+1));
|
ui->lblProblemCaseInput->setText(tr("Line %1").arg(cursor.block().firstLineNumber()+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_actionMove_Selection_Up_triggered()
|
||||||
|
{
|
||||||
|
Editor * editor = mEditorList->getEditor();
|
||||||
|
if (editor != NULL ) {
|
||||||
|
editor->moveSelUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MainWindow::on_actionMove_Selection_Down_triggered()
|
||||||
|
{
|
||||||
|
Editor * editor = mEditorList->getEditor();
|
||||||
|
if (editor != NULL ) {
|
||||||
|
editor->moveSelDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -663,6 +663,10 @@ private slots:
|
||||||
|
|
||||||
void on_txtProblemCaseInput_cursorPositionChanged();
|
void on_txtProblemCaseInput_cursorPositionChanged();
|
||||||
|
|
||||||
|
void on_actionMove_Selection_Up_triggered();
|
||||||
|
|
||||||
|
void on_actionMove_Selection_Down_triggered();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
EditorList *mEditorList;
|
EditorList *mEditorList;
|
||||||
|
|
|
@ -1633,6 +1633,8 @@
|
||||||
<addaction name="actionFoldAll"/>
|
<addaction name="actionFoldAll"/>
|
||||||
<addaction name="actionUnfoldAll"/>
|
<addaction name="actionUnfoldAll"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
|
<addaction name="actionMove_Selection_Up"/>
|
||||||
|
<addaction name="actionMove_Selection_Down"/>
|
||||||
<addaction name="actionDelete_Line"/>
|
<addaction name="actionDelete_Line"/>
|
||||||
<addaction name="actionDuplicate_Line"/>
|
<addaction name="actionDuplicate_Line"/>
|
||||||
<addaction name="actionDelete_Word"/>
|
<addaction name="actionDelete_Word"/>
|
||||||
|
@ -3018,6 +3020,22 @@
|
||||||
<string>Ctrl+]</string>
|
<string>Ctrl+]</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionMove_Selection_Up">
|
||||||
|
<property name="text">
|
||||||
|
<string>Move Selection Up</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+Up</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionMove_Selection_Down">
|
||||||
|
<property name="text">
|
||||||
|
<string>Move Selection Down</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+Shift+Down</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
<customwidget>
|
<customwidget>
|
||||||
|
|
|
@ -2180,97 +2180,87 @@ void SynEdit::doDuplicateLine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynEdit::doMoveSelUp()
|
void SynEdit::doMoveSelUp(bool addUndo)
|
||||||
{
|
{
|
||||||
if (!mReadOnly && (mLines->count() > 0) && (blockBegin().Line > 1)) {
|
if (!mReadOnly && (mLines->count() > 0) && (blockBegin().Line > 1)) {
|
||||||
doOnPaintTransient(SynTransientType::ttBefore);
|
doOnPaintTransient(SynTransientType::ttBefore);
|
||||||
|
|
||||||
// Backup caret and selection
|
// Backup caret and selection
|
||||||
BufferCoord OrigBlockBegin = blockBegin();
|
BufferCoord origBlockBegin = blockBegin();
|
||||||
BufferCoord OrigBlockEnd = blockEnd();
|
BufferCoord origBlockEnd = blockEnd();
|
||||||
|
|
||||||
// Delete line above selection
|
if (addUndo) {
|
||||||
QString s = mLines->getString(OrigBlockBegin.Line - 2); // before start, 0 based
|
|
||||||
mLines->deleteAt(OrigBlockBegin.Line - 2); // before start, 0 based
|
|
||||||
doLinesDeleted(OrigBlockBegin.Line - 1, 1); // before start, 1 based
|
|
||||||
|
|
||||||
// Insert line below selection
|
|
||||||
mLines->insert(OrigBlockEnd.Line - 1, s);
|
|
||||||
doLinesInserted(OrigBlockEnd.Line, 1);
|
|
||||||
|
|
||||||
// Restore caret and selection
|
|
||||||
setCaretAndSelection(
|
|
||||||
BufferCoord{mCaretX, mCaretY - 1},
|
|
||||||
BufferCoord{1, OrigBlockBegin.Line - 1},
|
|
||||||
BufferCoord{mLines->getString(OrigBlockEnd.Line - 2).length() + 1, OrigBlockEnd.Line - 1}
|
|
||||||
);
|
|
||||||
// Retrieve end of line we moved up
|
|
||||||
BufferCoord MoveDelim = BufferCoord{mLines->getString(OrigBlockEnd.Line - 1).length() + 1, OrigBlockEnd.Line};
|
|
||||||
// Support undo, implement as drag and drop
|
|
||||||
{
|
|
||||||
mUndoList->BeginBlock();
|
mUndoList->BeginBlock();
|
||||||
auto action = finally([this]{
|
mUndoList->AddChange(SynChangeReason::crCaret, // backup original selection
|
||||||
mUndoList->EndBlock();
|
caretXY(),
|
||||||
});
|
caretXY(),
|
||||||
mUndoList->AddChange(SynChangeReason::crSelection, // backup original selection
|
|
||||||
OrigBlockBegin,
|
|
||||||
OrigBlockEnd,
|
|
||||||
"",
|
"",
|
||||||
SynSelectionMode::smNormal);
|
SynSelectionMode::smNormal);
|
||||||
mUndoList->AddChange(SynChangeReason::crDragDropInsert,
|
mUndoList->AddChange(SynChangeReason::crMoveSelectionUp, // backup original selection
|
||||||
mBlockBegin, // modified
|
origBlockBegin,
|
||||||
MoveDelim, // put at end of line me moved up
|
origBlockEnd,
|
||||||
s + lineBreak() + selText(),
|
"",
|
||||||
SynSelectionMode::smNormal);
|
SynSelectionMode::smNormal);
|
||||||
|
mUndoList->EndBlock();
|
||||||
}
|
}
|
||||||
|
// Delete line above selection
|
||||||
|
QString s = mLines->getString(origBlockBegin.Line - 2); // before start, 0 based
|
||||||
|
mLines->deleteAt(origBlockBegin.Line - 2); // before start, 0 based
|
||||||
|
doLinesDeleted(origBlockBegin.Line - 1, 1); // before start, 1 based
|
||||||
|
|
||||||
|
// Insert line below selection
|
||||||
|
mLines->insert(origBlockEnd.Line - 1, s);
|
||||||
|
doLinesInserted(origBlockEnd.Line, 1);
|
||||||
|
// Restore caret and selection
|
||||||
|
setCaretAndSelection(
|
||||||
|
BufferCoord{mCaretX, origBlockBegin.Line - 1},
|
||||||
|
BufferCoord{origBlockBegin.Char, origBlockBegin.Line - 1},
|
||||||
|
BufferCoord{origBlockEnd.Char, origBlockEnd.Line - 1}
|
||||||
|
);
|
||||||
|
|
||||||
doOnPaintTransient(SynTransientType::ttAfter);
|
doOnPaintTransient(SynTransientType::ttAfter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SynEdit::doMoveSelDown()
|
void SynEdit::doMoveSelDown(bool addUndo)
|
||||||
{
|
{
|
||||||
if (!mReadOnly && (mLines->count() > 0) && (blockEnd().Line < mLines->count())) {
|
if (!mReadOnly && (mLines->count() > 0) && (blockEnd().Line < mLines->count())) {
|
||||||
doOnPaintTransient(SynTransientType::ttBefore);
|
doOnPaintTransient(SynTransientType::ttBefore);
|
||||||
// Backup caret and selection
|
// Backup caret and selection
|
||||||
BufferCoord OrigBlockBegin = blockBegin();
|
BufferCoord origBlockBegin = blockBegin();
|
||||||
BufferCoord OrigBlockEnd = blockEnd();
|
BufferCoord origBlockEnd = blockEnd();
|
||||||
|
if (addUndo) {
|
||||||
|
mUndoList->BeginBlock();
|
||||||
|
mUndoList->AddChange(SynChangeReason::crCaret, // backup original selection
|
||||||
|
caretXY(),
|
||||||
|
caretXY(),
|
||||||
|
"",
|
||||||
|
SynSelectionMode::smNormal);
|
||||||
|
mUndoList->AddChange(SynChangeReason::crMoveSelectionDown, // backup original selection
|
||||||
|
origBlockBegin,
|
||||||
|
origBlockEnd,
|
||||||
|
"",
|
||||||
|
SynSelectionMode::smNormal);
|
||||||
|
mUndoList->EndBlock();
|
||||||
|
}
|
||||||
|
|
||||||
// Delete line below selection
|
// Delete line below selection
|
||||||
QString s = mLines->getString(OrigBlockEnd.Line); // after end, 0 based
|
QString s = mLines->getString(origBlockEnd.Line); // after end, 0 based
|
||||||
mLines->deleteAt(OrigBlockEnd.Line); // after end, 0 based
|
mLines->deleteAt(origBlockEnd.Line); // after end, 0 based
|
||||||
doLinesDeleted(OrigBlockEnd.Line, 1); // before start, 1 based
|
doLinesDeleted(origBlockEnd.Line, 1); // before start, 1 based
|
||||||
|
|
||||||
// Insert line above selection
|
// Insert line above selection
|
||||||
mLines->insert(OrigBlockBegin.Line - 1, s);
|
mLines->insert(origBlockBegin.Line - 1, s);
|
||||||
doLinesInserted(OrigBlockBegin.Line, 1);
|
doLinesInserted(origBlockBegin.Line, 1);
|
||||||
|
|
||||||
// Restore caret and selection
|
// Restore caret and selection
|
||||||
setCaretAndSelection(
|
setCaretAndSelection(
|
||||||
BufferCoord{mCaretX, mCaretY + 1},
|
BufferCoord{mCaretX, origBlockEnd.Line + 1},
|
||||||
BufferCoord{1, OrigBlockBegin.Line + 1},
|
BufferCoord{origBlockBegin.Char, origBlockBegin.Line + 1},
|
||||||
BufferCoord{mLines->getString(OrigBlockEnd.Line).length() + 1, OrigBlockEnd.Line + 1}
|
BufferCoord{origBlockEnd.Char, origBlockEnd.Line + 1}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Retrieve start of line we moved down
|
// Retrieve start of line we moved down
|
||||||
BufferCoord MoveDelim = BufferCoord{1, OrigBlockBegin.Line};
|
|
||||||
|
|
||||||
// Support undo, implement as drag and drop
|
|
||||||
{
|
|
||||||
mUndoList->BeginBlock();
|
|
||||||
auto action = finally([this] {
|
|
||||||
mUndoList->EndBlock();
|
|
||||||
});
|
|
||||||
mUndoList->AddChange(SynChangeReason::crSelection,
|
|
||||||
OrigBlockBegin,
|
|
||||||
OrigBlockEnd,
|
|
||||||
"",
|
|
||||||
SynSelectionMode::smNormal);
|
|
||||||
mUndoList->AddChange(SynChangeReason::crDragDropInsert,
|
|
||||||
MoveDelim, // put at start of line me moved down
|
|
||||||
mBlockEnd, // modified
|
|
||||||
selText() + lineBreak() + s,
|
|
||||||
SynSelectionMode::smNormal);
|
|
||||||
}
|
|
||||||
doOnPaintTransient(SynTransientType::ttAfter);
|
doOnPaintTransient(SynTransientType::ttAfter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4302,6 +4292,28 @@ void SynEdit::doUndoItem()
|
||||||
internalSetCaretXY(Item->changeStartPos());
|
internalSetCaretXY(Item->changeStartPos());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case SynChangeReason::crMoveSelectionUp:
|
||||||
|
setBlockBegin(BufferCoord{Item->changeStartPos().Char, Item->changeStartPos().Line-1});
|
||||||
|
setBlockEnd(BufferCoord{Item->changeEndPos().Char, Item->changeEndPos().Line-1});
|
||||||
|
doMoveSelDown(false);
|
||||||
|
mRedoList->AddChange(
|
||||||
|
Item->changeReason(),
|
||||||
|
Item->changeStartPos(),
|
||||||
|
Item->changeEndPos(),
|
||||||
|
Item->changeStr(),
|
||||||
|
Item->changeSelMode());
|
||||||
|
break;
|
||||||
|
case SynChangeReason::crMoveSelectionDown:
|
||||||
|
setBlockBegin(BufferCoord{Item->changeStartPos().Char, Item->changeStartPos().Line+1});
|
||||||
|
setBlockEnd(BufferCoord{Item->changeEndPos().Char, Item->changeEndPos().Line+1});
|
||||||
|
doMoveSelUp(false);
|
||||||
|
mRedoList->AddChange(
|
||||||
|
Item->changeReason(),
|
||||||
|
Item->changeStartPos(),
|
||||||
|
Item->changeEndPos(),
|
||||||
|
Item->changeStr(),
|
||||||
|
Item->changeSelMode());
|
||||||
|
break;
|
||||||
case SynChangeReason::crDeleteAfterCursor:
|
case SynChangeReason::crDeleteAfterCursor:
|
||||||
case SynChangeReason::crDelete:
|
case SynChangeReason::crDelete:
|
||||||
case SynChangeReason::crSilentDelete:
|
case SynChangeReason::crSilentDelete:
|
||||||
|
@ -4531,6 +4543,28 @@ void SynEdit::doRedoItem()
|
||||||
Item->changeStartPos(),
|
Item->changeStartPos(),
|
||||||
Item->changeEndPos());
|
Item->changeEndPos());
|
||||||
break;
|
break;
|
||||||
|
case SynChangeReason::crMoveSelectionUp:
|
||||||
|
setBlockBegin(BufferCoord{Item->changeStartPos().Char, Item->changeStartPos().Line});
|
||||||
|
setBlockEnd(BufferCoord{Item->changeEndPos().Char, Item->changeEndPos().Line});
|
||||||
|
doMoveSelUp(false);
|
||||||
|
mUndoList->AddChange(
|
||||||
|
Item->changeReason(),
|
||||||
|
Item->changeStartPos(),
|
||||||
|
Item->changeEndPos(),
|
||||||
|
Item->changeStr(),
|
||||||
|
Item->changeSelMode());
|
||||||
|
break;
|
||||||
|
case SynChangeReason::crMoveSelectionDown:
|
||||||
|
setBlockBegin(BufferCoord{Item->changeStartPos().Char, Item->changeStartPos().Line});
|
||||||
|
setBlockEnd(BufferCoord{Item->changeEndPos().Char, Item->changeEndPos().Line});
|
||||||
|
doMoveSelDown(false);
|
||||||
|
mUndoList->AddChange(
|
||||||
|
Item->changeReason(),
|
||||||
|
Item->changeStartPos(),
|
||||||
|
Item->changeEndPos(),
|
||||||
|
Item->changeStr(),
|
||||||
|
Item->changeSelMode());
|
||||||
|
break;
|
||||||
case SynChangeReason::crInsert:
|
case SynChangeReason::crInsert:
|
||||||
case SynChangeReason::crPaste:
|
case SynChangeReason::crPaste:
|
||||||
case SynChangeReason::crDragDropInsert:
|
case SynChangeReason::crDragDropInsert:
|
||||||
|
@ -6135,7 +6169,7 @@ void SynEdit::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QAbstractScrollArea::mouseReleaseEvent(event);
|
QAbstractScrollArea::mouseReleaseEvent(event);
|
||||||
int X=event->pos().x();
|
int X=event->pos().x();
|
||||||
int Y=event->pos().y();
|
/* int Y=event->pos().y(); */
|
||||||
|
|
||||||
if (!mMouseMoved && (X < mGutterWidth + 2)) {
|
if (!mMouseMoved && (X < mGutterWidth + 2)) {
|
||||||
processGutterClick(event);
|
processGutterClick(event);
|
||||||
|
|
|
@ -280,6 +280,8 @@ public:
|
||||||
virtual void toggleComment() { commandProcessor(SynEditorCommand::ecToggleComment);}
|
virtual void toggleComment() { commandProcessor(SynEditorCommand::ecToggleComment);}
|
||||||
virtual void toggleBlockComment() { commandProcessor(SynEditorCommand::ecToggleBlockComment);}
|
virtual void toggleBlockComment() { commandProcessor(SynEditorCommand::ecToggleBlockComment);}
|
||||||
virtual void matchBracket() { commandProcessor(SynEditorCommand::ecMatchBracket);}
|
virtual void matchBracket() { commandProcessor(SynEditorCommand::ecMatchBracket);}
|
||||||
|
virtual void moveSelUp(){ commandProcessor(SynEditorCommand::ecMoveSelUp);}
|
||||||
|
virtual void moveSelDown(){ commandProcessor(SynEditorCommand::ecMoveSelDown);}
|
||||||
|
|
||||||
virtual void beginUpdate();
|
virtual void beginUpdate();
|
||||||
virtual void endUpdate();
|
virtual void endUpdate();
|
||||||
|
@ -573,8 +575,8 @@ private:
|
||||||
void doDeleteLine();
|
void doDeleteLine();
|
||||||
void doSelecteLine();
|
void doSelecteLine();
|
||||||
void doDuplicateLine();
|
void doDuplicateLine();
|
||||||
void doMoveSelUp();
|
void doMoveSelUp(bool addUndo=true);
|
||||||
void doMoveSelDown();
|
void doMoveSelDown(bool addUndo=true);
|
||||||
void clearAll();
|
void clearAll();
|
||||||
void insertLine(bool moveCaret);
|
void insertLine(bool moveCaret);
|
||||||
void doTabKey();
|
void doTabKey();
|
||||||
|
|
|
@ -163,7 +163,9 @@ enum class SynChangeReason {crInsert, crPaste, crDragDropInsert,
|
||||||
crSelection, //restore Selection
|
crSelection, //restore Selection
|
||||||
crNothing,
|
crNothing,
|
||||||
crGroupBreak,
|
crGroupBreak,
|
||||||
crDeleteAll
|
crDeleteAll,
|
||||||
|
crMoveSelectionUp,
|
||||||
|
crMoveSelectionDown
|
||||||
};
|
};
|
||||||
class SynEditUndoItem {
|
class SynEditUndoItem {
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in New Issue