]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
require libsm-dev, it's needed for KDE/GNOME detection
[wxWidgets.git] / src / generic / listctrl.cpp
index d96d2cbff239390e70c53ef3d38a24d4e8f17bd1..97c78dfd4230919bb2fe8e0760cd615749b679af 100644 (file)
@@ -98,6 +98,9 @@ static const int WIDTH_COL_DEFAULT = 80;
 // the space between the image and the text in the report mode
 static const int IMAGE_MARGIN_IN_REPORT_MODE = 5;
 
 // the space between the image and the text in the report mode
 static const int IMAGE_MARGIN_IN_REPORT_MODE = 5;
 
+// the space between the image and the text in the report mode in header
+static const int HEADER_IMAGE_MARGIN_IN_REPORT_MODE = 2;
+
 // ============================================================================
 // private classes
 // ============================================================================
 // ============================================================================
 // private classes
 // ============================================================================
@@ -695,7 +698,7 @@ public:
 
     // send out a wxListEvent
     void SendNotify( size_t line,
 
     // send out a wxListEvent
     void SendNotify( size_t line,
-                     wxEventType command, 
+                     wxEventType command,
                      const wxPoint& point = wxDefaultPosition );
 
     // override base class virtual to reset m_lineHeight when the font changes
                      const wxPoint& point = wxDefaultPosition );
 
     // override base class virtual to reset m_lineHeight when the font changes
@@ -728,7 +731,7 @@ public:
     {
         return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush;
     }
     {
         return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush;
     }
-    
+
     bool HasFocus() const
     {
         return m_hasFocus;
     bool HasFocus() const
     {
         return m_hasFocus;
@@ -1036,7 +1039,7 @@ void wxListHeaderData::SetItem( const wxListItem &item )
 
     if ( m_mask & wxLIST_MASK_WIDTH )
         SetWidth(item.m_width);
 
     if ( m_mask & wxLIST_MASK_WIDTH )
         SetWidth(item.m_width);
-        
+
     if ( m_mask & wxLIST_MASK_STATE )
         SetState(item.m_state);
 }
     if ( m_mask & wxLIST_MASK_STATE )
         SetState(item.m_state);
 }
