From 35a496e5197c26060ac5ccdecbbe44b8fc9afb46 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Tue, 19 Nov 2013 23:30:41 +0000 Subject: [PATCH] [NEW_FEATURE] Add sort lines feature. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1149 f5eea248-9336-0410-98b8-ebc06183d4e3 --- PowerEditor/src/Notepad_plus.rc | 2 + PowerEditor/src/NppCommands.cpp | 18 ++++ PowerEditor/src/Parameters.cpp | 2 + .../ScitillaComponent/ScintillaEditView.cpp | 100 ++++++++++++------ .../src/ScitillaComponent/ScintillaEditView.h | 6 +- PowerEditor/src/menuCmdID.h | 32 +++--- 6 files changed, 109 insertions(+), 51 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 80fe1782f..af01f6c59 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -262,6 +262,8 @@ BEGIN MENUITEM "Duplicate Current Line", IDM_EDIT_DUP_LINE MENUITEM "Split Lines", IDM_EDIT_SPLIT_LINES MENUITEM "Join Lines", IDM_EDIT_JOIN_LINES + MENUITEM "Sort Lines in Ascending Order", IDM_EDIT_SORTLINES + MENUITEM "Sort Lines in Descending Order", IDM_EDIT_SORTLINESREVERSE MENUITEM "Move Up Current Line", IDM_EDIT_LINE_UP MENUITEM "Move Down Current Line", IDM_EDIT_LINE_DOWN MENUITEM "Remove Empty Lines", IDM_EDIT_REMOVEEMPTYLINES diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 751134532..29a3ebec2 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -326,6 +326,22 @@ void Notepad_plus::command(int id) } break; + case IDM_EDIT_SORTLINES: + { + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->quickSortLines(0, _pEditView->execute(SCI_GETLINECOUNT) - 1); + _pEditView->execute(SCI_ENDUNDOACTION); + } + break; + + case IDM_EDIT_SORTLINESREVERSE: + { + _pEditView->execute(SCI_BEGINUNDOACTION); + _pEditView->quickSortLines(0, _pEditView->execute(SCI_GETLINECOUNT) - 1, true); + _pEditView->execute(SCI_ENDUNDOACTION); + } + break; + case IDM_EDIT_BLANKLINEABOVECURRENT: { _pEditView->insertNewLineAboveCurrentLine(); @@ -2569,6 +2585,8 @@ void Notepad_plus::command(int id) case IDM_EDIT_RTL : case IDM_EDIT_LTR : case IDM_EDIT_BEGINENDSELECT: + case IDM_EDIT_SORTLINES: + case IDM_EDIT_SORTLINESREVERSE: case IDM_EDIT_BLANKLINEABOVECURRENT: case IDM_EDIT_BLANKLINEBELOWCURRENT: case IDM_VIEW_FULLSCREENTOGGLE : diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index a26f635b4..0b48c6849 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -123,6 +123,8 @@ WinMenuKeyDefinition winKeyDefs[] = { {VK_SPACE, IDM_EDIT_FUNCCALLTIP, true, false, true, NULL}, {VK_R, IDM_EDIT_RTL, true, true, false, NULL}, {VK_L, IDM_EDIT_LTR, true, true, false, NULL}, + {VK_NULL, IDM_EDIT_SORTLINES, false, false, false, NULL}, + {VK_NULL, IDM_EDIT_SORTLINESREVERSE, false, false, false, NULL}, {VK_RETURN, IDM_EDIT_BLANKLINEABOVECURRENT, true, true, false, NULL}, {VK_RETURN, IDM_EDIT_BLANKLINEBELOWCURRENT, true, true, true, NULL}, {VK_F, IDM_SEARCH_FIND, true, false, false, NULL}, diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp index c18eac63d..beb41b6a9 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.cpp @@ -2886,34 +2886,56 @@ void ScintillaEditView::insertNewLineBelowCurrentLine() execute(SCI_SETEMPTYSELECTION, execute(SCI_POSITIONFROMLINE, current_line + 1)); } -// Get the first left index, in which the value greater or equal than pivot's one -// If no one is greater than pivot, then pivot's index will be returned -size_t ScintillaEditView::getLeftLineIndex(size_t leftIndex, size_t pivotIndex) +// Get the first left index, in which the value greater/equal or smaller/equal than pivot's one +// If not found, then pivot's index will be returned +size_t ScintillaEditView::getLeftLineIndex(size_t leftIndex, size_t pivotIndex, bool isReverse) { size_t i = leftIndex; while (i < pivotIndex) { - size_t iLine = getGreaterLineBetween(i, pivotIndex); - if (iLine == pivotIndex) - i++; + if (!isReverse) + { + size_t iLine = getGreaterLineBetween(i, pivotIndex); + if (iLine == pivotIndex) // pivotIndex > i + ++i; + else + break; // Bingo! + } else - break; + { + size_t iLine = getGreaterLineBetween(i, pivotIndex); + if (iLine == pivotIndex) // pivotIndex < i + break; // Bingo! + else + ++i; + } } return i; } -// Get the first right index, in which the value smaller or equal than pivot's one -// If no one is smaller or equal than pivot, then pivot's index will be returned -size_t ScintillaEditView::getRightLineIndex(size_t rightIndex, size_t pivotIndex) +// Get the first right index, in which the value smaller/equal or greater/equal than pivot's one +// If not found, then pivot's index will be returned +size_t ScintillaEditView::getRightLineIndex(size_t rightIndex, size_t pivotIndex, bool isReverse) { size_t i = rightIndex; while (i > pivotIndex) { - size_t iLine = getGreaterLineBetween(i, pivotIndex); - if (iLine == i) - i--; + if (!isReverse) + { + size_t iLine = getGreaterLineBetween(i, pivotIndex); + if (iLine == i) // pivotIndex > i + i--; + else + break; // Bingo! + } else - break; + { + size_t iLine = getGreaterLineBetween(i, pivotIndex); + if (iLine == i) // pivotIndex < i + break; // Bingo! + else + i--; + } } return i; } @@ -2937,7 +2959,7 @@ size_t ScintillaEditView::getGreaterLineBetween(size_t l1, size_t l2) if (s1.compare(s2) > 0) res = l1; else - res = l2 + res = l2; delete[] line1text; delete[] line2text; @@ -2945,15 +2967,16 @@ size_t ScintillaEditView::getGreaterLineBetween(size_t l1, size_t l2) return res; } -size_t ScintillaEditView::getRandomPivot(size_t /*fromLine*/, size_t /*toLine*/) +size_t ScintillaEditView::getRandomPivot(size_t fromLine, size_t toLine) { - return 2; + srand((unsigned int)time(NULL)); + return rand() % (toLine - fromLine) + fromLine; } -void ScintillaEditView::quickSortLines(size_t fromLine, size_t toLine) +void ScintillaEditView::quickSortLines(size_t fromLine, size_t toLine, bool isReverse) { - if (fromLine == toLine) + if (fromLine >= toLine) return; // choose the pivot @@ -2963,28 +2986,39 @@ void ScintillaEditView::quickSortLines(size_t fromLine, size_t toLine) size_t leftIndex = fromLine; size_t rightIndex = toLine; - while (leftIndex != rightIndex) + while (rightIndex > leftIndex) { - leftIndex = getLeftLineIndex(leftIndex, pivotIndex); // get the first left index, in which the value greater or equal than pivot's one - rightIndex = getRightLineIndex(rightIndex, pivotIndex); // get the first right index, in which the value smaller or equal than pivot's one + leftIndex = getLeftLineIndex(leftIndex, pivotIndex, isReverse); // get the first left index, in which the value greater or equal than pivot's one + rightIndex = getRightLineIndex(rightIndex, pivotIndex, isReverse); // get the first right index, in which the value smaller or equal than pivot's one - - swapLines(leftIndex, rightIndex); + if ((leftIndex != rightIndex) && swapLines(leftIndex, rightIndex)) + { + if (leftIndex == pivotIndex) + { + pivotIndex = rightIndex; + ++leftIndex; + } + else if (rightIndex == pivotIndex) + { + pivotIndex = leftIndex; + --rightIndex; + } + else + { + ++leftIndex; + --rightIndex; + } + } - //if (val(leftIndex) <= val(pivotIndex)) - // ++leftIndex; - - //for (size_t j = toLine; i >= pivotIndex; --j) - //{ - - //} } // check the left side recursively - quickSortLines(fromLine, pivotIndex - 1); + if (pivotIndex != fromLine) + quickSortLines(fromLine, pivotIndex - 1, isReverse); // check the right side recursively - quickSortLines(pivotIndex + 1, toLine); + if (pivotIndex != toLine) + quickSortLines(pivotIndex + 1, toLine, isReverse); } diff --git a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h index 652a06236..4a4f6ea57 100644 --- a/PowerEditor/src/ScitillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScitillaComponent/ScintillaEditView.h @@ -657,7 +657,7 @@ public: }; void scrollPosToCenter(int pos); bool swapLines(size_t line1, size_t line2); - void quickSortLines(size_t fromLine, size_t toLine); + void quickSortLines(size_t fromLine, size_t toLine, bool isReverse = false); protected: static HINSTANCE _hLib; @@ -958,8 +958,8 @@ protected: bool expandWordSelection(); // For the quicksort on lines - size_t getLeftLineIndex(size_t leftIndex, size_t pivotIndex); - size_t getRightLineIndex(size_t rightIndex, size_t pivotIndex); + size_t getLeftLineIndex(size_t leftIndex, size_t pivotIndex, bool isReverse); + size_t getRightLineIndex(size_t rightIndex, size_t pivotIndex, bool isReverse); size_t getGreaterLineBetween(size_t l1, size_t l2); size_t getRandomPivot(size_t fromLine, size_t toLine); }; diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 26b5c5670..833ca1489 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -63,7 +63,7 @@ #define IDM_EDIT_PASTE (IDM_EDIT + 5) #define IDM_EDIT_DELETE (IDM_EDIT + 6) #define IDM_EDIT_SELECTALL (IDM_EDIT + 7) - #define IDM_EDIT_BEGINENDSELECT (IDM_EDIT + 20) + #define IDM_EDIT_BEGINENDSELECT (IDM_EDIT + 20) #define IDM_EDIT_INS_TAB (IDM_EDIT + 8) #define IDM_EDIT_RMV_TAB (IDM_EDIT + 9) @@ -75,10 +75,12 @@ #define IDM_EDIT_LINE_DOWN (IDM_EDIT + 15) #define IDM_EDIT_UPPERCASE (IDM_EDIT + 16) #define IDM_EDIT_LOWERCASE (IDM_EDIT + 17) - #define IDM_EDIT_REMOVEEMPTYLINES (IDM_EDIT + 55) - #define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56) - #define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57) - #define IDM_EDIT_BLANKLINEBELOWCURRENT (IDM_EDIT + 58) + #define IDM_EDIT_REMOVEEMPTYLINES (IDM_EDIT + 55) + #define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56) + #define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57) + #define IDM_EDIT_BLANKLINEBELOWCURRENT (IDM_EDIT + 58) + #define IDM_EDIT_SORTLINES (IDM_EDIT + 59) + #define IDM_EDIT_SORTLINESREVERSE (IDM_EDIT + 60) // Menu macro #define IDM_MACRO_STARTRECORDINGMACRO (IDM_EDIT + 18) @@ -96,7 +98,7 @@ #define IDM_EDIT_TAB2SW (IDM_EDIT + 46) #define IDM_EDIT_SW2TAB_LEADING (IDM_EDIT + 53) #define IDM_EDIT_SW2TAB_ALL (IDM_EDIT + 54) - #define IDM_EDIT_STREAM_UNCOMMENT (IDM_EDIT + 47) + #define IDM_EDIT_STREAM_UNCOMMENT (IDM_EDIT + 47) // Menu macro #define IDM_MACRO_SAVECURRENTMACRO (IDM_EDIT + 25) @@ -117,19 +119,19 @@ #define IDM_EDIT_COLUMNMODE (IDM_EDIT + 34) #define IDM_EDIT_BLOCK_COMMENT_SET (IDM_EDIT + 35) #define IDM_EDIT_BLOCK_UNCOMMENT (IDM_EDIT + 36) - #define IDM_EDIT_COLUMNMODETIP (IDM_EDIT + 37) - #define IDM_EDIT_PASTE_AS_HTML (IDM_EDIT + 38) - #define IDM_EDIT_PASTE_AS_RTF (IDM_EDIT + 39) - #define IDM_EDIT_COPY_BINARY (IDM_EDIT + 48) - #define IDM_EDIT_CUT_BINARY (IDM_EDIT + 49) - #define IDM_EDIT_PASTE_BINARY (IDM_EDIT + 50) - #define IDM_EDIT_CHAR_PANEL (IDM_EDIT + 51) - #define IDM_EDIT_CLIPBOARDHISTORY_PANEL (IDM_EDIT + 52) + #define IDM_EDIT_COLUMNMODETIP (IDM_EDIT + 37) + #define IDM_EDIT_PASTE_AS_HTML (IDM_EDIT + 38) + #define IDM_EDIT_PASTE_AS_RTF (IDM_EDIT + 39) + #define IDM_EDIT_COPY_BINARY (IDM_EDIT + 48) + #define IDM_EDIT_CUT_BINARY (IDM_EDIT + 49) + #define IDM_EDIT_PASTE_BINARY (IDM_EDIT + 50) + #define IDM_EDIT_CHAR_PANEL (IDM_EDIT + 51) + #define IDM_EDIT_CLIPBOARDHISTORY_PANEL (IDM_EDIT + 52) #define IDM_EDIT_AUTOCOMPLETE (50000 + 0) #define IDM_EDIT_AUTOCOMPLETE_CURRENTFILE (50000 + 1) #define IDM_EDIT_FUNCCALLTIP (50000 + 2) - #define IDM_EDIT_AUTOCOMPLETE_PATH (50000 + 6) + #define IDM_EDIT_AUTOCOMPLETE_PATH (50000 + 6) //Belong to MENU FILE #define IDM_OPEN_ALL_RECENT_FILE (IDM_EDIT + 40)