]> git.saurik.com Git - wxWidgets.git/blobdiff - src/generic/grid.cpp
Updated makewx... scripts
[wxWidgets.git] / src / generic / grid.cpp
index 64932052596cd28323cfc87227501d01ba0c88d7..8e541e67f2bcc62a24c703b6f5fbe1c2b5351356 100644 (file)
@@ -1556,6 +1556,15 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
                                     bool isSelected)
 {
     wxRect rect = rectCell;
+    rect.Inflate(-1);
+
+    // erase only this cells background, overflow cells should have been erased
+    wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
+
+    int hAlign, vAlign;
+    attr.GetAlignment(&hAlign, &vAlign);
+
+    int overflowCols = 0;
 
     if (attr.GetOverflow())
     {
@@ -1568,30 +1577,64 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid,
             int i, c_cols, c_rows;
             for (i = col+cell_cols; i < cols; i++)
             {
-                // check w/ anchor cell for multicell block
-                grid.GetCellSize(row, i, &c_rows, &c_cols);
-                if (c_rows > 0) c_rows = 0;
-                if (grid.GetTable()->IsEmptyCell(row+c_rows, i))
+               bool is_empty = TRUE;
+                for (int j=row; j<row+cell_rows; j++)
                 {
+                    // check w/ anchor cell for multicell block
+                    grid.GetCellSize(row, i, &c_rows, &c_cols);
+                    if (c_rows > 0) c_rows = 0;
+                    if (grid.GetTable()->IsEmptyCell(row+c_rows, i))
+                    {
+                       is_empty = FALSE;
+                       break;
+                    }
+                }
+                if (is_empty)
                     rect.width += grid.GetColSize(i);
-                    if (rect.width >= best_width) break;
+                else
+                {
+                    i--;
+                    break;
                 }
-                else break;
+                if (rect.width >= best_width) break;
+           }
+            overflowCols = i - col - cell_cols + 1;
+           if (overflowCols >= cols) overflowCols = cols - 1;
+        }
+
+        if (overflowCols > 0) // redraw overflow cells w/ proper hilight
+        {
+            hAlign = wxALIGN_LEFT; // if oveflowed then it's left aligned
+            wxRect clip = rect; 
+            clip.x += rectCell.width;
+            // draw each overflow cell individually
+            int col_end = col+cell_cols+overflowCols;
+            if (col_end >= grid.GetNumberCols())
+               col_end = grid.GetNumberCols() - 1;
+            for (int i = col+cell_cols; i <= col_end; i++)
+            {
+                clip.width = grid.GetColSize(i) - 1;
+                dc.DestroyClippingRegion();
+                dc.SetClippingRegion(clip);
+
+                SetTextColoursAndFont(grid, attr, dc,
+                                     grid.IsInSelection(row,i));
+
+                grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
+                                       rect, hAlign, vAlign);
+                clip.x += grid.GetColSize(i) - 1;
             }
+
+            rect = rectCell;
+           rect.Inflate(-1);
+            rect.width++;
+            dc.DestroyClippingRegion();
         }
     }
 
-    // erase only this cells background, overflow cells should have been erased
-    wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected);
-
     // now we only have to draw the text
     SetTextColoursAndFont(grid, attr, dc, isSelected);
 
-    int hAlign, vAlign;
-    attr.GetAlignment(&hAlign, &vAlign);
-
-    rect.Inflate(-1);
-
     grid.DrawTextRectangle(dc, grid.GetCellValue(row, col),
                            rect, hAlign, vAlign);
 }
@@ -3074,10 +3117,14 @@ bool wxGridStringTable::DeleteRows( size_t pos, size_t numRows )
 
     if ( pos >= curNumRows )
     {
-        wxString errmsg;
-        errmsg.Printf(wxT("Called wxGridStringTable::DeleteRows(pos=%d, N=%d)\nPos value is invalid for present table with %d rows"),
-                      pos, numRows, curNumRows );
-        wxFAIL_MSG( errmsg );
+        wxFAIL_MSG( wxString::Format
+                    (
+                        wxT("Called wxGridStringTable::DeleteRows(pos=%lu, N=%lu)\nPos value is invalid for present table with %lu rows"),
+                        (unsigned long)pos,
+                        (unsigned long)numRows,
+                        (unsigned long)curNumRows
+                    ) );
+
         return FALSE;
     }
 
