Fix spurious selection events generation in generic wxDataViewCtrl

Don't send a wxEVT_DATAVIEW_SELECTION_CHANGED event if an already selected
item is clicked, this is unexpected and inconsistent with the other platforms.

Split SelectAllRows(bool) method in a (trivial) SelectAllRows() and a more
useful UnselectAllRows() which now can check if a particular row is selected
and leave it selected in this case, helping implementing the correct logic and
also avoiding an extra unnecessary refresh due to deselecting the item first
and then selecting it again.
This commit is contained in:
Vadim Zeitlin
2016-02-06 02:04:00 +01:00
parent 189aedd89a
commit 73f2603917
2 changed files with 53 additions and 24 deletions

View File

@@ -183,6 +183,7 @@ wxMSW:
- Fix updating wxSlider background when its parent background changes. - Fix updating wxSlider background when its parent background changes.
- Implement wxListBox::EnsureVisible() (RIVDSL). - Implement wxListBox::EnsureVisible() (RIVDSL).
- Drastically improve efficiency of selecting all items in wxDataViewCtrl. - Drastically improve efficiency of selecting all items in wxDataViewCtrl.
- Fix spurious selection events generation in wxDataViewCtrl.
- Fix wxMenuEvent::GetMenu() for wxEVT_MENU_{OPEN,CLOSE} in MDI frames. - Fix wxMenuEvent::GetMenu() for wxEVT_MENU_{OPEN,CLOSE} in MDI frames.
- Fix updating wxSpinCtrlDouble tooltip text (Laurent Poujoulat). - Fix updating wxSpinCtrlDouble tooltip text (Laurent Poujoulat).
- Fix appearance of checked disabled wxToolBar tools with custom images. - Fix appearance of checked disabled wxToolBar tools with custom images.

View File

@@ -741,7 +741,18 @@ public:
const wxSelectionStore& GetSelections() const { return m_selection; } const wxSelectionStore& GetSelections() const { return m_selection; }
void ClearSelection() { m_selection.SelectRange(0, GetRowCount() - 1, false); } void ClearSelection() { m_selection.SelectRange(0, GetRowCount() - 1, false); }
void Select( const wxArrayInt& aSelections ); void Select( const wxArrayInt& aSelections );
void SelectAllRows( bool on );
void SelectAllRows()
{
m_selection.SelectRange(0, GetRowCount() - 1);
Refresh();
}
// If a valid row is specified and it was previously selected, it is left
// selected and the function returns false. Otherwise, i.e. if there is
// really no selection left in the control, it returns true.
bool UnselectAllRows(unsigned int except = (unsigned int)-1);
void SelectRow( unsigned int row, bool on ); void SelectRow( unsigned int row, bool on );
void SelectRows( unsigned int from, unsigned int to ); void SelectRows( unsigned int from, unsigned int to );
void ReverseRowSelection( unsigned int row ); void ReverseRowSelection( unsigned int row );
@@ -2726,25 +2737,36 @@ void wxDataViewMainWindow::ChangeCurrentRow( unsigned int row )
// send event // send event
} }
void wxDataViewMainWindow::SelectAllRows( bool on ) bool wxDataViewMainWindow::UnselectAllRows(unsigned int except)
{ {
if (IsEmpty()) if (!m_selection.IsEmpty())
return;
if (on)
{
m_selection.SelectRange(0, GetRowCount() - 1);
Refresh();
}
else if (!m_selection.IsEmpty())
{ {
for (unsigned i = GetFirstVisibleRow(); i <= GetLastVisibleRow(); i++) for (unsigned i = GetFirstVisibleRow(); i <= GetLastVisibleRow(); i++)
{ {
if (m_selection.IsSelected(i)) if (m_selection.IsSelected(i) && i != except)
RefreshRow(i); RefreshRow(i);
} }
ClearSelection();
if (except != (unsigned int)-1)
{
const bool wasSelected = m_selection.IsSelected(except);
ClearSelection();
if (wasSelected)
{
m_selection.SelectItem(except);
// The special item is still selected.
return false;
}
}
else
{
ClearSelection();
}
} }
// There are no selected items left.
return true;
} }
void wxDataViewMainWindow::SelectRow( unsigned int row, bool on ) void wxDataViewMainWindow::SelectRow( unsigned int row, bool on )
@@ -3837,7 +3859,7 @@ void wxDataViewMainWindow::OnVerticalNavigation(const wxKeyEvent& event, int del
// all previously selected items are unselected unless ctrl is held // all previously selected items are unselected unless ctrl is held
if ( !event.ControlDown() ) if ( !event.ControlDown() )
SelectAllRows(false); UnselectAllRows();
ChangeCurrentRow( newCurrent ); ChangeCurrentRow( newCurrent );
@@ -4264,9 +4286,12 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
if (m_lineSelectSingleOnUp != (unsigned int)-1) if (m_lineSelectSingleOnUp != (unsigned int)-1)
{ {
// select single line // select single line
SelectAllRows( false ); if ( UnselectAllRows(m_lineSelectSingleOnUp) )
SelectRow( m_lineSelectSingleOnUp, true ); {
SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) ); SelectRow( m_lineSelectSingleOnUp, true );
SendSelectionChangedEvent( GetItemByRow(m_lineSelectSingleOnUp) );
}
//else: it was already selected, nothing to do
} }
// If the user click the expander, we do not do editing even if the column // If the user click the expander, we do not do editing even if the column
@@ -4301,7 +4326,8 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
// Multi-selections should not be cleared if a selected item is clicked. // Multi-selections should not be cleared if a selected item is clicked.
if (!IsRowSelected(current)) if (!IsRowSelected(current))
{ {
SelectAllRows(false); UnselectAllRows();
const unsigned oldCurrent = m_currentRow; const unsigned oldCurrent = m_currentRow;
ChangeCurrentRow(current); ChangeCurrentRow(current);
SelectRow(m_currentRow,true); SelectRow(m_currentRow,true);
@@ -4338,10 +4364,12 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
{ {
if ( IsSingleSel() || !IsRowSelected(current) ) if ( IsSingleSel() || !IsRowSelected(current) )
{ {
SelectAllRows( false );
ChangeCurrentRow(current); ChangeCurrentRow(current);
SelectRow(m_currentRow,true); if ( UnselectAllRows(current) )
SendSelectionChangedEvent(GetItemByRow( m_currentRow ) ); {
SelectRow(m_currentRow,true);
SendSelectionChangedEvent(GetItemByRow( m_currentRow ) );
}
} }
else // multi sel & current is highlighted & no mod keys else // multi sel & current is highlighted & no mod keys
{ {
@@ -5185,7 +5213,7 @@ void wxDataViewCtrl::Select( const wxDataViewItem & item )
{ {
// Unselect all rows before select another in the single select mode // Unselect all rows before select another in the single select mode
if (m_clientArea->IsSingleSel()) if (m_clientArea->IsSingleSel())
m_clientArea->SelectAllRows(false); m_clientArea->UnselectAllRows();
m_clientArea->SelectRow(row, true); m_clientArea->SelectRow(row, true);
@@ -5218,12 +5246,12 @@ void wxDataViewCtrl::SetAlternateRowColour(const wxColour& colour)
void wxDataViewCtrl::SelectAll() void wxDataViewCtrl::SelectAll()
{ {
m_clientArea->SelectAllRows(true); m_clientArea->SelectAllRows();
} }
void wxDataViewCtrl::UnselectAll() void wxDataViewCtrl::UnselectAll()
{ {
m_clientArea->SelectAllRows(false); m_clientArea->UnselectAllRows();
} }
void wxDataViewCtrl::EnsureVisible( int row, int column ) void wxDataViewCtrl::EnsureVisible( int row, int column )