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 The 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 <sch_edit_frame.h>
28#include <widgets/wx_grid.h>
30#include <grid_tricks.h>
32#include <sch_table.h>
33#include <sch_commit.h>
34#include <tool/tool_manager.h>
36
37
40 m_frame( aFrame ),
41 m_table( aTable ),
42 m_borderWidth( aFrame, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits ),
43 m_separatorsWidth( aFrame, m_separatorsWidthLabel, m_separatorsWidthCtrl,
44 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 for( int row = 0; row < m_table->GetRowCount(); ++row )
67 {
68 for( int col = 0; col < m_table->GetColCount(); ++col )
69 {
70 const SCH_TABLECELL* cell = m_table->GetCell( row, col );
71 wxGridCellAttr* attr = new wxGridCellAttr;
72
73 if( cell->GetColSpan() == 0 || cell->GetRowSpan() == 0 )
74 {
75 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( this ) );
76 attr->SetReadOnly();
77 }
78 else
79 {
80 attr->SetEditor( new GRID_CELL_STC_EDITOR( true, false,
81 // onCharFn
82 [this]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
83 {
84 aScintillaTricks->DoTextVarAutocomplete(
85 // getTokensFn
86 [this]( const wxString& xRef, wxArrayString* tokens )
87 {
88 getContextualTextVars( xRef, tokens );
89 } );
90 } ) );
91 }
92
93 m_grid->SetAttr( row, col, attr );
94 }
95 }
96
97 for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
98 {
99 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
100 m_separatorsStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
101 }
102
106
108 m_infoBar->ShowMessage( _( "Note: individual item colors overridden in Preferences." ) );
109
111 Layout();
112
113 // Now all widgets have the size fixed, call FinishDialogSettings
115}
116
117
119{
120 // Delete the GRID_TRICKS.
121 m_grid->PopEventHandler( true );
122}
123
124
126{
127 if( !wxDialog::TransferDataToWindow() )
128 return false;
129
130 //
131 // Cell Contents
132 //
133
134 wxColour coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
135
137 coveredColor = coveredColor.ChangeLightness( 140 );
138 else
139 coveredColor = coveredColor.ChangeLightness( 100 );
140
141 for( int row = 0; row < m_table->GetRowCount(); ++row )
142 {
143 for( int col = 0; col < m_table->GetColCount(); ++col )
144 {
145 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
146
147 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
148 {
149 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
150 continue;
151 }
152
153 wxString text = tableCell->GetText();
154
155 // show text variable cross-references in a human-readable format
156 if( SCHEMATIC* schematic = tableCell->Schematic() )
157 text = schematic->ConvertKIIDsToRefs( text );
158
159 m_grid->SetCellValue( row, col, text );
160 }
161 }
162
163 CallAfter( [this]()
164 {
165 for( int row = 0; row < m_table->GetRowCount(); ++row )
166 {
167 for( int col = 0; col < m_table->GetColCount(); ++col )
168 {
169 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
170
171 if( tableCell->IsSelected() )
172 {
173 m_grid->SetGridCursor( row, col );
174 m_grid->EnableCellEditControl();
175 m_grid->ShowCellEditControl();
176 return;
177 }
178 }
179 }
180 } );
181
183
184 //
185 // Table Properties
186 //
187
190
191 if( m_table->GetBorderStroke().GetWidth() >= 0 )
193
195
196 int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
197
198 if( style >= 0 && style < (int) lineTypeNames.size() )
199 m_borderStyleCombo->SetSelection( style );
200 else
201 m_borderStyleCombo->SetSelection( 0 );
202
208
209 bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
210 bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
211
212 m_rowSeparators->SetValue( rows );
213 m_colSeparators->SetValue( cols );
214
215 if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
217
219
220 style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
221
222 if( style >= 0 && style < (int) lineTypeNames.size() )
223 m_separatorsStyleCombo->SetSelection( style );
224 else
225 m_separatorsStyleCombo->SetSelection( 0 );
226
227 m_separatorsWidth.Enable( rows || cols );
228 m_separatorsColorLabel->Enable( rows || cols );
229 m_separatorsColorSwatch->Enable( rows || cols );
230 m_separatorsStyleLabel->Enable( rows || cols );
231 m_separatorsStyleCombo->Enable( rows || cols );
232
233 return true;
234}
235
236
238 wxArrayString* aTokens )
239{
240 if( !aCrossRef.IsEmpty() )
241 {
243 SCH_SYMBOL* refSymbol = nullptr;
244
246
247 for( int jj = 0; jj < (int) refs.GetCount(); jj++ )
248 {
249 SCH_REFERENCE& ref = refs[jj];
250
251 if( ref.GetSymbol()->GetRef( &ref.GetSheetPath(), true ) == aCrossRef )
252 {
253 refSymbol = ref.GetSymbol();
254 break;
255 }
256 }
257
258 if( refSymbol )
259 refSymbol->GetContextualTextVars( aTokens );
260 }
261 else
262 {
263 SCHEMATIC* schematic = m_table->Schematic();
264
265 if( schematic && schematic->CurrentSheet().Last() )
266 {
267 schematic->CurrentSheet().Last()->GetContextualTextVars( aTokens );
268 }
269 else
270 {
271 for( std::pair<wxString, wxString> entry : Prj().GetTextVars() )
272 aTokens->push_back( entry.first );
273 }
274 }
275}
276
277
278void DIALOG_TABLE_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
279{
280 bool border = m_borderCheckbox->GetValue();
281 bool headerSeparator = m_headerBorder->GetValue();
282
283 if( ( border || headerSeparator ) && m_borderWidth.GetValue() < 0 )
285
286 m_borderWidth.Enable( border || headerSeparator );
287 m_borderColorLabel->Enable( border || headerSeparator );
288 m_borderColorSwatch->Enable( border || headerSeparator );
289 m_borderStyleLabel->Enable( border || headerSeparator );
290 m_borderStyleCombo->Enable( border || headerSeparator );
291
292 bool row = m_rowSeparators->GetValue();
293 bool col = m_colSeparators->GetValue();
294
295 if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
297
298 m_separatorsWidth.Enable( row || col );
299 m_separatorsColorLabel->Enable( row || col );
300 m_separatorsColorSwatch->Enable( row || col );
301 m_separatorsStyleLabel->Enable( row || col );
302 m_separatorsStyleCombo->Enable( row || col );
303}
304
305
307{
309 return false;
310
311 if( !wxDialog::TransferDataFromWindow() )
312 return false;
313
314 SCH_COMMIT commit( m_frame );
315
316 /* save table in undo list if not already in edit */
317 if( m_table->GetEditFlags() == 0 )
318 commit.Modify( m_table, m_frame->GetScreen() );
319
320 for( int row = 0; row < m_table->GetRowCount(); ++row )
321 {
322 for( int col = 0; col < m_table->GetColCount(); ++col )
323 {
324 SCH_TABLECELL* tableCell = m_table->GetCell( row, col );
325 wxString txt = m_grid->GetCellValue( row, col );
326
327 // convert any text variable cross-references to their UUIDs
328 if( SCHEMATIC* schematic = tableCell->Schematic() )
329 txt = schematic->ConvertRefsToKIIDs( txt );
330
331#ifdef __WXMAC__
332 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
333 // Replace it now.
334 txt.Replace( "\r", "\n" );
335#elif defined( __WINDOWS__ )
336 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
337 // drawing routines so strip the \r char.
338 txt.Replace( "\r", "" );
339#endif
340
341 tableCell->SetText( txt );
342 }
343 }
344
347 {
349
350 if( m_borderCheckbox->GetValue() || m_headerBorder->GetValue() )
351 stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
352 else
353 stroke.SetWidth( -1 );
354
355 auto it = lineTypeNames.begin();
356 std::advance( it, m_borderStyleCombo->GetSelection() );
357
358 if( it == lineTypeNames.end() )
359 stroke.SetLineStyle( LINE_STYLE::SOLID );
360 else
361 stroke.SetLineStyle( it->first );
362
364
365 m_table->SetBorderStroke( stroke );
366 }
367
368 m_table->SetStrokeRows( m_rowSeparators->GetValue() );
370 {
372
373 if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
374 stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
375 else
376 stroke.SetWidth( -1 );
377
378 auto it = lineTypeNames.begin();
379 std::advance( it, m_separatorsStyleCombo->GetSelection() );
380
381 if( it == lineTypeNames.end() )
382 stroke.SetLineStyle( LINE_STYLE::SOLID );
383 else
384 stroke.SetLineStyle( it->first );
385
387
388 m_table->SetSeparatorsStroke( stroke );
389 }
390
391 if( !commit.Empty() )
392 commit.Push( _( "Edit Table" ) );
393
394 return true;
395}
396
397
399{
400 Layout(); // Make sure we get the current client size for the grid
401
402 wxSize availableGridSize = m_grid->GetClientSize();
403
404 if( availableGridSize.x == 0 || availableGridSize.y == 0 )
405 return;
406
407 BOX2I tableBBox = m_table->GetBoundingBox();
408 double scalerX = static_cast<double>( availableGridSize.x ) / tableBBox.GetWidth();
409 double scalerY = static_cast<double>( availableGridSize.y ) / tableBBox.GetHeight();
410
411 for( int row = 0; row < m_table->GetRowCount(); ++row )
412 m_grid->SetRowSize( row, std::floor( m_table->GetRowHeight( row ) * scalerY ) );
413
414 for( int col = 0; col < m_table->GetColCount(); ++col )
415 m_grid->SetColSize( col, std::floor( m_table->GetColWidth( col ) * scalerX ) );
416}
417
418
419void DIALOG_TABLE_PROPERTIES::onSize( wxSizeEvent& aEvent )
420{
421 if( m_table )
423
424 aEvent.Skip();
425}
426
427
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
constexpr size_type GetWidth() const
Definition: box2.h:214
constexpr size_type GetHeight() const
Definition: box2.h:215
bool GetOverrideSchItemColors() const
COLOR4D GetColor(int aLayer) const
void SetSwatchColor(const KIGFX::COLOR4D &aColor, bool aSendEvent)
Set the current swatch color directly.
KIGFX::COLOR4D GetSwatchColor() const
void SetSwatchBackground(const KIGFX::COLOR4D &aBackground)
Set the swatch background color.
bool Empty() const
Definition: commit.h:152
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
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:148
bool IsSelected() const
Definition: eda_item.h:127
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:270
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
PROJECT & Prj() const
Return a reference to the PROJECT associated with this KIWAY.
virtual std::map< wxString, wxString > & GetTextVars() const
Definition: project.cpp:98
Holds all the data relating to one schematic.
Definition: schematic.h:88
SCH_SHEET_LIST Hierarchy() const
Return the full schematic flattened hierarchical sheet list.
Definition: schematic.cpp:258
SCH_SHEET_PATH & CurrentSheet() const
Definition: schematic.h:171
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
Execute the changes.
Definition: sch_commit.cpp:489
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
Search the item hierarchy to find a SCHEMATIC.
Definition: sch_item.cpp:246
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
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:177
Schematic symbol object.
Definition: sch_symbol.h:75
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:558
int GetColSpan() const
Definition: sch_tablecell.h:64
int GetRowSpan() const
Definition: sch_tablecell.h:67
const STROKE_PARAMS & GetSeparatorsStroke() const
Definition: sch_table.h:77
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: sch_table.cpp:253
bool StrokeExternal() const
Definition: sch_table.h:53
int GetRowHeight(int aRow) const
Definition: sch_table.h:139
int GetColWidth(int aCol) const
Definition: sch_table.h:129
void SetStrokeHeaderSeparator(bool aDoStroke)
Definition: sch_table.h:55
const STROKE_PARAMS & GetBorderStroke() const
Definition: sch_table.h:59
void SetStrokeExternal(bool aDoStroke)
Definition: sch_table.h:52
int GetColCount() const
Definition: sch_table.h:120
bool StrokeHeaderSeparator() const
Definition: sch_table.h:56
void SetStrokeColumns(bool aDoStroke)
Definition: sch_table.h:98
SCH_TABLECELL * GetCell(int aRow, int aCol) const
Definition: sch_table.h:147
bool StrokeColumns() const
Definition: sch_table.h:99
void SetSeparatorsStroke(const STROKE_PARAMS &aParams)
Definition: sch_table.h:76
bool StrokeRows() const
Definition: sch_table.h:102
int GetRowCount() const
Definition: sch_table.h:122
void SetStrokeRows(bool aDoStroke)
Definition: sch_table.h:101
void SetBorderStroke(const STROKE_PARAMS &aParams)
Definition: sch_table.h:58
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:94
int GetWidth() const
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
void SetColor(const KIGFX::COLOR4D &aColor)
LINE_STYLE GetLineStyle() const
KIGFX::COLOR4D GetColor() const
int GetIntValue()
Definition: unit_binder.h:134
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:252
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:632
void ShowMessage(const wxString &aMessage, int aFlags=wxICON_INFORMATION) override
Show the info bar with the provided message and icon.
Definition: wx_infobar.cpp:156
#define _(s)
@ LAYER_SCHEMATIC_BACKGROUND
Definition: layer_ids.h:478
bool IsDarkTheme()
Determine if the desktop interface is currently using a dark theme or a light theme.
Definition: wxgtk/ui.cpp:48
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames
Conversion map between LINE_STYLE values and style names displayed.