Harmonize wxDataViewCtrl::GetSelection() behaviour in all ports.

wxDataViewCtrl::GetSelection() now always returns invalid item if more than
a single item is selected in a multi-selection control.

Also add HasSelection() and GetSelectedItemsCount() to allow checking if any
items are selected.

Updated the documentation, all ports and added a test for all these functions.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68844 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2011-08-22 12:41:19 +00:00
parent c3ad4d4a45
commit fa93d732e2
16 changed files with 160 additions and 68 deletions

View File

@ -199,6 +199,10 @@ Changes in behaviour not resulting in compilation errors, please read this!
prevent the parent wxTopLevelWindow from interfering with the keyboard
handling of the window that captured the mouse.
- wxDataViewCtrl::GetSelection() now returns invalid item in all ports (this
behaved differently in wxMSW and wxGTK/wxOSX before) if more than one item
is selected in a control with wxDV_MULTIPLE style.
Changes in behaviour which may result in compilation errors
-----------------------------------------------------------
@ -458,6 +462,7 @@ All (GUI):
- Added customizable wxDocManager::OnMRUFileNotExist() virtual method.
- Fix stock labels when not using mnemonics for Chinese (cw.ahbong).
- Added wxComboBox::IsListEmpty() and IsTextEmpty().
- Added wxDataViewCtrl::GetSelectedItemsCount() and HasSelection().
OSX:

View File

@ -663,7 +663,15 @@ public:
wxDataViewItem GetCurrentItem() const;
void SetCurrentItem(const wxDataViewItem& item);
virtual wxDataViewItem GetSelection() const = 0;
// Selection: both GetSelection() and GetSelections() can be used for the
// controls both with and without wxDV_MULTIPLE style. For single selection
// controls GetSelections() is not very useful however. And for multi
// selection controls GetSelection() returns an invalid item if more than
// one item is selected. Use GetSelectedItemsCount() or HasSelection() to
// check if any items are selected at all.
virtual int GetSelectedItemsCount() const = 0;
bool HasSelection() const { return GetSelectedItemsCount() != 0; }
wxDataViewItem GetSelection() const;
virtual int GetSelections( wxDataViewItemArray & sel ) const = 0;
virtual void SetSelections( const wxDataViewItemArray & sel ) = 0;
virtual void Select( const wxDataViewItem & item ) = 0;

View File

@ -155,7 +155,7 @@ public:
virtual wxDataViewColumn *GetSortingColumn() const;
virtual wxDataViewItem GetSelection() const;
virtual int GetSelectedItemsCount() const;
virtual int GetSelections( wxDataViewItemArray & sel ) const;
virtual void SetSelections( const wxDataViewItemArray & sel );
virtual void Select( const wxDataViewItem & item );

View File

@ -142,7 +142,7 @@ public:
virtual wxDataViewColumn *GetSortingColumn() const;
virtual wxDataViewItem GetSelection() const;
virtual int GetSelectedItemsCount() const;
virtual int GetSelections( wxDataViewItemArray & sel ) const;
virtual void SetSelections( const wxDataViewItemArray & sel );
virtual void Select( const wxDataViewItem & item );

View File

@ -406,6 +406,7 @@ public:
//
virtual wxDataViewItem GetCurrentItem() const;
virtual void SetCurrentItem(const wxDataViewItem& item);
virtual int GetSelectedItemsCount() const;
virtual int GetSelections(wxDataViewItemArray& sel) const;
virtual bool IsSelected (wxDataViewItem const& item) const;
virtual void Select (wxDataViewItem const& item);

View File

@ -474,6 +474,7 @@ public:
//
virtual wxDataViewItem GetCurrentItem() const;
virtual void SetCurrentItem(const wxDataViewItem& item);
virtual int GetSelectedItemsCount() const;
virtual int GetSelections(wxDataViewItemArray& sel) const;
virtual bool IsSelected(const wxDataViewItem& item) const;
virtual void Select(const wxDataViewItem& item);

View File

