[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 "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

View File

@ -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 :

View File

@ -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},

View File

@ -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);
}

View File

@ -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);
};

View File

@ -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)