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 )
80 aEntry->SetMargins( 0, 0 );
86#if defined( __WXMSW__ ) || defined( __WXGTK__ )
94 KIGFX::COLOR4D bg = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
95 KIGFX::COLOR4D fg = wxSystemSettings::GetColour( wxSYS_COLOUR_ACTIVEBORDER );
106 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
109 rect.SetTop( rect.GetTop() + 1 );
110 rect.SetLeft( rect.GetLeft() + 1 );
111 rect.SetBottom( rect.GetBottom() - 1 );
112 rect.SetRight( rect.GetRight() - 1 );
113 dc.DrawRectangle( rect );
123 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
126 rect.SetTop( rect.GetTop() + 1 );
127 rect.SetLeft( rect.GetLeft() );
128 rect.SetBottom( rect.GetBottom() - 1 );
129 rect.SetRight( rect.GetRight() - 1 );
130 dc.DrawRectangle( rect );
140 wxDCBrushChanger SetBrush( dc, *wxTRANSPARENT_BRUSH );
143 rect.SetTop( rect.GetTop() + 1 );
144 rect.SetLeft( rect.GetLeft() + 1 );
145 rect.SetBottom( rect.GetBottom() - 1 );
146 rect.SetRight( rect.GetRight() );
147 dc.DrawRectangle( rect );
176 wxGridCellAttr::wxAttrKind kind )
const override
178 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 );
238 wxGrid::SetColLabelSize( wxGRID_AUTOSIZE );
251 if( aHeight == 0 || aHeight == wxGRID_AUTOSIZE )
253 wxGrid::SetColLabelSize( aHeight );
260 wxGrid::SetColLabelSize( std::max( aHeight, minHeight ) );
274 int numberCols = GetNumberCols();
275 int* formBuilderColWidths =
new int[numberCols];
277 for(
int i = 0; i < numberCols; ++i )
278 formBuilderColWidths[ i ] = GetColSize( i );
280 wxGrid::SetTable( aTable );
284 numberCols = std::min( numberCols, GetNumberCols() );
286 for(
int i = 0; i < numberCols; ++i )
291 SetColSize( i, std::max( formBuilderColWidths[ i ], headingWidth ) );
294 delete[] formBuilderColWidths;
307 wxGridTableBase* table = wxGrid::GetTable();
309 wxCHECK_MSG( table, ,
310 "Tried to enable alternate row colors without a table assigned to the grid" );
314 wxColor
color = wxGrid::GetDefaultCellBackgroundColour();
319 table->SetAttrProvider(
nullptr );
329 int row = aEvent.GetRow();
330 int col = aEvent.GetCol();
332 if( row >= 0 && row < GetNumberRows() && col >= 0 && col < GetNumberCols() )
334 if( GetSelectionMode() == wxGrid::wxGridSelectCells )
336 SelectBlock( row, col, row, col,
false );
338 else if( GetSelectionMode() == wxGrid::wxGridSelectRows
339 || GetSelectionMode() == wxGrid::wxGridSelectRowsOrColumns )
341 SelectBlock( row, 0, row, GetNumberCols() - 1,
false );
343 else if( GetSelectionMode() == wxGrid::wxGridSelectColumns )
345 SelectBlock( 0, col, GetNumberRows() - 1, col,
false );
355 int row = aEvent.GetRow();
356 int col = aEvent.GetCol();
358 const std::pair<wxString, wxString>& beforeAfter =
m_evalBeforeAfter[ { row, col } ];
360 if( GetCellValue( row, col ) == beforeAfter.second )
361 SetCellValue( row, col, beforeAfter.first );
377 int row = aEvent.GetRow();
378 int col = aEvent.GetCol();
381 bool isNullable =
false;
382 wxGridCellEditor* cellEditor = GetCellEditor( row, col );
392 cellEditor->DecRef();
396 [
this, row, col, isNullable, unitsProvider]()
398 wxString stringValue = GetCellValue( row, col );
399 bool processedOk =
true;
402 processedOk =
m_eval->Process( stringValue );
410 std::optional<int> val;
430 if( stringValue != evalValue )
432 SetCellValue( row, col, evalValue );
452 wxGrid::SetTable(
nullptr );
459 wxString shownColumns;
461 for(
int i = 0; i < GetNumberCols(); ++i )
463 if( IsColShown( i ) )
465 if( shownColumns.Length() )
466 shownColumns << wxT(
" " );
478 std::bitset<64> shownColumns;
480 for(
int ii = 0; ii < GetNumberCols(); ++ii )
481 shownColumns[ii] = IsColShown( ii );
489 for(
int i = 0; i < GetNumberCols(); ++i )
492 wxStringTokenizer shownTokens( shownColumns );
494 while( shownTokens.HasMoreTokens() )
497 shownTokens.GetNextToken().ToLong( &colNumber );
499 if( colNumber >= 0 && colNumber < GetNumberCols() )
500 ShowCol( (
int) colNumber );
507 for(
int ii = 0; ii < GetNumberCols(); ++ ii )
509 if( aShownColumns[ii] )
519 if( m_nativeColumnLabels )
520 wxGrid::DrawCornerLabel( dc );
522 wxRect rect( wxSize( m_rowLabelWidth, m_colLabelHeight ) );
529 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
530 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
531 dc.DrawRectangle( rect.Inflate( 1 ) );
540 if( m_nativeColumnLabels )
541 wxGrid::DrawColLabel( dc, col );
543 if( GetColWidth( col ) <= 0 || m_colLabelHeight <= 0 )
546 wxRect rect( GetColLeft( col ), 0, GetColWidth( col ), m_colLabelHeight );
553 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
554 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
555 dc.DrawRectangle( rect.Inflate( 1 ) );
561 dc.SetFont( GetLabelFont() );
564 GetColLabelAlignment( &hAlign, &vAlign );
565 const int orient = GetColLabelTextOrientation();
568 hAlign = wxALIGN_LEFT;
570 if( hAlign == wxALIGN_LEFT )
573 rend.DrawLabel( *
this, dc, GetColLabelValue( col ), rect, hAlign, vAlign, orient );
579 if ( GetRowHeight( row ) <= 0 || m_rowLabelWidth <= 0 )
582 wxRect rect( 0, GetRowTop( row ), m_rowLabelWidth, GetRowHeight( row ) );
589 wxDCBrushChanger setBrush( dc, m_colLabelWin->GetBackgroundColour() );
590 wxDCPenChanger setPen( dc, m_colLabelWin->GetBackgroundColour() );
591 dc.DrawRectangle( rect.Inflate( 1 ) );
597 dc.SetFont( GetLabelFont() );
600 GetRowLabelAlignment(&hAlign, &vAlign);
602 if( hAlign == wxALIGN_LEFT )
605 rend.DrawLabel( *
this, dc, GetRowLabelValue( row ), rect, hAlign, vAlign, wxHORIZONTAL );
611 if( !IsCellEditControlEnabled() )
614 HideCellEditControl();
617 m_cellEditCtrlEnabled =
false;
619 int row = m_currentCellCoords.GetRow();
620 int col = m_currentCellCoords.GetCol();
622 wxString oldval = GetCellValue( row, col );
625 wxGridCellAttr* attr = GetCellAttr( row, col );
626 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
628 editor->EndEdit( row, col,
this, oldval, &newval );
639 if( !IsCellEditControlEnabled() )
642 if( !aQuietMode && SendEvent( wxEVT_GRID_EDITOR_HIDDEN ) == -1 )
645 HideCellEditControl();
648 m_cellEditCtrlEnabled =
false;
650 int row = m_currentCellCoords.GetRow();
651 int col = m_currentCellCoords.GetCol();
653 wxString oldval = GetCellValue( row, col );
656 wxGridCellAttr* attr = GetCellAttr( row, col );
657 wxGridCellEditor*
editor = attr->GetEditor(
this, row, col );
659 bool changed =
editor->EndEdit( row, col,
this, oldval, &newval );
666 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGING, newval ) == -1 )
669 editor->ApplyEdit( row, col,
this );
674 if( !aQuietMode && SendEvent( wxEVT_GRID_CELL_CHANGED, oldval ) == -1 )
677 SetCellValue( row, col, oldval );
705 wxString stringValue = GetCellValue( aRow, aCol );
711 if(
m_eval->Process( stringValue ) )
712 stringValue =
m_eval->Result();
726 wxString stringValue = GetCellValue( aRow, aCol );
733 stringValue =
m_eval->Result();
747 SetCellValue( aRow, aCol, unitsProvider->
StringFromValue( aValue,
true ) );
776 size = GetRowLabelSize();
778 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
779 size = std::max( size,
int( GetTextExtent( GetRowLabelValue( row ) + wxS(
"M" ) ).x ) );
784 size = GetColSize( aCol );
792 size = std::max( size,
int( GetTextExtent( GetColLabelValue( aCol ) + wxS(
"M" ) ).x ) );
795 for(
int row = 0; aContents && row < GetNumberRows(); row++ )
798 if( GetTable()->CanGetValueAs( row, aCol, wxGRID_VALUE_STRING ) )
799 size = std::max( size, GetTextExtent( GetCellValue( row, aCol ) + wxS(
"M" ) ).x );
801 size = std::max( size, GetTextExtent(
"MM" ).x );
811 int line_height = int( GetTextExtent(
"Mj" ).y ) + 3;
812 int row_height = GetColLabelSize();
813 int initial_row_height = row_height;
818 for(
int col = 0; col < GetNumberCols(); col++ )
820 int nl_count = GetColLabelValue( col ).Freq(
'\n' );
825 if( row_height < line_height * ( nl_count+1 ) )
826 row_height += line_height * nl_count;
832 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)
Calculates 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 UNITS_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