]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treelist.cpp
Correcting typo in commit 69203
[wxWidgets.git] / src / generic / treelist.cpp
index 806ae748bae7359a2580997b0f3613989632ac73..6063ccf0a6f9c8ebe0da6ea8000b5c871642482d 100644 (file)
@@ -378,6 +378,10 @@ public:
     virtual unsigned GetChildren(const wxDataViewItem& item,
                                  wxDataViewItemArray& children) const;
     virtual bool IsListModel() const { return m_isFlat; }
+    virtual int Compare(const wxDataViewItem& item1,
+                        const wxDataViewItem& item2,
+                        unsigned col,
+                        bool ascending) const;
 
 private:
     // The control we're associated with.
@@ -953,6 +957,27 @@ wxTreeListModel::GetChildren(const wxDataViewItem& item,
     return numChildren;
 }
 
+int
+wxTreeListModel::Compare(const wxDataViewItem& item1,
+                         const wxDataViewItem& item2,
+                         unsigned col,
+                         bool ascending) const
+{
+    // Compare using default alphabetical order if no custom comparator.
+    wxTreeListItemComparator* const comp = m_treelist->m_comparator;
+    if ( !comp )
+        return wxDataViewModel::Compare(item1, item2, col, ascending);
+
+    // Forward comparison to the comparator:
+    int result = comp->Compare(m_treelist, col, FromDVI(item1), FromDVI(item2));
+
+    // And adjust by the sort order if necessary.
+    if ( !ascending )
+        result = -result;
+
+    return result;
+}
+
 // ============================================================================
 // wxTreeListCtrl implementation
 // ============================================================================
@@ -963,6 +988,7 @@ BEGIN_EVENT_TABLE(wxTreeListCtrl, wxWindow)
     EVT_DATAVIEW_ITEM_EXPANDED(wxID_ANY, wxTreeListCtrl::OnItemExpanded)
     EVT_DATAVIEW_ITEM_ACTIVATED(wxID_ANY, wxTreeListCtrl::OnItemActivated)
     EVT_DATAVIEW_ITEM_CONTEXT_MENU(wxID_ANY, wxTreeListCtrl::OnItemContextMenu)
+    EVT_DATAVIEW_COLUMN_SORTED(wxID_ANY, wxTreeListCtrl::OnColumnSorted)
 
     EVT_SIZE(wxTreeListCtrl::OnSize)
 END_EVENT_TABLE()
