]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
minor cleanup
[wxWidgets.git] / src / generic / listctrl.cpp
index e6b3a70c0753a95d816ac5ca93874bc8509a888e..c6a51c95247c50b3e3259971879d6eedb405b930 100644 (file)
 // headers
 // ----------------------------------------------------------------------------
 
 // headers
 // ----------------------------------------------------------------------------
 
-#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
-    #pragma implementation "listctrl.h"
-    #pragma implementation "listctrlbase.h"
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -142,9 +137,8 @@ static const int MARGIN_BETWEEN_ROWS = 6;
 // when autosizing the columns, add some slack
 static const int AUTOSIZE_COL_MARGIN = 10;
 
 // when autosizing the columns, add some slack
 static const int AUTOSIZE_COL_MARGIN = 10;
 
-// default and minimal widths for the header columns
+// default width for the header columns
 static const int WIDTH_COL_DEFAULT = 80;
 static const int WIDTH_COL_DEFAULT = 80;
-static const int WIDTH_COL_MIN = 10;
 
 // 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;
@@ -170,7 +164,7 @@ struct wxColWidthInfo
     }
 };
 
     }
 };
 
-WX_DEFINE_ARRAY(wxColWidthInfo *, ColWidthArray);
+WX_DEFINE_ARRAY_PTR(wxColWidthInfo *, ColWidthArray);
 
 //-----------------------------------------------------------------------------
 //  wxListItemData (internal)
 
 //-----------------------------------------------------------------------------
 //  wxListItemData (internal)
@@ -290,7 +284,7 @@ private:
 
 WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
 #include "wx/listimpl.cpp"
 
 WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
 #include "wx/listimpl.cpp"
-WX_DEFINE_LIST(wxListItemDataList);
+WX_DEFINE_LIST(wxListItemDataList)
 
 class wxListLineData
 {
 
 class wxListLineData
 {
@@ -367,7 +361,7 @@ public:
     void GetItem( int index, wxListItem &info );
 
     wxString GetText(int index) const;
     void GetItem( int index, wxListItem &info );
 
     wxString GetText(int index) const;
-    void SetText( int index, const wxString s );
+    void SetText( int index, const wxString& s );
 
     wxListItemAttr *GetAttr() const;
     void SetAttr(wxListItemAttr *attr);
 
     wxListItemAttr *GetAttr() const;
     void SetAttr(wxListItemAttr *attr);
@@ -418,7 +412,7 @@ private:
 
 WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData, wxListLineDataArray);
 #include "wx/arrimpl.cpp"
 
 WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData, wxListLineDataArray);
 #include "wx/arrimpl.cpp"
-WX_DEFINE_OBJARRAY(wxListLineDataArray);
+WX_DEFINE_OBJARRAY(wxListLineDataArray)
 
 //-----------------------------------------------------------------------------
 //  wxListHeaderWindow (internal)
 
 //-----------------------------------------------------------------------------
 //  wxListHeaderWindow (internal)
@@ -471,7 +465,7 @@ private:
 
     // generate and process the list event of the given type, return true if
     // it wasn't vetoed, i.e. if we should proceed
 
     // generate and process the list event of the given type, return true if
     // it wasn't vetoed, i.e. if we should proceed
-    bool SendListEvent(wxEventType type, wxPoint pos);
+    bool SendListEvent(wxEventType type, const wxPoint& pos);
 
     DECLARE_DYNAMIC_CLASS(wxListHeaderWindow)
     DECLARE_EVENT_TABLE()
 
     DECLARE_DYNAMIC_CLASS(wxListHeaderWindow)
     DECLARE_EVENT_TABLE()
@@ -500,6 +494,8 @@ class WXDLLEXPORT wxListTextCtrl: public wxTextCtrl
 public:
     wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit);
 
 public:
     wxListTextCtrl(wxListMainWindow *owner, size_t itemEdit);
 
+    void AcceptChangesAndFinish();
+
 protected:
     void OnChar( wxKeyEvent &event );
     void OnKeyUp( wxKeyEvent &event );
 protected:
     void OnChar( wxKeyEvent &event );
     void OnKeyUp( wxKeyEvent &event );
@@ -524,7 +520,7 @@ private:
 
 WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
 #include "wx/listimpl.cpp"
 
 WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
 #include "wx/listimpl.cpp"
