[NEW_FEATURE] Add sort lines feature.

git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@1149 f5eea248-9336-0410-98b8-ebc06183d4e3
This commit is contained in:
Don Ho 2013-11-19 23:30:41 +00:00
parent 806dee917d
commit 35a496e519
6 changed files with 109 additions and 51 deletions

View File

@ -262,6 +262,8 @@ BEGIN
MENUITEM "Duplicate Current Line", IDM_EDIT_DUP_LINE MENUITEM "Duplicate Current Line", IDM_EDIT_DUP_LINE
MENUITEM "Split Lines", IDM_EDIT_SPLIT_LINES MENUITEM "Split Lines", IDM_EDIT_SPLIT_LINES
MENUITEM "Join Lines", IDM_EDIT_JOIN_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 Up Current Line", IDM_EDIT_LINE_UP
MENUITEM "Move Down Current Line", IDM_EDIT_LINE_DOWN MENUITEM "Move Down Current Line", IDM_EDIT_LINE_DOWN
MENUITEM "Remove Empty Lines", IDM_EDIT_REMOVEEMPTYLINES MENUITEM "Remove Empty Lines", IDM_EDIT_REMOVEEMPTYLINES

View File

@ -326,6 +326,22 @@ void Notepad_plus::command(int id)
} }
break; 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: case IDM_EDIT_BLANKLINEABOVECURRENT:
{ {
_pEditView->insertNewLineAboveCurrentLine(); _pEditView->insertNewLineAboveCurrentLine();
@ -2569,6 +2585,8 @@ void Notepad_plus::command(int id)
case IDM_EDIT_RTL : case IDM_EDIT_RTL :
case IDM_EDIT_LTR : case IDM_EDIT_LTR :
case IDM_EDIT_BEGINENDSELECT: case IDM_EDIT_BEGINENDSELECT:
case IDM_EDIT_SORTLINES:
case IDM_EDIT_SORTLINESREVERSE:
case IDM_EDIT_BLANKLINEABOVECURRENT: case IDM_EDIT_BLANKLINEABOVECURRENT:
case IDM_EDIT_BLANKLINEBELOWCURRENT: case IDM_EDIT_BLANKLINEBELOWCURRENT:
case IDM_VIEW_FULLSCREENTOGGLE : case IDM_VIEW_FULLSCREENTOGGLE :

View File

@ -123,6 +123,8 @@ WinMenuKeyDefinition winKeyDefs[] = {
{VK_SPACE, IDM_EDIT_FUNCCALLTIP, true, false, true, NULL}, {VK_SPACE, IDM_EDIT_FUNCCALLTIP, true, false, true, NULL},
{VK_R, IDM_EDIT_RTL, true, true, false, NULL}, {VK_R, IDM_EDIT_RTL, true, true, false, NULL},
{VK_L, IDM_EDIT_LTR, 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_BLANKLINEABOVECURRENT, true, true, false, NULL},
{VK_RETURN, IDM_EDIT_BLANKLINEBELOWCURRENT, true, true, true, NULL}, {VK_RETURN, IDM_EDIT_BLANKLINEBELOWCURRENT, true, true, true, NULL},
{VK_F, IDM_SEARCH_FIND, true, false, false, NULL}, {VK_F, IDM_SEARCH_FIND, true, false, false, NULL},

View File

@ -2886,34 +2886,56 @@ void ScintillaEditView::insertNewLineBelowCurrentLine()
execute(SCI_SETEMPTYSELECTION, execute(SCI_POSITIONFROMLINE, current_line + 1)); 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 // Get the first left index, in which the value greater/equal or smaller/equal than pivot's one
// If no one is greater than pivot, then pivot's index will be returned // If not found, then pivot's index will be returned
size_t ScintillaEditView::getLeftLineIndex(size_t leftIndex, size_t pivotIndex) size_t ScintillaEditView::getLeftLineIndex(size_t leftIndex, size_t pivotIndex, bool isReverse)
{ {
size_t i = leftIndex; size_t i = leftIndex;
while (i < pivotIndex) while (i < pivotIndex)
{
if (!isReverse)
{ {
size_t iLine = getGreaterLineBetween(i, pivotIndex); size_t iLine = getGreaterLineBetween(i, pivotIndex);
if (iLine == pivotIndex) if (iLine == pivotIndex) // pivotIndex > i
i++; ++i;
else else
break; break; // Bingo!
}
else
{
size_t iLine = getGreaterLineBetween(i, pivotIndex);
if (iLine == pivotIndex) // pivotIndex < i
break; // Bingo!
else
++i;
}
} }
return i; return i;
} }
// Get the first right index, in which the value smaller or equal than pivot's one // Get the first right index, in which the value smaller/equal or greater/equal than pivot's one
// If no one is smaller or equal than pivot, then pivot's index will be returned // If not found, then pivot's index will be returned
size_t ScintillaEditView::getRightLineIndex(size_t rightIndex, size_t pivotIndex) size_t ScintillaEditView::getRightLineIndex(size_t rightIndex, size_t pivotIndex, bool isReverse)
{ {
size_t i = rightIndex; size_t i = rightIndex;
while (i > pivotIndex) while (i > pivotIndex)
{
if (!isReverse)
{ {
size_t iLine = getGreaterLineBetween(i, pivotIndex); size_t iLine = getGreaterLineBetween(i, pivotIndex);
if (iLine == i) if (iLine == i) // pivotIndex > i
i--; i--;
else else
break; break; // Bingo!
}
else
{
size_t iLine = getGreaterLineBetween(i, pivotIndex);
if (iLine == i) // pivotIndex < i
break; // Bingo!
else
i--;
}
} }
return i; return i;
} }
@ -2937,7 +2959,7 @@ size_t ScintillaEditView::getGreaterLineBetween(size_t l1, size_t l2)
if (s1.compare(s2) > 0) if (s1.compare(s2) > 0)
res = l1; res = l1;
else else
res = l2 res = l2;
delete[] line1text; delete[] line1text;
delete[] line2text; delete[] line2text;
@ -2945,15 +2967,16 @@ size_t ScintillaEditView::getGreaterLineBetween(size_t l1, size_t l2)
return res; 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; return;
// choose the pivot // choose the pivot
@ -2963,28 +2986,39 @@ void ScintillaEditView::quickSortLines(size_t fromLine, size_t toLine)
size_t leftIndex = fromLine; size_t leftIndex = fromLine;
size_t rightIndex = toLine; 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 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); // get the first right index, in which the value smaller 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
if ((leftIndex != rightIndex) && swapLines(leftIndex, rightIndex))
{
if (leftIndex == pivotIndex)
{
pivotIndex = rightIndex;
++leftIndex;
}
else if (rightIndex == pivotIndex)
{
pivotIndex = leftIndex;
--rightIndex;
}
else
{
++leftIndex;
--rightIndex;
}
}
swapLines(leftIndex, rightIndex);
//if (val(leftIndex) <= val(pivotIndex))
// ++leftIndex;
//for (size_t j = toLine; i >= pivotIndex; --j)
//{
//}
} }
// check the left side recursively // check the left side recursively
quickSortLines(fromLine, pivotIndex - 1); if (pivotIndex != fromLine)
quickSortLines(fromLine, pivotIndex - 1, isReverse);
// check the right side recursively // check the right side recursively
quickSortLines(pivotIndex + 1, toLine); if (pivotIndex != toLine)
quickSortLines(pivotIndex + 1, toLine, isReverse);
} }

