]> git.saurik.com Git - wxWidgets.git/commitdiff
Harmonize wxDataViewCtrl::GetSelection() behaviour in all ports.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 22 Aug 2011 12:41:19 +0000 (12:41 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 22 Aug 2011 12:41:19 +0000 (12:41 +0000)
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

16 files changed:
docs/changes.txt
include/wx/dataview.h
include/wx/generic/dataview.h
include/wx/gtk/dataview.h
include/wx/osx/carbon/dataview.h
include/wx/osx/cocoa/dataview.h
include/wx/osx/core/dataview.h
include/wx/osx/dataview.h
interface/wx/dataview.h
src/common/datavcmn.cpp
src/generic/datavgen.cpp
src/gtk/dataview.cpp
src/osx/carbon/dataview.cpp
src/osx/cocoa/dataview.mm
src/osx/dataview_osx.cpp
tests/controls/dataviewctrltest.cpp

index fd5ba917f5dbfb918a4c19221ed95699833cf54d..0e560db2783ad115dfa7662e93b1c7070dd6d1ea 100644 (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:
 
index c99fe07fe7a3053d6019fc296dfdd511ccb4863e..a1639f2533e0f1356f71a9faca8c8f14fba3173a 100644 (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;
index 51c0e590779c52625b79999d8ba0cc25711d5b63..ce3540749d662486b455527d852e7e203d6d4c8d 100644 (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 );
index 55beb85d484b24cfbbc691dd716b5afd1b03e157..8a4e12c3545dc2395de6c3810332517ccfa106e9 100644 (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 );
index b6d88a2661726aa317547eece7b9d851e5c6d42d..ca6a5e5ea4d625046fa139efc4216b46248732b5 100644 (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);
index 624c2cb3f746c9b7fa8a6df43fff60ab4270dad8..e4c5ef65d42bb261969a88839882f94f82719afa 100644 (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);
index 1a554d704b7ea232fa88aec58cc07c52eaadfa1c..20b0fe9bdde8b62e42aadfd3b0df32a46ec82e13 100644 (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
index e585fa01d39f0235bb6c28990067b33d1218b08c..883438001fd8aa40fdadc5b1812c5ace1112e4b8 100644 (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;
index 9c24be7d765cc04f8e2536464466c7b9f302baa7..0c06dae862881751c1d3e7a4d41cf8c1277b34ff 100644 (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.
     */
index 7c2f06f45733cac0648d05eb7918890c0e007d93..059b7df1b3f5ab6ab87e24807ca5a9b0fa48a710 100644 (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 )
index af9e477cb7df341a6e7d1581a5c5cc90eacb292a..582137ff02e39dd80776537f1683b62171f8e6ac 100644 (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
index b664d402d58257bab1283a061a0e987901c94980..a1b7a3ccbbf77fd5838450337afb733026a62ec8 100644 (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 )
index 2d316d9e0cb6e306cb2cb48d675b14faea68b250..dd288d8e17f243e3d549bb7c302b1d2694e09590 100644 (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;
index 148c9b0113fc0beed58e78275feedabb22b07537..f9600c916ed7bf0ae632b596076bb9ca587fc4a2 100644 (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]);
index c239ca35ffb4df386ec5725450743cc4b4eec18c..490f6d9fd71626c9fcb203823739877f8fda21d9 100644 (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
index a02aa313e71f9a835ff57443d3a1be777ee06de8..e62b1b95a86954a06ddb60ba3c466c490e3b7112 100644 (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