]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/treectlg.cpp
Handler when the cases when the MGL timer wraps
[wxWidgets.git] / src / generic / treectlg.cpp
index ed8f47b512e3ee998c23bc6a2a02afafc108c364..bdd3003ec196ec3a1aca14526a72b1ea1886d30e 100644 (file)
@@ -108,6 +108,7 @@ private:
     wxGenericTreeItem  *m_itemEdited;
     wxString            m_startValue;
     bool                m_finished;
+    bool                m_aboutToFinish;
 
     DECLARE_EVENT_TABLE()
     DECLARE_NO_COPY_CLASS(wxTreeTextCtrl)
@@ -341,6 +342,7 @@ wxTreeTextCtrl::wxTreeTextCtrl(wxGenericTreeCtrl *owner,
 {
     m_owner = owner;
     m_finished = false;
+    m_aboutToFinish = false;
 
     int w = m_itemEdited->GetWidth(),
         h = m_itemEdited->GetHeight();
@@ -390,6 +392,12 @@ bool wxTreeTextCtrl::AcceptChanges()
     if ( value == m_startValue )
     {
         // nothing changed, always accept
+        // when an item remains unchanged, the owner
+        // needs to be notified that the user decided
+        // not to change the tree item label, and that
+        // the edit has been cancelled
+
+        m_owner->OnRenameCancelled(m_itemEdited);
         return true;
     }
 
@@ -407,7 +415,7 @@ bool wxTreeTextCtrl::AcceptChanges()
 
 void wxTreeTextCtrl::Finish()
 {
-    if ( !m_finished )
+    if ( !m_finished  )
     {
         m_owner->ResetTextControl();
 
@@ -424,12 +432,11 @@ void wxTreeTextCtrl::OnChar( wxKeyEvent &event )
     switch ( event.m_keyCode )
     {
         case WXK_RETURN:
-            if ( AcceptChanges() )
-            {
-                // Close the text control, changes were accepted
-                Finish();
-            }
-            // else do nothing, do not accept and do not close
+            m_aboutToFinish = true;
+            // Notify the owner about the changes
+            AcceptChanges();
+            // Even if vetoed, close the control (consistent with MSW)
+            Finish();
             break;
 
         case WXK_ESCAPE:
@@ -463,16 +470,18 @@ void wxTreeTextCtrl::OnKeyUp( wxKeyEvent &event )
 
 void wxTreeTextCtrl::OnKillFocus( wxFocusEvent &event )
 {
-    if ( !m_finished )
+    if ( !m_finished && !m_aboutToFinish )
     {
-        AcceptChanges();
         // We must finish regardless of success, otherwise we'll get
         // focus problems:
         Finish();
+
+        if ( !AcceptChanges() )
+            m_owner->OnRenameCancelled( m_itemEdited );
     }
 
     // We must let the native text control handle focus, too, otherwise
-    // it could have problems with the cursor (e.g., in wxGTK):
+    // it could have problems with the cursor (e.g., in wxGTK).
     event.Skip();
 }
 
@@ -908,7 +917,7 @@ void wxGenericTreeCtrl::SetWindowStyle(const long styles)
 
 wxString wxGenericTreeCtrl::GetItemText(const wxTreeItemId& item) const
 {
-    wxCHECK_MSG( item.IsOk(), wxT(""), wxT("invalid tree item") );
+    wxCHECK_MSG( item.IsOk(), wxEmptyString, wxT("invalid tree item") );
 
     return ((wxGenericTreeItem*) item.m_pItem)->GetText();
 }
@@ -1009,6 +1018,25 @@ void wxGenericTreeCtrl::SetItemBold(const wxTreeItemId& item, bool bold)
     }
 }
 
+void wxGenericTreeCtrl::SetItemDropHighlight(const wxTreeItemId& item,
+                                             bool highlight)
+{
+    wxCHECK_RET( item.IsOk(), wxT("invalid tree item") );
+
+    wxColour fg, bg;
+
+    if (highlight)
+    {
+        bg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
+        fg = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
+    }
+
+    wxGenericTreeItem *pItem = (wxGenericTreeItem*) item.m_pItem;
+    pItem->Attr().SetTextColour(fg);
+    pItem->Attr().SetBackgroundColour(bg);
+    RefreshLine(pItem);
+}
+
 void wxGenericTreeCtrl::SetItemTextColour(const wxTreeItemId& item,
                                    const wxColour& col)
 {
@@ -1903,7 +1931,7 @@ void wxGenericTreeCtrl::SelectItem(const wxTreeItemId& itemId, bool select)
 {
     if ( select )
     {
-        DoSelectItem(itemId);
+        DoSelectItem(itemId, !HasFlag(wxTR_MULTIPLE));
     }
     else // deselect
     {
@@ -2227,6 +2255,7 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
     }
 
     int total_h = GetLineHeight(item);
+    bool drawItemBackground = false;
 
     if ( item->IsSelected() )
     {
@@ -2244,14 +2273,20 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
 #else
         dc.SetBrush(*(m_hasFocus ? m_hilightBrush : m_hilightUnfocusedBrush));
 #endif
+        drawItemBackground = true;
     }
     else
     {
         wxColour colBg;
         if ( attr && attr->HasBackgroundColour() )
+        {
+            drawItemBackground = true;
             colBg = attr->GetBackgroundColour();
+        }
         else
+        {
             colBg = m_backgroundColour;
+        }
         dc.SetBrush(wxBrush(colBg, wxSOLID));
     }
 
@@ -2275,7 +2310,10 @@ void wxGenericTreeCtrl::PaintItem(wxGenericTreeItem *item, wxDC& dc)
             dc.DrawRectangle( item->GetX() + image_w - 2, item->GetY()+offset,
                               item->GetWidth() - image_w + 2, total_h-offset );
         }
-        else
+        // On GTK+ 2, drawing a 'normal' background is wrong for themes that
+        // don't allow backgrounds to be customized. Not drawing the background,
+        // except for custom item backgrounds, works for both kinds of theme.
+        else if (drawItemBackground)
         {
             dc.DrawRectangle( item->GetX()-2, item->GetY()+offset,
                               item->GetWidth()+2, total_h-offset );
@@ -2612,7 +2650,7 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
     bool is_multiple, extended_select, unselect_others;
     EventFlagsToSelType(GetWindowStyleFlag(),
                         event.ShiftDown(),
-                        event.ControlDown(),
+                        event.CmdDown(),
                         is_multiple, extended_select, unselect_others);
 
     // + : Expand
@@ -2657,8 +2695,15 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event )
 
         case WXK_MENU:
             {
+                // Use the item's bounding rectangle to determine position for the event
+                wxRect ItemRect;
+                GetBoundingRect(m_current, ItemRect, true);
+
                 wxTreeEvent event( wxEVT_COMMAND_TREE_ITEM_MENU, GetId() );
                 event.m_item = m_current;
+                // Use the left edge, vertical middle
+                event.m_pointDrag = wxPoint(ItemRect.GetX(),
+                                            ItemRect.GetY() + ItemRect.GetHeight() / 2);
                 event.SetEventObject( this );
                 GetEventHandler()->ProcessEvent( event );
                 break;
@@ -3075,6 +3120,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
         wxTreeEvent nevent( command, GetId() );
         nevent.m_item = m_current;
         nevent.SetEventObject(this);
+        nevent.SetPoint(pt);
 
         // by default the dragging is not supported, the user code must
         // explicitly allow the event for it to take place
@@ -3088,7 +3134,7 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
             // remember the old cursor because we will change it while
             // dragging
             m_oldCursor = m_cursor;
-            
+
             // in a single selection control, hide the selection temporarily
             if ( !(GetWindowStyleFlag() & wxTR_MULTIPLE) )
             {
@@ -3177,23 +3223,38 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
 
         if ( event.RightDown() )
         {
+            // If the item is already selected, do not update the selection.
+            // Multi-selections should not be cleared if a selected item is clicked.
+            if (!IsSelected(item))
+            {
+                DoSelectItem(item, true, false);
+            }
+
             wxTreeEvent nevent(wxEVT_COMMAND_TREE_ITEM_RIGHT_CLICK, GetId());
             nevent.m_item = item;
             nevent.m_pointDrag = CalcScrolledPosition(pt);
             nevent.SetEventObject(this);
-            GetEventHandler()->ProcessEvent(nevent);
+            event.Skip(!GetEventHandler()->ProcessEvent(nevent));
+
+            // Consistent with MSW (for now), send the ITEM_MENU *after*
+            // the RIGHT_CLICK event. TODO: This behavior may change.
+            wxTreeEvent nevent2(wxEVT_COMMAND_TREE_ITEM_MENU, GetId());
+            nevent2.m_item = item;
+            nevent2.m_pointDrag = CalcScrolledPosition(pt);
+            nevent2.SetEventObject(this);
+            GetEventHandler()->ProcessEvent(nevent2);
         }
         else if ( event.LeftUp() )
         {
             // this facilitates multiple-item drag-and-drop
 
-            if (item && HasFlag(wxTR_MULTIPLE))
+            if ( /* item && */ HasFlag(wxTR_MULTIPLE))
             {
                 wxArrayTreeItemIds selections;
                 size_t count = GetSelections(selections);
 
                 if (count > 1 &&
-                    !event.ControlDown() &&
+                    !event.CmdDown() &&
                     !event.ShiftDown())
                 {
                     DoSelectItem(item, true, false);
@@ -3247,14 +3308,14 @@ void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event )
             // user clicked outside of the present selection.
             // otherwise, perform the deselection on mouse-up.
             // this allows multiple drag and drop to work.
-
-            if (!IsSelected(item))
+            // but if Cmd is down, toggle selection of the clicked item
+            if (!IsSelected(item) || event.CmdDown())
             {
                 // how should the selection work for this event?
                 bool is_multiple, extended_select, unselect_others;
                 EventFlagsToSelType(GetWindowStyleFlag(),
                                     event.ShiftDown(),
-                                    event.ControlDown(),
+                                    event.CmdDown(),
                                     is_multiple, extended_select, unselect_others);
 
                 DoSelectItem(item, unselect_others, extended_select);
@@ -3563,6 +3624,20 @@ wxGenericTreeCtrl::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 #endif
 }
 
+#if WXWIN_COMPATIBILITY_2_4
+
+int wxGenericTreeCtrl::GetItemSelectedImage(const wxTreeItemId& item) const
+{
+    return GetItemImage(item, wxTreeItemIcon_Selected);
+}
+
+void wxGenericTreeCtrl::SetItemSelectedImage(const wxTreeItemId& item, int image)
+{
+    SetItemImage(item, image, wxTreeItemIcon_Selected);
+}
+
+#endif // WXWIN_COMPATIBILITY_2_4
+
 #if WXWIN_COMPATIBILITY_2_2
 
 wxTreeItemId wxGenericTreeCtrl::GetParent(const wxTreeItemId& item) const