KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pcbnew/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 <widgets/font_choice.h>
27#include <widgets/wx_grid.h>
30#include <grid_tricks.h>
31#include <scintilla_tricks.h>
32#include <confirm.h>
33#include <board.h>
34#include <board_commit.h>
36#include <footprint.h>
37#include <pcb_textbox.h>
38#include <pcb_tablecell.h>
39#include <pcb_table.h>
40#include <project.h>
41#include <pcb_edit_frame.h>
43#include <tool/tool_manager.h>
44#include <tools/pcb_actions.h>
46
47
50 m_frame( aFrame ),
51 m_table( aTable ),
52 m_borderWidth( aFrame, m_borderWidthLabel, m_borderWidthCtrl, m_borderWidthUnits ),
53 m_separatorsWidth( aFrame, m_separatorsWidthLabel, m_separatorsWidthCtrl, m_separatorsWidthUnits )
54{
55 m_grid = new WX_GRID( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
56
57 m_grid->CreateGrid( m_table->GetRowCount(), m_table->GetColCount() );
58 m_grid->EnableEditing( true );
59 m_grid->EnableGridLines( true );
60 m_grid->EnableDragGridSize( false );
61 m_grid->SetMargins( 0, 0 );
62 m_grid->SetCellHighlightROPenWidth( 0 );
63
64 m_grid->EnableDragColMove( false );
65 m_grid->EnableDragColSize( false );
67 m_grid->EnableDragRowMove( false );
68 m_grid->EnableDragRowSize( false );
69 m_grid->SetRowLabelSize( 0 );
70 m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
71
72 m_gridSizer->Add( m_grid, 1, wxEXPAND, 5 );
73 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
74
75 for( int row = 0; row < m_table->GetRowCount(); ++row )
76 {
77 for( int col = 0; col < m_table->GetColCount(); ++col )
78 {
79 PCB_TABLECELL* cell = m_table->GetCell( row, col );
80 wxGridCellAttr* attr = new wxGridCellAttr;
81
82 if( cell->GetColSpan() == 0 || cell->GetRowSpan() == 0 )
83 {
84 attr->SetRenderer( new GRID_CELL_COLOR_RENDERER( this ) );
85 attr->SetReadOnly();
86 }
87 else
88 {
89 attr->SetEditor( new GRID_CELL_STC_EDITOR( true,
90 [this, cell]( wxStyledTextEvent& aEvent, SCINTILLA_TRICKS* aScintillaTricks )
91 {
92 aScintillaTricks->DoTextVarAutocomplete(
93 // getTokensFn
94 [this, cell]( const wxString& xRef, wxArrayString* tokens )
95 {
96 m_frame->GetContextualTextVars( cell, xRef, tokens );
97 } );
98 } ) );
99 }
100
101 m_grid->SetAttr( row, col, attr );
102 }
103 }
104
105 if( m_table->GetParentFootprint() )
106 {
107 // Do not allow locking items in the footprint editor
108 m_cbLocked->Show( false );
109 }
110
111 // Configure the layers list selector. Note that footprints are built outside the current
112 // board and so we may need to show all layers if the text is on an unactivated layer.
113 if( !m_frame->GetBoard()->IsLayerEnabled( m_table->GetLayer() ) )
115
119
120 for( const auto& [lineStyle, lineStyleDesc] : lineTypeNames )
121 {
122 m_borderStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
123 m_separatorsStyleCombo->Append( lineStyleDesc.name, KiBitmap( lineStyleDesc.bitmap ) );
124 }
125
127 Layout();
128
129 // Now all widgets have the size fixed, call FinishDialogSettings
131}
132
133
135{
136 // Delete the GRID_TRICKS.
137 m_grid->PopEventHandler( true );
138}
139
140
142{
143 if( !wxDialog::TransferDataToWindow() )
144 return false;
145
146 //
147 // Cell Contents
148 //
149
150 wxColour coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
151
153 coveredColor = coveredColor.ChangeLightness( 140 );
154 else
155 coveredColor = coveredColor.ChangeLightness( 100 );
156
157 for( int row = 0; row < m_table->GetRowCount(); ++row )
158 {
159 for( int col = 0; col < m_table->GetColCount(); ++col )
160 {
161 PCB_TABLECELL* tableCell;
162
163 if( IsBackLayer( m_table->GetLayer() ) )
164 tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
165 else
166 tableCell = m_table->GetCell( row, col );
167
168 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
169 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
170 else
171 m_grid->SetCellValue( row, col, tableCell->GetText() );
172 }
173 }
174
175 CallAfter( [this]()
176 {
177 for( int row = 0; row < m_table->GetRowCount(); ++row )
178 {
179 for( int col = 0; col < m_table->GetColCount(); ++col )
180 {
181 PCB_TABLECELL* tableCell = m_table->GetCell( row, col );
182
183 if( tableCell->IsSelected() )
184 {
185 m_grid->SetGridCursor( row, col );
186 m_grid->EnableCellEditControl();
187 m_grid->ShowCellEditControl();
188 return;
189 }
190 }
191 }
192 } );
193
195
196 //
197 // Table Properties
198 //
199
201 m_cbLocked->SetValue( m_table->IsLocked() );
202
204 m_headerBorder->SetValue( m_table->StrokeHeader() );
205
206 if( m_table->GetBorderStroke().GetWidth() >= 0 )
208
209 int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
210
211 if( style >= 0 && style < (int) lineTypeNames.size() )
212 m_borderStyleCombo->SetSelection( style );
213 else
214 m_borderStyleCombo->SetSelection( 0 );
215
219
220 bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
221 bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
222
223 m_rowSeparators->SetValue( rows );
224 m_colSeparators->SetValue( cols );
225
226 if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
228
229 style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
230
231 if( style >= 0 && style < (int) lineTypeNames.size() )
232 m_separatorsStyleCombo->SetSelection( style );
233 else
234 m_separatorsStyleCombo->SetSelection( 0 );
235
236 m_separatorsWidth.Enable( rows || cols );
237 m_separatorsStyleLabel->Enable( rows || cols );
238 m_separatorsStyleCombo->Enable( rows || cols );
239
240 return true;
241}
242
243
244void DIALOG_TABLE_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
245{
246 BOARD_DESIGN_SETTINGS& bds = m_frame->GetDesignSettings();
248 int defaultLineThickness = bds.GetLineThickness( currentLayer );
249
250 bool border = m_borderCheckbox->GetValue();
251
252 if( border && m_borderWidth.GetValue() < 0 )
253 m_borderWidth.SetValue( defaultLineThickness );
254
255 m_borderWidth.Enable( border );
256 m_borderStyleLabel->Enable( border );
257 m_borderStyleCombo->Enable( border );
258
259 bool row = m_rowSeparators->GetValue();
260 bool col = m_colSeparators->GetValue();
261
262 if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
263 m_separatorsWidth.SetValue( defaultLineThickness );
264
265 m_separatorsWidth.Enable( row || col );
266 m_separatorsStyleLabel->Enable( row || col );
267 m_separatorsStyleCombo->Enable( row || col );
268}
269
270
272{
274 return false;
275
276 if( !wxDialog::TransferDataFromWindow() )
277 return false;
278
279 BOARD_COMMIT commit( m_frame );
280 commit.Modify( m_table );
281
282 // If no other command in progress, prepare undo command
283 // (for a command in progress, will be made later, at the completion of command)
284 bool pushCommit = ( m_table->GetEditFlags() == 0 );
285
286 // Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
287 // SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
288 if( !pushCommit )
290
291 for( int row = 0; row < m_table->GetRowCount(); ++row )
292 {
293 for( int col = 0; col < m_table->GetColCount(); ++col )
294 {
295 PCB_TABLECELL* tableCell;
296
297 if( IsBackLayer( m_table->GetLayer() ) )
298 tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
299 else
300 tableCell = m_table->GetCell( row, col );
301
302 wxString txt = m_grid->GetCellValue( row, col );
303
304#ifdef __WXMAC__
305 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
306 // Replace it now.
307 txt.Replace( "\r", "\n" );
308#elif defined( __WINDOWS__ )
309 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
310 // drawing routines so strip the \r char.
311 txt.Replace( "\r", "" );
312#endif
313
314 tableCell->SetText( txt );
315 }
316 }
317
319 m_table->SetLocked( m_cbLocked->GetValue() );
320
322 m_table->SetStrokeHeader( m_headerBorder->GetValue() );
323 {
325
326 if( m_borderCheckbox->GetValue() )
327 stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
328 else
329 stroke.SetWidth( -1 );
330
331 auto it = lineTypeNames.begin();
332 std::advance( it, m_borderStyleCombo->GetSelection() );
333
334 if( it == lineTypeNames.end() )
335 stroke.SetLineStyle( LINE_STYLE::SOLID );
336 else
337 stroke.SetLineStyle( it->first );
338
339 m_table->SetBorderStroke( stroke );
340 }
341
342 m_table->SetStrokeRows( m_rowSeparators->GetValue() );
344 {
346
347 if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
348 stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
349 else
350 stroke.SetWidth( -1 );
351
352 auto it = lineTypeNames.begin();
353 std::advance( it, m_separatorsStyleCombo->GetSelection() );
354
355 if( it == lineTypeNames.end() )
356 stroke.SetLineStyle( LINE_STYLE::SOLID );
357 else
358 stroke.SetLineStyle( it->first );
359
360 m_table->SetSeparatorsStroke( stroke );
361 }
362
363 if( pushCommit )
364 commit.Push( _( "Edit Table" ), SKIP_CONNECTIVITY );
365
366 return true;
367}
368
369
371{
372 Layout(); // Make sure we get the current client size for the grid
373
374 wxSize availableGridSize = m_grid->GetClientSize();
375
376 if( availableGridSize.x == 0 || availableGridSize.y == 0 )
377 return;
378
379 BOX2I tableBBox = m_table->GetBoundingBox();
380 double scalerX = static_cast<double>( availableGridSize.x ) / tableBBox.GetWidth();
381 double scalerY = static_cast<double>( availableGridSize.y ) / tableBBox.GetHeight();
382
383 for( int row = 0; row < m_table->GetRowCount(); ++row )
384 m_grid->SetRowSize( row, std::floor( m_table->GetRowHeight( row ) * scalerY ) );
385
386 for( int col = 0; col < m_table->GetColCount(); ++col )
387 m_grid->SetColSize( col, std::floor( m_table->GetColWidth( col ) * scalerX ) );
388}
389
390
391void DIALOG_TABLE_PROPERTIES::onSize( wxSizeEvent& aEvent )
392{
393 if( m_table )
395
396 aEvent.Skip();
397}
398
399
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
#define SKIP_CONNECTIVITY
Definition: board_commit.h:42
Container for design settings for a BOARD object.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
constexpr size_type GetWidth() const
Definition: box2.h:214
constexpr size_type GetHeight() const
Definition: box2.h:215
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 onBorderChecked(wxCommandEvent &aEvent) override
void onSize(wxSizeEvent &aEvent) override
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:133
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:127
bool IsSelected() const
Definition: eda_item.h:110
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:268
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
Common, abstract interface for edit frames.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void ShowNonActivatedLayers(bool aShow)
int GetRowSpan() const
Definition: pcb_tablecell.h:65
int GetColSpan() const
Definition: pcb_tablecell.h:62
virtual bool IsLocked() const
Definition: sch_item.h:269
virtual void SetLocked(bool aLocked)
Definition: sch_item.h:270
void SetLayer(SCH_LAYER_ID aLayer)
Definition: sch_item.h:283
SCH_LAYER_ID GetLayer() const
Return the layer this item is on.
Definition: sch_item.h:282
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:386
bool StrokeExternal() const
Definition: sch_table.h:54
int GetRowHeight(int aRow) const
Definition: sch_table.h:124
void SetStrokeHeader(bool aDoStroke)
Definition: sch_table.h:56
int GetColWidth(int aCol) const
Definition: sch_table.h:114
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:105
void SetStrokeColumns(bool aDoStroke)
Definition: sch_table.h:83
SCH_TABLECELL * GetCell(int aRow, int aCol) const
Definition: sch_table.h:132
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:107
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:93
int GetWidth() const
void SetLineStyle(LINE_STYLE aLineStyle)
void SetWidth(int aWidth)
LINE_STYLE GetLineStyle() const
int GetIntValue()
Definition: unit_binder.h:129
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:256
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:646
This file is part of the common library.
#define _(s)
#define IN_EDIT
Item currently edited.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
Definition: layer_ids.h:705
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:699
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.