25#include <wx/tokenzr.h>
27#include <wx/settings.h>
29#include <wx/textentry.h>
46 wxGridCellAttr::wxAttrKind aKind )
48 wxGridCellAttr* attr = aInputAttr;
50 if( wxGridCellAttrProvider* provider = GetAttrProvider() )
52 wxGridCellAttr* providerAttr = provider->GetAttr( aRow, aCol, aKind );
56 attr =
new wxGridCellAttr;
57 attr->SetKind( wxGridCellAttr::Merged );
61 attr->MergeWith( aInputAttr );
65 attr->MergeWith( providerAttr );
66 providerAttr->DecRef();
74#define MIN_GRIDCELL_MARGIN FromDIP( 2 )
81 aEntry->SetMargins( 0, 0 );
87#if defined( __WXMSW__ ) || defined( __WXGTK__ )
95 KIGFX::COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
96 KIGFX::COLOR4D fg = wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER );
107 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
110 rect.SetTop( rect.GetTop() + 1 );
111 rect.SetLeft( rect.GetLeft() + 1 );
112 rect.SetBottom( rect.GetBottom() - 1 );
113 rect.SetRight( rect.GetRight() - 1 );
114 dc.DrawRectangle( rect );
124 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
127 rect.SetTop( rect.GetTop() + 1 );
128 rect.SetLeft( rect.GetLeft() );
129 rect.SetBottom( rect.GetBottom() - 1 );
130 rect.SetRight( rect.GetRight() - 1 );
131 dc.DrawRectangle( rect );
141 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
144 rect.SetTop( rect.GetTop() + 1 );
145 rect.SetLeft( rect.GetLeft() + 1 );
146 rect.SetBottom( rect.GetBottom() - 1 );
147 rect.SetRight( rect.GetRight() );
148 dc.DrawRectangle( rect );
177 wxGridCellAttr::wxAttrKind kind )
const override
179 wxGridCellAttrPtr cellAttr( wxGridCellAttrProvider::GetAttr( row, col, kind ) );
184 return cellAttr.release();
192 if( !cellAttr->HasBackgroundColour() )
194 cellAttr = cellAttr->Clone();
195 cellAttr->SetBackgroundColour(
m_attrEven->GetBackgroundColour() );
199 return cellAttr.release();
208 long style,
const wxString&
name ) :
209 wxGrid( parent, id, pos, size, style,
name ),
210 m_weOwnTable( false )
212 SetDefaultCellOverflow(
false );
245 wxGrid::SetColLabelSize( wxGRID_AUTOSIZE );
258 if( aHeight == 0 || aHeight == wxGRID_AUTOSIZE )
260 wxGrid::SetColLabelSize( aHeight );
267 wxGrid::SetColLabelSize( std::max( aHeight, minHeight ) );
281 int numberCols = GetNumberCols();
282 int* formBuilderColWidths =
new int[numberCols];
284 for(
int i = 0; i < numberCols; ++i )
285 formBuilderColWidths[ i ] = GetColSize( i );
287 wxGrid::SetTable( aTable );
291 numberCols = std::min( numberCols, GetNumberCols() );
293 for(
int i = 0; i < numberCols; ++i )
298 SetColSize( i, std::max( formBuilderColWidths[ i ], headingWidth ) );
301 delete[] formBuilderColWidths;
315 wxGridTableBase* table = wxGrid::GetTable();
317 wxCHECK_MSG( table, ,
318 "Tried to enable alternate row colors without a table assigned to the grid" );
322 wxColor
color = wxGrid::GetDefaultCellBackgroundColour();
327 table->SetAttrProvider(
nullptr );
337 int row = aEvent.GetRow();
338 int col = aEvent.GetCol();
340 if( row >= 0 && row < GetNumberRows() && col >= 0 && col < GetNumberCols() )
342 if( GetSelectionMode() == wxGrid::wxGridSelectCells )
344 SelectBlock( row, col, row, col,
false );
346 else if( GetSelectionMode() == wxGrid::wxGridSelectRows
347 || GetSelectionMode() == wxGrid::wxGridSelectRowsOrColumns )
349 SelectBlock( row, 0, row, GetNumberCols() - 1,
false );
351 else if( GetSelectionMode() == wxGrid::wxGridSelectColumns )
353 SelectBlock( 0, col, GetNumberRows() - 1, col,
false );
363 int row = aEvent.GetRow();
364 int col = aEvent.GetCol();
366 const std::pair<wxString, wxString>& beforeAfter =
m_evalBeforeAfter[ { row, col } ];
368 if( GetCellValue( row, col ) == beforeAfter.second )
369 SetCellValue( row, col, beforeAfter.first );
385 int row = aEvent.GetRow();
386 int col = aEvent.GetCol();
389 bool isNullable =
false;
390 wxGridCellEditor* cellEditor = GetCellEditor( row, col );
400 cellEditor->DecRef();
404 [
this, row, col, isNullable, unitsProvider]()
406 wxString stringValue = GetCellValue( row, col );
407 bool processedOk =
true;
410 processedOk =
m_eval->Process( stringValue );
418 std::optional<int> val;
438 if( stringValue != evalValue )
440 SetCellValue( row, col, evalValue );
461 wxGrid::SetTable(
nullptr );
468 wxString shownColumns;
470 for(
int i = 0; i < GetNumberCols(); ++i )
472 if( IsColShown( i ) )
474 if( shownColumns.Length() )
475 shownColumns << wxT(
" " );
487 std::bitset<64> shownColumns;
489 for(
int ii = 0; ii < GetNumberCols(); ++ii )
490 shownColumns[ii] = IsColShown( ii );
498 for(
int i = 0; i < GetNumberCols(); ++i )
501 wxStringTokenizer shownTokens( shownColumns );
503 while( shownTokens.HasMoreTokens() )
506 shownTokens.GetNextToken().ToLong( &colNumber );
508 if( colNumber >= 0 && colNumber < GetNumberCols() )
509 ShowCol( (
int) colNumber );
516 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
518 if( aShownColumns[ii] )
528 if( m_nativeColumnLabels )
529 wxGrid::DrawCornerLabel( dc );
531 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
538 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
539 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
540 dc.DrawRectangle( rect.Inflate( 1 ) );
549 if( m_nativeColumnLabels )
550 wxGrid::DrawColLabel( dc, col );
552 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
555 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
562 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
563 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
564 dc.DrawRectangle( rect.Inflate( 1 ) );
570 dc.SetFont( GetLabelFont() );
573 GetColLabelAlignment( &hAlign, &vAlign );
574 const int orient = GetColLabelTextOrientation();
577 hAlign = wxALIGN_LEFT;
579 if( hAlign == wxALIGN_LEFT )
582 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
588 if( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
591 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
598 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
599 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
600 dc.DrawRectangle( rect.Inflate( 1 ) );
606 dc.SetFont( GetLabelFont() );
609 GetRowLabelAlignment(&hAlign, &vAlign);
611 if( hAlign == wxALIGN_LEFT )
614 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
620 if( !IsCellEditControlEnabled() )
623 HideCellEditControl();
626 m_cellEditCtrlEnabled =
false;
628 int row = m_currentCellCoords.GetRow();
629 int col = m_currentCellCoords.GetCol();
631 wxString oldval = GetCellValue( row, col );
634 wxGridCellAttr* attr = GetCellAttr( row, col );
635 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
637 editor->EndEdit( row, col,
this, oldval, &newval );
648 if( !IsCellEditControlEnabled() )
651 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
654 HideCellEditControl();
657 m_cellEditCtrlEnabled =
false;
659 int row = m_currentCellCoords.GetRow();
660 int col = m_currentCellCoords.GetCol();
662 wxString oldval = GetCellValue( row, col );
665 wxGridCellAttr* attr = GetCellAttr( row, col );
666 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
668 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
675 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
678 editor->ApplyEdit( row, col,
this );
683 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
686 SetCellValue( row, col, oldval );
714 wxString stringValue = GetCellValue( aRow, aCol );
720 if(
m_eval->Process( stringValue ) )
721 stringValue =
m_eval->Result();
735 wxString stringValue = GetCellValue( aRow, aCol );
742 stringValue =
m_eval->Result();
756 SetCellValue( aRow, aCol, unitsProvider->
StringFromValue( aValue,
true ) );
785 size = GetRowLabelSize();
787 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
788 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
793 size = GetColSize( aCol );
801 size = std::max( size,
802 int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
805 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
808 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
809 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
811 size = std::max( size, GetTextExtent(
"MM" ).x );
821 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
822 int row_height = GetColLabelSize();
823 int initial_row_height = row_height;
828 for(
int col = 0; col < GetNumberCols(); col++ )
830 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
835 if( row_height < line_height * ( nl_count+1 ) )
836 row_height += line_height * nl_count;
842 if( initial_row_height != row_height )
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
A color representation with 4 components: red, green, blue, alpha.
wxColour ToColour() const
COLOR4D Mix(const COLOR4D &aColor, double aFactor) const
Return a color that is mixed with the input by a factor.
static const wxString NullUiString
The string that is used in the UI to represent a null value.
std::optional< int > OptionalValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aTextValue in aUnits to internal units used by the frame.
wxString StringFromOptionalValue(std::optional< int > aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts an optional aValue in internal units into a united string.
EDA_UNITS GetUserUnits() const
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
int ValueFromString(const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aTextValue in aUnits to internal units used by the frame.
Attribute provider that provides attributes (or modifies the existing attribute) to alternate a row c...
WX_GRID_ALT_ROW_COLOR_PROVIDER(const wxColor &aBaseColor)
wxGridCellAttr * GetAttr(int row, int col, wxGridCellAttr::wxAttrKind kind) const override
wxGridCellAttrPtr m_attrEven
void UpdateColors(const wxColor &aBaseColor)
void DrawBorder(const wxGrid &grid, wxDC &dc, wxRect &rect) const override
wxGridCellAttr * enhanceAttr(wxGridCellAttr *aInputAttr, int aRow, int aCol, wxGridCellAttr::wxAttrKind aKind)
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculate the specified column based on the actual size of the text on screen.
void onGridCellSelect(wxGridEvent &aEvent)
void SetLabelFont(const wxFont &aFont)
Hide wxGrid's SetLabelFont() because for some reason on MSW it's a one-shot and subsequent calls to i...
void onDPIChanged(wxDPIChangedEvent &event)
void ShowHideColumns(const wxString &shownColumns)
Show/hide the grid columns based on a tokenized string of shown column indexes.
std::map< int, UNITS_PROVIDER * > m_unitsProviders
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
void DestroyTable(wxGridTableBase *aTable)
Work-around for a bug in wxGrid which crashes when deleting the table if the cell edit control was no...
bool CancelPendingChanges()
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
void SetUnitValue(int aRow, int aCol, int aValue)
Set a unitized cell's value.
WX_GRID(wxWindow *parent, wxWindowID id, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxWANTS_CHARS, const wxString &name=wxGridNameStr)
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
std::vector< int > m_autoEvalCols
std::map< std::pair< int, int >, std::pair< wxString, wxString > > m_evalBeforeAfter
void DrawCornerLabel(wxDC &dc) override
A re-implementation of wxGrid::DrawCornerLabel which draws flat borders.
void onCellEditorHidden(wxGridEvent &aEvent)
void onGridColMove(wxGridEvent &aEvent)
void SetOptionalUnitValue(int aRow, int aCol, std::optional< int > aValue)
Set a unitized cell's optional value.
void onCellEditorShown(wxGridEvent &aEvent)
void EnsureColLabelsVisible()
Ensure the height of the row displaying the column labels is enough, even if labels are multiline tex...
wxString GetShownColumnsAsString()
Get a tokenized string containing the shown column indexes.
void DrawRowLabel(wxDC &dc, int row) override
A re-implementation of wxGrid::DrawRowLabel which draws flat borders.
std::bitset< 64 > GetShownColumns()
static void CellEditorSetMargins(wxTextEntryBase *aEntry)
A helper function to set OS-specific margins for text-based cell editors.
std::optional< int > GetOptionalUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
void EnableAlternateRowColors(bool aEnable=true)
Enable alternate row highlighting, where every odd row has a different background color than the even...
void SetUnitsProvider(UNITS_PROVIDER *aProvider, int aCol=0)
Set a EUNITS_PROVIDER to enable use of unit- and eval-based Getters.
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
std::unique_ptr< NUMERIC_EVALUATOR > m_eval
void DrawColLabel(wxDC &dc, int col) override
A re-implementation of wxGrid::DrawColLabel which left-aligns the first column and draws flat borders...
static void CellEditorTransformSizeRect(wxRect &aRect)
A helper function to tweak sizes of text-based cell editors depending on OS.
KICOMMON_API wxFont GetControlFont(wxWindow *aWindow)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
PGM_BASE & Pgm()
The global program "get" accessor.
Functions to provide common constants and other functions to assist in making a consistent UI.
wxColour getBorderColour()
#define MIN_GRIDCELL_MARGIN