]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/listctrl.cpp
Bring back double border
[wxWidgets.git] / src / generic / listctrl.cpp
index c485403edb4bf1df2e528953a0fae2bf91bfed2f..67562c04aa3c3c3458f30ae4c3c9e11520db88f2 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
 // ============================================================================
@@ -1590,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);
 
@@ -1841,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;
@@ -1851,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
@@ -1880,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 )
         {
@@ -1887,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 );
 
@@ -2155,16 +2160,17 @@ bool wxListTextCtrlWrapper::AcceptChanges()
 {
     const wxString value = m_text->GetValue();
 
 {
     const wxString value = m_text->GetValue();
 
-    if ( value == m_startValue )
-        // nothing changed, always accept
-        return true;
-
+    // notice that we should always call OnRenameAccept() to generate the "end
+    // label editing" event, even if the user hasn't really changed anything
     if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
     if ( !m_owner->OnRenameAccept(m_itemEdited, value) )
+    {
         // vetoed by the user
         return false;
         // vetoed by the user
         return false;
+    }
 
 
-    // accepted, do rename the item
-    m_owner->SetItemText(m_itemEdited, value);
+    // accepted, do rename the item (unless nothing changed)
+    if ( value != m_startValue )
+        m_owner->SetItemText(m_itemEdited, value);
 
     return true;
 }
 
     return true;
 }
@@ -2444,6 +2450,20 @@ wxRect wxListMainWindow::GetLineLabelRect(size_t line) const
     if ( !InReportView() )
         return GetLine(line)->m_gi->m_rectLabel;
 
     if ( !InReportView() )
         return GetLine(line)->m_gi->m_rectLabel;
 
+    int image_x = 0;
+    wxListLineData *data = GetLine(line);
+    wxListItemDataList::compatibility_iterator node = data->m_items.GetFirst();
+    if (node)
+    {
+        wxListItemData *item = node->GetData();
+        if ( item->HasImage() )
+        {
+            int ix, iy;
+            GetImageSize( item->GetImage(), ix, iy );
+            image_x = 3 + ix + IMAGE_MARGIN_IN_REPORT_MODE;
+        }
+    }
+
     wxRect rect;
     rect.x = HEADER_OFFSET_X;
     rect.y = GetLineY(line);
     wxRect rect;
     rect.x = HEADER_OFFSET_X;
     rect.y = GetLineY(line);
@@ -2766,8 +2786,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             wxPen pen(GetRuleColour(), 1, wxSOLID);
             wxSize clientSize = GetClientSize();
 
             wxPen pen(GetRuleColour(), 1, wxSOLID);
             wxSize clientSize = GetClientSize();
 
-            // Don't draw the first one
-            for ( size_t i = visibleFrom + 1; i <= visibleTo; i++ )
+            size_t i = visibleFrom;
+            if (i == 0) i = 1; // Don't draw the first one
+            for ( ; i <= visibleTo; i++ )
             {
                 dc.SetPen(pen);
                 dc.SetBrush( *wxTRANSPARENT_BRUSH );
             {
                 dc.SetPen(pen);
                 dc.SetBrush( *wxTRANSPARENT_BRUSH );
@@ -2801,8 +2822,10 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
             {
                 int colWidth = GetColumnWidth(col);
                 x += colWidth;
             {
                 int colWidth = GetColumnWidth(col);
                 x += colWidth;
-                dc.DrawLine(x - dev_x - 2, firstItemRect.GetY() - 1 - dev_y,
-                            x - dev_x - 2, lastItemRect.GetBottom() + 1 - dev_y);
+                int x_pos = x - dev_x;
+                if (col < GetColumnCount()-1) x_pos -= 2;
+                dc.DrawLine(x_pos, firstItemRect.GetY() - 1 - dev_y,
+                            x_pos, lastItemRect.GetBottom() + 1 - dev_y);
             }
         }
     }
             }
         }
     }
@@ -3134,7 +3157,15 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
                 (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
                 HasFlag(wxLC_EDIT_LABELS) )
             {
                 (hitResult == wxLIST_HITTEST_ONITEMLABEL) &&
                 HasFlag(wxLC_EDIT_LABELS) )
             {
-                m_renameTimer->Start( 100, true );
+                if (InReportView())
+                {
+                    wxRect label = GetLineLabelRect( current );
+                    if (label.Contains( x, y ))
+                        m_renameTimer->Start( 250, true );
+
+                }
+                else
+                    m_renameTimer->Start( 250, true );
             }
         }
 
             }
         }
 