@@ -1410,7 +1413,11 @@ bool wxListLineData::SetAttributes(wxDC *dc,
     if ( highlighted )
 #ifdef __WXMAC__
     {
     if ( highlighted )
 #ifdef __WXMAC__
     {
-        if (m_owner->HasFocus())
+        if (m_owner->HasFocus()
+#ifdef __WXMAC__
+                && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+        )
             colText = *wxWHITE;
         else
             colText = *wxBLACK;
             colText = *wxWHITE;
         else
             colText = *wxBLACK;
@@ -1470,10 +1477,14 @@ void wxListLineData::Draw( wxDC *dc )
         if (highlighted)
         {
             int flags = wxCONTROL_SELECTED;
         if (highlighted)
         {
             int flags = wxCONTROL_SELECTED;
-            if (m_owner->HasFocus())
+            if (m_owner->HasFocus()
+#ifdef __WXMAC__
+                && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+            )
                 flags |= wxCONTROL_FOCUSED;
             wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags );
                 flags |= wxCONTROL_FOCUSED;
             wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, m_gi->m_rectHighlight, flags );
-            
+
         }
         else
         {
         }
         else
         {
@@ -1529,7 +1540,11 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
         if (highlighted)
         {
             int flags = wxCONTROL_SELECTED;
         if (highlighted)
         {
             int flags = wxCONTROL_SELECTED;
-            if (m_owner->HasFocus())
+            if (m_owner->HasFocus()
+#ifdef __WXMAC__
+                && IsControlActive( (ControlRef)m_owner->GetHandle() )
+#endif
+            )
                 flags |= wxCONTROL_FOCUSED;
             wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
         }
                 flags |= wxCONTROL_FOCUSED;
             wxRendererNative::Get().DrawItemSelectionRect( m_owner, *dc, rectHL, flags );
         }
@@ -1578,12 +1593,17 @@ void wxListLineData::DrawInReportMode( wxDC *dc,
 }
 
 void wxListLineData::DrawTextFormatted(wxDC *dc,
 }
 
 void wxListLineData::DrawTextFormatted(wxDC *dc,
-                                       const wxString &text,
+                                       const wxString& textOrig,
                                        int col,
                                        int x,
                                        int yMid,
                                        int width)
 {
                                        int col,
                                        int x,
                                        int yMid,
                                        int width)
 {
+    // we don't support displaying multiple lines currently (and neither does
+    // wxMSW FWIW) so just merge all the lines
+    wxString text(textOrig);
+    text.Replace(_T("\n"), _T(" "));
+
     wxCoord w, h;
     dc->GetTextExtent(text, &w, &h);
 
     wxCoord w, h;
     dc->GetTextExtent(text, &w, &h);
 
@@ -1802,12 +1822,12 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         if (!m_parent->IsEnabled())
             flags |= wxCONTROL_DISABLED;
 
         if (!m_parent->IsEnabled())
             flags |= wxCONTROL_DISABLED;
 
-// NB: The code below is not really Mac-specific, but since we are close 
+// NB: The code below is not really Mac-specific, but since we are close
 // to 2.8 release and I don't have time to test on other platforms, I
 // defined this only for wxMac. If this behavior is desired on
 // other platforms, please go ahead and revise or remove the #ifdef.
 #ifdef __WXMAC__
 // to 2.8 release and I don't have time to test on other platforms, I
 // defined this only for wxMac. If this behavior is desired on
 // other platforms, please go ahead and revise or remove the #ifdef.
 #ifdef __WXMAC__
-        if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) && 
+        if ( !m_owner->IsVirtual() && (item.m_mask & wxLIST_MASK_STATE) &&
                 (item.m_state & wxLIST_STATE_SELECTED) )
             flags |= wxCONTROL_SELECTED;
 #endif
                 (item.m_state & wxLIST_STATE_SELECTED) )
             flags |= wxCONTROL_SELECTED;
 #endif
@@ -1829,7 +1849,6 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         wLabel += 2 * EXTRA_WIDTH;
 
         // and the width of the icon, if any
         wLabel += 2 * EXTRA_WIDTH;
 
         // and the width of the icon, if any
-        static const int MARGIN_BETWEEN_TEXT_AND_ICON = 2;
         int ix = 0, iy = 0;    // init them just to suppress the compiler warnings
         const int image = item.m_image;
         wxImageList *imageList;
         int ix = 0, iy = 0;    // init them just to suppress the compiler warnings
         const int image = item.m_image;
         wxImageList *imageList;
@@ -1839,7 +1858,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             if ( imageList )
             {
                 imageList->GetSize(image, ix, iy);
             if ( imageList )
             {
                 imageList->GetSize(image, ix, iy);
-                wLabel += ix + MARGIN_BETWEEN_TEXT_AND_ICON;
+                wLabel += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
             }
         }
         else
             }
         }
         else
@@ -1868,6 +1887,10 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
                 break;
         }
 
                 break;
         }
 
+        // draw the text and image clipping them so that they
+        // don't overwrite the column boundary
+        wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
+
         // if we have an image, draw it on the right of the label
         if ( imageList )
         {
         // if we have an image, draw it on the right of the label
         if ( imageList )
         {
@@ -1875,18 +1898,12 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
                        (
                         image,
                         dc,
                        (
                         image,
                         dc,
-                        xAligned + wLabel - ix - MARGIN_BETWEEN_TEXT_AND_ICON,
+                        xAligned + wLabel - ix - HEADER_IMAGE_MARGIN_IN_REPORT_MODE,
                         HEADER_OFFSET_Y + (h - 4 - iy)/2,
                         wxIMAGELIST_DRAW_TRANSPARENT
                        );
                         HEADER_OFFSET_Y + (h - 4 - iy)/2,
                         wxIMAGELIST_DRAW_TRANSPARENT
                        );
-
-            cw -= ix + MARGIN_BETWEEN_TEXT_AND_ICON;
         }
 
         }
 
