KiCad PCB EDA Suite
Loading...
Searching...
No Matches
eeschema/dialogs/dialog_table_properties.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <kiplatform/ui.h>
25#include <ee_actions.h>
26#include <sch_edit_frame.h>
29#include <widgets/wx_grid.h>
31#include <grid_tricks.h>
33#include <sch_table.h>
34#include <sch_commit.h>
35#include <tool/tool_manager.h>
37
38
41 m_frame( aFrame ),
42 m_table( aTable ),
43 m_borderWidth( aFrame, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits ),
44 m_separatorsWidth( aFrame, m_separatorsWidthLabel, m_separatorsWidthCtrl, m_separatorsWidthUnits )
45{
46 m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
47
48 m_grid->CreateGrid( m_table->GetRowCount(), m_table->GetColCount() );
49 m_grid->EnableEditing( true );
50 m_grid->EnableGridLines( true );
51 m_grid->EnableDragGridSize( false );
52 m_grid->SetMargins( 0, 0 );
53 m_grid->SetCellHighlightROPenWidth( 0 );
54
55 m_grid->EnableDragColMove( false );
56 m_grid->EnableDragColSize( false );
58 m_grid->EnableDragRowMove( false );
59 m_grid->EnableDragRowSize( false );
60 m_grid->SetRowLabelSize( 0 );
61 m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
62
63 m_gridSizer->Add( m_grid, 1, wxEXPAND, 5 );
64 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
65
66 wxColor coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT );
67
68 for( int row = 0; row < m_table->GetRowCount(); ++row )
69 {
70 for( int col = 0; col < m_table->GetColCount(); ++col )
71 {
72 const SCH_TABLECELL* cell = m_table->GetCell( row, col );
73 wxGridCellAttr* attr = new wxGridCellAttr;
74
75 if( cell->GetColSpan() == 0 || cell->GetRowSpan() == 0 )
76 {
77 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( this ) );
78 attr->SetReadOnly();
79 }
80 else
81 {
82 attr->SetEditor( new GRID_CELL_STC_EDITOR( true,
83 // onCharFn
84 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
85 {
86 aScintillaTricks->DoTextVarAutocomplete(
87 // getTokensFn
88 [this]( const wxString& xRef, wxArrayString* tokens )
89 {
90 getContextualTextVars( xRef, tokens );
91 } );
92 } ) );
93 }
94
95 m_grid->SetAttr( row, col, attr );
96 }
97 }
98
99 for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
100 {
101 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
102 m_separatorsStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
103 }
104
107
109 m_infoBar->ShowMessage( _( "Note: individual item colors overridden in Preferences." ) );
110
112 Layout();
113
114 // Now all widgets have the size fixed, call FinishDialogSettings
116}
117
118
120{
121 // Delete the GRID_TRICKS.
122 m_grid->PopEventHandler( true );
123}
124
125
127{
128 if( !wxDialog::TransferDataToWindow() )
129 return false;
130
131 //
132 // Cell Contents
133 //
134
135 wxColour coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
136
138 coveredColor = coveredColor.ChangeLightness( 140 );
139 else
140 coveredColor = coveredColor.ChangeLightness( 100 );
141
142 for( int row = 0; row < m_table->GetRowCount(); ++row )
143 {
144 for( int col = 0; col < m_table->GetColCount(); ++col )
145 {
146 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
147
148 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
149 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
150 else
151 m_grid->SetCellValue( row, col, tableCell->GetText() );
152 }
153 }
154
155 CallAfter( [this]()
156 {
157 for( int row = 0; row < m_table->GetRowCount(); ++row )
158 {
159 for( int col = 0; col < m_table->GetColCount(); ++col )
160 {
161 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
162
163 if( tableCell->IsSelected() )
164 {
165 m_grid->SetGridCursor( row, col );
166 m_grid->EnableCellEditControl();
167 m_grid->ShowCellEditControl();
168 return;
169 }
170 }
171 }
172 } );
173
175
176 //
177 // Table Properties
178 //
179
181 m_headerBorder->SetValue( m_table->StrokeHeader() );
182
183 if( m_table->GetBorderStroke().GetWidth() >= 0 )
185
187
188 int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
189
190 if( style == -1 )
191 m_borderStyleCombo->SetStringSelection( DEFAULT_STYLE );
192 else if( style < (int) lineTypeNames.size() )
193 m_borderStyleCombo->SetSelection( style );
194 else
195 wxFAIL_MSG( "Line type not found in the type lookup map" );
196
202
203 bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
204 bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
205
206 m_rowSeparators->SetValue( rows );
207 m_colSeparators->SetValue( cols );
208
209 if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
211
213
214 style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
215
216 if( style == -1 )
217 m_separatorsStyleCombo->SetStringSelection( DEFAULT_STYLE );
218 else if( style < (int) lineTypeNames.size() )
219 m_separatorsStyleCombo->SetSelection( style );
220 else
221 wxFAIL_MSG( "Line type not found in the type lookup map" );
222
223 m_separatorsWidth.Enable( rows || cols );
224 m_separatorsColorLabel->Enable( rows || cols );
225 m_separatorsColorSwatch->Enable( rows || cols );
226 m_separatorsStyleLabel->Enable( rows || cols );
227 m_separatorsStyleCombo->Enable( rows || cols );
228
229 return true;
230}
231
232
234 wxArrayString* aTokens )
235{
236 if( !aCrossRef.IsEmpty() )
237 {
240 SCH_SYMBOL* refSymbol = nullptr;
241
242 sheets.GetSymbols( refs );
243
244 for( int jj = 0; jj < (int) refs.GetCount(); jj++ )
245 {
246 SCH_REFERENCE& ref = refs[jj];
247
248 if( ref.GetSymbol()->GetRef( &ref.GetSheetPath(), true ) == aCrossRef )
249 {
250 refSymbol = ref.GetSymbol();
251 break;
252 }
253 }
254
255 if( refSymbol )
256 refSymbol->GetContextualTextVars( aTokens );
257 }
258 else
259 {
260 SCHEMATIC* schematic = m_table->Schematic();
261
262 if( schematic && schematic->CurrentSheet().Last() )
263 {
264 schematic->CurrentSheet().Last()->GetContextualTextVars( aTokens );
265 }
266 else
267 {
268 for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
269 aTokens->push_back( entry.first );
270 }
271 }
272}
273
274
275void DIALOG_TABLE_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
276{
277 bool border = m_borderCheckbox->GetValue();
278
279 if( border && m_borderWidth.GetValue() < 0 )
281
282 m_borderWidth.Enable( border );
283 m_borderColorLabel->Enable( border );
284 m_borderColorSwatch->Enable( border );
285 m_borderStyleLabel->Enable( border );
286 m_borderStyleCombo->Enable( border );
287
288 bool row = m_rowSeparators->GetValue();
289 bool col = m_colSeparators->GetValue();
290
291 if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
293
294 m_separatorsWidth.Enable( row || col );
295 m_separatorsColorLabel->Enable( row || col );
296 m_separatorsColorSwatch->Enable( row || col );
297 m_separatorsStyleLabel->Enable( row || col );
298 m_separatorsStyleCombo->Enable( row || col );
299}
300
301
303{
305 return false;
306
307 if( !wxDialog::TransferDataFromWindow() )
308 return false;
309
310 SCH_COMMIT commit( m_frame );
311
312 /* save table in undo list if not already in edit */
313 if( m_table->GetEditFlags() == 0 )
314 commit.Modify( m_table, m_frame->GetScreen() );
315
316 for( int row = 0; row < m_table->GetRowCount(); ++row )
317 {
318 for( int col = 0; col < m_table->GetColCount(); ++col )
319 {
320 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
321 wxString txt = m_grid->GetCellValue( row, col );
322
323#ifdef __WXMAC__
324 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
325 // Replace it now.
326 txt.Replace( "\r", "\n" );
327#elif defined( __WINDOWS__ )
328 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
329 // drawing routines so strip the \r char.
330 txt.Replace( "\r", "" );
331#endif
332
333 tableCell->SetText( txt );
334 }
335 }
336
338 m_table->SetStrokeHeader( m_headerBorder->GetValue() );
339 {
341
342 if( m_borderCheckbox->GetValue() )
343 stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
344 else
345 stroke.SetWidth( -1 );
346
347 auto it = lineTypeNames.begin();
348 std::advance( it, m_borderStyleCombo->GetSelection() );
349
350 if( it == lineTypeNames.end() )
351 stroke.SetLineStyle( LINE_STYLE::DEFAULT );
352 else
353 stroke.SetLineStyle( it->first );
354
356
357 m_table->SetBorderStroke( stroke );
358 }
359
360 m_table->SetStrokeRows( m_rowSeparators->GetValue() );
362 {
364
365 if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
366 stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
367 else
368 stroke.SetWidth( -1 );
369
370 auto it = lineTypeNames.begin();
371 std::advance( it, m_separatorsStyleCombo->GetSelection() );
372
373 if( it == lineTypeNames.end() )
374 stroke.SetLineStyle( LINE_STYLE::DEFAULT );
375 else
376 stroke.SetLineStyle( it->first );
377
379
380 m_table->SetSeparatorsStroke( stroke );
381 }
382
383 if( !commit.Empty() )
384 commit.Push( _( "Edit Table" ) );
385
386 return true;
387}
388
389
391{
392 Layout(); // Make sure we get the current client size for the grid
393
394 wxSize availableGridSize = m_grid->GetClientSize();
395
396 if( availableGridSize.x == 0 || availableGridSize.y == 0 )
397 return;
398
399 BOX2I tableBBox = m_table->GetBoundingBox();
400 double scalerX = static_cast<double>( availableGridSize.x ) / tableBBox.GetWidth();
401 double scalerY = static_cast<double>( availableGridSize.y ) / tableBBox.GetHeight();
402
403 for( int row = 0; row < m_table->GetRowCount(); ++row )
404 m_grid->SetRowSize( row, std::floor( m_table->GetRowHeight( row ) * scalerY ) );
405
406 for( int col = 0; col < m_table->GetColCount(); ++col )
407 m_grid->SetColSize( col, std::floor( m_table->GetColWidth( col ) * scalerX ) );
408}
409
410
411void DIALOG_TABLE_PROPERTIES::onSize( wxSizeEvent& aEvent )
412{
413 if( m_table )
415
416 aEvent.Skip();
417}
418
419
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
size_type GetHeight() const
Definition: box2.h:205
size_type GetWidth() const
Definition: box2.h:204
bool GetOverrideSchItemColors() const
void SetSwatchColor(const KIGFX::COLOR4D &aColor, bool aSendEvent)
Set the current swatch color directly.
KIGFX::COLOR4D GetSwatchColor() const
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:105
bool Empty() const
Returns status of an item.
Definition: commit.h:144
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
DIALOG_TABLE_PROPERTIES(SCH_EDIT_FRAME *aParentFrame, SCH_TABLE *aTable)
void getContextualTextVars(const wxString &aCrossRef, wxArrayString *aTokens)
void onBorderChecked(wxCommandEvent &aEvent) override
void onSize(wxSizeEvent &aEvent) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:132
bool IsSelected() const
Definition: eda_item.h:109
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:84
Holds all the data relating to one schematic.
Definition: schematic.h:75
SCH_SHEET_PATH & CurrentSheet() const override
Definition: schematic.h:136
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:100
EESCHEMA_SETTINGS * eeconfig() const
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Returns a pointer to the active color theme settings.
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Definition: sch_commit.cpp:405
Schematic editor (Eeschema) main window.
SCH_SCREEN * GetScreen() const override
Return a pointer to a BASE_SCREEN or one of its derivatives.
SCHEMATIC & Schematic() const
SCHEMATIC * Schematic() const
Searches the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:139
Container to create a flattened list of symbols because in a complex hierarchy, a symbol can be used ...
size_t GetCount() const
A helper to define a symbol's reference designator in a schematic.
const SCH_SHEET_PATH & GetSheetPath() const
SCH_SYMBOL * GetSymbol() const
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
void GetSymbols(SCH_REFERENCE_LIST &aReferences, bool aIncludePowerSymbols=true, bool aForceIncludeOrphanSymbols=false) const
Add a SCH_REFERENCE object to aReferences for each symbol in the list of sheets.
SCH_SHEET * Last() const
Return a pointer to the last SCH_SHEET of the list.
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this sheet.
Definition: sch_sheet.cpp:202
Schematic symbol object.
Definition: sch_symbol.h:108
void GetContextualTextVars(wxArrayString *aVars) const
Return the list of system text vars & fields for this symbol.
const wxString GetRef(const SCH_SHEET_PATH *aSheet, bool aIncludeUnit=false) const override
Definition: sch_symbol.cpp:711
int GetColSpan() const
Definition: sch_tablecell.h:61
int GetRowSpan() const
Definition: sch_tablecell.h:64
const STROKE_PARAMS & GetSeparatorsStroke() const
Definition: sch_table.h:72
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_table.cpp:362
bool StrokeExternal() const
Definition: sch_table.h:54
int GetRowHeight(int aRow) const
Definition: sch_table.h:123
void SetStrokeHeader(bool aDoStroke)
Definition: sch_table.h:56
int GetColWidth(int aCol) const
Definition: sch_table.h:113
const STROKE_PARAMS & GetBorderStroke() const
Definition: sch_table.h:60
void SetStrokeExternal(bool aDoStroke)
Definition: sch_table.h:53
int GetColCount() const
Definition: sch_table.h:104
void SetStrokeColumns(bool aDoStroke)
Definition: sch_table.h:83
SCH_TABLECELL * GetCell(int aRow, int aCol) const
Definition: sch_table.h:131
bool StrokeColumns() const
Definition: sch_table.h:84
void SetSeparatorsStroke(const STROKE_PARAMS &aParams)
Definition: sch_table.h:71
bool StrokeRows() const
Definition: sch_table.h:87
int GetRowCount() const
Definition: sch_table.h:106
void SetStrokeRows(bool aDoStroke)
Definition: sch_table.h:86
void SetBorderStroke(const STROKE_PARAMS &aParams)
Definition: sch_table.h:59
bool StrokeHeader() const
Definition: sch_table.h:57
Add cut/copy/paste, dark theme, autocomplete and brace highlighting to a wxStyleTextCtrl instance.
void DoTextVarAutocomplete(const std::function< void(const wxString &xRef, wxArrayString *tokens)> &getTokensFn)
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
int GetWidth() const
Definition: stroke_params.h:91
void SetLineStyle(LINE_STYLE aLineStyle)
Definition: stroke_params.h:95
void SetWidth(int aWidth)
Definition: stroke_params.h:92
void SetColor(const KIGFX::COLOR4D &aColor)
Definition: stroke_params.h:98
LINE_STYLE GetLineStyle() const
Definition: stroke_params.h:94
KIGFX::COLOR4D GetColor() const
Definition: stroke_params.h:97
int GetIntValue()
Definition: unit_binder.h:127
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void SetColLabelSize(int aHeight)
Hide wxGrid's SetColLabelSize() method with one which makes sure the size is tall enough for the syst...
Definition: wx_grid.cpp:211
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:558
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:154
#define _(s)
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition: gtk/ui.cpp:48
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames