]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
Applied some of patch [ 688466 ] MSVC7 build & bug fixes
[wxWidgets.git] / src / generic / grid.cpp
index 405f72dc0df4b88b50e683de3d7cd0bf60e1dc4e..f60e2bced655fa141799fc2421fa8d87f5b66099 100644 (file)
 
 #if wxUSE_GRID
 
-#if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID)
-    #include "gridg.cpp"
-#else // wxUSE_NEW_GRID
-
 #ifndef WX_PRECOMP
     #include "wx/utils.h"
     #include "wx/dcclient.h"
@@ -89,6 +85,10 @@ struct wxGridCellWithAttr
 
     wxGridCellCoords coords;
     wxGridCellAttr  *attr;
+
+// Cannot do this:
+//  DECLARE_NO_COPY_CLASS(wxGridCellWithAttr)
+// without rewriting the macros, which require a public copy constructor.
 };
 
 WX_DECLARE_EXPORTED_OBJARRAY(wxGridCellWithAttr, wxGridCellWithAttrArray);
@@ -141,6 +141,7 @@ private:
 
     DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow)
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxGridRowLabelWindow)
 };
 
 
@@ -162,6 +163,7 @@ private:
 
     DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow)
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxGridColLabelWindow)
 };
 
 
@@ -183,6 +185,7 @@ private:
 
     DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow)
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxGridCornerLabelWindow)
 };
 
 class WXDLLEXPORT wxGridWindow : public wxWindow
@@ -203,6 +206,8 @@ public:
 
     void ScrollWindow( int dx, int dy, const wxRect *rect );
 
+    wxGrid* GetOwner() { return m_owner; }
+
 private:
     wxGrid                   *m_owner;
     wxGridRowLabelWindow     *m_rowLabelWin;
@@ -218,6 +223,7 @@ private:
 
     DECLARE_DYNAMIC_CLASS(wxGridWindow)
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxGridWindow)
 };
 
 
@@ -240,6 +246,7 @@ private:
     wxGridCellEditor*   m_editor;
     DECLARE_DYNAMIC_CLASS(wxGridCellEditorEvtHandler)
     DECLARE_EVENT_TABLE()
+    DECLARE_NO_COPY_CLASS(wxGridCellEditorEvtHandler)
 };
 
 
@@ -320,6 +327,8 @@ struct wxGridDataTypeInfo
     wxString            m_typeName;
     wxGridCellRenderer* m_renderer;
     wxGridCellEditor*   m_editor;
+
+    DECLARE_NO_COPY_CLASS(wxGridDataTypeInfo)
 };
 
 
@@ -424,6 +433,7 @@ static inline int GetScrollY(int y)
 wxGridCellEditor::wxGridCellEditor()
 {
     m_control = NULL;
+    m_attr = NULL;
 }
 
 
@@ -445,6 +455,10 @@ void wxGridCellEditor::PaintBackground(const wxRect& rectCell,
 {
     // erase the background because we might not fill the cell
     wxClientDC dc(m_control->GetParent());
+    wxGridWindow* gridWindow = wxDynamicCast(m_control->GetParent(), wxGridWindow);
+    if (gridWindow)
+        gridWindow->GetOwner()->PrepareDC(dc);
+    
     dc.SetPen(*wxTRANSPARENT_PEN);
     dc.SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID));
     dc.DrawRectangle(rectCell);