@ -89,6 +89,7 @@ public:
virtual wxDataViewItem GetCurrentItem() const = 0;
virtual void SetCurrentItem(const wxDataViewItem& item) = 0;
virtual int GetSelectedItemsCount() const = 0;
virtual int GetSelections(wxDataViewItemArray& sel) const = 0; // returns all selected items in the native control
virtual bool IsSelected (wxDataViewItem const& item) const = 0; // checks if the passed item is selected in the native control
virtual void Select (wxDataViewItem const& item) = 0; // selects the passed item in the native control

View File

@ -176,7 +176,7 @@ public:
virtual unsigned int GetCount() const;
virtual wxRect GetItemRect(const wxDataViewItem& item, const wxDataViewColumn* columnPtr) const;
virtual wxDataViewItem GetSelection() const;
virtual int GetSelectedItemsCount() const;
virtual int GetSelections(wxDataViewItemArray& sel) const;
virtual void HitTest(const wxPoint& point, wxDataViewItem& item, wxDataViewColumn*& columnPtr) const;

View File

@ -1016,13 +1016,35 @@ public:
*/
wxDataViewModel* GetModel();
/**
Returns the number of currently selected items.
This method may be called for both the controls with single and
multiple selections and returns the number of selected item, possibly
0, in any case.
@since 2.9.3
*/
virtual int GetSelectedItemsCount() const;
/**
Returns first selected item or an invalid item if none is selected.
This method may be called for both the controls with single and
multiple selections but returns an invalid item if more than one item
is selected in the latter case, use HasSelection() to determine if
there are any selected items when using multiple selection.
*/
virtual wxDataViewItem GetSelection() const;
/**
Fills @a sel with currently selected items and returns their number.
This method may be called for both the controls with single and
multiple selections. In the single selection case it returns the array
with at most one element in it.
@see GetSelectedItemsCount()
*/
virtual int GetSelections(wxDataViewItemArray& sel) const;
@ -1032,6 +1054,20 @@ public:
*/
virtual wxDataViewColumn* GetSortingColumn() const;
/**
Returns true if any items are currently selected.
This method may be called for both the controls with single and
multiple selections.
Calling this method is equivalent to calling GetSelectedItemsCount()
and comparing its result with 0 but is more clear and might also be
implemented more efficiently in the future.
@since 2.9.3
*/
bool HasSelection() const;
/**
Hittest.
*/

View File

@ -1094,6 +1094,16 @@ void wxDataViewCtrlBase::SetCurrentItem(const wxDataViewItem& item)
Select(item);
}
wxDataViewItem wxDataViewCtrlBase::GetSelection() const
{
if ( GetSelectedItemsCount() != 1 )
return wxDataViewItem();
wxDataViewItemArray selections;
GetSelections(selections);
return selections[0];
}
wxDataViewColumn *
wxDataViewCtrlBase::AppendTextColumn( const wxString &label, unsigned int model_column,
wxDataViewCellMode mode, int width, wxAlignment align, int flags )

View File

@ -518,7 +518,6 @@ public:
unsigned int GetLastVisibleRow();
unsigned int GetRowCount();
wxDataViewItem GetSelection() const;
const wxDataViewSelection& GetSelections() const { return m_selection; }
void SetSelections( const wxDataViewSelection & sel )
{ m_selection = sel; UpdateDisplay(); }
@ -3962,14 +3961,6 @@ void wxDataViewMainWindow::OnKillFocus( wxFocusEvent &event )
event.Skip();
}
wxDataViewItem wxDataViewMainWindow::GetSelection() const
{
if( m_selection.GetCount() != 1 )
return wxDataViewItem();
return GetItemByRow( m_selection.Item(0));
}
//-----------------------------------------------------------------------------
// wxDataViewCtrl
//-----------------------------------------------------------------------------
@ -4486,10 +4477,9 @@ void wxDataViewCtrl::DoSetCurrentItem(const wxDataViewItem& item)
}
}
// Selection code with wxDataViewItem as parameters
wxDataViewItem wxDataViewCtrl::GetSelection() const
int wxDataViewCtrl::GetSelectedItemsCount() const
{
return m_clientArea->GetSelection();
return m_clientArea->GetSelections().size();
}
int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const

View File

