diff --git a/checkin_notes b/checkin_notes index d0fee2b3d7..2f3bbc0deb 100644 --- a/checkin_notes +++ b/checkin_notes @@ -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 diff --git a/clientgui/BOINCBaseView.cpp b/clientgui/BOINCBaseView.cpp index aef394b97f..af5edab7fc 100644 --- a/clientgui/BOINCBaseView.cpp +++ b/clientgui/BOINCBaseView.cpp @@ -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= 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; iRefreshItem(i); + } + } +} int CBOINCBaseView::UpdateCache( diff --git a/clientgui/BOINCBaseView.h b/clientgui/BOINCBaseView.h index 3018282fc1..c50ddb3c30 100644 --- a/clientgui/BOINCBaseView.h +++ b/clientgui/BOINCBaseView.h @@ -70,6 +70,8 @@ public: std::vector 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; }; diff --git a/clientgui/ViewWork.cpp b/clientgui/ViewWork.cpp index 1647c612f6..44d6224570 100644 --- a/clientgui/ViewWork.cpp +++ b/clientgui/ViewWork.cpp @@ -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; diff --git a/clientgui/ViewWork.h b/clientgui/ViewWork.h index eff595c09e..87ea48cfee 100644 --- a/clientgui/ViewWork.h +++ b/clientgui/ViewWork.h @@ -65,10 +65,7 @@ public: void OnProjectWebsiteClicked( wxEvent& event ); - void OnColClick(wxListEvent& event); - std::vector 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;