]> git.saurik.com Git - wxWidgets.git/blobdiff - src/msw/treectrl.cpp
Spell contributor name correctly.
[wxWidgets.git] / src / msw / treectrl.cpp
index 776740fa1cce13db836d7940b397a3b470df1aac..9464bec90b3669822d36e04c1e34098d4910e195 100644 (file)
@@ -750,6 +750,7 @@ void wxTreeCtrl::Init()
     m_focusLost = true;
     m_changingSelection = false;
     m_triggerStateImageClick = false;
+    m_mouseUpDeselect = false;
 
     // initialize the global array of events now as it can't be done statically
     // with the wxEVT_XXX values being allocated during run-time only
@@ -1666,6 +1667,12 @@ void wxTreeCtrl::Delete(const wxTreeItemId& item)
             return;
         }
 
+        if ( item == m_htSelStart )
+            m_htSelStart.Unset();
+
+        if ( item == m_htClickedItem )
+            m_htClickedItem.Unset();
+
         if ( next.IsOk() )
         {
             wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this, next);
@@ -1720,6 +1727,10 @@ void wxTreeCtrl::DeleteAllItems()
     // unlock tree selections on vista for the duration of this call
     TreeItemUnlocker unlock_all;
 
+    // invalidate all the items we store as they're going to become invalid
+    m_htSelStart =
+    m_htClickedItem = wxTreeItemId();
+
     // delete the "virtual" root item.
     if ( GET_VIRTUAL_ROOT() )
     {
@@ -1872,6 +1883,39 @@ void wxTreeCtrl::UnselectAll()
     }
 }
 
+void wxTreeCtrl::DoSelectChildren(const wxTreeItemId& parent)
+{
+    DoUnselectAll();
+
+    wxTreeItemIdValue cookie;
+    wxTreeItemId child = GetFirstChild(parent, cookie);
+    while ( child.IsOk() )
+    {
+        DoSelectItem(child, true);
+        child = GetNextChild(child, cookie);
+    }
+}
+
+void wxTreeCtrl::SelectChildren(const wxTreeItemId& parent)
+{
+    wxCHECK_RET( HasFlag(wxTR_MULTIPLE),
+                 "this only works with multiple selection controls" );
+
+    HTREEITEM htFocus = (HTREEITEM)TreeView_GetSelection(GetHwnd());
+
+    wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING, this);
+    changingEvent.m_itemOld = htFocus;
+
+    if ( IsTreeEventAllowed(changingEvent) )
+    {
+        DoSelectChildren(parent);
+
+        wxTreeEvent changedEvent(wxEVT_COMMAND_TREE_SEL_CHANGED, this);
+        changedEvent.m_itemOld = htFocus;
+        (void)HandleTreeEvent(changedEvent);
+    }
+}
+
 void wxTreeCtrl::DoSelectItem(const wxTreeItemId& item, bool select)
 {
     TempSetter set(m_changingSelection);
@@ -2214,6 +2258,15 @@ bool wxTreeCtrl::MSWCommand(WXUINT cmd, WXWORD id_)
     return true;
 }
 
+bool wxTreeCtrl::MSWIsOnItem(unsigned flags) const
+{
+    unsigned mask = TVHT_ONITEM;
+    if ( HasFlag(wxTR_FULL_ROW_HIGHLIGHT) )
+        mask |= TVHT_ONITEMINDENT | TVHT_ONITEMRIGHT;
+
+    return (flags & mask) != 0;
+}
+
 bool wxTreeCtrl::MSWHandleSelectionKey(unsigned vkey)
 {
     const bool bCtrl = wxIsCtrlDown();
@@ -2715,11 +2768,19 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
 
                 m_htClickedItem.Unset();
 
-                if ( !(tvht.flags & TVHT_ONITEM) )
+                if ( !MSWIsOnItem(tvht.flags) )
                 {
-                    if ( !HandleMouseEvent(nMsg, x, y, wParam) )
+                    if ( tvht.flags & TVHT_ONITEMBUTTON )
                     {
-                        if ( tvht.flags & TVHT_ONITEMBUTTON )
+                        // either it's going to be handled by user code or
+                        // we're going to use it ourselves to toggle the
+                        // branch, in either case don't pass it to the base
+                        // class which would generate another mouse click event
+                        // for it even though it's already handled here
+                        processed = true;
+                        SetFocus();
+
+                        if ( !HandleMouseEvent(nMsg, x, y, wParam) )
                         {
                             if ( !IsExpanded(htItem) )
                             {
@@ -2730,8 +2791,6 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                                 Collapse(htItem);
                             }
                         }
-
-                        processed = true;
                     }
 
                     m_focusLost = false;
@@ -2870,6 +2929,7 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                         else
                         {
                             SetFocusedItem(wxTreeItemId(htItem));
+                            m_mouseUpDeselect = true;
                         }
                     }
                     else // click on a single selected item
@@ -3019,16 +3079,13 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
             case WM_LBUTTONUP:
                 if ( isMultiple )
                 {
-                    // deselect other items if multiple items selected
+                    // deselect other items if needed
                     if ( htItem )
                     {
-                        wxArrayTreeItemIds selections;
-                        size_t count = GetSelections(selections);
-
-                        if ( count > 1 &&
-                             !(wParam & MK_CONTROL) &&
-                             !(wParam & MK_SHIFT) )
+                        if ( m_mouseUpDeselect )
                         {
+                            m_mouseUpDeselect = false;
+
                             wxTreeEvent changingEvent(wxEVT_COMMAND_TREE_SEL_CHANGING,
                                                       this, htItem);
                             changingEvent.m_itemOld = htOldItem;
@@ -3062,10 +3119,7 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
                         }
                     }
 
-                    if ( !m_dragStarted &&
-                         (tvht.flags & TVHT_ONITEMSTATEICON ||
-                          tvht.flags & TVHT_ONITEMICON ||
-                          tvht.flags & TVHT_ONITEM) )
+                    if ( !m_dragStarted && MSWIsOnItem(tvht.flags) )
                     {
                         processed = true;
                     }
@@ -3156,7 +3210,8 @@ wxTreeCtrl::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam)
             case VK_END:
             case VK_PRIOR:
             case VK_NEXT:
-                if ( !MSWHandleTreeKeyDownEvent(wParam, lParam) )
+                if ( !HandleKeyDown(wParam, lParam) &&
+                        !MSWHandleTreeKeyDownEvent(wParam, lParam) )
                 {
                     // use the key to update the selection if it was left
                     // unprocessed
@@ -3647,7 +3702,7 @@ bool wxTreeCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result)
                 ::ScreenToClient(GetHwnd(), &tvhti.pt);
                 if ( TreeView_HitTest(GetHwnd(), &tvhti) )
                 {
-                    if ( tvhti.flags & TVHT_ONITEM )
+                    if ( MSWIsOnItem(tvhti.flags) )
                     {
                         event.m_item = tvhti.hItem;
                         eventType = (int)hdr->code == NM_DBLCLK