@ -4930,39 +4930,11 @@ void wxDataViewCtrl::StartEditor(const wxDataViewItem& item, unsigned int column
gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_treeview), path, gcolumn, TRUE);
}
wxDataViewItem wxDataViewCtrl::GetSelection() const
int wxDataViewCtrl::GetSelectedItemsCount() const
{
GtkTreeSelection *selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(m_treeview) );
if (m_windowStyle & wxDV_MULTIPLE)
{
// Report the first one
GtkTreeModel *model;
GList *list = gtk_tree_selection_get_selected_rows( selection, &model );
if (list)
{
GtkTreePath *path = (GtkTreePath*) list->data;
wxDataViewItem item(GTKPathToItem(path));
// delete list
g_list_foreach( list, (GFunc) gtk_tree_path_free, NULL );
g_list_free( list );
return item;
}
}
else
{
GtkTreeIter iter;
if (gtk_tree_selection_get_selected( selection, NULL, &iter ))
{
wxDataViewItem item( iter.user_data );
return item;
}
}
return wxDataViewItem(0);
return gtk_tree_selection_count_selected_rows(selection);
}
int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
@ -4975,30 +4947,23 @@ int wxDataViewCtrl::GetSelections( wxDataViewItemArray & sel ) const
GtkTreeModel *model;
wxGtkTreePathList list(gtk_tree_selection_get_selected_rows(selection, &model));
int count = 0;
for ( GList* current = list; current; current = g_list_next(current) )
{
GtkTreePath *path = (GtkTreePath*) list->data;
GtkTreePath *path = (GtkTreePath*) current->data;
sel.Add(GTKPathToItem(path));
count++;
}
return count;
}
else
{
GtkTreeModel *model;
GtkTreeIter iter;
gboolean has_selection = gtk_tree_selection_get_selected( selection, &model, &iter );
if (has_selection)
if (gtk_tree_selection_get_selected( selection, NULL, &iter ))
{
sel.Add( wxDataViewItem( (void*) iter.user_data) );
return 1;
sel.Add( wxDataViewItem(iter.user_data) );
}
}
return 0;
return sel.size();
}
void wxDataViewCtrl::SetSelections( const wxDataViewItemArray & sel )

View File