-        // draw the text clipping it so that it doesn't overwrite the column
-        // boundary
-        wxDCClipper clipper(dc, x, HEADER_OFFSET_Y, cw, h - 4 );
-
         dc.DrawText( item.GetText(),
                      xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
 
         dc.DrawText( item.GetText(),
                      xAligned + EXTRA_WIDTH, h / 2 - hLabel / 2 ); //HEADER_OFFSET_Y + EXTRA_HEIGHT );
 
@@ -2020,7 +2037,7 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
                     {
                         wxListItem colItem;
                         m_owner->GetColumn(i, colItem);
                     {
                         wxListItem colItem;
                         m_owner->GetColumn(i, colItem);
-                        long state = colItem.GetState(); 
+                        long state = colItem.GetState();
                         if (i == m_column)
                             colItem.SetState(state | wxLIST_STATE_SELECTED);
                         else
                         if (i == m_column)
                             colItem.SetState(state | wxLIST_STATE_SELECTED);
                         else
@@ -2028,7 +2045,7 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
                         m_owner->SetColumn(i, colItem);
                     }
                 }
                         m_owner->SetColumn(i, colItem);
                     }
                 }
-                
+
                 SendListEvent( event.LeftDown()
                                     ? wxEVT_COMMAND_LIST_COL_CLICK
                                     : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
                 SendListEvent( event.LeftDown()
                                     ? wxEVT_COMMAND_LIST_COL_CLICK
                                     : wxEVT_COMMAND_LIST_COL_RIGHT_CLICK,
@@ -2234,7 +2251,7 @@ BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse)
   EVT_CHAR           (wxListMainWindow::OnChar)
   EVT_KEY_DOWN       (wxListMainWindow::OnKeyDown)
   EVT_MOUSE_EVENTS   (wxListMainWindow::OnMouse)
   EVT_CHAR           (wxListMainWindow::OnChar)
   EVT_KEY_DOWN       (wxListMainWindow::OnKeyDown)
-  EVT_KEY_UP         (wxListMainWindow::OnKeyUp)      
+  EVT_KEY_UP         (wxListMainWindow::OnKeyUp)
   EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus)
   EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus)
   EVT_SCROLLWIN      (wxListMainWindow::OnScroll)
   EVT_SET_FOCUS      (wxListMainWindow::OnSetFocus)
   EVT_KILL_FOCUS     (wxListMainWindow::OnKillFocus)
   EVT_SCROLLWIN      (wxListMainWindow::OnScroll)
@@ -2300,7 +2317,7 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
                             ),
                             wxSOLID
                          );
                             ),
                             wxSOLID
                          );
-                         
+
     m_highlightUnfocusedBrush = new wxBrush
                               (
                                  wxSystemSettings::GetColour
     m_highlightUnfocusedBrush = new wxBrush
                               (
                                  wxSystemSettings::GetColour
@@ -2719,7 +2736,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
         wxRect rectLine;
         int xOrig = dc.LogicalToDeviceX( 0 );
         int yOrig = dc.LogicalToDeviceY( 0 );
         wxRect rectLine;
         int xOrig = dc.LogicalToDeviceX( 0 );
         int yOrig = dc.LogicalToDeviceY( 0 );
-        
+
         // tell the caller cache to cache the data
         if ( IsVirtual() )
         {
         // tell the caller cache to cache the data
         if ( IsVirtual() )
         {
@@ -2816,7 +2833,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             dc.DrawRectangle( rect );
 #else
             wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, wxCONTROL_CURRENT|wxCONTROL_FOCUSED );
             dc.DrawRectangle( rect );
 #else
             wxRendererNative::Get().DrawItemSelectionRect( this, dc, rect, wxCONTROL_CURRENT|wxCONTROL_FOCUSED );
-            
+
 #endif
         }
     }
 #endif
         }
     }
