From 9ed1465a78cc69038d8a5655e6e1dba9c4258e5b Mon Sep 17 00:00:00 2001 From: nyamatongwe Date: Sat, 21 May 2011 10:18:24 +1000 Subject: Move Selected Lines Up / Down. Feature #3304850. From Olivier Dagenais. --- doc/ScintillaDoc.html | 18 ++++++++++++++ include/Scintilla.h | 2 ++ include/Scintilla.iface | 6 +++++ src/Editor.cxx | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ src/Editor.h | 3 +++ 5 files changed, 92 insertions(+) diff --git a/doc/ScintillaDoc.html b/doc/ScintillaDoc.html index 50a7ed477..36e04f239 100644 --- a/doc/ScintillaDoc.html +++ b/doc/ScintillaDoc.html @@ -1112,6 +1112,8 @@ struct Sci_TextToFind { SCI_TEXTWIDTH(int styleNumber, const char *text)
SCI_TEXTHEIGHT(int line)
SCI_CHOOSECARETX
+ SCI_MOVESELECTEDLINESUP
+ SCI_MOVESELECTEDLINESDOWN

SCI_GETTEXTLENGTH
@@ -1456,6 +1458,16 @@ struct Sci_TextToFind { user and this value is then used when moving vertically such as by using the up and down keys. This message sets the current x position of the caret as the remembered value.

+

SCI_MOVESELECTEDLINESUP
+ Move the selected lines up one line, shifting the line above after the selection. + The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. + If nothing was selected, the line the cursor is currently at will be selected.

+ +

SCI_MOVESELECTEDLINESDOWN
+ Move the selected lines down one line, shifting the line below before the selection. + The selection will be automatically extended to the beginning of the selection's first line and the end of the seletion's last line. + If nothing was selected, the line the cursor is currently at will be selected.

+

Multiple Selection and Virtual Space

@@ -4337,6 +4349,12 @@ struct Sci_TextToFind { SCI_VERTICALCENTRECARET + + + SCI_MOVESELECTEDLINESUP + + SCI_MOVESELECTEDLINESDOWN + diff --git a/include/Scintilla.h b/include/Scintilla.h index c0ed9545e..f1c4fa99f 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -799,6 +799,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCI_CHANGELEXERSTATE 2617 #define SCI_CONTRACTEDFOLDNEXT 2618 #define SCI_VERTICALCENTRECARET 2619 +#define SCI_MOVESELECTEDLINESUP 2620 +#define SCI_MOVESELECTEDLINESDOWN 2621 #define SCI_STARTRECORD 3001 #define SCI_STOPRECORD 3002 #define SCI_SETLEXER 4001 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 2cd7eba1d..8cd3ab5d0 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2125,6 +2125,12 @@ fun int ContractedFoldNext=2618(int lineStart,) # Centre current line in window. fun void VerticalCentreCaret=2619(,) +# Move the selected lines up one line, shifting the line above after the selection +fun void MoveSelectedLinesUp=2620(,) + +# Move the selected lines down one line, shifting the line below before the selection +fun void MoveSelectedLinesDown=2621(,) + # Start notifying the container of all key presses and commands. fun void StartRecord=3001(,) diff --git a/src/Editor.cxx b/src/Editor.cxx index ae2d670ce..2fa3a4340 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -1027,6 +1027,59 @@ void Editor::VerticalCentreCaret() { } } +void Editor::MoveSelectedLines(int lineDelta) { + + // if selection doesn't start at the beginning of the line, set the new start + int selectionStart = SelectionStart().Position(); + int startLine = pdoc->LineFromPosition(selectionStart); + int beginningOfStartLine = pdoc->LineStart(startLine); + selectionStart = beginningOfStartLine; + + // if selection doesn't end at the beginning of a line greater than that of the start, + // then set it at the beginning of the next one + int selectionEnd = SelectionEnd().Position(); + int endLine = pdoc->LineFromPosition(selectionEnd); + int beginningOfEndLine = pdoc->LineStart(endLine); + if (selectionEnd > beginningOfEndLine + || selectionStart == selectionEnd) { + selectionEnd = pdoc->LineStart(endLine + 1); + } + + // if there's nowhere for the selection to move + // (i.e. at the beginning going up or at the end going down), + // stop it right there! + if ((selectionStart == 0 && lineDelta < 0) + || (selectionEnd == pdoc->Length() && lineDelta > 0) + || selectionStart == selectionEnd) { + return; + } + + UndoGroup ug(pdoc); + + SetSelection(selectionStart, selectionEnd); + + SelectionText selectedText; + CopySelectionRange(&selectedText); + + int selectionLength = SelectionRange(selectionStart, selectionEnd).Length(); + ClearSelection(); + + Point currentLocation = LocationFromPosition(CurrentPosition()); + int currentLine = LineFromLocation(currentLocation); + GoToLine(currentLine + lineDelta); + + pdoc->InsertCString(CurrentPosition(), selectedText.s); + SetSelection(CurrentPosition(), CurrentPosition() + selectionLength); +} + +void Editor::MoveSelectedLinesUp() { + MoveSelectedLines(-1); +} + +void Editor::MoveSelectedLinesDown() { + MoveSelectedLines(1); +} + void Editor::MoveCaretInsideView(bool ensureVisible) { PRectangle rcClient = GetTextRectangle(); Point pt = PointMainCaret(); @@ -4688,6 +4741,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar case SCI_SELECTIONDUPLICATE: case SCI_COPYALLOWLINE: case SCI_VERTICALCENTRECARET: + case SCI_MOVESELECTEDLINESUP: + case SCI_MOVESELECTEDLINESDOWN: break; // Filter out all others like display changes. Also, newlines are redundant @@ -6957,6 +7012,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) { VerticalCentreCaret(); break; + case SCI_MOVESELECTEDLINESUP: + MoveSelectedLinesUp(); + break; + + case SCI_MOVESELECTEDLINESDOWN: + MoveSelectedLinesDown(); + break; + case SCI_COPYRANGE: CopyRangeToClipboard(wParam, lParam); break; diff --git a/src/Editor.h b/src/Editor.h index ef3fb78f0..5c01ee83d 100644 --- a/src/Editor.h +++ b/src/Editor.h @@ -335,6 +335,9 @@ protected: // ScintillaBase subclass needs access to much of Editor virtual void ScrollText(int linesToMove); void HorizontalScrollTo(int xPos); void VerticalCentreCaret(); + void MoveSelectedLines(int lineDelta); + void MoveSelectedLinesUp(); + void MoveSelectedLinesDown(); void MoveCaretInsideView(bool ensureVisible=true); int DisplayFromPosition(int pos); -- cgit v1.2.3