@ -1107,6 +1107,23 @@ void wxMacDataViewDataBrowserListViewControl::SetCurrentItem(const wxDataViewIte
wxFAIL_MSG( "unimplemented for Carbon" );
}
int wxMacDataViewDataBrowserListViewControl::GetSelectedItemsCount() const
{
Handle handle(::NewHandle(0));
if ( GetItems(kDataBrowserNoItem,true,kDataBrowserItemIsSelected,handle) != noErr )
{
wxFAIL_MSG( "failed to get selected items" );
return 0;
}
size_t noOfItems = static_cast<size_t>(::GetHandleSize(handle)/sizeof(DataBrowserItemID));
HUnlock(handle);
DisposeHandle(handle);
return noOfItems;
}
int wxMacDataViewDataBrowserListViewControl::GetSelections(wxDataViewItemArray& sel) const
{
size_t noOfSelectedItems;

View File

@ -2265,6 +2265,11 @@ void wxCocoaDataViewControl::SetCurrentItem(const wxDataViewItem& item)
Select(item);
}
int wxCocoaDataViewControl::GetSelectedItemsCount() const
{
return [m_OutlineView numberOfSelectedRows];
}
int wxCocoaDataViewControl::GetSelections(wxDataViewItemArray& sel) const
{
NSIndexSet* selectedRowIndexes([m_OutlineView selectedRowIndexes]);

View File

@ -535,15 +535,9 @@ wxRect wxDataViewCtrl::GetItemRect(wxDataViewItem const& item, wxDataViewColumn
return wxRect();
}
wxDataViewItem wxDataViewCtrl::GetSelection() const
int wxDataViewCtrl::GetSelectedItemsCount() const
{
wxDataViewItemArray itemIDs;
if (GetDataViewPeer()->GetSelections(itemIDs) > 0)
return itemIDs[0];
else
return wxDataViewItem();
return GetDataViewPeer()->GetSelectedItemsCount();
}
int wxDataViewCtrl::GetSelections(wxDataViewItemArray& sel) const

View File

@ -40,10 +40,19 @@ private:
CPPUNIT_TEST_SUITE( DataViewCtrlTestCase );
CPPUNIT_TEST( DeleteSelected );
CPPUNIT_TEST( DeleteNotSelected );
CPPUNIT_TEST( GetSelectionForMulti );
CPPUNIT_TEST( GetSelectionForSingle );
CPPUNIT_TEST_SUITE_END();
// Create wxDataViewTreeCtrl with the given style.
void Create(long style);
void DeleteSelected();
void DeleteNotSelected();
void GetSelectionForMulti();
void GetSelectionForSingle();
void TestSelectionFor0and1();
// the dataview control itself
wxDataViewTreeCtrl *m_dvc;
@ -67,13 +76,13 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( DataViewCtrlTestCase, "DataViewCtrlTestCa
// test initialization
// ----------------------------------------------------------------------------
void DataViewCtrlTestCase::setUp()
void DataViewCtrlTestCase::Create(long style)
{
m_dvc = new wxDataViewTreeCtrl(wxTheApp->GetTopWindow(),
wxID_ANY,
wxDefaultPosition,
wxSize(400, 200),
wxDV_MULTIPLE);
style);
m_root = m_dvc->AppendContainer(wxDataViewItem(), "The root");
m_child1 = m_dvc->AppendContainer(m_root, "child1");
@ -86,6 +95,11 @@ void DataViewCtrlTestCase::setUp()
m_dvc->Update();
}
void DataViewCtrlTestCase::setUp()
{
Create(wxDV_MULTIPLE);
}
void DataViewCtrlTestCase::tearDown()
{
delete m_dvc;
@ -131,10 +145,55 @@ void DataViewCtrlTestCase::DeleteNotSelected()
m_dvc->GetSelections(sel);
// m_child1 and its children should be removed from the selection now
// m_child1 and its children should be unaffected
CPPUNIT_ASSERT_EQUAL( 2, sel.size() );
CPPUNIT_ASSERT( sel[0] == m_child1 );
CPPUNIT_ASSERT( sel[1] == m_grandchild );
}
void DataViewCtrlTestCase::TestSelectionFor0and1()
{
wxDataViewItemArray selections;
// Initially there is no selection.
CPPUNIT_ASSERT_EQUAL( 0, m_dvc->GetSelectedItemsCount() );
CPPUNIT_ASSERT( !m_dvc->HasSelection() );
CPPUNIT_ASSERT( !m_dvc->GetSelection().IsOk() );
CPPUNIT_ASSERT( !m_dvc->GetSelections(selections) );
CPPUNIT_ASSERT( selections.empty() );
// Select one item.
m_dvc->Select(m_child1);
CPPUNIT_ASSERT_EQUAL( 1, m_dvc->GetSelectedItemsCount() );
CPPUNIT_ASSERT( m_dvc->HasSelection() );
CPPUNIT_ASSERT( m_dvc->GetSelection().IsOk() );
CPPUNIT_ASSERT_EQUAL( 1, m_dvc->GetSelections(selections) );
CPPUNIT_ASSERT( selections[0] == m_child1 );
}
void DataViewCtrlTestCase::GetSelectionForMulti()
{
wxDataViewItemArray selections;
TestSelectionFor0and1();
// Also test with more than one selected item.
m_dvc->Select(m_child2);
CPPUNIT_ASSERT_EQUAL( 2, m_dvc->GetSelectedItemsCount() );
CPPUNIT_ASSERT( m_dvc->HasSelection() );
CPPUNIT_ASSERT( !m_dvc->GetSelection().IsOk() );
CPPUNIT_ASSERT_EQUAL( 2, m_dvc->GetSelections(selections) );
CPPUNIT_ASSERT( selections[1] == m_child2 );
}
void DataViewCtrlTestCase::GetSelectionForSingle()
{
delete m_dvc;
Create(0);
TestSelectionFor0and1();
}
#endif //wxUSE_TREECTRL