@@ -905,7 +919,7 @@ void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event)
 {
     if ( !HasRange() )
     {
-        int keycode = (int) event.KeyCode();
+        int keycode = event.GetKeyCode();
         if ( isdigit(keycode) || keycode == '+' || keycode == '-'
             || keycode ==  WXK_NUMPAD0
             || keycode ==  WXK_NUMPAD1
@@ -1045,7 +1059,7 @@ void wxGridCellFloatEditor::Reset()
 
 void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event)
 {
-    int keycode = (int)event.KeyCode();
+    int keycode = event.GetKeyCode();
         if ( isdigit(keycode) || keycode == '+' || keycode == '-' || keycode == '.'
             || keycode ==  WXK_NUMPAD0
             || keycode ==  WXK_NUMPAD1
@@ -1216,7 +1230,32 @@ void wxGridCellBoolEditor::SetSize(const wxRect& r)
     size.y -= 2;
 #endif
 
-    m_control->Move(r.x + r.width/2 - size.x/2, r.y + r.height/2 - size.y/2);
+    int hAlign = wxALIGN_CENTRE;
+    int vAlign = wxALIGN_CENTRE;
+    if (GetCellAttr())
+        GetCellAttr()->GetAlignment(& hAlign, & vAlign);
+
+    int x = 0, y = 0;
+    if (hAlign == wxALIGN_LEFT)
+    {
+        x = r.x + 2;
+#ifdef __WXMSW__
+        x += 2;
+#endif
+        y = r.y + r.height/2 - size.y/2;
+    }
+    else if (hAlign == wxALIGN_RIGHT)
+    {
+        x = r.x + r.width - size.x - 2;
+        y = r.y + r.height/2 - size.y/2;
+    }
+    else if (hAlign == wxALIGN_CENTRE)
+    {
+        x = r.x + r.width/2 - size.x/2;
+        y = r.y + r.height/2 - size.y/2;
+    }
+
+    m_control->Move(x, y);
 }
 
 void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr)
@@ -1452,7 +1491,7 @@ wxString wxGridCellChoiceEditor::GetValue() const
 
 void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
 {
-    switch ( event.KeyCode() )
+    switch ( event.GetKeyCode() )
     {
         case WXK_ESCAPE:
             m_editor->Reset();
@@ -1477,7 +1516,7 @@ void wxGridCellEditorEvtHandler::OnKeyDown(wxKeyEvent& event)
 
 void wxGridCellEditorEvtHandler::OnChar(wxKeyEvent& event)
 {
-    switch ( event.KeyCode() )
+    switch ( event.GetKeyCode() )
     {
         case WXK_ESCAPE:
         case WXK_TAB:
@@ -1532,7 +1571,7 @@ void wxGridCellRenderer::Draw(wxGrid& grid,
       {
           dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) );
       }
-    }  
+    }
     else
     {
       dc.SetBrush(wxBrush(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_BTNFACE), wxSOLID));
@@ -1950,11 +1989,31 @@ void wxGridCellBoolRenderer::Draw(wxGrid& grid,
     }
 
     // draw a border around checkmark
+    int vAlign, hAlign;
+    attr.GetAlignment(& hAlign, &vAlign);
+
     wxRect rectBorder;
-    rectBorder.x = rect.x + rect.width/2 - size.x/2;
-    rectBorder.y = rect.y + rect.height/2 - size.y/2;
-    rectBorder.width = size.x;
-    rectBorder.height = size.y;
+    if (hAlign == wxALIGN_CENTRE)
+    {
+        rectBorder.x = rect.x + rect.width/2 - size.x/2;
+        rectBorder.y = rect.y + rect.height/2 - size.y/2;
+        rectBorder.width = size.x;
+        rectBorder.height = size.y;
+    }
+    else if (hAlign == wxALIGN_LEFT)
+    {
+        rectBorder.x = rect.x + 2;
+        rectBorder.y = rect.y + rect.height/2 - size.y/2;
+        rectBorder.width = size.x;
+        rectBorder.height = size.y;
+    }
+    else if (hAlign == wxALIGN_RIGHT)
+    {
+        rectBorder.x = rect.x + rect.width - size.x - 2;
+        rectBorder.y = rect.y + rect.height/2 - size.y/2;
+        rectBorder.width = size.x;
+        rectBorder.height = size.y;
+    }
 
     bool value;
     if ( grid.GetTable()->CanGetValueAs(row, col, wxGRID_VALUE_BOOL) )
@@ -3900,14 +3959,14 @@ void wxGrid::Init()
     // TODO: something better than this ?
     //
     m_labelFont = this->GetFont();
-//    m_labelFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
-//    m_labelFont.SetWeight( m_labelFont.GetWeight() + 2 );
+    m_labelFont.SetWeight( wxBOLD );
 
     m_rowLabelHorizAlign = wxALIGN_CENTRE;
     m_rowLabelVertAlign  = wxALIGN_CENTRE;
 
     m_colLabelHorizAlign = wxALIGN_CENTRE;
     m_colLabelVertAlign  = wxALIGN_CENTRE;
+    m_colLabelTextOrientation = wxHORIZONTAL;
 
     m_defaultColWidth  = WXGRID_DEFAULT_COL_WIDTH;
     m_defaultRowHeight = m_gridWin->GetCharHeight();
@@ -3943,10 +4002,8 @@ void wxGrid::Init()
 
     m_selectingTopLeft = wxGridNoCellCoords;
     m_selectingBottomRight = wxGridNoCellCoords;
-//  m_selectionBackground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
-//  m_selectionForeground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
-    m_selectionBackground = *wxBLACK; 
-    m_selectionForeground = *wxWHITE; 
+    m_selectionBackground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
+    m_selectionForeground = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT);
 
     m_editable = TRUE;  // default for whole grid
 
@@ -4730,11 +4787,20 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
     //
     else if (event.LeftDClick() )
     {
-        if ( YToEdgeOfRow(y) < 0 )
+        int row = YToEdgeOfRow(y);
+        if ( row < 0 )
         {
             row = YToRow(y);
             SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, row, -1, event );
         }
+        else
+        {
+            // adjust row height depending on label text
+            AutoSizeRowLabelSize( row );
+
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin);
+            m_dragLastPos  = -1;
+        }
     }
 
 