@@ -3088,7 +3135,7 @@ bool wxGridStringTable::DeleteRows( size_t pos, size_t numRows )
 
     if ( numRows >= curNumRows )
     {
-        m_data.Empty();  // don't release memory just yet
+        m_data.Clear();
     }
     else
     {
@@ -3182,10 +3229,13 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols )
 
     if ( pos >= curNumCols )
     {
-        wxString errmsg;
-        errmsg.Printf( wxT("Called wxGridStringTable::DeleteCols(pos=%d, N=%d)...\nPos value is invalid for present table with %d cols"),
-                        pos, numCols, curNumCols );
-        wxFAIL_MSG( errmsg );
+        wxFAIL_MSG( wxString::Format
+                    (
+                        wxT("Called wxGridStringTable::DeleteCols(pos=%lu, N=%lu)\nPos value is invalid for present table with %lu cols"),
+                        (unsigned long)pos,
+                        (unsigned long)numCols,
+                        (unsigned long)curNumCols
+                    ) );
         return FALSE;
     }
 
@@ -3566,14 +3616,15 @@ void wxGridWindow::OnEraseBackground( wxEraseEvent& WXUNUSED(event) )
 // Internal helper macros for simpler use of that function
 
 static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
-                           const wxArrayInt& BorderArray, bool maxOnOverflow);
+                           const wxArrayInt& BorderArray, int nMax,
+                           bool maxOnOverflow);
 
 #define internalXToCol(x) CoordToRowOrCol(x, m_defaultColWidth, \
                                           WXGRID_MIN_COL_WIDTH, \
-                                          m_colRights, TRUE)
+                                          m_colRights, m_numCols, TRUE)
 #define internalYToRow(y) CoordToRowOrCol(y, m_defaultRowHeight, \
                                           WXGRID_MIN_ROW_HEIGHT, \
-                                          m_rowBottoms, TRUE)
+                                          m_rowBottoms, m_numRows, TRUE)
 /////////////////////////////////////////////////////////////////////
 
 IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow )
@@ -4007,7 +4058,7 @@ bool wxGrid::Redimension( wxGridTableMessage& msg )
     // removed, not only if the cell "underneath" it actually changes.
     // For now, I intentionally do not save the editor's content as the
     // cell it might want to save that stuff to might no longer exist.
-    DisableCellEditControl();
+    HideCellEditControl();
 #if 0
     // if we were using the default widths/heights so far, we must change them
     // now