@@ -975,6 +1001,7 @@ void wxTreeListCtrl::Init()
 {
     m_view = NULL;
     m_model = NULL;
+    m_comparator = NULL;
 }
 
 bool wxTreeListCtrl::Create(wxWindow* parent,
@@ -1454,11 +1481,48 @@ wxTreeListCtrl::AreAllChildrenInState(wxTreeListItem item,
     return true;
 }
 
+// ----------------------------------------------------------------------------
+// Sorting
+// ----------------------------------------------------------------------------
+
+void wxTreeListCtrl::SetSortColumn(unsigned col, bool ascendingOrder)
+{
+    wxCHECK_RET( col < m_view->GetColumnCount(), "Invalid column index" );
+
+    m_view->GetColumn(col)->SetSortOrder(ascendingOrder);
+}
+
+bool wxTreeListCtrl::GetSortColumn(unsigned* col, bool* ascendingOrder)
+{
+    const unsigned numColumns = m_view->GetColumnCount();
+    for ( unsigned n = 0; n < numColumns; n++ )
+    {
+        wxDataViewColumn* const column = m_view->GetColumn(n);
+        if ( column->IsSortKey() )
+        {
+            if ( col )
+                *col = n;
+
+            if ( ascendingOrder )
+                *ascendingOrder = column->IsSortOrderAscending();
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void wxTreeListCtrl::SetItemComparator(wxTreeListItemComparator* comparator)
+{
+    m_comparator = comparator;
+}
+
 // ----------------------------------------------------------------------------
 // Events
 // ----------------------------------------------------------------------------
 
-void wxTreeListCtrl::SendEvent(wxEventType evt, wxDataViewEvent& eventDV)
+void wxTreeListCtrl::SendItemEvent(wxEventType evt, wxDataViewEvent& eventDV)
 {
     wxTreeListEvent eventTL(evt, this, m_model->FromDVI(eventDV.GetItem()));
 
@@ -1474,6 +1538,23 @@ void wxTreeListCtrl::SendEvent(wxEventType evt, wxDataViewEvent& eventDV)
     }
 }
 
+void wxTreeListCtrl::SendColumnEvent(wxEventType evt, wxDataViewEvent& eventDV)
+{
+    wxTreeListEvent eventTL(evt, this, wxTreeListItem());
+    eventTL.SetColumn(eventDV.GetColumn());
+
+    if ( !ProcessWindowEvent(eventTL) )
+    {
+        eventDV.Skip();
+        return;
+    }
+
+    if ( !eventTL.IsAllowed() )
+    {
+        eventDV.Veto();
+    }
+}
+
 void
 wxTreeListCtrl::OnItemToggled(wxTreeListItem item, wxCheckBoxState stateOld)
 {
@@ -1485,27 +1566,32 @@ wxTreeListCtrl::OnItemToggled(wxTreeListItem item, wxCheckBoxState stateOld)
 
 void wxTreeListCtrl::OnSelectionChanged(wxDataViewEvent& event)
 {
-    SendEvent(wxEVT_COMMAND_TREELIST_SELECTION_CHANGED, event);
+    SendItemEvent(wxEVT_COMMAND_TREELIST_SELECTION_CHANGED, event);
 }
 
 void wxTreeListCtrl::OnItemExpanding(wxDataViewEvent& event)
 {
-    SendEvent(wxEVT_COMMAND_TREELIST_ITEM_EXPANDING, event);
+    SendItemEvent(wxEVT_COMMAND_TREELIST_ITEM_EXPANDING, event);
 }
 
 void wxTreeListCtrl::OnItemExpanded(wxDataViewEvent& event)
 {
-    SendEvent(wxEVT_COMMAND_TREELIST_ITEM_EXPANDED, event);
+    SendItemEvent(wxEVT_COMMAND_TREELIST_ITEM_EXPANDED, event);
 }
 
 void wxTreeListCtrl::OnItemActivated(wxDataViewEvent& event)
 {
-    SendEvent(wxEVT_COMMAND_TREELIST_ITEM_ACTIVATED, event);
+    SendItemEvent(wxEVT_COMMAND_TREELIST_ITEM_ACTIVATED, event);
 }
 
 void wxTreeListCtrl::OnItemContextMenu(wxDataViewEvent& event)
 {
-    SendEvent(wxEVT_COMMAND_TREELIST_ITEM_CONTEXT_MENU, event);
+    SendItemEvent(wxEVT_COMMAND_TREELIST_ITEM_CONTEXT_MENU, event);
+}
+
+void wxTreeListCtrl::OnColumnSorted(wxDataViewEvent& event)
+{
+    SendColumnEvent(wxEVT_COMMAND_TREELIST_COLUMN_SORTED, event);
 }
 
 // ----------------------------------------------------------------------------
@@ -1522,32 +1608,50 @@ void wxTreeListCtrl::OnSize(wxSizeEvent& event)
         const wxRect rect = GetClientRect();
         m_view->SetSize(rect);
 
-        // Resize the first column to take the remaining available space, if
-        // any.
+#ifdef wxHAS_GENERIC_DATAVIEWCTRL
+        // The generic implementation doesn't refresh itself immediately which
+        // is annoying during "live resizing", so do it forcefully here to
+        // ensure that the items are re-laid out and the focus rectangle is
+        // redrawn correctly (instead of leaving traces) while our size is
+        // being changed.
+        wxWindow* const view = GetView();
+        view->Refresh();
+        view->Update();
+#endif // wxHAS_GENERIC_DATAVIEWCTRL
+
+        // Resize the first column to take the remaining available space.
         const unsigned numColumns = GetColumnCount();
         if ( !numColumns )
             return;
 
         // There is a bug in generic wxDataViewCtrl: if the column width sums
         // up to the total size, horizontal scrollbar (unnecessarily) appears,
-        // so subtract 10 pixels to ensure this doesn't happen.
-        int remainingWidth = rect.width - 10;
+        // so subtract a bit to ensure this doesn't happen.
+        int remainingWidth = rect.width - 5;
         for ( unsigned n = 1; n < GetColumnCount(); n++ )
         {
             remainingWidth -= GetColumnWidth(n);
-            if ( remainingWidth < 0 )
-                break;
+            if ( remainingWidth <= 0 )
+            {
+                // There is not enough space, as we're not going to give the
+                // first column negative width anyhow, just don't do anything.
+                return;
+            }
         }
 
-        // We don't decrease the width of the first column, even if we had
-        // increased it ourselves, because we want to avoid changing its size
-        // if the user resized it. We might want to remember if this was the
-        // case or if we only ever adjusted it automatically in the future.
-        if ( remainingWidth > GetColumnWidth(0) )
-            SetColumnWidth(0, remainingWidth);
+        SetColumnWidth(0, remainingWidth);
     }
 }
 
+wxWindow* wxTreeListCtrl::GetView() const
+{
+#ifdef wxHAS_GENERIC_DATAVIEWCTRL
+    return m_view->GetMainWindow();
+#else
+    return m_view;
+#endif
+}
+
 // ============================================================================
 // wxTreeListEvent implementation
 // ============================================================================
@@ -1563,6 +1667,7 @@ wxDEFINE_TREELIST_EVENT(ITEM_EXPANDED);
 wxDEFINE_TREELIST_EVENT(ITEM_CHECKED);
 wxDEFINE_TREELIST_EVENT(ITEM_ACTIVATED);
 wxDEFINE_TREELIST_EVENT(ITEM_CONTEXT_MENU);
+wxDEFINE_TREELIST_EVENT(COLUMN_SORTED);
 
 #undef wxDEFINE_TREELIST_EVENT