@@ -2848,7 +2865,7 @@ void wxListMainWindow::SendNotify( size_t line,
 {
     wxListEvent le( command, GetParent()->GetId() );
     le.SetEventObject( GetParent() );
 {
     wxListEvent le( command, GetParent()->GetId() );
     le.SetEventObject( GetParent() );
-    
+
     le.m_itemIndex = line;
 
     // set only for events which have position
     le.m_itemIndex = line;
 
     // set only for events which have position
@@ -2876,6 +2893,11 @@ void wxListMainWindow::ChangeCurrent(size_t current)
 {
     m_current = current;
 
 {
     m_current = current;
 
+    // as the current item changed, we shouldn't start editing it when the
+    // "slow click" timer expires as the click happened on another item
+    if ( m_renameTimer->IsRunning() )
+        m_renameTimer->Stop();
+
     SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED);
 }
 
     SendNotify(current, wxEVT_COMMAND_LIST_ITEM_FOCUSED);
 }
 
@@ -2905,8 +2927,15 @@ wxTextCtrl *wxListMainWindow::EditLabel(long item, wxClassInfo* textControlClass
     // We have to call this here because the label in question might just have
     // been added and no screen update taken place.
     if ( m_dirty )
     // We have to call this here because the label in question might just have
     // been added and no screen update taken place.
     if ( m_dirty )
+    {
         wxSafeYield();
 
         wxSafeYield();
 
+        // Pending events dispatched by wxSafeYield might have changed the item
+        // count
+        if ( (size_t)item >= GetItemCount() )
+            return NULL;
+    }
+
     wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
     m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item);
     return m_textctrlWrapper->GetText();
     wxTextCtrl * const text = (wxTextCtrl *)textControlClass->CreateObject();
     m_textctrlWrapper = new wxListTextCtrlWrapper(this, text, item);
     return m_textctrlWrapper->GetText();
@@ -2966,7 +2995,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
 
     if ( event.LeftDown() )
         SetFocus();
 
     if ( event.LeftDown() )
         SetFocus();
-    
+
     event.SetEventObject( GetParent() );
     if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
         return;
     event.SetEventObject( GetParent() );
     if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
         return;
@@ -3076,7 +3105,9 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
     bool forceClick = false;
     if (event.ButtonDClick())
     {
     bool forceClick = false;
     if (event.ButtonDClick())
     {
-        m_renameTimer->Stop();
+        if ( m_renameTimer->IsRunning() )
+            m_renameTimer->Stop();
+
         m_lastOnSame = false;
 
         if ( current == m_lineLastClicked )
         m_lastOnSame = false;
 
         if ( current == m_lineLastClicked )
@@ -3673,6 +3704,19 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
     if (width == wxLIST_AUTOSIZE_USEHEADER)
     {
         width = GetTextLength(column->GetText());
     if (width == wxLIST_AUTOSIZE_USEHEADER)
     {
         width = GetTextLength(column->GetText());
+        width += 2*EXTRA_WIDTH;
+
+        // check for column header's image availability
+        const int image = column->GetImage();
+        if ( image != -1 )
+        {
+            if ( m_small_image_list )
+            {
+                int ix = 0, iy = 0;
+                m_small_image_list->GetSize(image, ix, iy);
+                width += ix + HEADER_IMAGE_MARGIN_IN_REPORT_MODE;
+            }
+        }
     }
     else if ( width == wxLIST_AUTOSIZE )
     {
     }
     else if ( width == wxLIST_AUTOSIZE )
     {
@@ -4361,7 +4405,7 @@ void wxListMainWindow::DeleteItem( long lindex )
         if ( m_current != index || m_current == count - 1 )
             m_current--;
     }
         if ( m_current != index || m_current == count - 1 )
             m_current--;
     }
+
     if ( InReportView() )
     {
         //  mark the Column Max Width cache as dirty if the items in the line
     if ( InReportView() )
     {
         //  mark the Column Max Width cache as dirty if the items in the line
@@ -4508,7 +4552,7 @@ long wxListMainWindow::FindItem(long start, const wxString& str, bool partial )
 {
     if (str.empty())
         return wxNOT_FOUND;
 {
     if (str.empty())
         return wxNOT_FOUND;
-        
+
     long pos = start;
     wxString str_upper = str.Upper();
     if (pos < 0)
     long pos = start;
     wxString str_upper = str.Upper();
     if (pos < 0)