From 431f5bbcedf93c0940c0a958d7ce652c730ee320 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Fri, 1 Apr 2022 23:10:38 +0800 Subject: [PATCH] - enhancement: shift+ctrl+down/up to move currenlt selection lines up / down --- NEWS.md | 1 + RedPandaIDE/mainwindow.cpp | 17 ++++ RedPandaIDE/mainwindow.h | 4 + RedPandaIDE/mainwindow.ui | 18 ++++ RedPandaIDE/qsynedit/SynEdit.cpp | 160 ++++++++++++++++++------------ RedPandaIDE/qsynedit/SynEdit.h | 6 +- RedPandaIDE/qsynedit/TextBuffer.h | 4 +- 7 files changed, 144 insertions(+), 66 deletions(-) diff --git a/NEWS.md b/NEWS.md index 54911375..3b7c5a32 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ Red Panda C++ Version 1.0.3 - fix: when oj problem grabbed by competitive companion received, 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: shift+ctrl+down/up to move currenlt selection lines up / down Red Panda C++ Version 1.0.2 - enhancement: press tab in column mode won't exit column mode diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index faf4fe64..a0134e06 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -7523,3 +7523,20 @@ void MainWindow::on_txtProblemCaseInput_cursorPositionChanged() 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(); + } +} diff --git a/RedPandaIDE/mainwindow.h b/RedPandaIDE/mainwindow.h index ad2906c4..8a62ef32 100644 --- a/RedPandaIDE/mainwindow.h +++ b/RedPandaIDE/mainwindow.h @@ -663,6 +663,10 @@ private slots: void on_txtProblemCaseInput_cursorPositionChanged(); + void on_actionMove_Selection_Up_triggered(); + + void on_actionMove_Selection_Down_triggered(); + private: Ui::MainWindow *ui; EditorList *mEditorList; diff --git a/RedPandaIDE/mainwindow.ui b/RedPandaIDE/mainwindow.ui index 26b5c116..6dd4c956 100644 --- a/RedPandaIDE/mainwindow.ui +++ b/RedPandaIDE/mainwindow.ui @@ -1633,6 +1633,8 @@ + + @@ -3018,6 +3020,22 @@ Ctrl+] + + + Move Selection Up + + + Ctrl+Shift+Up + + + + + Move Selection Down + + + Ctrl+Shift+Down + + diff --git a/RedPandaIDE/qsynedit/SynEdit.cpp b/RedPandaIDE/qsynedit/SynEdit.cpp index f9ef6afb..6bf86100 100644 --- a/RedPandaIDE/qsynedit/SynEdit.cpp +++ b/RedPandaIDE/qsynedit/SynEdit.cpp @@ -2180,97 +2180,87 @@ void SynEdit::doDuplicateLine() } } -void SynEdit::doMoveSelUp() +void SynEdit::doMoveSelUp(bool addUndo) { if (!mReadOnly && (mLines->count() > 0) && (blockBegin().Line > 1)) { doOnPaintTransient(SynTransientType::ttBefore); // Backup caret and selection - BufferCoord OrigBlockBegin = blockBegin(); - BufferCoord OrigBlockEnd = blockEnd(); + BufferCoord origBlockBegin = blockBegin(); + BufferCoord origBlockEnd = blockEnd(); - // 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, 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 - { + if (addUndo) { mUndoList->BeginBlock(); - auto action = finally([this]{ - mUndoList->EndBlock(); - }); - mUndoList->AddChange(SynChangeReason::crSelection, // backup original selection - OrigBlockBegin, - OrigBlockEnd, + mUndoList->AddChange(SynChangeReason::crCaret, // backup original selection + caretXY(), + caretXY(), "", SynSelectionMode::smNormal); - mUndoList->AddChange(SynChangeReason::crDragDropInsert, - mBlockBegin, // modified - MoveDelim, // put at end of line me moved up - s + lineBreak() + selText(), + mUndoList->AddChange(SynChangeReason::crMoveSelectionUp, // backup original selection + origBlockBegin, + origBlockEnd, + "", 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); } } -void SynEdit::doMoveSelDown() +void SynEdit::doMoveSelDown(bool addUndo) { if (!mReadOnly && (mLines->count() > 0) && (blockEnd().Line < mLines->count())) { doOnPaintTransient(SynTransientType::ttBefore); // Backup caret and selection - BufferCoord OrigBlockBegin = blockBegin(); - BufferCoord OrigBlockEnd = blockEnd(); + BufferCoord origBlockBegin = blockBegin(); + 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 - QString s = mLines->getString(OrigBlockEnd.Line); // after end, 0 based - mLines->deleteAt(OrigBlockEnd.Line); // after end, 0 based - doLinesDeleted(OrigBlockEnd.Line, 1); // before start, 1 based + QString s = mLines->getString(origBlockEnd.Line); // after end, 0 based + mLines->deleteAt(origBlockEnd.Line); // after end, 0 based + doLinesDeleted(origBlockEnd.Line, 1); // before start, 1 based // Insert line above selection - mLines->insert(OrigBlockBegin.Line - 1, s); - doLinesInserted(OrigBlockBegin.Line, 1); + mLines->insert(origBlockBegin.Line - 1, s); + doLinesInserted(origBlockBegin.Line, 1); // Restore caret and selection setCaretAndSelection( - BufferCoord{mCaretX, mCaretY + 1}, - BufferCoord{1, OrigBlockBegin.Line + 1}, - BufferCoord{mLines->getString(OrigBlockEnd.Line).length() + 1, OrigBlockEnd.Line + 1} + BufferCoord{mCaretX, origBlockEnd.Line + 1}, + BufferCoord{origBlockBegin.Char, origBlockBegin.Line + 1}, + BufferCoord{origBlockEnd.Char, origBlockEnd.Line + 1} ); // 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); } } @@ -4302,6 +4292,28 @@ void SynEdit::doUndoItem() internalSetCaretXY(Item->changeStartPos()); 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::crDelete: case SynChangeReason::crSilentDelete: @@ -4531,6 +4543,28 @@ void SynEdit::doRedoItem() Item->changeStartPos(), Item->changeEndPos()); 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::crPaste: case SynChangeReason::crDragDropInsert: @@ -6135,7 +6169,7 @@ void SynEdit::mouseReleaseEvent(QMouseEvent *event) { QAbstractScrollArea::mouseReleaseEvent(event); int X=event->pos().x(); - int Y=event->pos().y(); + /* int Y=event->pos().y(); */ if (!mMouseMoved && (X < mGutterWidth + 2)) { processGutterClick(event); diff --git a/RedPandaIDE/qsynedit/SynEdit.h b/RedPandaIDE/qsynedit/SynEdit.h index b6a41671..9e4c1287 100644 --- a/RedPandaIDE/qsynedit/SynEdit.h +++ b/RedPandaIDE/qsynedit/SynEdit.h @@ -280,6 +280,8 @@ public: virtual void toggleComment() { commandProcessor(SynEditorCommand::ecToggleComment);} virtual void toggleBlockComment() { commandProcessor(SynEditorCommand::ecToggleBlockComment);} virtual void matchBracket() { commandProcessor(SynEditorCommand::ecMatchBracket);} + virtual void moveSelUp(){ commandProcessor(SynEditorCommand::ecMoveSelUp);} + virtual void moveSelDown(){ commandProcessor(SynEditorCommand::ecMoveSelDown);} virtual void beginUpdate(); virtual void endUpdate(); @@ -573,8 +575,8 @@ private: void doDeleteLine(); void doSelecteLine(); void doDuplicateLine(); - void doMoveSelUp(); - void doMoveSelDown(); + void doMoveSelUp(bool addUndo=true); + void doMoveSelDown(bool addUndo=true); void clearAll(); void insertLine(bool moveCaret); void doTabKey(); diff --git a/RedPandaIDE/qsynedit/TextBuffer.h b/RedPandaIDE/qsynedit/TextBuffer.h index 039ff177..4c2b4b63 100644 --- a/RedPandaIDE/qsynedit/TextBuffer.h +++ b/RedPandaIDE/qsynedit/TextBuffer.h @@ -163,7 +163,9 @@ enum class SynChangeReason {crInsert, crPaste, crDragDropInsert, crSelection, //restore Selection crNothing, crGroupBreak, - crDeleteAll + crDeleteAll, + crMoveSelectionUp, + crMoveSelectionDown }; class SynEditUndoItem { private: