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 );
161 wxGridCellAttrProvider(),
175 wxGridCellAttr*
GetAttr(
int row,
int col, wxGridCellAttr::wxAttrKind kind )
const override
177 wxGridCellAttrPtr cellAttr( wxGridCellAttrProvider::GetAttr( row, col, kind ) );
182 return cellAttr.release();
190 if( !cellAttr->HasBackgroundColour() )
192 cellAttr = cellAttr->Clone();
193 cellAttr->SetBackgroundColour(
m_attrEven->GetBackgroundColour() );
197 return cellAttr.release();
206 long style,
const wxString&
name ) :
207 wxGrid( parent, id, pos, size, style,
name ),
208 m_weOwnTable( false )
210 SetDefaultCellOverflow(
false );
243 wxGrid::SetColLabelSize( wxGRID_AUTOSIZE );
256 if( aHeight == 0 || aHeight == wxGRID_AUTOSIZE )
258 wxGrid::SetColLabelSize( aHeight );
265 wxGrid::SetColLabelSize( std::max( aHeight, minHeight ) );
279 int numberCols = GetNumberCols();
280 int* formBuilderColWidths =
new int[numberCols];
282 for(
int i = 0; i < numberCols; ++i )
283 formBuilderColWidths[ i ] = GetColSize( i );
285 wxGrid::SetTable( aTable );
289 numberCols = std::min( numberCols, GetNumberCols() );
291 for(
int i = 0; i < numberCols; ++i )
296 SetColSize( i, std::max( formBuilderColWidths[ i ], headingWidth ) );
299 delete[] formBuilderColWidths;
313 wxGridTableBase*
table = wxGrid::GetTable();
315 wxCHECK_MSG(
table, ,
316 "Tried to enable alternate row colors without a table assigned to the grid" );
320 wxColor
color = wxGrid::GetDefaultCellBackgroundColour();
325 table->SetAttrProvider(
nullptr );
335 int row = aEvent.GetRow();
336 int col = aEvent.GetCol();
338 if( row >= 0 && row < GetNumberRows() && col >= 0 && col < GetNumberCols() )
340 if( GetSelectionMode() == wxGrid::wxGridSelectCells )
342 SelectBlock( row, col, row, col,
false );
344 else if( GetSelectionMode() == wxGrid::wxGridSelectRows
345 || GetSelectionMode() == wxGrid::wxGridSelectRowsOrColumns )
347 SelectBlock( row, 0, row, GetNumberCols() - 1,
false );
349 else if( GetSelectionMode() == wxGrid::wxGridSelectColumns )
351 SelectBlock( 0, col, GetNumberRows() - 1, col,
false );
361 int row = aEvent.GetRow();
362 int col = aEvent.GetCol();
364 const std::pair<wxString, wxString>& beforeAfter =
m_evalBeforeAfter[ { row, col } ];
366 if( GetCellValue( row, col ) == beforeAfter.second )
367 SetCellValue( row, col, beforeAfter.first );
374 const int col = aEvent.GetCol();
381 EDA_UNITS cellUnits = cellUnitsData.first;
384 m_eval->SetDefaultUnits( cellUnits );
386 const int row = aEvent.GetRow();
389 bool isNullable =
false;
390 wxGridCellEditor* cellEditor = GetCellEditor( row, col );
400 cellEditor->DecRef();
404 [
this, row, col, isNullable, unitsProvider, cellDataType]()
406 wxString stringValue = GetCellValue( row, col );
407 bool processedOk =
true;
410 processedOk =
m_eval->Process( stringValue );
418 std::optional<int> val;
441 if( stringValue != evalValue )
443 SetCellValue( row, col, evalValue );
464 wxGrid::SetTable(
nullptr );
471 wxString shownColumns;
473 for(
int i = 0; i < GetNumberCols(); ++i )
475 if( IsColShown( i ) )
477 if( shownColumns.Length() )
478 shownColumns << wxT(
" " );
490 std::bitset<64> shownColumns;
492 for(
int ii = 0; ii < GetNumberCols(); ++ii )
493 shownColumns[ii] = IsColShown( ii );
501 for(
int i = 0; i < GetNumberCols(); ++i )
504 wxStringTokenizer shownTokens( shownColumns );
506 while( shownTokens.HasMoreTokens() )
509 shownTokens.GetNextToken().ToLong( &colNumber );
511 if( colNumber >= 0 && colNumber < GetNumberCols() )
512 ShowCol( (
int) colNumber );
519 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
521 if( aShownColumns[ii] )
531 if( m_nativeColumnLabels )
532 wxGrid::DrawCornerLabel( dc );
534 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
541 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
542 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
543 dc.DrawRectangle( rect.Inflate( 1 ) );
552 if( m_nativeColumnLabels )
553 wxGrid::DrawColLabel( dc, col );
555 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
558 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
565 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
566 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
567 dc.DrawRectangle( rect.Inflate( 1 ) );
573 dc.SetFont( GetLabelFont() );
576 GetColLabelAlignment( &hAlign, &vAlign );
577 const int orient = GetColLabelTextOrientation();
580 hAlign = wxALIGN_LEFT;
582 if( hAlign == wxALIGN_LEFT )
585 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
591 if( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
594 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
601 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
602 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
603 dc.DrawRectangle( rect.Inflate( 1 ) );
609 dc.SetFont( GetLabelFont() );
612 GetRowLabelAlignment(&hAlign, &vAlign);
614 if( hAlign == wxALIGN_LEFT )
617 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
623 if( !IsCellEditControlEnabled() )
626 HideCellEditControl();
629 m_cellEditCtrlEnabled =
false;
631 int row = m_currentCellCoords.GetRow();
632 int col = m_currentCellCoords.GetCol();
634 wxString oldval = GetCellValue( row, col );
637 wxGridCellAttr* attr = GetCellAttr( row, col );
638 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
640 editor->EndEdit( row, col,
this, oldval, &newval );
651 if( !IsCellEditControlEnabled() )
654 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
657 HideCellEditControl();
660 m_cellEditCtrlEnabled =
false;
662 int row = m_currentCellCoords.GetRow();
663 int col = m_currentCellCoords.GetCol();
665 wxString oldval = GetCellValue( row, col );
668 wxGridCellAttr* attr = GetCellAttr( row, col );
669 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
671 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
678 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
681 editor->ApplyEdit( row, col,
this );
686 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
689 SetCellValue( row, col, oldval );
725 wxString stringValue = GetCellValue( aRow, aCol );
731 m_eval->SetDefaultUnits( cellUnits );
733 if(
m_eval->Process( stringValue ) )
734 stringValue =
m_eval->Result();
743 wxString stringValue = GetCellValue( aRow, aCol );
749 m_eval->SetDefaultUnits( cellUnits );
752 stringValue =
m_eval->Result();
766 cellDataType = EDA_DATA_TYPE::DISTANCE;
768 SetCellValue( aRow, aCol,
getUnitsProvider( aCol )->StringFromValue( aValue,
true, cellDataType ) );
774 SetCellValue( aRow, aCol,
getUnitsProvider( aCol )->StringFromOptionalValue( aValue,
true ) );
792 size = GetRowLabelSize();
794 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
795 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
800 size = GetColSize( aCol );
808 size = std::max( size,
809 int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
812 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
815 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
816 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
818 size = std::max( size, GetTextExtent(
"MM" ).x );
828 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
829 int row_height = GetColLabelSize();
830 int initial_row_height = row_height;
835 for(
int col = 0; col < GetNumberCols(); col++ )
837 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
842 if( row_height < line_height * ( nl_count+1 ) )
843 row_height += line_height * nl_count;
849 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
static EDA_DATA_TYPE GetTypeFromUnits(const EDA_UNITS aUnits)
Gets the inferred type from the given units.
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...
std::unordered_map< int, std::pair< EDA_UNITS, EDA_DATA_TYPE > > m_autoEvalColsUnits
void SetAutoEvalColUnits(int col, EDA_UNITS aUnit, EDA_DATA_TYPE aUnitType)
Set the unit and unit data type to use for a given column.
bool CancelPendingChanges()
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
std::pair< EDA_UNITS, EDA_DATA_TYPE > getColumnUnits(int aCol) const
Returns the units and data type associated with a given column.
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
UNITS_PROVIDER * getUnitsProvider(int aCol) const
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.
EDA_DATA_TYPE
The type of unit.
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