View File

@ -657,7 +657,7 @@ public:
}; };
void scrollPosToCenter(int pos); void scrollPosToCenter(int pos);
bool swapLines(size_t line1, size_t line2); 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: protected:
static HINSTANCE _hLib; static HINSTANCE _hLib;
@ -958,8 +958,8 @@ protected:
bool expandWordSelection(); bool expandWordSelection();
// For the quicksort on lines // For the quicksort on lines
size_t getLeftLineIndex(size_t leftIndex, size_t pivotIndex); size_t getLeftLineIndex(size_t leftIndex, size_t pivotIndex, bool isReverse);
size_t getRightLineIndex(size_t rightIndex, size_t pivotIndex); size_t getRightLineIndex(size_t rightIndex, size_t pivotIndex, bool isReverse);
size_t getGreaterLineBetween(size_t l1, size_t l2); size_t getGreaterLineBetween(size_t l1, size_t l2);
size_t getRandomPivot(size_t fromLine, size_t toLine); size_t getRandomPivot(size_t fromLine, size_t toLine);
}; };

View File

@ -79,6 +79,8 @@
#define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56) #define IDM_EDIT_REMOVEEMPTYLINESWITHBLANK (IDM_EDIT + 56)
#define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57) #define IDM_EDIT_BLANKLINEABOVECURRENT (IDM_EDIT + 57)
#define IDM_EDIT_BLANKLINEBELOWCURRENT (IDM_EDIT + 58) #define IDM_EDIT_BLANKLINEBELOWCURRENT (IDM_EDIT + 58)
#define IDM_EDIT_SORTLINES (IDM_EDIT + 59)
#define IDM_EDIT_SORTLINESREVERSE (IDM_EDIT + 60)
// Menu macro // Menu macro
#define IDM_MACRO_STARTRECORDINGMACRO (IDM_EDIT + 18) #define IDM_MACRO_STARTRECORDINGMACRO (IDM_EDIT + 18)