@@ -3302,7 +3333,8 @@ void wxListMainWindow::OnArrowChar(size_t newCurrent, const wxKeyEvent& event)
     else // !shift
     {
         // all previously selected items are unselected unless ctrl is held
     else // !shift
     {
         // all previously selected items are unselected unless ctrl is held
-        if ( !event.ControlDown() )
+        // in a multiselection control
+        if ( !event.ControlDown() || IsSingleSel() )
             HighlightAll(false);
 
         ChangeCurrent(newCurrent);
             HighlightAll(false);
 
         ChangeCurrent(newCurrent);
@@ -3310,10 +3342,9 @@ void wxListMainWindow::OnArrowChar(size_t newCurrent, const wxKeyEvent& event)
         // refresh the old focus to remove it
         RefreshLine( oldCurrent );
 
         // refresh the old focus to remove it
         RefreshLine( oldCurrent );
 
-        if ( !event.ControlDown() )
-        {
+        // in single selection mode we must always have a selected item
+        if ( !event.ControlDown() || IsSingleSel() )
             HighlightLine( m_current, true );
             HighlightLine( m_current, true );
-        }
     }
 
     RefreshLine( m_current );
     }
 
     RefreshLine( m_current );
@@ -3493,17 +3524,19 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
         case WXK_SPACE:
             if ( IsSingleSel() )
             {
         case WXK_SPACE:
             if ( IsSingleSel() )
             {
-                SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
-
-                if ( IsHighlighted(m_current) )
+                if ( event.ControlDown() )
+                {
+                    ReverseHighlight(m_current);
+                }
+                else // normal space press
                 {
                 {
-                    // don't unselect the item in single selection mode
-                    break;
+                    SendNotify( m_current, wxEVT_COMMAND_LIST_ITEM_ACTIVATED );
                 }
                 }
-                //else: select it in ReverseHighlight() below if unselected
             }
             }
-
-            ReverseHighlight(m_current);
+            else // multiple selection
+            {
+                ReverseHighlight(m_current);
+            }
             break;
 
         case WXK_RETURN:
             break;
 
         case WXK_RETURN:
@@ -3699,6 +3732,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 )
     {
@@ -4765,6 +4811,11 @@ int LINKAGEMODE list_ctrl_compare_func_1( wxListLineData **arg1, wxListLineData
 
 void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
 {
 
 void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
 {
+    // selections won't make sense any more after sorting the items so reset
+    // them
+    HighlightAll(false);
+    ResetCurrent();
+
     list_ctrl_compare_func_2 = fn;
     list_ctrl_compare_data = data;
     m_lines.Sort( list_ctrl_compare_func_1 );
     list_ctrl_compare_func_2 = fn;
     list_ctrl_compare_data = data;
     m_lines.Sort( list_ctrl_compare_func_1 );
@@ -4777,10 +4828,6 @@ void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data )
 
 void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
 {
 
 void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
 {
-    // update our idea of which lines are shown when we redraw the window the
-    // next time
-    ResetVisibleLinesRange();
-
     // FIXME
 #if ( defined(__WXGTK__) || defined(__WXMAC__) ) && !defined(__WXUNIVERSAL__)
     wxScrolledWindow::OnScroll(event);
     // FIXME
 #if ( defined(__WXGTK__) || defined(__WXMAC__) ) && !defined(__WXUNIVERSAL__)
     wxScrolledWindow::OnScroll(event);
@@ -4788,6 +4835,10 @@ void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
     HandleOnScroll( event );
 #endif
 
     HandleOnScroll( event );
 #endif
 
+    // update our idea of which lines are shown when we redraw the window the
+    // next time
+    ResetVisibleLinesRange();
+
     if ( event.GetOrientation() == wxHORIZONTAL && HasHeader() )
     {
         wxGenericListCtrl* lc = GetListCtrl();
     if ( event.GetOrientation() == wxHORIZONTAL && HasHeader() )
     {
         wxGenericListCtrl* lc = GetListCtrl();
@@ -4949,6 +5000,9 @@ bool wxGenericListCtrl::Create(wxWindow *parent,
     if ( !wxControl::Create( parent, id, pos, size, style, validator, name ) )
         return false;
 
     if ( !wxControl::Create( parent, id, pos, size, style, validator, name ) )
         return false;
 
+    // this window itself shouldn't get the focus, only m_mainWin should
+    SetCanFocus(false);
+
     // don't create the inner window with the border
     style &= ~wxBORDER_MASK;
 
     // don't create the inner window with the border
     style &= ~wxBORDER_MASK;
 
@@ -5159,7 +5213,7 @@ wxUIntPtr wxGenericListCtrl::GetItemData( long item ) const
     return info.m_data;
 }
 
     return info.m_data;
 }
 
-bool wxGenericListCtrl::SetItemData( long item, long data )
+bool wxGenericListCtrl::SetItemPtrData( long item, wxUIntPtr data )
 {
     wxListItem info;
     info.m_mask = wxLIST_MASK_DATA;
 {
     wxListItem info;
     info.m_mask = wxLIST_MASK_DATA;