@@ -4936,11 +5002,20 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
     //
     if ( event.LeftDClick() )
     {
-        if ( XToEdgeOfCol(x) < 0 )
+        int col = XToEdgeOfCol(x);
+        if ( col < 0 )
         {
             col = XToCol(x);
             SendEvent( wxEVT_GRID_LABEL_LEFT_DCLICK, -1, col, event );
         }
+        else
+        {
+            // adjust column width depending on label text
+            AutoSizeColLabelSize( col );
+
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_colLabelWin);
+            m_dragLastPos  = -1;
+        }
     }
 
 
@@ -5331,15 +5406,15 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     {
         if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
         {
+            if (m_winCapture)
+            {
+                if (m_winCapture->HasCapture()) m_winCapture->ReleaseMouse();
+                m_winCapture = NULL;
+            }
+
             if ( m_selectingTopLeft != wxGridNoCellCoords &&
                  m_selectingBottomRight != wxGridNoCellCoords )
             {
-                if (m_winCapture)
-                {
-                    if (m_winCapture->HasCapture()) m_winCapture->ReleaseMouse();
-                    m_winCapture = NULL;
-                }
-
                 if ( m_selection )
                 {
                     m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
@@ -6020,7 +6095,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
 
         // try local handlers
         //
-        switch ( event.KeyCode() )
+        switch ( event.GetKeyCode() )
         {
             case WXK_UP:
                 if ( event.ControlDown() )
@@ -6185,7 +6260,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
 
                     // <F2> is special and will always start editing, for
                     // other keys - ask the editor itself
-                    if ( (event.KeyCode() == WXK_F2 && !event.HasModifiers())
+                    if ( (event.GetKeyCode() == WXK_F2 && !event.HasModifiers())
                          || editor->IsAcceptedKey(event) )
                     {
                         // ensure cell is visble
@@ -6223,7 +6298,7 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
 {
     // try local handlers
     //
-    if ( event.KeyCode() == WXK_SHIFT )
+    if ( event.GetKeyCode() == WXK_SHIFT )
     {
         if ( m_selectingTopLeft != wxGridNoCellCoords &&
              m_selectingBottomRight != wxGridNoCellCoords )
@@ -7003,99 +7078,130 @@ void wxGrid::DrawColLabel( wxDC& dc, int col )
     dc.SetTextForeground( GetLabelTextColour() );
     dc.SetFont( GetLabelFont() );
 
-    dc.SetBackgroundMode( wxTRANSPARENT );
-    dc.SetTextForeground( GetLabelTextColour() );
-    dc.SetFont( GetLabelFont() );
-
-    int hAlign, vAlign;
+    int hAlign, vAlign, orient;
     GetColLabelAlignment( &hAlign, &vAlign );
+    orient = GetColLabelTextOrientation();
 
     wxRect rect;
     rect.SetX( colLeft + 2 );
     rect.SetY( 2 );
     rect.SetWidth( GetColWidth(col) - 4 );
     rect.SetHeight( m_colLabelHeight - 4 );
-    DrawTextRectangle( dc, GetColLabelValue( col ), rect, hAlign, vAlign );
+    DrawTextRectangle( dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
 }
 
 void wxGrid::DrawTextRectangle( wxDC& dc,
                                 const wxString& value,
                                 const wxRect& rect,
                                 int horizAlign,
-                                int vertAlign )
+                                int vertAlign,
+                                int textOrientation )
 {
     wxArrayString lines;
-
+    
     StringToLines( value, lines );
-
-
+    
+    
     //Forward to new API.
     DrawTextRectangle(  dc,
-                        lines,
-                        rect,
-                        horizAlign,
-                        vertAlign );
-
+        lines,
+        rect,
+        horizAlign,
+        vertAlign,
+        textOrientation );
+    
 }
 
 void wxGrid::DrawTextRectangle( wxDC& dc,
-                                const wxArrayString& lines,
-                                const wxRect& rect,
-                                int horizAlign,
-                                int vertAlign )
+                               const wxArrayString& lines,
+                               const wxRect& rect,
+                               int horizAlign,
+                               int vertAlign,
+                               int textOrientation )
 {
     long textWidth, textHeight;
     long lineWidth, lineHeight;
     int nLines;
-
+    
     dc.SetClippingRegion( rect );
-
+    
     nLines = lines.GetCount();
     if( nLines > 0 )
     {
-      int l;
-      float x, y;
-      GetTextBoxSize(dc, lines, &textWidth, &textHeight);
-      switch( vertAlign )
-      {
+        int l;
+        float x = 0.0, y = 0.0;
+        
+        if( textOrientation == wxHORIZONTAL )
+            GetTextBoxSize(dc, lines, &textWidth, &textHeight);
+        else
+            GetTextBoxSize( dc, lines, &textHeight, &textWidth );
+        
+        switch( vertAlign )
+        {
         case wxALIGN_BOTTOM:
-          y = rect.y + (rect.height - textHeight - 1);
-          break;
-
+            if( textOrientation == wxHORIZONTAL )
+                y = rect.y + (rect.height - textHeight - 1);
+            else
+                x = rect.x + rect.width - textWidth;
+            break;
+            
         case wxALIGN_CENTRE:
-          y = rect.y + ((rect.height - textHeight)/2);
-          break;
-
+            if( textOrientation == wxHORIZONTAL )
+                y = rect.y + ((rect.height - textHeight)/2);
+            else
+                x = rect.x + ((rect.width - textWidth)/2);
+            break;
+            
         case wxALIGN_TOP:
         default:
-          y = rect.y + 1;
-          break;
-      }
-
-      // Align each line of a multi-line label
-      for( l = 0; l < nLines; l++ )
-      {
-        dc.GetTextExtent(lines[l], &lineWidth, &lineHeight);
-
-        switch( horizAlign )
-        {
-          case wxALIGN_RIGHT:
-            x = rect.x + (rect.width - lineWidth - 1);
-            break;
-
-          case wxALIGN_CENTRE:
-            x = rect.x + ((rect.width - lineWidth)/2);
-            break;
-
-          case wxALIGN_LEFT:
-          default:
-            x = rect.x + 1;
+            if( textOrientation == wxHORIZONTAL )
+                y = rect.y + 1;
+            else
+                x = rect.x + 1;
             break;
         }
-
-        dc.DrawText( lines[l], (int)x, (int)y );
-        y += lineHeight;
-      }
+        
+        // Align each line of a multi-line label
+        for( l = 0; l < nLines; l++ )
+        {
+            dc.GetTextExtent(lines[l], &lineWidth, &lineHeight);
+            
+            switch( horizAlign )
+            {
+            case wxALIGN_RIGHT:
+                if( textOrientation == wxHORIZONTAL )
+                    x = rect.x + (rect.width - lineWidth - 1);
+                else
+                    y = rect.y + lineWidth + 1;
+                break;
+                
+            case wxALIGN_CENTRE:
+                if( textOrientation == wxHORIZONTAL )
+                    x = rect.x + ((rect.width - lineWidth)/2);
+                else
+                    y = rect.y + rect.height - ((rect.height - lineWidth)/2);
+                break;
+                
+            case wxALIGN_LEFT:
+            default:
+                if( textOrientation == wxHORIZONTAL )
+                    x = rect.x + 1;
+                else
+                    y = rect.y + rect.height - 1;
+                break;
+            }
+            
+            if( textOrientation == wxHORIZONTAL )
+            {
+                dc.DrawText( lines[l], (int)x, (int)y );
+                y += lineHeight;
+            }
+            else
+            {
+                dc.DrawRotatedText( lines[l], (int)x, (int)y, 90.0 );
+                x += lineHeight;
+            }
+        }
     }
     dc.DestroyClippingRegion();
 }
@@ -7388,6 +7494,7 @@ void wxGrid::ShowCellEditControl()
                     rect.SetRight(client_right-1);
             }
 
+            editor->SetCellAttr(attr);
             editor->SetSize( rect );
             editor->Show( TRUE, attr );
 
@@ -7396,6 +7503,7 @@ void wxGrid::ShowCellEditControl()
             CalcDimensions();
 
             editor->BeginEdit(row, col, this);
+            editor->SetCellAttr(NULL);
 
             editor->DecRef();
             attr->DecRef();
@@ -7890,7 +7998,7 @@ bool wxGrid::MovePageUp()
 
         int y = GetRowTop(row);
         int newRow = YToRow( y - ch + 1 );
-        if ( newRow == -1 )
+        if ( newRow < 0 )
         {
             newRow = 0;
         }
@@ -8211,6 +8319,11 @@ void wxGrid::GetColLabelAlignment( int *horiz, int *vert )
     *vert  = m_colLabelVertAlign;
 }
 
+int wxGrid::GetColLabelTextOrientation()
+{
+    return m_colLabelTextOrientation;
+}
+
 wxString wxGrid::GetRowLabelValue( int row )
 {
     if ( m_table )
@@ -8393,6 +8506,26 @@ void wxGrid::SetColLabelAlignment( int horiz, int vert )
     }
 }
 
+// Note:       under MSW, the default column label font must be changed because it
+//                             does not support vertical printing
+//
+// Example: wxFont font(9, wxSWISS, wxNORMAL, wxBOLD);
+//                             pGrid->SetLabelFont(font);
+//             pGrid->SetColLabelTextOrientation(wxVERTICAL);
+//
+void wxGrid::SetColLabelTextOrientation( int textOrientation )
+{
+    if( textOrientation == wxHORIZONTAL || textOrientation == wxVERTICAL )
+    {
+        m_colLabelTextOrientation = textOrientation;
+    }
+
+    if ( !GetBatchCount() )
+    {
+        m_colLabelWin->Refresh();
+    }
+}
+
 void wxGrid::SetRowLabelValue( int row, const wxString& s )
 {
     if ( m_table )
@@ -9264,7 +9397,11 @@ void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column )
     dc.SetFont( GetLabelFont() );
 
     if ( column )
+    {
         dc.GetTextExtent( GetColLabelValue(col), &w, &h );
+        if( GetColLabelTextOrientation() == wxVERTICAL )
+            w = h;
+    }
     else
         dc.GetTextExtent( GetRowLabelValue(row), &w, &h );
 
@@ -9449,6 +9586,55 @@ void wxGrid::AutoSize()
     SetClientSize(sizeFit);
 }
 
+void wxGrid::AutoSizeRowLabelSize( int row )
+{
+    wxArrayString lines;
+    long w, h;
+
+    // Hide the edit control, so it
+    // won't interfer with drag-shrinking.
+    if( IsCellEditControlShown() )
+    {
+        HideCellEditControl();
+        SaveEditControlValue();
+    }
+
+    // autosize row height depending on label text
+    StringToLines( GetRowLabelValue( row ), lines );
+    wxClientDC dc( m_rowLabelWin );
+    GetTextBoxSize( dc, lines, &w, &h);
+    if( h < m_defaultRowHeight )
+        h = m_defaultRowHeight;
+    SetRowSize(row, h);
+    ForceRefresh();
+}
+
+void wxGrid::AutoSizeColLabelSize( int col )
+{
+    wxArrayString lines;
+    long w, h;
+
+    // Hide the edit control, so it
+    // won't interfer with drag-shrinking.
+    if( IsCellEditControlShown() )
+    {
+        HideCellEditControl();
+        SaveEditControlValue();
+    }
+
+    // autosize column width depending on label text
+    StringToLines( GetColLabelValue( col ), lines );
+    wxClientDC dc( m_colLabelWin );
+    if( GetColLabelTextOrientation() == wxHORIZONTAL )
+        GetTextBoxSize( dc, lines, &w, &h);
+    else
+        GetTextBoxSize( dc, lines, &h, &w);
+    if( w < m_defaultColWidth )
+        w = m_defaultColWidth;
+    SetColSize(col, w);
+    ForceRefresh();
+}
+
 wxSize wxGrid::DoGetBestSize() const
 {
     // don't set sizes, only calculate them
@@ -9841,7 +10027,5 @@ wxGridEditorCreatedEvent::wxGridEditorCreatedEvent(int id, wxEventType type,
     m_ctrl = ctrl;
 }
 
-
-#endif // !wxUSE_NEW_GRID/wxUSE_NEW_GRID
-
 #endif // wxUSE_GRID
+