-WX_DEFINE_LIST(wxListHeaderDataList);
+WX_DEFINE_LIST(wxListHeaderDataList)
 
 class wxListMainWindow : public wxScrolledWindow
 {
 
 class wxListMainWindow : public wxScrolledWindow
 {
@@ -674,6 +670,7 @@ public:
     wxString GetItemText(long item) const
     {
         wxListItem info;
     wxString GetItemText(long item) const
     {
         wxListItem info;
+        info.m_mask = wxLIST_MASK_TEXT;
         info.m_itemId = item;
         GetItem( info );
         return info.m_text;
         info.m_itemId = item;
         GetItem( info );
         return info.m_text;
@@ -721,7 +718,7 @@ public:
     // send out a wxListEvent
     void SendNotify( size_t line,
                      wxEventType command,
     // send out a wxListEvent
     void SendNotify( size_t line,
                      wxEventType command,
-                     wxPoint point = wxDefaultPosition );
+                     const wxPoint& point = wxDefaultPosition );
 
     // override base class virtual to reset m_lineHeight when the font changes
     virtual bool SetFont(const wxFont& font)
 
     // override base class virtual to reset m_lineHeight when the font changes
     virtual bool SetFont(const wxFont& font)
@@ -795,6 +792,8 @@ public:
            m_lineBeforeLastClicked,
            m_lineSelectSingleOnUp;
 
            m_lineBeforeLastClicked,
            m_lineSelectSingleOnUp;
 
+    wxListTextCtrl*     m_textctrl;
+    
 protected:
     // the total count of items in a virtual list control
     size_t m_countVirt;
 protected:
     // the total count of items in a virtual list control
     size_t m_countVirt;
@@ -837,11 +836,7 @@ protected:
     // get the colour to be used for drawing the rules
     wxColour GetRuleColour() const
     {
     // get the colour to be used for drawing the rules
     wxColour GetRuleColour() const
     {
-#ifdef __WXMAC__
-        return *wxWHITE;
-#else
         return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
         return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
-#endif
     }
 
 private:
     }
 
 private:
@@ -1001,9 +996,19 @@ int wxListItemData::GetHeight() const
 
 void wxListItemData::GetItem( wxListItem &info ) const
 {
 
 void wxListItemData::GetItem( wxListItem &info ) const
 {
-    info.m_text = m_text;
-    info.m_image = m_image;
-    info.m_data = m_data;
+    long mask = info.m_mask;
+    if ( !mask )
+    {
+        // by default, get everything for backwards compatibility
+        mask = -1;
+    }
+
+    if ( mask & wxLIST_MASK_TEXT )
+        info.m_text = m_text;
+    if ( mask & wxLIST_MASK_IMAGE )
+        info.m_image = m_image;
+    if ( mask & wxLIST_MASK_DATA )
+        info.m_data = m_data;
 
     if ( m_attr )
     {
 
     if ( m_attr )
     {
@@ -1073,11 +1078,7 @@ void wxListHeaderData::SetHeight( int h )
 
 void wxListHeaderData::SetWidth( int w )
 {
 
 void wxListHeaderData::SetWidth( int w )
 {
-    m_width = w;
-    if (m_width < 0)
-        m_width = WIDTH_COL_DEFAULT;
-    else if (m_width < WIDTH_COL_MIN)
-        m_width = WIDTH_COL_MIN;
+    m_width = w < 0 ? WIDTH_COL_DEFAULT : w;
 }
 
 void wxListHeaderData::SetFormat( int format )
 }
 
 void wxListHeaderData::SetFormat( int format )
@@ -1363,7 +1364,7 @@ wxString wxListLineData::GetText(int index) const
     return s;
 }
 
     return s;
 }
 
-void wxListLineData::SetText( int index, const wxString s )
+void wxListLineData::SetText( int index, const wxString& s )
 {
     wxListItemDataList::compatibility_iterator node = m_items.Item( index );
     if (node)
 {
     wxListItemDataList::compatibility_iterator node = m_items.Item( index );
     if (node)
@@ -1932,7 +1933,7 @@ void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
         // end of the current column
         int xpos = 0;
 
         // end of the current column
         int xpos = 0;
 
-        // find the column where this event occured
+        // find the column where this event occurred
         int col,
             countCol = m_owner->GetColumnCount();
         for (col = 0; col < countCol; col++)
         int col,
             countCol = m_owner->GetColumnCount();
         for (col = 0; col < countCol; col++)
@@ -2007,7 +2008,7 @@ void wxListHeaderWindow::OnSetFocus( wxFocusEvent &WXUNUSED(event) )
     m_owner->Update();
 }
 
     m_owner->Update();
 }
 
-bool wxListHeaderWindow::SendListEvent(wxEventType type, wxPoint pos)
+bool wxListHeaderWindow::SendListEvent(wxEventType type, const wxPoint& pos)
 {
     wxWindow *parent = GetParent();
     wxListEvent le( type, parent->GetId() );
 {
     wxWindow *parent = GetParent();
     wxListEvent le( type, parent->GetId() );
@@ -2071,7 +2072,8 @@ void wxListTextCtrl::Finish()
     if ( !m_finished )
     {
         wxPendingDelete.Append(this);
     if ( !m_finished )
     {
         wxPendingDelete.Append(this);
-
+        m_owner->m_textctrl = NULL;
+        
         m_finished = true;
 
         m_owner->SetFocusIgnoringChildren();
         m_finished = true;
 
         m_owner->SetFocusIgnoringChildren();
@@ -2100,16 +2102,21 @@ bool wxListTextCtrl::AcceptChanges()
     return true;
 }
 
     return true;
 }
 
+void wxListTextCtrl::AcceptChangesAndFinish()
+{
+    m_aboutToFinish = true;
+    // Notify the owner about the changes
+    AcceptChanges();
+    // Even if vetoed, close the control (consistent with MSW)
+    Finish();
+}
+
 void wxListTextCtrl::OnChar( wxKeyEvent &event )
 {
     switch ( event.m_keyCode )
     {
         case WXK_RETURN:
 void wxListTextCtrl::OnChar( wxKeyEvent &event )
 {
     switch ( event.m_keyCode )
     {
         case WXK_RETURN:
-            m_aboutToFinish = true;
-            // Notify the owner about the changes
-            AcceptChanges();
-            // Even if vetoed, close the control (consistent with MSW)
-            Finish();
+            AcceptChangesAndFinish();
             break;
 
         case WXK_ESCAPE:
             break;
 
         case WXK_ESCAPE:
@@ -2147,7 +2154,7 @@ void wxListTextCtrl::OnKeyUp( wxKeyEvent &event )
 
 void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
 {
 
 void wxListTextCtrl::OnKillFocus( wxFocusEvent &event )
 {
-    if ( !m_finished )
+    if ( !m_finished && !m_aboutToFinish  )
     {
         // We must finish regardless of success, otherwise we'll get
         // focus problems:
     {
         // We must finish regardless of success, otherwise we'll get
         // focus problems:
@@ -2201,7 +2208,8 @@ void wxListMainWindow::Init()
 
     m_lastOnSame = false;
     m_renameTimer = new wxListRenameTimer( this );
 
     m_lastOnSame = false;
     m_renameTimer = new wxListRenameTimer( this );
-
+    m_textctrl = NULL;
+    
     m_current =
     m_lineLastClicked =
     m_lineSelectSingleOnUp =
     m_current =
     m_lineLastClicked =
     m_lineSelectSingleOnUp =
@@ -2247,9 +2255,6 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent,
                                        wxSOLID
                                     );
 
                                        wxSOLID
                                     );
 
-    wxSize sz = size;
-    sz.y = 25;
-
     SetScrollbars( 0, 0, 0, 0, 0, 0 );
 
     wxVisualAttributes attr = wxGenericListCtrl::GetClassDefaultAttributes();
     SetScrollbars( 0, 0, 0, 0, 0, 0 );
 
     wxVisualAttributes attr = wxGenericListCtrl::GetClassDefaultAttributes();
@@ -2263,6 +2268,7 @@ wxListMainWindow::~wxListMainWindow()
 {
     DoDeleteAllItems();
     WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
 {
     DoDeleteAllItems();
     WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
+    WX_CLEAR_ARRAY(m_aColWidths);
 
     delete m_highlightBrush;
     delete m_highlightUnfocusedBrush;
 
     delete m_highlightBrush;
     delete m_highlightUnfocusedBrush;
@@ -2794,7 +2800,7 @@ void wxListMainWindow::HighlightAll( bool on )
 
 void wxListMainWindow::SendNotify( size_t line,
                                    wxEventType command,
 
 void wxListMainWindow::SendNotify( size_t line,
                                    wxEventType command,
-                                   wxPoint point )
+                                   const wxPoint& point )
 {
     wxListEvent le( command, GetParent()->GetId() );
     le.SetEventObject( GetParent() );
 {
     wxListEvent le( command, GetParent()->GetId() );
     le.SetEventObject( GetParent() );
@@ -2852,9 +2858,8 @@ void wxListMainWindow::EditLabel( long item )
     if ( m_dirty )
         wxSafeYield();
 
     if ( m_dirty )
         wxSafeYield();
 
-    wxListTextCtrl *text = new wxListTextCtrl(this, itemEdit);
-
-    text->SetFocus();
+    m_textctrl = new wxListTextCtrl(this, itemEdit);
+    m_textctrl->SetFocus();
 }
 
 void wxListMainWindow::OnRenameTimer()
 }
 
 void wxListMainWindow::OnRenameTimer()
@@ -2899,6 +2904,17 @@ void wxListMainWindow::OnRenameCancelled(size_t itemEdit)
 
 void wxListMainWindow::OnMouse( wxMouseEvent &event )
 {
 
 void wxListMainWindow::OnMouse( wxMouseEvent &event )
 {
+#ifdef __WXMAC__
+    // On wxMac we can't depend on the EVT_KILL_FOCUS event to properly
+    // shutdown the edit control when the mouse is clicked elsewhere on the
+    // listctrl because the order of events is different (or something like
+    // that,) so explicitly end the edit if it is active.
+    if ( event.LeftDown() && m_textctrl)
+    {
+        m_textctrl->AcceptChangesAndFinish();
+    }
+#endif
+    
     event.SetEventObject( GetParent() );
     if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
         return;
     event.SetEventObject( GetParent() );
     if ( GetParent()->GetEventHandler()->ProcessEvent( event) )
         return;
@@ -3013,11 +3029,11 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
             HighlightAll( false );
             ReverseHighlight(m_lineSelectSingleOnUp);
         }
             HighlightAll( false );
             ReverseHighlight(m_lineSelectSingleOnUp);
         }
-        else if (m_lastOnSame)
+        if (m_lastOnSame)
         {
             if ((current == m_current) &&
                 (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
         {
             if ((current == m_current) &&
                 (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
-                HasFlag(wxLC_EDIT_LABELS)  )
+                HasFlag(wxLC_EDIT_LABELS) )
             {
                 m_renameTimer->Start( 100, true );
             }
             {
                 m_renameTimer->Start( 100, true );
             }
@@ -3027,7 +3043,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
     }
     else
     {
     }
     else
     {
-        // This is neccessary , because after a DnD operation in
+        // This is necessary, because after a DnD operation in
         // from and to ourself, the up event is swallowed by the
         // DnD code. So on next non-up event (which means here and
         // now) m_lineSelectSingleOnUp should be reset.
         // from and to ourself, the up event is swallowed by the
         // DnD code. So on next non-up event (which means here and
         // now) m_lineSelectSingleOnUp should be reset.
@@ -3060,6 +3076,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
         m_lineLastClicked = current;
 
         size_t oldCurrent = m_current;
         m_lineLastClicked = current;
 
         size_t oldCurrent = m_current;
+        bool oldWasSelected = IsHighlighted(m_current);
+
         bool cmdModifierDown = event.CmdDown();
         if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
         {
         bool cmdModifierDown = event.CmdDown();
         if ( IsSingleSel() || !(cmdModifierDown || event.ShiftDown()) )
         {
@@ -3113,7 +3131,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
         }
 
         // forceClick is only set if the previous click was on another item
         }
 
         // forceClick is only set if the previous click was on another item
-        m_lastOnSame = !forceClick && (m_current == oldCurrent);
+        m_lastOnSame = !forceClick && (m_current == oldCurrent) && oldWasSelected;
     }
 }
 
     }
 }
 
@@ -3652,6 +3670,10 @@ void wxListMainWindow::SetItem( wxListItem &item )
         wxListLineData *line = GetLine((size_t)id);
         line->SetItem( item.m_col, item );
 
         wxListLineData *line = GetLine((size_t)id);
         line->SetItem( item.m_col, item );
 
+        // Set item state if user wants
+        if ( item.m_mask & wxLIST_MASK_STATE )
+            SetItemState( item.m_itemId, item.m_state, item.m_state );
+
         if (InReportView())
         {
             //  update the Max Width Cache if needed
         if (InReportView())
         {
             //  update the Max Width Cache if needed
@@ -3720,8 +3742,8 @@ void wxListMainWindow::SetItemState( long litem, long state, long stateMask )
         return;
     }
 
         return;
     }
 
-     wxCHECK_RET( litem >= 0 && (size_t)litem < GetItemCount(),
-                  _T("invalid list ctrl item index in SetItem") );
+    wxCHECK_RET( litem >= 0 && (size_t)litem < GetItemCount(),
+                 _T("invalid list ctrl item index in SetItem") );
 
     size_t oldCurrent = m_current;
     size_t item = (size_t)litem;    // safe because of the check above
 
     size_t oldCurrent = m_current;
     size_t item = (size_t)litem;    // safe because of the check above
@@ -3835,6 +3857,11 @@ void wxListMainWindow::GetItem( wxListItem &item ) const
 
     wxListLineData *line = GetLine((size_t)item.m_itemId);
     line->GetItem( item.m_col, item );
 
     wxListLineData *line = GetLine((size_t)item.m_itemId);
     line->GetItem( item.m_col, item );
+
+    // Get item state if user wants it
+    if ( item.m_mask & wxLIST_MASK_STATE )
+        item.m_state = GetItemState( item.m_itemId, wxLIST_STATE_SELECTED |
+                                                 wxLIST_STATE_FOCUSED );
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -4353,7 +4380,7 @@ void wxListMainWindow::DoDeleteAllItems()
         ResetVisibleLinesRange();
         for (size_t i = 0; i < m_aColWidths.GetCount(); i++)
         {
         ResetVisibleLinesRange();
         for (size_t i = 0; i < m_aColWidths.GetCount(); i++)
         {
-            delete m_aColWidths.Item(i);
+            m_aColWidths.Item(i)->bNeedsUpdate = true;
         }
     }
 
         }
     }
 
@@ -4370,6 +4397,7 @@ void wxListMainWindow::DeleteAllItems()
 void wxListMainWindow::DeleteEverything()
 {
     WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
 void wxListMainWindow::DeleteEverything()
 {
     WX_CLEAR_LIST(wxListHeaderDataList, m_columns);
+    WX_CLEAR_ARRAY(m_aColWidths);
 
     DeleteAllItems();
 }
 
     DeleteAllItems();
 }
@@ -4501,9 +4529,7 @@ void wxListMainWindow::InsertItem( wxListItem &item )
 
         // calculate the width of the item and adjust the max column width
         wxColWidthInfo *pWidthInfo = m_aColWidths.Item(item.GetColumn());
 
         // calculate the width of the item and adjust the max column width
         wxColWidthInfo *pWidthInfo = m_aColWidths.Item(item.GetColumn());
-        int width = 0;
-
-        width = GetItemWidthWithImage(&item);
+        int width = GetItemWidthWithImage(&item);
         item.SetWidth(width);
         if (width > pWidthInfo->nMaxWidth)
             pWidthInfo->nMaxWidth = width;
         item.SetWidth(width);
         if (width > pWidthInfo->nMaxWidth)
             pWidthInfo->nMaxWidth = width;
@@ -4636,7 +4662,7 @@ void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
     ResetVisibleLinesRange();
 
     // FIXME
     ResetVisibleLinesRange();
 
     // FIXME
-#if defined(__WXGTK__) && !defined(__WXUNIVERSAL__)
+#if ( defined(__WXGTK__) || defined(__WXMAC__) ) && !defined(__WXUNIVERSAL__)
     wxScrolledWindow::OnScroll(event);
 #else
     HandleOnScroll( event );
     wxScrolledWindow::OnScroll(event);
 #else
     HandleOnScroll( event );
@@ -5001,6 +5027,7 @@ void wxGenericListCtrl::SetItemText( long item, const wxString& str )
 wxUIntPtr wxGenericListCtrl::GetItemData( long item ) const
 {
     wxListItem info;
 wxUIntPtr wxGenericListCtrl::GetItemData( long item ) const
 {
     wxListItem info;
+    info.m_mask = wxLIST_MASK_DATA;
     info.m_itemId = item;
     m_mainWin->GetItem( info );
     return info.m_data;
     info.m_itemId = item;
     m_mainWin->GetItem( info );
     return info.m_data;
@@ -5099,6 +5126,22 @@ wxColour wxGenericListCtrl::GetItemBackgroundColour( long item ) const
     return info.GetBackgroundColour();
 }
 
     return info.GetBackgroundColour();
 }
 
+void wxGenericListCtrl::SetItemFont( long item, const wxFont &f )
+{
+    wxListItem info;
+    info.m_itemId = item;
+    info.SetFont( f );
+    m_mainWin->SetItem( info );
+}
+
+wxFont wxGenericListCtrl::GetItemFont( long item ) const
+{
+    wxListItem info;
+    info.m_itemId = item;
+    m_mainWin->GetItem( info );
+    return info.GetFont();
+}
+
 int wxGenericListCtrl::GetSelectedItemCount() const
 {
     return m_mainWin->GetSelectedItemCount();
 int wxGenericListCtrl::GetSelectedItemCount() const
 {
     return m_mainWin->GetSelectedItemCount();