@@ -4551,7 +4602,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event )
             {
                 if ( !event.ShiftDown() && !event.ControlDown() )
                     ClearSelection();
-                else if ( m_selection )
+                if ( m_selection )
                 {
                     if ( event.ShiftDown() )
                     {
@@ -5300,6 +5351,13 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
     //
     else if ( event.Moving() && !event.IsButton() )
     {
+        if( coords.GetRow() < 0 || coords.GetCol() < 0 )
+        {
+            // out of grid cell area
+            ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
+            return;
+        }
+
         int dragRow = YToEdgeOfRow( y );
         int dragCol = XToEdgeOfCol( x );
 
@@ -5760,41 +5818,90 @@ void wxGrid::OnPaint( wxPaintEvent& WXUNUSED(event) )
     wxPaintDC dc(this);  // needed to prevent zillions of paint events on MSW
 }
 
-void wxGrid::Refresh(bool eraseb, wxRect* rect)
+void wxGrid::Refresh(bool eraseb, const wxRect* rect)
 {
     // Don't do anything if between Begin/EndBatch...
     // EndBatch() will do all this on the last nested one anyway.
     if (! GetBatchCount())
     {
+        // Refresh to get correct scrolled position:
         wxScrolledWindow::Refresh(eraseb,rect);
 
-        int off_x=0 ,off_y=0;
-        wxRect * anotherrect = NULL ;
-        
         if (rect)
         {
+            int rect_x, rect_y, rectWidth, rectHeight;
+            int width_label, width_cell, height_label, height_cell;
+            int x, y;
+
             //Copy rectangle can get scroll offsets..
-            anotherrect = new wxRect(*rect);
-            CalcScrolledPosition( 0, 0, &off_x, &off_y );
-        }
-        //Corner label Doesn't move from the origin.
-        m_cornerLabelWin->Refresh(eraseb,rect);
+            rect_x = rect->GetX();
+            rect_y = rect->GetY();
+            rectWidth = rect->GetWidth();
+            rectHeight = rect->GetHeight();
 
-        //Move Rect down for row labels...
-        if (rect)
-            rect->Offset(0,off_y);
-        m_rowLabelWin->Refresh(eraseb,rect);
+            width_label = m_rowLabelWidth - rect_x;
+            if (width_label > rectWidth) width_label = rectWidth;
 
-        //Move rect copy along for col labels...
-        if (anotherrect)
-            anotherrect->Offset(off_x,0);
-        m_colLabelWin->Refresh(eraseb,anotherrect);     
+            height_label = m_colLabelHeight - rect_y;
+            if (height_label > rectHeight) height_label = rectHeight;
 
-        //Move main rect along (so it's down and across!)
-        //  for cell window.
-        if (rect)
-            rect->Offset(off_x,0);
-        m_gridWin->Refresh(eraseb,rect);
+            if (rect_x > m_rowLabelWidth)
+            {
+                x = rect_x - m_rowLabelWidth;
+                width_cell = rectWidth;
+            }
+            else
+            {
+                x = 0;
+                width_cell = rectWidth - (m_rowLabelWidth - rect_x);
+            }
+
+            if (rect_y > m_colLabelHeight)
+            {
+                y = rect_y - m_colLabelHeight;
+                height_cell = rectHeight;
+            }
+            else
+            {
+                y = 0;
+                height_cell = rectHeight - (m_colLabelHeight - rect_y);
+            }
+
+            // Paint corner label part intersecting rect.
+            if ( width_label > 0 && height_label > 0 )
+            {
+                wxRect anotherrect(rect_x, rect_y, width_label, height_label);
+                m_cornerLabelWin->Refresh(eraseb, &anotherrect);
+            }
+
+            // Paint col labels part intersecting rect.
+            if ( width_cell > 0 && height_label > 0 )
+            {
+                wxRect anotherrect(x, rect_y, width_cell, height_label);
+                m_colLabelWin->Refresh(eraseb, &anotherrect);
+            }
+
+            // Paint row labels part intersecting rect.
+            if ( width_label > 0 && height_cell > 0 )
+            {
+                wxRect anotherrect(rect_x, y, width_label, height_cell);
+                m_rowLabelWin->Refresh(eraseb, &anotherrect);
+            }
+
+            // Paint cell area part intersecting rect.
+            if ( width_cell > 0 && height_cell > 0 )
+            {
+                wxRect anotherrect(x, y, width_cell, height_cell);
+                m_gridWin->Refresh(eraseb, &anotherrect);
+            }
+        }
+        else
+        {
+            m_cornerLabelWin->Refresh(eraseb, NULL);
+            m_colLabelWin->Refresh(eraseb, NULL);     
+            m_rowLabelWin->Refresh(eraseb, NULL);
+            m_gridWin->Refresh(eraseb, NULL);
+        }
     }
 }
 
@@ -6264,8 +6371,8 @@ void wxGrid::HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCo
 
 bool wxGrid::GetModelValues()
 {
-    // Disable the editor, so it won't hide a changed value.
-    DisableCellEditControl();
+    // Hide the editor, so it won't hide a changed value.
+    HideCellEditControl();
 
     if ( m_table )
     {
@@ -6286,7 +6393,6 @@ bool wxGrid::SetModelValues()
     // Disable the editor, so it won't hide a changed value.
     // Do we also want to save the current value of the editor first?
     // I think so ...
-    SaveEditControlValue();
     DisableCellEditControl();
 
     if ( m_table )
@@ -6315,7 +6421,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
 {
     if ( !m_numRows || !m_numCols ) return;
 
-    int i, j, k, l, numCells = cells.GetCount();
+    int i, numCells = cells.GetCount();
     int row, col, cell_rows, cell_cols;
     wxGridCellCoordsArray redrawCells;
 
@@ -6330,7 +6436,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
         {
             wxGridCellCoords cell(row+cell_rows, col+cell_cols);
             bool marked = FALSE;
-            for ( j = 0;  j < numCells;  j++ )
+            for ( int j = 0;  j < numCells;  j++ )
             {
                 if ( cell == cells[j] )
                 {
@@ -6341,7 +6447,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
             if (!marked)
             {
                 int count = redrawCells.GetCount();
-                for (j = 0; j < count; j++)
+                for (int j = 0; j < count; j++)
                 {
                     if ( cell == redrawCells[j] )
                     {
@@ -6357,9 +6463,18 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
         // If this cell is empty, find cell to left that might want to overflow
         if (m_table && m_table->IsEmptyCell(row, col))
         {
-            for ( l = 0; l < cell_rows; l++ )
+            for ( int l = 0; l < cell_rows; l++ )
             {
-                for (j = col-1; j >= 0; j--)
+                // find a cell in this row to left alreay marked for repaint
+                int left = col;
+                for (int k = 0; k < int(redrawCells.GetCount()); k++)
+                    if ((redrawCells[k].GetCol() < left) &&
+                        (redrawCells[k].GetRow() == row))
+                        left=redrawCells[k].GetCol();
+
+                if (left == col) left = 0; // oh well
+
+                for (int j = col-1; j >= left; j--)
                 {
                     if (!m_table->IsEmptyCell(row+l, j))
                     {
@@ -6368,7 +6483,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
                             wxGridCellCoords cell(row+l, j);
                             bool marked = FALSE;
 
-                            for (k = 0; k < numCells; k++)
+                            for (int k = 0; k < numCells; k++)
                             {
                                 if ( cell == cells[k] )
                                 {
@@ -6379,7 +6494,7 @@ void wxGrid::DrawGridCellArea( wxDC& dc, const wxGridCellCoordsArray& cells )
                             if (!marked)
                             {
                                 int count = redrawCells.GetCount();
-                                for (k = 0; k < count; k++)
+                                for (int k = 0; k < count; k++)
                                 {
                                     if ( cell == redrawCells[k] )
                                     {
@@ -7150,31 +7265,36 @@ void wxGrid::ShowCellEditControl()
             editor->Show( TRUE, attr );
 
             // resize editor to overflow into righthand cells if allowed
+            int maxWidth = rect.width;
             wxString value = GetCellValue(row, col);
             if ( (value != wxEmptyString) && (attr->GetOverflow()) )
             {
-                wxClientDC dc(m_gridWin);
-                wxCoord y = 0, best_width = 0;
-                dc.SetFont(attr->GetFont());
-                dc.GetTextExtent(value, &best_width, &y);
-
-                int cell_rows, cell_cols;
-                attr->GetSize( &cell_rows, &cell_cols );
-
-                if ((best_width > rect.width) && (col < m_numCols) && m_table)
-                {
-                    int i;
-                    for (i = col+cell_cols; i < m_numCols; i++)
-                    {
-                        if (m_table->IsEmptyCell(row,i))
-                        {
-                            rect.width += GetColWidth(i);
-                            if (rect.width >= best_width) break;
-                        }
-                        else
-                            break;
-                    }
-                }
+                int y;
+                GetTextExtent(value, &maxWidth, &y,
+                             NULL, NULL, &attr->GetFont());
+                if (maxWidth < rect.width) maxWidth = rect.width;
+            }
+            int client_right = m_gridWin->GetClientSize().GetWidth();
+            if (rect.x+maxWidth > client_right)
+               maxWidth = client_right - rect.x;
+
+           if ((maxWidth > rect.width) && (col < m_numCols) && m_table)
+           {
+                GetCellSize( row, col, &cell_rows, &cell_cols );
+               // may have changed earlier
+               for (int i = col+cell_cols; i < m_numCols; i++)
+               {
+                    int c_rows, c_cols;
+                    GetCellSize( row, i, &c_rows, &c_cols );
+                   // looks weird going over a multicell
+                   if (m_table->IsEmptyCell(row,i) &&
+                       (rect.width < maxWidth) && (c_rows == 1))
+                       rect.width += GetColWidth(i);
+                   else
+                     break;
+               }
+                if (rect.GetRight() > client_right)
+                   rect.SetRight(client_right-1);
             }
             editor->SetSize( rect );
 
@@ -7268,15 +7388,19 @@ void wxGrid::XYToCell( int x, int y, wxGridCellCoords& coords )
 // of m_rowBottoms/m_ColRights to speed up the search!
 
 static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
-                           const wxArrayInt& BorderArray, bool maxOnOverflow)
+                           const wxArrayInt& BorderArray, int nMax,
+                           bool maxOnOverflow)
 {
     if (!defaultDist)
         defaultDist = 1;
     size_t i_max = coord / defaultDist,
            i_min = 0;
+
     if (BorderArray.IsEmpty())
     {
-        return maxOnOverflow ? (int)i_max : -1;
+        if((int) i_max < nMax)
+            return i_max;
+        return maxOnOverflow ? nMax - 1 : -1;
     }
 
     if ( i_max >= BorderArray.GetCount())
@@ -7316,14 +7440,14 @@ static int CoordToRowOrCol(int coord, int defaultDist, int minDist,
 int wxGrid::YToRow( int y )
 {
     return CoordToRowOrCol(y, m_defaultRowHeight,
-                           WXGRID_MIN_ROW_HEIGHT, m_rowBottoms, FALSE);
+                           WXGRID_MIN_ROW_HEIGHT, m_rowBottoms, m_numRows, FALSE);
 }
 
 
 int wxGrid::XToCol( int x )
 {
     return CoordToRowOrCol(x, m_defaultColWidth,
-                           WXGRID_MIN_COL_WIDTH, m_colRights, FALSE);
+                           WXGRID_MIN_COL_WIDTH, m_colRights, m_numCols, FALSE);
 }
 
 
@@ -9405,7 +9529,7 @@ wxGridCellCoordsArray wxGrid::GetSelectionBlockTopLeft() const
 wxGridCellCoordsArray wxGrid::GetSelectionBlockBottomRight() const
 {
     if (!m_selection) { wxGridCellCoordsArray a; return a; }
-    return m_selection->m_blockSelectionTopLeft;
+    return m_selection->m_blockSelectionBottomRight;
 }
 wxArrayInt wxGrid::GetSelectedRows() const
 {