MGR: Grid views: When order of rows changes, reselect same data in new rows; update buttons when selected row is deleted.

svn path=/trunk/boinc/; revision=14844
This commit is contained in:
Charlie Fenton 2008-03-05 07:13:53 +00:00
parent 0daec9a557
commit 1dcc71e035
7 changed files with 84 additions and 40 deletions

View File

@ -1873,6 +1873,21 @@ Charlie Mar 4 2008
The other tabs disabled all buttons when multiple items were
selected, so allowing multiple selections was confusing to
users.
- MGR: When order of rows in grid views changes (due to sorting or
changes in data), reselect the same data in the rearranged rows
using:
Projects tab: project name only
Tasks tab: project name and work unit (task) name
Transfers tab: project name and file name
Messages tab: sequence number only.
- MGR: set m_bForceUpdateSelection=true when deleting rows from grid
views. Fixes bug: if the last row was selected and is deleted,
the new last row is automatically selected but the buttons were
not updated to reflect the new selection.
clientgui/
ViewTransfersGrid.cpp,h
BOINCGridGtrl.cpp,h
ViewMessagesGrid.cpp
ViewProjectsGrid.cpp
ViewTransfersGrid.cpp
ViewWorkGrid.cpp

View File

@ -130,9 +130,13 @@ CBOINCGridCtrl::CBOINCGridCtrl(wxWindow* parent, wxWindowID iGridWindowID) : wxG
sortColumn=-1;
sortAscending=true;
sortNeededByLabelClick=false;
m_pkColumnIndex=-1;
m_pkColumnIndex1=-1;
m_pkColumnIndex2=-1;
m_cursorcol=-1;
m_cursorrow=-1;
m_cursorrow=-1;
m_arrSelectedKeys1.Clear();
m_arrSelectedKeys2.Clear();
//load sorting bitmaps
ascBitmap = wxBitmap(sortascending_xpm);
descBitmap = wxBitmap(sortdescending_xpm);
@ -185,8 +189,9 @@ wxArrayInt CBOINCGridCtrl::GetSelectedRows2() {
}
/* sets the column with unique values */
void CBOINCGridCtrl::SetPrimaryKeyColumn(int col) {
m_pkColumnIndex = col;
void CBOINCGridCtrl::SetPrimaryKeyColumns(int col1,int col2) {
m_pkColumnIndex1 = col1;
m_pkColumnIndex2 = col2;
}
/* If the user clicked inside the grid, the former selected cells must be deselected.
@ -195,16 +200,22 @@ void CBOINCGridCtrl::SetPrimaryKeyColumn(int col) {
*/
void CBOINCGridCtrl::ClearSavedSelection() {
if(this->GetBatchCount()<=0) {
m_arrSelectedKeys.Empty();
m_arrSelectedKeys1.Empty();
m_arrSelectedKeys2.Empty();
}
}
/* save the key values of the currently selected rows for later restore */
void CBOINCGridCtrl::SaveSelection() {
if(m_pkColumnIndex>=0) {
if(m_pkColumnIndex1>=0) {
wxArrayInt arrSelRows = GetSelectedRows2();
m_arrSelectedKeys1.Empty();
m_arrSelectedKeys2.Empty();
for(unsigned int i=0; i< arrSelRows.GetCount();i++) {
m_arrSelectedKeys.Add(GetCellValue(arrSelRows[i],m_pkColumnIndex));
m_arrSelectedKeys1.Add(GetCellValue(arrSelRows[i],m_pkColumnIndex1));
if (m_pkColumnIndex2 >= 0) {
m_arrSelectedKeys2.Add(GetCellValue(arrSelRows[i],m_pkColumnIndex2));
}
}
}
}
@ -212,9 +223,11 @@ void CBOINCGridCtrl::SaveSelection() {
/* select all rows, that were formerly selected
this raises selection events without user interaction */
void CBOINCGridCtrl::RestoreSelection() {
ClearSelection();
for(unsigned int i=0;i < m_arrSelectedKeys.size();i++) {
int index = GetTable()->FindRowIndexByColValue(m_pkColumnIndex,m_arrSelectedKeys[i]);
// ClearSelection();
for(unsigned int i=0;i < m_arrSelectedKeys1.size();i++) {
int index = GetTable()->FindRowIndexByColValue(
m_pkColumnIndex1,m_arrSelectedKeys1[i],m_pkColumnIndex2,m_arrSelectedKeys2[i]
);
if(index >=0) {
SelectRow(index,true);
}
@ -225,12 +238,15 @@ void CBOINCGridCtrl::SaveGridCursorPosition() {
m_cursorcol = GetGridCursorCol();
m_cursorrow = GetGridCursorRow();
if(m_cursorrow>=0 && m_cursorcol >=0) {
m_szCursorKey = GetCellValue(m_cursorrow,m_pkColumnIndex);
m_szCursorKey1 = GetCellValue(m_cursorrow,m_pkColumnIndex1);
if (m_pkColumnIndex2 >= 0) {
m_szCursorKey2 = GetCellValue(m_cursorrow,m_pkColumnIndex2);
}
}
}
void CBOINCGridCtrl::RestoreGridCursorPosition() {
int index = GetTable()->FindRowIndexByColValue(m_pkColumnIndex,m_szCursorKey);
int index = GetTable()->FindRowIndexByColValue(m_pkColumnIndex1,m_szCursorKey1,m_pkColumnIndex2,m_szCursorKey2);
if(index >=0) {
SetGridCursor(index,m_cursorcol);
}
@ -571,8 +587,7 @@ void CBOINCGridCtrl::OnLabelLClick(wxGridEvent& ev) {
wxTimerEvent tEvent;
wxDynamicCast(GetParent(),CBOINCBaseView)->FireOnListRender(tEvent);
}
ev.Skip();
// The base class calls ClearSelection(), so do NOT call ev.Skip();
}
void CBOINCGridCtrl::SortData() {
@ -869,7 +884,7 @@ void CBOINCGridTable::SortData(int col,bool ascending) {
wxGridStringArray newArray;
for(unsigned int i=0; i< arColValues.GetCount();i++) {
//find the original row index
int indexold = FindRowIndexByColValue(col,arColValues[i]);
int indexold = FindRowIndexByColValue(col,arColValues[i],-1,arColValues[i]);
wxArrayString rowArray;
for(int j=0; j < this->GetNumberCols(); j++) {
rowArray.Add(this->GetValue(indexold,j));
@ -888,16 +903,16 @@ void CBOINCGridTable::SortData(int col,bool ascending) {
}
}
/* finds the first row index for the cell value value in column col
!! only use this (outside sorting method) with a column, that has unique values !!
/* finds the first row index for the cell with value value1 in column col1 and value2 in col2
ignores col2 and value2 if col2 < 0
!! only use this (outside sorting method) with a pair of columns, that have unique value pairs !!
*/
int CBOINCGridTable::FindRowIndexByColValue(int col,wxString& value) {
int CBOINCGridTable::FindRowIndexByColValue(int col1,wxString& value1,int col2,wxString& value2) {
for(int i=0; i < this->GetNumberRows(); i++) {
wxString curr = GetValue(i,col);
if(this->GetValue(i,col).IsSameAs(value)) {
return i;
}
if(! this->GetValue(i,col1).IsSameAs(value1)) continue;
if (col2 < 0) return i;
if(this->GetValue(i,col2).IsSameAs(value2)) return i;
}
return -1;
}

View File

@ -67,7 +67,7 @@ public:
CBOINCGridTable(int rows,int cols);
virtual ~CBOINCGridTable();
void SortData(int col,bool ascending);
int FindRowIndexByColValue(int col,wxString& value);
int FindRowIndexByColValue(int col1,wxString& value1,int col2,wxString& value2);
void SetColumnSortType(int col,int sortType=CST_STRING);
private:
wxArrayInt arrColumnSortTypes;
@ -98,7 +98,7 @@ public:
wxArrayInt GetSelectedRows2();
CBOINCGridTable* GetTable();
//methods to handle selection and grid cursor positions correct with sorting
void SetPrimaryKeyColumn(int col);
void SetPrimaryKeyColumns(int col1,int col2);
void SaveSelection();
void RestoreSelection();
void SaveGridCursorPosition();
@ -117,11 +117,14 @@ private:
int ccollast,crowlast;
wxBitmap ascBitmap;
wxBitmap descBitmap;
int m_pkColumnIndex;//col index act as a primary key
wxArrayString m_arrSelectedKeys;//array for remembering the current selected rows by primary key column value
int m_pkColumnIndex1; //col index to use as a primary key
int m_pkColumnIndex2; //col index to use as secondary key
wxArrayString m_arrSelectedKeys1;//array for remembering the current selected rows by primary key column value
wxArrayString m_arrSelectedKeys2;//array for remembering the current selected rows by secondary key column value
int m_cursorcol; //saved grid cursor column index
int m_cursorrow; //saved grid cursor row index
wxString m_szCursorKey;//key value for grid cursor cell
wxString m_szCursorKey1;//primary key value for grid cursor cell
wxString m_szCursorKey2;//secondary key value for grid cursor cell
};
#endif //_BOINCGRIDCTRL_H_

View File

@ -142,7 +142,7 @@ CViewMessagesGrid::CViewMessagesGrid(wxNotebook* pNotebook) :
m_pGridPane->SetColumnSortType(COLUMN_TIME,CST_TIME);
m_pGridPane->SetColumnSortType(COLUMN_SEQNO,CST_LONG);
//set primary key column index
m_pGridPane->SetPrimaryKeyColumn(COLUMN_SEQNO);
m_pGridPane->SetPrimaryKeyColumns(COLUMN_SEQNO,-1);
UpdateSelection();
}

View File

@ -176,7 +176,7 @@ CViewProjectsGrid::CViewProjectsGrid(wxNotebook* pNotebook) :
m_pGridPane->SetColumnSortType(COLUMN_RESOURCESHARE,CST_FLOAT);
m_pGridPane->SetColumnSortType(COLUMN_AVGCREDIT,CST_FLOAT);
//
m_pGridPane->SetPrimaryKeyColumn(COLUMN_PROJECT);
m_pGridPane->SetPrimaryKeyColumns(COLUMN_PROJECT,-1);
UpdateSelection();
}
@ -771,12 +771,15 @@ void CViewProjectsGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
if(docCount != m_pGridPane->GetNumberRows()) {
if (docCount > m_pGridPane->GetNumberRows()) {
m_pGridPane->AppendRows(docCount - m_pGridPane->GetNumberRows());
} else {
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
} else {
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
m_bForceUpdateSelection = true;
}
wxASSERT(docCount == m_pGridPane->GetNumberRows());
}
m_pGridPane->SaveSelection();
wxString strBuffer;
int iMax = m_pGridPane->GetNumberRows();
for(int iRow = 0; iRow < iMax; iRow++) {
@ -821,7 +824,8 @@ void CViewProjectsGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
m_pGridPane->SortData();
UpdateSelection();
m_pGridPane->RestoreSelection();
UpdateSelection();
wxLogTrace(wxT("Function Start/End"), wxT("CViewProjectsGrid::OnListRender - Function End"));
}

View File

@ -140,7 +140,7 @@ CViewTransfersGrid::CViewTransfersGrid(wxNotebook* pNotebook) :
//m_pGridPane->SetColumnSortType(COLUMN_SIZE,CST_FLOAT);
m_pGridPane->SetColumnSortType(COLUMN_SPEED,CST_FLOAT);
//set primary key column index
m_pGridPane->SetPrimaryKeyColumn(COLUMN_FILE);
m_pGridPane->SetPrimaryKeyColumns(COLUMN_FILE,COLUMN_PROJECT);
UpdateSelection();
}
@ -485,11 +485,14 @@ void CViewTransfersGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
if (docCount > m_pGridPane->GetNumberRows()) {
m_pGridPane->AppendRows(docCount - m_pGridPane->GetNumberRows());
} else {
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
m_bForceUpdateSelection = true;
}
wxASSERT(docCount == m_pGridPane->GetNumberRows());
}
m_pGridPane->SaveSelection();
//update cell values
wxString strBuffer;
int iMax = m_pGridPane->GetNumberRows();
@ -535,6 +538,7 @@ void CViewTransfersGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
m_pGridPane->SortData();
m_pGridPane->RestoreSelection();
UpdateSelection();
}

View File

@ -160,7 +160,7 @@ CViewWorkGrid::CViewWorkGrid(wxNotebook* pNotebook) :
m_pGridPane->SetColumnSortType(COLUMN_REPORTDEADLINE,CST_DATETIME);
m_pGridPane->SetColumnSortType(COLUMN_RESULTS_INDEX,CST_LONG);
//set primary key column index
m_pGridPane->SetPrimaryKeyColumn(COLUMN_NAME);
m_pGridPane->SetPrimaryKeyColumns(COLUMN_NAME,COLUMN_PROJECT);
// Hide the Index column
int min_width = m_pGridPane->GetColMinimalAcceptableWidth();
m_pGridPane->SetColMinimalAcceptableWidth(0);
@ -845,8 +845,8 @@ void CViewWorkGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
return;
}
// flag for row count changes
bool rowCountChanged=false;
// flag for row count changes
bool rowCountChanged=false;
// Right-size the grid so that the number of rows matches
// the document state.
if(docCount != m_pGridPane->GetNumberRows()) {
@ -854,8 +854,9 @@ void CViewWorkGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
m_pGridPane->AppendRows(docCount - m_pGridPane->GetNumberRows());
rowCountChanged=true;
} else {
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
m_pGridPane->DeleteRows(0, m_pGridPane->GetNumberRows() - docCount);
rowCountChanged=true;
m_bForceUpdateSelection = true;
}
wxASSERT(docCount == m_pGridPane->GetNumberRows());
}
@ -938,7 +939,8 @@ void CViewWorkGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
m_pGridPane->sortNeededByLabelClick)
{
wxArrayString ordered_indexes;
for(int iRow = 0; iRow < iMax; iRow++) {
m_pGridPane->SaveSelection();
for(int iRow = 0; iRow < iMax; iRow++) {
ordered_indexes.Add(m_pGridPane->GetCellValue(iRow, COLUMN_RESULTS_INDEX));
}
@ -947,6 +949,7 @@ void CViewWorkGrid::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
for(int iRow = 0; iRow < iMax; iRow++) {
if (ordered_indexes[iRow] != m_pGridPane->GetCellValue(iRow, COLUMN_RESULTS_INDEX)) {
// Refresh entire grid if sort order has changed
m_pGridPane->RestoreSelection();
m_pGridPane->ForceRefresh();
break;
}