diff --git a/checkin_notes b/checkin_notes index f9bff5ef6d..b89b372be9 100644 --- a/checkin_notes +++ b/checkin_notes @@ -5502,7 +5502,16 @@ David 6 July 2008 Charlie 8 July 2008 - MGR: Add "Show only this project" button to messages tab; filters message display to show only messages for the selected project. + - MGR: Fix problem of rows with equal values in the sort column + changing places randomly with each re-sort. wxArrayInt::Sort() + uses std::sort(), which is not stable in such cases. The + solution is to use std::stable_sort() instea + clientgui/ Events.h + BOINCBaseView.cpp,.h ViewMessages.cpp,.h + ViewProjects.cpp + ViewTransfers.cpp + ViewWork.cpp diff --git a/clientgui/BOINCBaseView.cpp b/clientgui/BOINCBaseView.cpp index 558b5b3211..3075b03776 100644 --- a/clientgui/BOINCBaseView.cpp +++ b/clientgui/BOINCBaseView.cpp @@ -530,7 +530,7 @@ void CBOINCBaseView::sortData() { m_pListPane->SetItemState(i, 0, wxLIST_STATE_SELECTED); } - m_iSortedIndexes.Sort(m_funcSortCompare); + std::stable_sort(m_iSortedIndexes.begin(), m_iSortedIndexes.end(), m_funcSortCompare); // Reselect previously selected cache elements in the sorted list m = (int)selections.GetCount(); diff --git a/clientgui/BOINCBaseView.h b/clientgui/BOINCBaseView.h index eea0ea1ece..c4b968871a 100644 --- a/clientgui/BOINCBaseView.h +++ b/clientgui/BOINCBaseView.h @@ -70,7 +70,7 @@ public: std::vector m_Tasks; }; -typedef int (*ListSortCompareFunc)(int*, int*); +typedef bool (*ListSortCompareFunc)(int, int); class CBOINCBaseView : public wxPanel { diff --git a/clientgui/ViewProjects.cpp b/clientgui/ViewProjects.cpp index a58854b4fa..5fca528d01 100644 --- a/clientgui/ViewProjects.cpp +++ b/clientgui/ViewProjects.cpp @@ -92,9 +92,9 @@ END_EVENT_TABLE () static CViewProjects* myCViewProjects; -static int CompareViewProjectsItems(int *iRowIndex1, int *iRowIndex2) { - CProject* project1 = myCViewProjects->m_ProjectCache.at(*iRowIndex1); - CProject* project2 = myCViewProjects->m_ProjectCache.at(*iRowIndex2); +static bool CompareViewProjectsItems(int iRowIndex1, int iRowIndex2) { + CProject* project1 = myCViewProjects->m_ProjectCache.at(iRowIndex1); + CProject* project2 = myCViewProjects->m_ProjectCache.at(iRowIndex2); int result = 0; switch (myCViewProjects->m_iSortColumn) { @@ -133,7 +133,8 @@ static int CompareViewProjectsItems(int *iRowIndex1, int *iRowIndex2) { break; } - return (myCViewProjects->m_bReverseSort ? result * (-1) : result); + // Always return FALSE for equality (result == 0) + return (myCViewProjects->m_bReverseSort ? (result > 0) : (result <= 0)); } diff --git a/clientgui/ViewTransfers.cpp b/clientgui/ViewTransfers.cpp index de9e8aec1e..3414b75ce5 100644 --- a/clientgui/ViewTransfers.cpp +++ b/clientgui/ViewTransfers.cpp @@ -79,9 +79,9 @@ END_EVENT_TABLE () static CViewTransfers* MyCViewTransfers; -static int CompareViewTransferItems(int *iRowIndex1, int *iRowIndex2) { - CTransfer* transfer1 = MyCViewTransfers->m_TransferCache.at(*iRowIndex1); - CTransfer* transfer2 = MyCViewTransfers->m_TransferCache.at(*iRowIndex2); +static bool CompareViewTransferItems(int iRowIndex1, int iRowIndex2) { + CTransfer* transfer1 = MyCViewTransfers->m_TransferCache.at(iRowIndex1); + CTransfer* transfer2 = MyCViewTransfers->m_TransferCache.at(iRowIndex2); int result = 0; switch (MyCViewTransfers->m_iSortColumn) { @@ -124,7 +124,8 @@ static int CompareViewTransferItems(int *iRowIndex1, int *iRowIndex2) { break; } - return (MyCViewTransfers->m_bReverseSort ? result * (-1) : result); + // Always return FALSE for equality (result == 0) + return (MyCViewTransfers->m_bReverseSort ? (result > 0) : (result <= 0)); } diff --git a/clientgui/ViewWork.cpp b/clientgui/ViewWork.cpp index ef5986eaba..d06153ad53 100644 --- a/clientgui/ViewWork.cpp +++ b/clientgui/ViewWork.cpp @@ -91,10 +91,10 @@ END_EVENT_TABLE () static CViewWork* myCViewWork; -static int CompareViewWorkItems(int *iRowIndex1, int *iRowIndex2) { - CWork* work1 = myCViewWork->m_WorkCache.at(*iRowIndex1); - CWork* work2 = myCViewWork->m_WorkCache.at(*iRowIndex2); - int result = 0; +static bool CompareViewWorkItems(int iRowIndex1, int iRowIndex2) { + CWork* work1 = myCViewWork->m_WorkCache.at(iRowIndex1); + CWork* work2 = myCViewWork->m_WorkCache.at(iRowIndex2); + int result = false; switch (myCViewWork->m_iSortColumn) { case COLUMN_PROJECT: @@ -139,7 +139,8 @@ static int CompareViewWorkItems(int *iRowIndex1, int *iRowIndex2) { break; } - return (myCViewWork->m_bReverseSort ? result * (-1) : result); + // Always return FALSE for equality (result == 0) + return (myCViewWork->m_bReverseSort ? (result > 0) : (result < 0)); }