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 );
383 int row = aEvent.GetRow();
384 int col = aEvent.GetCol();
387 bool isNullable =
false;
388 wxGridCellEditor* cellEditor = GetCellEditor( row, col );
398 cellEditor->DecRef();
402 [
this, row, col, isNullable, unitsProvider]()
404 wxString stringValue = GetCellValue( row, col );
405 bool processedOk =
true;
408 processedOk =
m_eval->Process( stringValue );
416 std::optional<int> val;
436 if( stringValue != evalValue )
438 SetCellValue( row, col, evalValue );
459 wxGrid::SetTable(
nullptr );
466 wxString shownColumns;
468 for(
int i = 0; i < GetNumberCols(); ++i )
470 if( IsColShown( i ) )
472 if( shownColumns.Length() )
473 shownColumns << wxT(
" " );
485 std::bitset<64> shownColumns;
487 for(
int ii = 0; ii < GetNumberCols(); ++ii )
488 shownColumns[ii] = IsColShown( ii );
496 for(
int i = 0; i < GetNumberCols(); ++i )
499 wxStringTokenizer shownTokens( shownColumns );
501 while( shownTokens.HasMoreTokens() )
504 shownTokens.GetNextToken().ToLong( &colNumber );
506 if( colNumber >= 0 && colNumber < GetNumberCols() )
507 ShowCol( (
int) colNumber );
514 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
516 if( aShownColumns[ii] )
526 if( m_nativeColumnLabels )
527 wxGrid::DrawCornerLabel( dc );
529 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
536 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
537 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
538 dc.DrawRectangle( rect.Inflate( 1 ) );
547 if( m_nativeColumnLabels )
548 wxGrid::DrawColLabel( dc, col );
550 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
553 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
560 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
561 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
562 dc.DrawRectangle( rect.Inflate( 1 ) );
568 dc.SetFont( GetLabelFont() );
571 GetColLabelAlignment( &hAlign, &vAlign );
572 const int orient = GetColLabelTextOrientation();
575 hAlign = wxALIGN_LEFT;
577 if( hAlign == wxALIGN_LEFT )
580 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
586 if( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
589 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
596 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
597 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
598 dc.DrawRectangle( rect.Inflate( 1 ) );
604 dc.SetFont( GetLabelFont() );
607 GetRowLabelAlignment(&hAlign, &vAlign);
609 if( hAlign == wxALIGN_LEFT )
612 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
618 if( !IsCellEditControlEnabled() )
621 HideCellEditControl();
624 m_cellEditCtrlEnabled =
false;
626 int row = m_currentCellCoords.GetRow();
627 int col = m_currentCellCoords.GetCol();
629 wxString oldval = GetCellValue( row, col );
632 wxGridCellAttr* attr = GetCellAttr( row, col );
633 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
635 editor->EndEdit( row, col,
this, oldval, &newval );
646 if( !IsCellEditControlEnabled() )
649 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
652 HideCellEditControl();
655 m_cellEditCtrlEnabled =
false;
657 int row = m_currentCellCoords.GetRow();
658 int col = m_currentCellCoords.GetCol();
660 wxString oldval = GetCellValue( row, col );
663 wxGridCellAttr* attr = GetCellAttr( row, col );
664 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
666 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
673 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
676 editor->ApplyEdit( row, col,
this );
681 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
684 SetCellValue( row, col, oldval );
712 wxString stringValue = GetCellValue( aRow, aCol );
718 if(
m_eval->Process( stringValue ) )
719 stringValue =
m_eval->Result();
733 wxString stringValue = GetCellValue( aRow, aCol );
740 stringValue =
m_eval->Result();
754 SetCellValue( aRow, aCol, unitsProvider->
StringFromValue( aValue,
true ) );
783 size = GetRowLabelSize();
785 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
786 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
791 size = GetColSize( aCol );
799 size = std::max( size,
800 int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
803 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
806 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
807 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
809 size = std::max( size, GetTextExtent(
"MM" ).x );
819 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
820 int row_height = GetColLabelSize();
821 int initial_row_height = row_height;
826 for(
int col = 0; col < GetNumberCols(); col++ )
828 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
833 if( row_height < line_height * ( nl_count+1 ) )
834 row_height += line_height * nl_count;
840 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