X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f2d7623799d9756be1d48d2a91b8c8c7a57b911a..2912e35f1774b140b44cb9f9568aa5ab8122cd02:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 75cecfcf35..dd06aeda0b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -41,10 +41,12 @@ #include "wx/log.h" #include "wx/textctrl.h" #include "wx/checkbox.h" + #include "wx/combobox.h" + #include "wx/valtext.h" #endif -// this include needs to be outside precomp for BCC #include "wx/textfile.h" +#include "wx/spinctrl.h" #include "wx/grid.h" @@ -468,18 +470,49 @@ void wxGridCellTextEditor::PaintBackground(const wxRect& WXUNUSED(rectCell), // flicker } +void wxGridCellTextEditor::SetSize(const wxRect& rectOrig) +{ + wxRect rect(rectOrig); + + // Make the edit control large enough to allow for internal + // margins + // + // TODO: remove this if the text ctrl sizing is improved esp. for + // unix + // +#if defined(__WXGTK__) + rect.Inflate(rect.x ? 1 : 0, rect.y ? 1 : 0); +#else // !GTK + int extra = row && col ? 2 : 1; +#if defined(__WXMOTIF__) + extra *= 2; +#endif + rect.SetLeft( wxMax(0, rect.x - extra) ); + rect.SetTop( wxMax(0, rect.y - extra) ); + rect.SetRight( rect.GetRight() + 2*extra ); + rect.SetBottom( rect.GetBottom() + 2*extra ); +#endif // GTK/!GTK + + wxGridCellEditor::SetSize(rect); +} + void wxGridCellTextEditor::BeginEdit(int row, int col, wxGrid* grid) { wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be Created first!")); m_startValue = grid->GetTable()->GetValue(row, col); - Text()->SetValue(m_startValue); + + DoBeginEdit(m_startValue); +} + +void wxGridCellTextEditor::DoBeginEdit(const wxString& startValue) +{ + Text()->SetValue(startValue); Text()->SetInsertionPointEnd(); Text()->SetFocus(); } - bool wxGridCellTextEditor::EndEdit(int row, int col, bool saveValue, wxGrid* grid) { @@ -506,7 +539,12 @@ void wxGridCellTextEditor::Reset() wxASSERT_MSG(m_control, wxT("The wxGridCellEditor must be Created first!")); - Text()->SetValue(m_startValue); + DoReset(m_startValue); +} + +void wxGridCellTextEditor::DoReset(const wxString& startValue) +{ + Text()->SetValue(startValue); Text()->SetInsertionPointEnd(); } @@ -550,6 +588,187 @@ void wxGridCellTextEditor::HandleReturn(wxKeyEvent& event) #endif } +// ---------------------------------------------------------------------------- +// wxGridCellNumberEditor +// ---------------------------------------------------------------------------- + +wxGridCellNumberEditor::wxGridCellNumberEditor(int min, int max) +{ + m_min = min; + m_max = max; +} + +void wxGridCellNumberEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + if ( HasRange() ) + { + // create a spin ctrl + m_control = new wxSpinCtrl(parent, -1, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, + m_min, m_max); + + wxGridCellEditor::Create(parent, id, evtHandler); + } + else + { + // just a text control + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC)); +#endif // wxUSE_VALIDATORS + } +} + +void wxGridCellNumberEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase *table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + m_valueOld = table->GetValueAsLong(row, col); + } + else + { + wxFAIL_MSG( _T("this cell doesn't have numeric value") ); + + return; + } + + if ( HasRange() ) + { + Spin()->SetValue(m_valueOld); + } + else + { + DoBeginEdit(GetString()); + } +} + +bool wxGridCellNumberEditor::EndEdit(int row, int col, bool saveValue, + wxGrid* grid) +{ + bool changed; + long value; + + if ( HasRange() ) + { + value = Spin()->GetValue(); + changed = value != m_valueOld; + } + else + { + changed = Text()->GetValue().ToLong(&value) && (value != m_valueOld); + } + + if ( changed ) + { + grid->GetTable()->SetValueAsLong(row, col, value); + } + + return changed; +} + +void wxGridCellNumberEditor::Reset() +{ + if ( HasRange() ) + { + Spin()->SetValue(m_valueOld); + } + else + { + DoReset(GetString()); + } +} + +void wxGridCellNumberEditor::StartingKey(wxKeyEvent& event) +{ + if ( !HasRange() ) + { + long keycode = event.KeyCode(); + if ( isdigit(keycode) || keycode == '+' || keycode == '-' ) + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + } + + event.Skip(); +} +// ---------------------------------------------------------------------------- +// wxGridCellFloatEditor +// ---------------------------------------------------------------------------- + +void wxGridCellFloatEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + wxGridCellTextEditor::Create(parent, id, evtHandler); + +#if wxUSE_VALIDATORS + Text()->SetValidator(new wxTextValidator(wxFILTER_NUMERIC)); +#endif // wxUSE_VALIDATORS +} + +void wxGridCellFloatEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + // first get the value + wxGridTableBase *table = grid->GetTable(); + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + m_valueOld = table->GetValueAsDouble(row, col); + } + else + { + wxFAIL_MSG( _T("this cell doesn't have float value") ); + + return; + } + + DoBeginEdit(GetString()); +} + +bool wxGridCellFloatEditor::EndEdit(int row, int col, bool saveValue, + wxGrid* grid) +{ + double value; + if ( Text()->GetValue().ToDouble(&value) && (value != m_valueOld) ) + { + grid->GetTable()->SetValueAsDouble(row, col, value); + + return TRUE; + } + else + { + return FALSE; + } +} + +void wxGridCellFloatEditor::Reset() +{ + DoReset(GetString()); +} + +void wxGridCellFloatEditor::StartingKey(wxKeyEvent& event) +{ + long keycode = event.KeyCode(); + if ( isdigit(keycode) || + keycode == '+' || keycode == '-' || keycode == '.' ) + { + wxGridCellTextEditor::StartingKey(event); + + // skip Skip() below + return; + } + + event.Skip(); +} + // ---------------------------------------------------------------------------- // wxGridCellBoolEditor // ---------------------------------------------------------------------------- @@ -582,10 +801,10 @@ void wxGridCellBoolEditor::SetSize(const wxRect& r) void wxGridCellBoolEditor::Show(bool show, wxGridCellAttr *attr) { - wxGridCellEditor::Show(show, attr); + m_control->Show(show); + if ( show ) { - // VZ: normally base class already does it, but it doesn't work (FIXME) wxColour colBg = attr ? attr->GetBackgroundColour() : *wxLIGHT_GREY; CBox()->SetBackgroundColour(colBg); } @@ -640,6 +859,84 @@ void wxGridCellBoolEditor::StartingClick() CBox()->SetValue(!CBox()->GetValue()); } +// ---------------------------------------------------------------------------- +// wxGridCellChoiceEditor +// ---------------------------------------------------------------------------- + +wxGridCellChoiceEditor::wxGridCellChoiceEditor(size_t count, + const wxChar* choices[], + bool allowOthers) + : m_allowOthers(allowOthers) +{ + m_choices.Alloc(count); + for ( size_t n = 0; n < count; n++ ) + { + m_choices.Add(choices[n]); + } +} + +void wxGridCellChoiceEditor::Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) +{ + size_t count = m_choices.GetCount(); + wxString *choices = new wxString[count]; + for ( size_t n = 0; n < count; n++ ) + { + choices[n] = m_choices[n]; + } + + m_control = new wxComboBox(parent, id, wxEmptyString, + wxDefaultPosition, wxDefaultSize, + count, choices, + m_allowOthers ? 0 : wxCB_READONLY); + + delete [] choices; + + wxGridCellEditor::Create(parent, id, evtHandler); +} + +void wxGridCellChoiceEditor::PaintBackground(const wxRect& WXUNUSED(rectCell), + wxGridCellAttr * WXUNUSED(attr)) +{ + // as we fill the entire client area, don't do anything here to minimize + // flicker +} + +void wxGridCellChoiceEditor::BeginEdit(int row, int col, wxGrid* grid) +{ + wxASSERT_MSG(m_control, + wxT("The wxGridCellEditor must be Created first!")); + + m_startValue = grid->GetTable()->GetValue(row, col); + + Combo()->SetValue(m_startValue); + Combo()->SetInsertionPointEnd(); + Combo()->SetFocus(); +} + +bool wxGridCellChoiceEditor::EndEdit(int row, int col, + bool saveValue, + wxGrid* grid) +{ + wxString value = Combo()->GetValue(); + bool changed = value != m_startValue; + + if ( changed ) + grid->GetTable()->SetValue(row, col, value); + + m_startValue = wxEmptyString; + Combo()->SetValue(m_startValue); + + return changed; +} + +void wxGridCellChoiceEditor::Reset() +{ + Combo()->SetValue(m_startValue); + Combo()->SetInsertionPointEnd(); +} + // ---------------------------------------------------------------------------- // wxGridCellEditorEvtHandler // ---------------------------------------------------------------------------- @@ -712,20 +1009,19 @@ void wxGridCellRenderer::Draw(wxGrid& grid, dc.DrawRectangle(rect); } +wxGridCellRenderer::~wxGridCellRenderer() +{ +} + // ---------------------------------------------------------------------------- // wxGridCellStringRenderer // ---------------------------------------------------------------------------- -void wxGridCellStringRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rectCell, - int row, int col, - bool isSelected) +void wxGridCellStringRenderer::SetTextColoursAndFont(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + bool isSelected) { - wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); - - // now we only have to draw the text dc.SetBackgroundMode( wxTRANSPARENT ); // TODO some special colours for attr.IsReadOnly() case? @@ -740,65 +1036,215 @@ void wxGridCellStringRenderer::Draw(wxGrid& grid, dc.SetTextBackground( attr.GetBackgroundColour() ); dc.SetTextForeground( attr.GetTextColour() ); } + dc.SetFont( attr.GetFont() ); +} + +wxSize wxGridCellStringRenderer::DoGetBestSize(wxGridCellAttr& attr, + wxDC& dc, + const wxString& text) +{ + wxCoord x, y; + dc.SetFont(attr.GetFont()); + dc.GetTextExtent(text, &x, &y); + + return wxSize(x, y); +} + +wxSize wxGridCellStringRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, grid.GetCellValue(row, col)); +} + +void wxGridCellStringRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + 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); wxRect rect = rectCell; - rect.x++; - rect.y++; - rect.width -= 2; - rect.height -= 2; + rect.Inflate(-1); grid.DrawTextRectangle(dc, grid.GetCellValue(row, col), rect, hAlign, vAlign); } // ---------------------------------------------------------------------------- -// wxGridCellBoolRenderer +// wxGridCellNumberRenderer // ---------------------------------------------------------------------------- -void wxGridCellBoolRenderer::Draw(wxGrid& grid, - wxGridCellAttr& attr, - wxDC& dc, - const wxRect& rect, - int row, int col, - bool isSelected) +wxString wxGridCellNumberRenderer::GetString(wxGrid& grid, int row, int col) { - wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + wxGridTableBase *table = grid.GetTable(); + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_NUMBER) ) + { + text.Printf(_T("%ld"), table->GetValueAsLong(row, col)); + } + //else: leave the string empty or put 0 into it? + + return text; +} + +void wxGridCellNumberRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxRIGHT; - // between checkmark and box - static const wxCoord margin = 4; + wxRect rect = rectCell; + rect.Inflate(-1); + + grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); +} + +wxSize wxGridCellNumberRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, GetString(grid, row, col)); +} + +// ---------------------------------------------------------------------------- +// wxGridCellFloatRenderer +// ---------------------------------------------------------------------------- + +wxGridCellFloatRenderer::wxGridCellFloatRenderer(int width, int precision) +{ + SetWidth(width); + SetPrecision(precision); +} + +wxString wxGridCellFloatRenderer::GetString(wxGrid& grid, int row, int col) +{ + wxGridTableBase *table = grid.GetTable(); + wxString text; + if ( table->CanGetValueAs(row, col, wxGRID_VALUE_FLOAT) ) + { + if ( !m_format ) + { + m_format.Printf(_T("%%%d.%d%%f"), m_width, m_precision); + } + + text.Printf(m_format, table->GetValueAsDouble(row, col)); + } + //else: leave the string empty or put 0 into it? + + return text; +} + +void wxGridCellFloatRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rectCell, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rectCell, row, col, isSelected); + + SetTextColoursAndFont(grid, attr, dc, isSelected); + + // draw the text right aligned by default + int hAlign, vAlign; + attr.GetAlignment(&hAlign, &vAlign); + hAlign = wxRIGHT; + + wxRect rect = rectCell; + rect.Inflate(-1); + + grid.DrawTextRectangle(dc, GetString(grid, row, col), rect, hAlign, vAlign); +} + +wxSize wxGridCellFloatRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + int row, int col) +{ + return DoGetBestSize(attr, dc, GetString(grid, row, col)); +} - // get checkbox size - static wxCoord s_checkSize = 0; - if ( s_checkSize == 0 ) +// ---------------------------------------------------------------------------- +// wxGridCellBoolRenderer +// ---------------------------------------------------------------------------- + +wxSize wxGridCellBoolRenderer::ms_sizeCheckMark; + +// between checkmark and box +static const wxCoord wxGRID_CHECKMARK_MARGIN = 4; + +wxSize wxGridCellBoolRenderer::GetBestSize(wxGrid& grid, + wxGridCellAttr& WXUNUSED(attr), + wxDC& WXUNUSED(dc), + int WXUNUSED(row), + int WXUNUSED(col)) +{ + // compute it only once (no locks for MT safeness in GUI thread...) + if ( !ms_sizeCheckMark.x ) { - // compute it only once (no locks for MT safeness in GUI thread...) + // get checkbox size + wxCoord checkSize = 0; wxCheckBox *checkbox = new wxCheckBox(&grid, -1, wxEmptyString); wxSize size = checkbox->GetBestSize(); - s_checkSize = size.y + margin; + checkSize = size.y + wxGRID_CHECKMARK_MARGIN; - // FIXME wxGTK::wxCheckBox::GetBestSize() is really weird... + // FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result #ifdef __WXGTK__ - s_checkSize -= size.y / 2; + checkSize -= size.y / 2; #endif delete checkbox; + + ms_sizeCheckMark.x = ms_sizeCheckMark.y = checkSize; } + return ms_sizeCheckMark; +} + +void wxGridCellBoolRenderer::Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected) +{ + wxGridCellRenderer::Draw(grid, attr, dc, rect, row, col, isSelected); + // draw a check mark in the centre (ignoring alignment - TODO) + wxSize size = GetBestSize(grid, attr, dc, row, col); wxRect rectMark; - rectMark.x = rect.x + rect.width/2 - s_checkSize/2; - rectMark.y = rect.y + rect.height/2 - s_checkSize/2; - rectMark.width = rectMark.height = s_checkSize; + rectMark.x = rect.x + rect.width/2 - size.x/2; + rectMark.y = rect.y + rect.height/2 - size.y/2; + rectMark.width = size.x; + rectMark.height = size.y; dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID)); dc.DrawRectangle(rectMark); - rectMark.Inflate(-margin); + rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN); bool value; if (grid.GetTable()->CanGetValueAs(row, col, wxT("bool"))) @@ -1449,13 +1895,13 @@ wxString wxGridTableBase::GetColLabelValue( int col ) wxString wxGridTableBase::GetTypeName( int WXUNUSED(row), int WXUNUSED(col) ) { - return wxT("string"); + return wxGRID_VALUE_STRING; } bool wxGridTableBase::CanGetValueAs( int WXUNUSED(row), int WXUNUSED(col), const wxString& typeName ) { - return typeName == wxT("string"); + return typeName == wxGRID_VALUE_STRING; } bool wxGridTableBase::CanSetValueAs( int row, int col, const wxString& typeName ) @@ -2262,13 +2708,18 @@ void wxGrid::Create() m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH; m_colLabelHeight = WXGRID_DEFAULT_COL_LABEL_HEIGHT; - // data type registration + // data type registration: register all standard data types + // TODO: may be allow the app to selectively disable some of them? m_typeRegistry = new wxGridTypeRegistry; - RegisterDataType(wxT("string"), new wxGridCellStringRenderer, - new wxGridCellTextEditor); - RegisterDataType(wxT("bool"), new wxGridCellBoolRenderer, - new wxGridCellBoolEditor); - + RegisterDataType(wxGRID_VALUE_STRING, + new wxGridCellStringRenderer, + new wxGridCellTextEditor); + RegisterDataType(wxGRID_VALUE_BOOL, + new wxGridCellBoolRenderer, + new wxGridCellBoolEditor); + RegisterDataType(wxGRID_VALUE_NUMBER, + new wxGridCellNumberRenderer, + new wxGridCellNumberEditor); // subwindow components that make up the wxGrid m_cornerLabelWin = new wxGridCornerLabelWindow( this, @@ -2398,6 +2849,8 @@ void wxGrid::Init() m_cursorMode = WXGRID_CURSOR_SELECT_CELL; m_winCapture = (wxWindow *)NULL; + m_canDragRowSize = TRUE; + m_canDragColSize = TRUE; m_dragLastPos = -1; m_dragRowOrCol = -1; m_isDragging = FALSE; @@ -2974,7 +3427,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) { // starting to drag-resize a row // - ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin); + if ( CanDragRowSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin); } } @@ -3044,7 +3498,8 @@ void wxGrid::ProcessRowLabelMouseEvent( wxMouseEvent& event ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { // don't capture the mouse yet - ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin, FALSE); + if ( CanDragRowSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, m_rowLabelWin, FALSE); } } else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL ) @@ -3139,7 +3594,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) { // starting to drag-resize a col // - ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin); + if ( CanDragColSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin); } } @@ -3209,7 +3665,8 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { // don't capture the cursor yet - ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin, FALSE); + if ( CanDragColSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, m_colLabelWin, FALSE); } } else if ( m_cursorMode != WXGRID_CURSOR_SELECT_CELL ) @@ -3590,7 +4047,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW); + if ( CanDragRowSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW); } return; @@ -3602,7 +4060,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) { - ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL); + if ( CanDragColSize() ) + ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL); } return; @@ -4462,6 +4921,12 @@ void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords ) void wxGrid::DrawHighlight(wxDC& dc) { + if ( IsCellEditControlEnabled() ) + { + // don't show highlight when the edit control is shown + return; + } + // if the active cell was repainted, repaint its highlight too because it // might have been damaged by the grid lines size_t count = m_cellsExposed.GetCount(); @@ -4848,11 +5313,6 @@ bool wxGrid::IsCellEditControlEnabled() const return m_cellEditCtrlEnabled ? !IsCurrentCellReadOnly() : FALSE; } -wxWindow *wxGrid::GetGridWindow() const -{ - return m_gridWin; -} - void wxGrid::ShowCellEditControl() { if ( IsCellEditControlEnabled() ) @@ -4869,58 +5329,22 @@ void wxGrid::ShowCellEditControl() // convert to scrolled coords // - int left, top, right, bottom; - CalcScrolledPosition( rect.GetLeft(), rect.GetTop(), &left, &top ); - CalcScrolledPosition( rect.GetRight(), rect.GetBottom(), &right, &bottom ); + CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); - // cell is shifted by one pixel - left--; - top--; - right--; - bottom--; - - // Make the edit control large enough to allow for internal - // margins - // - // TODO: remove this if the text ctrl sizing is improved esp. for - // unix - // - int extra; -#if defined(__WXMOTIF__) - if ( row == 0 || col == 0 ) - { - extra = 2; - } - else - { - extra = 4; - } -#else - if ( row == 0 || col == 0 ) - { - extra = 1; - } - else - { - extra = 2; - } -#endif + // done in PaintBackground() +#if 0 + // erase the highlight and the cell contents because the editor + // might not cover the entire cell + wxClientDC dc( m_gridWin ); + PrepareDC( dc ); + dc.SetBrush(*wxLIGHT_GREY_BRUSH); //wxBrush(attr->GetBackgroundColour(), wxSOLID)); + dc.SetPen(*wxTRANSPARENT_PEN); + dc.DrawRectangle(rect); +#endif // 0 -#if defined(__WXGTK__) - int top_diff = 0; - int left_diff = 0; - if (left != 0) left_diff++; - if (top != 0) top_diff++; - rect.SetLeft( left + left_diff ); - rect.SetTop( top + top_diff ); - rect.SetRight( rect.GetRight() - left_diff ); - rect.SetBottom( rect.GetBottom() - top_diff ); -#else - rect.SetLeft( wxMax(0, left - extra) ); - rect.SetTop( wxMax(0, top - extra) ); - rect.SetRight( rect.GetRight() + 2*extra ); - rect.SetBottom( rect.GetBottom() + 2*extra ); -#endif + // cell is shifted by one pixel + rect.x--; + rect.y--; wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellEditor* editor = attr->GetEditor(GetDefaultEditorForCell(row, col)); @@ -4931,6 +5355,7 @@ void wxGrid::ShowCellEditControl() } editor->SetSize( rect ); + editor->Show( TRUE, attr ); editor->BeginEdit(row, col, this); attr->DecRef(); @@ -5017,7 +5442,7 @@ int wxGrid::YToRow( int y ) return i; } - return m_numRows; //-1; + return -1; } @@ -5031,7 +5456,7 @@ int wxGrid::XToCol( int x ) return i; } - return m_numCols; //-1; + return -1; } @@ -5866,15 +6291,15 @@ void wxGrid::SetDefaultCellFont( const wxFont& font ) m_defaultCellAttr->SetFont(font); } -// void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer) -// { -// m_defaultCellAttr->SetRenderer(renderer); -// } +void wxGrid::SetDefaultRenderer(wxGridCellRenderer *renderer) +{ + m_defaultCellAttr->SetRenderer(renderer); +} -// void wxGrid::SetDefaultEditor(wxGridCellEditor *editor) -// { -// m_defaultCellAttr->SetEditor(editor); -// } +void wxGrid::SetDefaultEditor(wxGridCellEditor *editor) +{ + m_defaultCellAttr->SetEditor(editor); +} // ---------------------------------------------------------------------------- // access to the default attrbiutes @@ -5900,15 +6325,15 @@ void wxGrid::GetDefaultCellAlignment( int *horiz, int *vert ) m_defaultCellAttr->GetAlignment(horiz, vert); } -// wxGridCellRenderer *wxGrid::GetDefaultRenderer() const -// { -// return m_defaultCellAttr->GetRenderer(); -// } +wxGridCellRenderer *wxGrid::GetDefaultRenderer() const +{ + return m_defaultCellAttr->GetRenderer(NULL); +} -// wxGridCellEditor *wxGrid::GetDefaultEditor() const -// { -// return m_defaultCellAttr->GetEditor(); -// } +wxGridCellEditor *wxGrid::GetDefaultEditor() const +{ + return m_defaultCellAttr->GetEditor(NULL); +} // ---------------------------------------------------------------------------- // access to cell attributes @@ -6182,19 +6607,20 @@ void wxGrid::RegisterDataType(const wxString& typeName, } -wxGridCellEditor* wxGrid::GetDefaultEditorForCell(int row, int col) +wxGridCellEditor* wxGrid::GetDefaultEditorForCell(int row, int col) const { wxString typeName = m_table->GetTypeName(row, col); return GetDefaultEditorForType(typeName); } -wxGridCellRenderer* wxGrid::GetDefaultRendererForCell(int row, int col) +wxGridCellRenderer* wxGrid::GetDefaultRendererForCell(int row, int col) const { wxString typeName = m_table->GetTypeName(row, col); return GetDefaultRendererForType(typeName); } -wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName) +wxGridCellEditor* +wxGrid::GetDefaultEditorForType(const wxString& typeName) const { int index = m_typeRegistry->FindDataType(typeName); if (index == -1) { @@ -6205,7 +6631,8 @@ wxGridCellEditor* wxGrid::GetDefaultEditorForType(const wxString& typeName) return m_typeRegistry->GetEditor(index); } -wxGridCellRenderer* wxGrid::GetDefaultRendererForType(const wxString& typeName) +wxGridCellRenderer* +wxGrid::GetDefaultRendererForType(const wxString& typeName) const { int index = m_typeRegistry->FindDataType(typeName); if (index == -1) { @@ -6221,6 +6648,18 @@ wxGridCellRenderer* wxGrid::GetDefaultRendererForType(const wxString& typeName) // row/col size // ---------------------------------------------------------------------------- +void wxGrid::EnableDragRowSize( bool enable ) +{ + m_canDragRowSize = enable; +} + + +void wxGrid::EnableDragColSize( bool enable ) +{ + m_canDragColSize = enable; +} + + void wxGrid::SetDefaultRowSize( int height, bool resizeExistingRows ) { m_defaultRowHeight = wxMax( height, WXGRID_MIN_ROW_HEIGHT ); @@ -6303,6 +6742,62 @@ int wxGrid::GetColMinimalWidth(int col) const return obj ? (int)obj : WXGRID_MIN_COL_WIDTH; } +void wxGrid::AutoSizeColumn( int col, bool setAsMin ) +{ + wxClientDC dc(m_gridWin); + + wxCoord width, widthMax = 0; + for ( int row = 0; row < m_numRows; row++ ) + { + wxGridCellAttr* attr = GetCellAttr(row, col); + wxGridCellRenderer* renderer = attr->GetRenderer(GetDefaultRendererForCell(row,col)); + if ( renderer ) + { + width = renderer->GetBestSize(*this, *attr, dc, row, col).x; + if ( width > widthMax ) + { + widthMax = width; + } + } + + attr->DecRef(); + } + + // now also compare with the column label width + dc.SetFont( GetLabelFont() ); + dc.GetTextExtent( GetColLabelValue(col), &width, NULL ); + if ( width > widthMax ) + { + widthMax = width; + } + + if ( !widthMax ) + { + // empty column - give default width (notice that if widthMax is less + // than default width but != 0, it's ok) + widthMax = m_defaultColWidth; + } + else + { + // leave some space around text + widthMax += 10; + } + + SetColSize(col, widthMax); + if ( setAsMin ) + { + SetColMinimalWidth(col, widthMax); + } +} + +void wxGrid::AutoSizeColumns( bool setAsMin ) +{ + for ( int col = 0; col < m_numCols; col++ ) + { + AutoSizeColumn(col, setAsMin); + } +} + // // ------ cell value accessor functions //