MGR List View: after sort, refresh only moved rows, start adding multiple selection support

svn path=/workspaces/wxListCtrl/; revision=15476
This commit is contained in:
Charlie Fenton 2008-06-26 01:25:31 +00:00
parent 4b885b2601
commit 2b12a255e8
5 changed files with 133 additions and 98 deletions

View File

@ -4925,3 +4925,12 @@ Charlie 24 June 2008
clientgui/
BOINCBaseView.cpp,h
ViewWork.cpp,h
Charlie 24 June 2008
- MGR List View: Move more functionality into base class. After sorting,
refresh only those rows which have moved. Begin implementing multiple
selections. Restore correct selections after sort.
clientgui/
BOINCBaseView.cpp,h
ViewWork.cpp,h

View File

@ -55,6 +55,8 @@ CBOINCBaseView::CBOINCBaseView(wxNotebook* pNotebook) :
//
m_pTaskPane = NULL;
m_pListPane = NULL;
m_iProgressColumn = -1;
m_iSortColumn = -1;
m_SortArrows = NULL;
SetName(GetViewName());
@ -480,7 +482,65 @@ bool CBOINCBaseView::SynchronizeCacheItem(wxInt32 iRowIndex, wxInt32 iColumnInde
}
void CBOINCBaseView::sortData() {}
void CBOINCBaseView::OnColClick(wxListEvent& event) {
wxListItem item;
int newSortColumn = event.GetColumn();
item.SetMask(wxLIST_MASK_IMAGE);
if (newSortColumn == m_iSortColumn) {
m_bReverseSort = !m_bReverseSort;
} else {
// Remove sort arrow from old sort column
if (m_iSortColumn >= 0) {
item.SetImage(-1);
m_pListPane->SetColumn(m_iSortColumn, item);
}
m_iSortColumn = newSortColumn;
m_bReverseSort = false;
}
item.SetImage(m_bReverseSort ? 0 : 1);
m_pListPane->SetColumn(newSortColumn, item);
sortData();
}
void CBOINCBaseView::sortData() {
if (m_iSortColumn < 0) return;
wxArrayInt oldSortedIndexes(m_iSortedIndexes);
wxArrayInt selections;
int i, j, m, n = m_iSortedIndexes.GetCount();
// Remember which cache elements are selected and deselect them
m_bIgnoreUIEvents = true;
i = -1;
while (1) {
i = m_pListPane->GetNextItem(i, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
if (i < 0) break;
selections.Add(m_iSortedIndexes[i]);
m_pListPane->SetItemState(i, 0, wxLIST_STATE_SELECTED);
}
m_iSortedIndexes.Sort(m_funcSortCompare);
// Reselect previously selected cache elements in the sorted list
m = selections.GetCount();
for (i=0; i<m; i++) {
if (selections[i] >= 0) {
j = m_iSortedIndexes.Index(selections[i]);
m_pListPane->SetItemState(j, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED);
}
}
m_bIgnoreUIEvents = false;
// Refresh rows which have moved
for (i=0; i<n; i++) {
if (m_iSortedIndexes[i] != oldSortedIndexes[i]) {
m_pListPane->RefreshItem(i);
}
}
}
int CBOINCBaseView::UpdateCache(

View File

@ -70,6 +70,8 @@ public:
std::vector<CTaskItem*> m_Tasks;
};
typedef int (*ListSortCompareFunc)(int*, int*);
class CBOINCBaseView : public wxPanel {
DECLARE_DYNAMIC_CLASS( CBOINCBaseView )
@ -116,8 +118,6 @@ public:
protected:
wxImageList * m_SortArrows;
virtual bool OnSaveState( wxConfigBase* pConfig );
virtual bool OnRestoreState( wxConfigBase* pConfig );
@ -128,6 +128,8 @@ protected:
virtual int OnListGetItemImage( long item ) const;
virtual wxListItemAttr* OnListGetItemAttr( long item ) const;
void OnColClick(wxListEvent& event);
virtual void OnGridSelectCell( wxGridEvent& event );
virtual void OnGridSelectRange( wxGridRangeSelectEvent& event );
@ -142,7 +144,7 @@ protected:
virtual int RemoveCacheElement();
virtual int SynchronizeCache();
virtual bool SynchronizeCacheItem(wxInt32 iRowIndex, wxInt32 iColumnIndex);
virtual void sortData();
void sortData();
virtual int UpdateCache( long item, long column, wxString& strNewData );
virtual void EmptyTasks();
@ -168,6 +170,10 @@ protected:
int m_iProgressColumn;
wxImageList * m_SortArrows;
ListSortCompareFunc m_funcSortCompare;
wxArrayInt m_iSortedIndexes;
CBOINCTaskCtrl* m_pTaskPane;
CBOINCListCtrl* m_pListPane;
};

View File

@ -88,13 +88,65 @@ 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;
switch (myCViewWork->m_iSortColumn) {
case COLUMN_PROJECT:
result = work1->m_strProjectName.CmpNoCase(work2->m_strProjectName);
break;
case COLUMN_APPLICATION:
result = work1->m_strApplicationName.CmpNoCase(work2->m_strApplicationName);
break;
case COLUMN_NAME:
result = work1->m_strName.CmpNoCase(work2->m_strName);
break;
case COLUMN_CPUTIME:
if (work1->m_fCPUTime < work2->m_fCPUTime) {
result = -1;
} else if (work1->m_fCPUTime > work2->m_fCPUTime) {
result = 1;
}
break;
case COLUMN_PROGRESS:
if (work1->m_fProgress < work2->m_fProgress) {
result = -1;
} else if (work1->m_fProgress > work2->m_fProgress) {
result = 1;
}
break;
case COLUMN_TOCOMPLETION:
if (work1->m_fTimeToCompletion < work2->m_fTimeToCompletion) {
result = -1;
} else if (work1->m_fTimeToCompletion > work2->m_fTimeToCompletion) {
result = 1;
}
break;
case COLUMN_REPORTDEADLINE:
if (work1->m_tReportDeadline < work2->m_tReportDeadline) {
result = -1;
} else if (work1->m_tReportDeadline > work2->m_tReportDeadline) {
result = 1;
}
break;
case COLUMN_STATUS:
result = work1->m_strStatus.CmpNoCase(work2->m_strStatus);
break;
}
return (myCViewWork->m_bReverseSort ? result * (-1) : result);
}
CViewWork::CViewWork()
{}
/*DEFAULT_LIST_SINGLE_SEL_FLAGS*/
CViewWork::CViewWork(wxNotebook* pNotebook) :
CBOINCBaseView(pNotebook, ID_TASK_WORKVIEW, DEFAULT_TASK_FLAGS, ID_LIST_WORKVIEW, DEFAULT_LIST_SINGLE_SEL_FLAGS)
CBOINCBaseView(pNotebook, ID_TASK_WORKVIEW, DEFAULT_TASK_FLAGS, ID_LIST_WORKVIEW, DEFAULT_LIST_MULTI_SEL_FLAGS)
{
CTaskItemGroup* pGroup = NULL;
CTaskItem* pItem = NULL;
@ -148,6 +200,7 @@ CViewWork::CViewWork(wxNotebook* pNotebook) :
// Needed by static sort routine;
myCViewWork = this;
m_funcSortCompare = CompareViewWorkItems;
UpdateSelection();
}
@ -511,95 +564,6 @@ void CViewWork::UpdateSelection() {
}
static int CompareViewWorkItems(int *iRowIndex1, int *iRowIndex2) {
CWork* work1 = myCViewWork->m_WorkCache.at(*iRowIndex1);
CWork* work2 = myCViewWork->m_WorkCache.at(*iRowIndex2);
int result = 0;
switch (myCViewWork->m_iSortColumn) {
case COLUMN_PROJECT:
result = work1->m_strProjectName.CmpNoCase(work2->m_strProjectName);
break;
case COLUMN_APPLICATION:
result = work1->m_strApplicationName.CmpNoCase(work2->m_strApplicationName);
break;
case COLUMN_NAME:
result = work1->m_strName.CmpNoCase(work2->m_strName);
break;
case COLUMN_CPUTIME:
if (work1->m_fCPUTime < work2->m_fCPUTime) {
result = -1;
} else if (work1->m_fCPUTime > work2->m_fCPUTime) {
result = 1;
}
break;
case COLUMN_PROGRESS:
if (work1->m_fProgress < work2->m_fProgress) {
result = -1;
} else if (work1->m_fProgress > work2->m_fProgress) {
result = 1;
}
break;
case COLUMN_TOCOMPLETION:
if (work1->m_fTimeToCompletion < work2->m_fTimeToCompletion) {
result = -1;
} else if (work1->m_fTimeToCompletion > work2->m_fTimeToCompletion) {
result = 1;
}
break;
case COLUMN_REPORTDEADLINE:
if (work1->m_tReportDeadline < work2->m_tReportDeadline) {
result = -1;
} else if (work1->m_tReportDeadline > work2->m_tReportDeadline) {
result = 1;
}
break;
case COLUMN_STATUS:
result = work1->m_strStatus.CmpNoCase(work2->m_strStatus);
break;
}
return (myCViewWork->m_bReverseSort ? result * (-1) : result);
}
void CViewWork::sortData() {
if (m_iSortColumn >= 0) {
CAdvancedFrame* pFrame = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
m_iSortedIndexes.Sort(CompareViewWorkItems);
pFrame->FireRefreshView();
}
}
void CViewWork::OnColClick(wxListEvent& event) {
wxListItem item;
int newSortColumn = event.GetColumn();
CAdvancedFrame* pFrame = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
item.SetMask(wxLIST_MASK_IMAGE);
if (newSortColumn == m_iSortColumn) {
m_bReverseSort = !m_bReverseSort;
} else {
// Remove sort arrow from old sort column
if (m_iSortColumn >= 0) {
item.SetImage(-1);
m_pListPane->SetColumn(m_iSortColumn, item);
}
m_iSortColumn = newSortColumn;
m_bReverseSort = false;
}
item.SetImage(m_bReverseSort ? 0 : 1);
m_pListPane->SetColumn(newSortColumn, item);
m_iSortedIndexes.Sort(CompareViewWorkItems);
pFrame->FireRefreshView();
}
bool CViewWork::SynchronizeCacheItem(wxInt32 iRowIndex, wxInt32 iColumnIndex) {
wxString strDocumentText = wxEmptyString;
float fDocumentFloat = 0.0;

View File

@ -65,10 +65,7 @@ public:
void OnProjectWebsiteClicked( wxEvent& event );
void OnColClick(wxListEvent& event);
std::vector<CWork*> m_WorkCache;
wxArrayInt m_iSortedIndexes;
protected:
@ -84,7 +81,6 @@ protected:
virtual wxInt32 RemoveCacheElement();
virtual wxInt32 UpdateCache( long item, long column, wxString& strNewData );
virtual bool SynchronizeCacheItem(wxInt32 iRowIndex, wxInt32 iColumnIndex);
virtual void sortData();
virtual void UpdateSelection();
void GetDocProjectName(wxInt32 item, wxString& strBuffer) const;