X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/29efc6e4a478652d6f59fb3f5ca7990d78a8ead4..b85b06e13d22e7fc1604ec1a49caa1227a1b3d36:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index aff01b06a9..dccf054460 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -48,6 +48,7 @@ #include "wx/tokenzr.h" #include "wx/renderer.h" #include "wx/headerctrl.h" +#include "wx/hashset.h" #include "wx/generic/gridsel.h" #include "wx/generic/gridctrl.h" @@ -71,6 +72,9 @@ const char wxGridNameStr[] = "grid"; // Required for wxIs... functions #include +WX_DECLARE_HASH_SET_WITH_DECL(int, wxIntegerHash, wxIntegerEqual, + wxGridFixedIndicesSet, class WXDLLIMPEXP_ADV); + // ---------------------------------------------------------------------------- // globals @@ -115,26 +119,26 @@ WX_DEFINE_OBJARRAY(wxGridCellWithAttrArray) // events // ---------------------------------------------------------------------------- -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_LEFT_DCLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_RIGHT_DCLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_BEGIN_DRAG) -DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_CLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_LEFT_DCLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_LABEL_RIGHT_DCLICK) -DEFINE_EVENT_TYPE(wxEVT_GRID_ROW_SIZE) -DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SIZE) -DEFINE_EVENT_TYPE(wxEVT_GRID_COL_MOVE) -DEFINE_EVENT_TYPE(wxEVT_GRID_COL_SORT) -DEFINE_EVENT_TYPE(wxEVT_GRID_RANGE_SELECT) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGING) -DEFINE_EVENT_TYPE(wxEVT_GRID_CELL_CHANGED) -DEFINE_EVENT_TYPE(wxEVT_GRID_SELECT_CELL) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_SHOWN) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_HIDDEN) -DEFINE_EVENT_TYPE(wxEVT_GRID_EDITOR_CREATED) +wxDEFINE_EVENT( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_RIGHT_CLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_LEFT_DCLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_RIGHT_DCLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_BEGIN_DRAG, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_LABEL_LEFT_CLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_LABEL_RIGHT_CLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_LABEL_LEFT_DCLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_LABEL_RIGHT_DCLICK, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_ROW_SIZE, wxGridSizeEvent ); +wxDEFINE_EVENT( wxEVT_GRID_COL_SIZE, wxGridSizeEvent ); +wxDEFINE_EVENT( wxEVT_GRID_COL_MOVE, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_COL_SORT, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_RANGE_SELECT, wxGridRangeSelectEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_CHANGING, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_CELL_CHANGED, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_SELECT_CELL, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_EDITOR_SHOWN, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent ); +wxDEFINE_EVENT( wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent ); // ============================================================================ // implementation @@ -193,8 +197,6 @@ wxGridCellWorker::~wxGridCellWorker() void wxGridCellAttr::Init(wxGridCellAttr *attrDefault) { - m_nRef = 1; - m_isReadOnly = Unset; m_renderer = NULL; @@ -641,30 +643,30 @@ void wxGridRowOrColAttrData::SetAttr(wxGridCellAttr *attr, int rowOrCol) { if ( attr ) { - // add the attribute - no need to do anything to reference count - // since we take ownership of the attribute. + // store the new attribute, taking its ownership m_rowsOrCols.Add(rowOrCol); m_attrs.Add(attr); } // nothing to remove } - else + else // we have an attribute for this row or column { size_t n = (size_t)i; - if ( m_attrs[n] == attr ) - // nothing to do - return; + + // notice that this code works correctly even when the old attribute is + // the same as the new one: as we own of it, we must call DecRef() on + // it in any case and this won't result in destruction of the new + // attribute if it's the same as old one because it must have ref count + // of at least 2 to be passed to us while we keep a reference to it too + m_attrs[n]->DecRef(); + if ( attr ) { - // change the attribute, handling reference count manually, - // taking ownership of the new attribute. - m_attrs[n]->DecRef(); + // replace the attribute with the new one m_attrs[n] = attr; } - else + else // remove the attribute { - // remove this attribute, handling reference count manually - m_attrs[n]->DecRef(); m_rowsOrCols.RemoveAt(n); m_attrs.RemoveAt(n); } @@ -1123,11 +1125,14 @@ IMPLEMENT_DYNAMIC_CLASS( wxGridStringTable, wxGridTableBase ) wxGridStringTable::wxGridStringTable() : wxGridTableBase() { + m_numCols = 0; } wxGridStringTable::wxGridStringTable( int numRows, int numCols ) : wxGridTableBase() { + m_numCols = numCols; + m_data.Alloc( numRows ); wxArrayString sa; @@ -1137,23 +1142,6 @@ wxGridStringTable::wxGridStringTable( int numRows, int numCols ) m_data.Add( sa, numRows ); } -wxGridStringTable::~wxGridStringTable() -{ -} - -int wxGridStringTable::GetNumberRows() -{ - return m_data.GetCount(); -} - -int wxGridStringTable::GetNumberCols() -{ - if ( m_data.GetCount() > 0 ) - return m_data[0].GetCount(); - else - return 0; -} - wxString wxGridStringTable::GetValue( int row, int col ) { wxCHECK_MSG( (row < GetNumberRows()) && (col < GetNumberCols()), @@ -1323,6 +1311,8 @@ bool wxGridStringTable::InsertCols( size_t pos, size_t numCols ) } } + m_numCols += numCols; + if ( GetView() ) { wxGridTableMessage msg( this, @@ -1347,6 +1337,8 @@ bool wxGridStringTable::AppendCols( size_t numCols ) m_data[row].Add( wxEmptyString, numCols ); } + m_numCols += numCols; + if ( GetView() ) { wxGridTableMessage msg( this, @@ -1400,16 +1392,23 @@ bool wxGridStringTable::DeleteCols( size_t pos, size_t numCols ) m_colLabels.RemoveAt( colID, nToRm ); } - for ( row = 0; row < curNumRows; row++ ) + if ( numCols >= curNumCols ) { - if ( numCols >= curNumCols ) + for ( row = 0; row < curNumRows; row++ ) { m_data[row].Clear(); } - else + + m_numCols = 0; + } + else // something will be left + { + for ( row = 0; row < curNumRows; row++ ) { m_data[row].RemoveAt( colID, numCols ); } + + m_numCols -= numCols; } if ( GetView() ) @@ -1822,6 +1821,9 @@ wxGrid::~wxGrid() delete m_typeRegistry; delete m_selection; + + delete m_setFixedRows; + delete m_setFixedCols; } // @@ -2047,6 +2049,9 @@ void wxGrid::Init() m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH; m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT; + m_setFixedRows = + m_setFixedCols = NULL; + // init attr cache m_attrCache.row = -1; m_attrCache.col = -1; @@ -2916,11 +2921,12 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) // else if ( event.LeftDown() ) { - // don't send a label click event for a hit on the - // edge of the row label - this is probably the user - // wanting to resize the row - // - if ( YToEdgeOfRow(y) < 0 ) + row = YToEdgeOfRow(y); + if ( row != wxNOT_FOUND && CanDragRowSize(row) ) + { + ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin); + } + else // not a request to start resizing { row = YToRow(y); if ( row >= 0 && @@ -2948,12 +2954,6 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) ChangeCursorMode(WXGRID_CURSOR_SELECT_ROW, m_rowLabelWin); } } - else - { - // starting to drag-resize a row - if ( CanDragRowSize() ) - ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin); - } } // ------------ Left double click @@ -2961,7 +2961,19 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) else if (event.LeftDClick() ) { row = YToEdgeOfRow(y); - if ( row < 0 ) + if ( row != wxNOT_FOUND && CanDragRowSize(row) ) + { + // adjust row height depending on label text + // + // TODO: generate RESIZING event, see #10754 + AutoSizeRowLabelSize( row ); + + SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, row, -1, event); + + ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow()); + m_dragLastPos = -1; + } + else // not on row separator or it's not resizeable { row = YToRow(y); if ( row >=0 && @@ -2970,14 +2982,6 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) // no default action at the moment } } - else - { - // adjust row height depending on label text - AutoSizeRowLabelSize( row ); - - ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow()); - m_dragLastPos = -1; - } } // ------------ Left button released @@ -2985,14 +2989,7 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) else if ( event.LeftUp() ) { if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW ) - { - DoEndDragResizeRow(); - - // Note: we are ending the event *after* doing - // default processing in this case - // - SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event ); - } + DoEndDragResizeRow(event); ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, m_rowLabelWin); m_dragLastPos = -1; @@ -3027,12 +3024,11 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) else if ( event.Moving() ) { m_dragRowOrCol = YToEdgeOfRow( y ); - if ( m_dragRowOrCol >= 0 ) + if ( m_dragRowOrCol != wxNOT_FOUND ) { if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - // don't capture the mouse yet - if ( CanDragRowSize() ) + if ( CanDragRowSize(m_dragRowOrCol) ) ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin, false); } } @@ -3248,12 +3244,14 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) // else if ( event.LeftDown() ) { - // don't send a label click event for a hit on the - // edge of the col label - this is probably the user - // wanting to resize the col - // - if ( XToEdgeOfCol(x) < 0 ) + int col = XToEdgeOfCol(x); + if ( col != wxNOT_FOUND && CanDragColSize(col) ) { + ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow()); + } + else // not a request to start resizing + { + col = XToCol(x); if ( col >= 0 && !SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) ) { @@ -3294,13 +3292,6 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) } } } - else - { - // starting to drag-resize a col - // - if ( CanDragColSize() ) - ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow()); - } } // ------------ Left double click @@ -3319,8 +3310,12 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) else { // adjust column width depending on label text + // + // TODO: generate RESIZING event, see #10754 AutoSizeColLabelSize( colEdge ); + SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, colEdge, event); + ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL, GetColLabelWindow()); m_dragLastPos = -1; } @@ -3333,7 +3328,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) switch ( m_cursorMode ) { case WXGRID_CURSOR_RESIZE_COL: - DoEndDragResizeCol(); + DoEndDragResizeCol(event); break; case WXGRID_CURSOR_MOVE_COL: @@ -3394,8 +3389,7 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) { if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - // don't capture the cursor yet - if ( CanDragColSize() ) + if ( CanDragColSize(m_dragRowOrCol) ) ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow(), false); } } @@ -3459,7 +3453,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode, wxWindow *win, bool captureMouse) { -#ifdef __WXDEBUG__ +#if wxUSE_LOG_TRACE static const wxChar *cursorModes[] = { _T("SELECT_CELL"), @@ -3476,7 +3470,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode, : win ? _T("rowLabelWin") : _T("gridWin"), cursorModes[m_cursorMode], cursorModes[mode]); -#endif +#endif // wxUSE_LOG_TRACE if ( mode == m_cursorMode && win == m_winCapture && @@ -3756,17 +3750,12 @@ wxGrid::DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords) else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW ) { ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL); - DoEndDragResizeRow(); - - // Note: we are ending the event *after* doing - // default processing in this case - // - SendEvent( wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event ); + DoEndDragResizeRow(event); } else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_COL ) { ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL); - DoEndDragResizeCol(); + DoEndDragResizeCol(event); } m_dragLastPos = -1; @@ -3796,27 +3785,24 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event), return; } - if ( dragRow >= 0 ) + if ( dragRow >= 0 && CanDragGridSize() && CanDragRowSize(dragRow) ) { - m_dragRowOrCol = dragRow; - if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - if ( CanDragRowSize() && CanDragGridSize() ) - ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, NULL, false); + m_dragRowOrCol = dragRow; + ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, NULL, false); } } // When using the native header window we can only resize the columns by // dragging the dividers in it because we can't make it enter into the // column resizing mode programmatically - else if ( dragCol >= 0 && !m_useNativeHeader ) + else if ( dragCol >= 0 && !m_useNativeHeader && + CanDragGridSize() && CanDragColSize(dragCol) ) { - m_dragRowOrCol = dragCol; - if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - if ( CanDragColSize() && CanDragGridSize() ) - ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, NULL, false); + m_dragRowOrCol = dragCol; + ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, NULL, false); } } else // Neither on a row or col edge @@ -3899,10 +3885,11 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event) } } -void wxGrid::DoEndDragResizeLine(const wxGridOperations& oper) +// this function returns true only if the size really changed +bool wxGrid::DoEndDragResizeLine(const wxGridOperations& oper) { if ( m_dragLastPos == -1 ) - return; + return false; const wxGridOperations& doper = oper.Dual(); @@ -3926,9 +3913,12 @@ void wxGrid::DoEndDragResizeLine(const wxGridOperations& oper) // do resize the line const int lineStart = oper.GetLineStartPos(this, m_dragRowOrCol); + const int lineSizeOld = oper.GetLineSize(this, m_dragRowOrCol); oper.SetLineSize(this, m_dragRowOrCol, wxMax(m_dragLastPos - lineStart, oper.GetMinimalLineSize(this, m_dragRowOrCol))); + const bool + sizeChanged = oper.GetLineSize(this, m_dragRowOrCol) != lineSizeOld; m_dragLastPos = -1; @@ -3991,24 +3981,24 @@ void wxGrid::DoEndDragResizeLine(const wxGridOperations& oper) // show the edit control back again ShowCellEditControl(); + + return sizeChanged; } -void wxGrid::DoEndDragResizeRow() +void wxGrid::DoEndDragResizeRow(const wxMouseEvent& event) { - DoEndDragResizeLine(wxGridRowOperations()); + // TODO: generate RESIZING event, see #10754 + + if ( DoEndDragResizeLine(wxGridRowOperations()) ) + SendGridSizeEvent(wxEVT_GRID_ROW_SIZE, m_dragRowOrCol, -1, event); } -void wxGrid::DoEndDragResizeCol(wxMouseEvent *event) +void wxGrid::DoEndDragResizeCol(const wxMouseEvent& event) { - DoEndDragResizeLine(wxGridColumnOperations()); + // TODO: generate RESIZING event, see #10754 - // Note: we are ending the event *after* doing - // default processing in this case - // - if ( event ) - SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, *event ); - else - SendEvent( wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol ); + if ( DoEndDragResizeLine(wxGridColumnOperations()) ) + SendGridSizeEvent(wxEVT_GRID_COL_SIZE, -1, m_dragRowOrCol, event); } void wxGrid::DoStartMoveCol(int col) @@ -4182,9 +4172,27 @@ wxGrid::DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t), return (m_table->*funcAppend)(num); } -// -// ----- event handlers -// +// ---------------------------------------------------------------------------- +// event generation helpers +// ---------------------------------------------------------------------------- + +void +wxGrid::SendGridSizeEvent(wxEventType type, + int row, int col, + const wxMouseEvent& mouseEv) +{ + int rowOrCol = row == -1 ? col : row; + + wxGridSizeEvent gridEvt( GetId(), + type, + this, + rowOrCol, + mouseEv.GetX() + GetRowLabelSize(), + mouseEv.GetY() + GetColLabelSize(), + mouseEv); + + GetEventHandler()->ProcessEvent(gridEvt); +} // Generate a grid event based on a mouse event and return: // -1 if the event was vetoed @@ -4193,26 +4201,11 @@ wxGrid::DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t), int wxGrid::SendEvent(const wxEventType type, int row, int col, - wxMouseEvent& mouseEv) + const wxMouseEvent& mouseEv) { bool claimed, vetoed; - if ( type == wxEVT_GRID_ROW_SIZE || type == wxEVT_GRID_COL_SIZE ) - { - int rowOrCol = (row == -1 ? col : row); - - wxGridSizeEvent gridEvt( GetId(), - type, - this, - rowOrCol, - mouseEv.GetX() + GetRowLabelSize(), - mouseEv.GetY() + GetColLabelSize(), - mouseEv); - - claimed = GetEventHandler()->ProcessEvent(gridEvt); - vetoed = !gridEvt.IsAllowed(); - } - else if ( type == wxEVT_GRID_RANGE_SELECT ) + if ( type == wxEVT_GRID_RANGE_SELECT ) { // Right now, it should _never_ end up here! wxGridRangeSelectEvent gridEvt( GetId(), @@ -4275,28 +4268,13 @@ wxGrid::SendEvent(const wxEventType type, int wxGrid::SendEvent(const wxEventType type, int row, int col, const wxString& s) { - bool claimed, vetoed; + wxGridEvent gridEvt( GetId(), type, this, row, col ); + gridEvt.SetString(s); - if ( type == wxEVT_GRID_ROW_SIZE || type == wxEVT_GRID_COL_SIZE ) - { - int rowOrCol = (row == -1 ? col : row); - - wxGridSizeEvent gridEvt( GetId(), type, this, rowOrCol ); - - claimed = GetEventHandler()->ProcessEvent(gridEvt); - vetoed = !gridEvt.IsAllowed(); - } - else - { - wxGridEvent gridEvt( GetId(), type, this, row, col ); - gridEvt.SetString(s); - - claimed = GetEventHandler()->ProcessEvent(gridEvt); - vetoed = !gridEvt.IsAllowed(); - } + const bool claimed = GetEventHandler()->ProcessEvent(gridEvt); // A Veto'd event may not be `claimed' so test this first - if (vetoed) + if ( !gridEvt.IsAllowed() ) return -1; return claimed ? 1 : 0; @@ -5976,7 +5954,7 @@ void wxGrid::SaveEditControlValue() wxGridCellEditor* editor = attr->GetEditor(this, row, col); wxString newval; - bool changed = editor->EndEdit(oldval, &newval); + bool changed = editor->EndEdit(row, col, this, oldval, &newval); if ( changed && SendEvent(wxEVT_GRID_CELL_CHANGING, newval) != -1 ) { @@ -6124,23 +6102,15 @@ int wxGrid::XToPos(int x) const return PosToLinePos(x, true /* clip */, wxGridColumnOperations()); } -// return the row number that that the y coord is near the edge of, or -1 if +// return the row number such that the y coord is near the edge of, or -1 if // not near an edge. // -// coords can only possibly be near an edge if -// (a) the row/column is large enough to still allow for an "inner" area -// that is _not_ near the edge (i.e., if the height/width is smaller -// than WXGRID_LABEL_EDGE_ZONE, coords are _never_ considered to be -// near the edge). -// and -// (b) resizing rows/columns (the thing for which edge detection is -// relevant at all) is enabled. -// +// notice that position can only possibly be near an edge if the row/column is +// large enough to still allow for an "inner" area that is _not_ near the edge +// (i.e., if the height/width is smaller than WXGRID_LABEL_EDGE_ZONE, pos will +// _never_ be considered to be near the edge). int wxGrid::PosToEdgeOfLine(int pos, const wxGridOperations& oper) const { - if ( !oper.CanResizeLines(this) ) - return -1; - const int line = oper.PosToLine(this, pos, true); if ( oper.GetLineSize(this, line) > WXGRID_LABEL_EDGE_ZONE ) @@ -6191,13 +6161,13 @@ wxRect wxGrid::CellToRect( int row, int col ) const rect.width += GetColWidth(i); for (i=row; i < row + cell_rows; i++) rect.height += GetRowHeight(i); - } - // if grid lines are enabled, then the area of the cell is a bit smaller - if (m_gridLinesEnabled) - { - rect.width -= 1; - rect.height -= 1; + // if grid lines are enabled, then the area of the cell is a bit smaller + if (m_gridLinesEnabled) + { + rect.width -= 1; + rect.height -= 1; + } } return rect; @@ -7481,6 +7451,22 @@ wxGridCellRenderer * wxGrid::GetDefaultRendererForType(const wxString& typeName) // row/col size // ---------------------------------------------------------------------------- +void wxGrid::DoDisableLineResize(int line, wxGridFixedIndicesSet *& setFixed) +{ + if ( !setFixed ) + { + setFixed = new wxGridFixedIndicesSet; + } + + setFixed->insert(line); +} + +bool +wxGrid::DoCanResizeLine(int line, const wxGridFixedIndicesSet *setFixed) const +{ + return !setFixed || !setFixed->count(line); +} + void wxGrid::EnableDragRowSize( bool enable ) { m_canDragRowSize = enable; @@ -8083,7 +8069,8 @@ void wxGrid::DeselectLine(int line, const wxGridOperations& oper) return; const wxGridSelectionModes mode = m_selection->GetSelectionMode(); - if ( mode == oper.GetSelectionMode() ) + if ( mode == oper.GetSelectionMode() || + mode == wxGrid::wxGridSelectRowsOrColumns ) { const wxGridCellCoords c(oper.MakeCoords(line, 0)); if ( m_selection->IsInSelection(c) ) @@ -8201,8 +8188,10 @@ void wxGrid::ClearSelection() m_selectedBlockBottomRight = m_selectedBlockCorner = wxGridNoCellCoords; - Refresh( false, &r1 ); - Refresh( false, &r2 ); + if ( !r1.IsEmpty() ) + RefreshRect(r1, false); + if ( !r2.IsEmpty() ) + RefreshRect(r2, false); if ( m_selection ) m_selection->ClearSelection(); @@ -8334,6 +8323,48 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords& topLeft, return resultRect; } +void wxGrid::DoSetSizes(const wxGridSizesInfo& sizeInfo, + const wxGridOperations& oper) +{ + BeginBatch(); + oper.SetDefaultLineSize(this, sizeInfo.m_sizeDefault, true); + const int numLines = oper.GetNumberOfLines(this); + for ( int i = 0; i < numLines; i++ ) + { + int size = sizeInfo.GetSize(i); + if ( size != sizeInfo.m_sizeDefault) + oper.SetLineSize(this, i, size); + } + EndBatch(); +} + +void wxGrid::SetColSizes(const wxGridSizesInfo& sizeInfo) +{ + DoSetSizes(sizeInfo, wxGridColumnOperations()); +} + +void wxGrid::SetRowSizes(const wxGridSizesInfo& sizeInfo) +{ + DoSetSizes(sizeInfo, wxGridRowOperations()); +} + +wxGridSizesInfo::wxGridSizesInfo(int defSize, const wxArrayInt& allSizes) +{ + m_sizeDefault = defSize; + for ( size_t i = 0; i < allSizes.size(); i++ ) + { + if ( allSizes[i] != defSize ) + m_customSizes[i] = allSizes[i]; + } +} + +int wxGridSizesInfo::GetSize(unsigned pos) const +{ + wxUnsignedToIntHashMap::const_iterator it = m_customSizes.find(pos); + + return it == m_customSizes.end() ? m_sizeDefault : it->second; +} + // ---------------------------------------------------------------------------- // drop target // ----------------------------------------------------------------------------