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 BOARD* board = m_frame->GetBoard();
144
145 if( !wxDialog::TransferDataToWindow() )
146 return false;
147
148 //
149 // Cell Contents
150 //
151
152 wxColour coveredColor = wxSystemSettings::GetColour( wxSYS_COLOUR_BTNFACE );
153
155 coveredColor = coveredColor.ChangeLightness( 140 );
156 else
157 coveredColor = coveredColor.ChangeLightness( 100 );
158
159 for( int row = 0; row < m_table->GetRowCount(); ++row )
160 {
161 for( int col = 0; col < m_table->GetColCount(); ++col )
162 {
163 PCB_TABLECELL* tableCell;
164
165 if( IsBackLayer( m_table->GetLayer() ) )
166 tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
167 else
168 tableCell = m_table->GetCell( row, col );
169
170 if( tableCell->GetColSpan() == 0 || tableCell->GetRowSpan() == 0 )
171 {
172 m_grid->SetCellValue( row, col, coveredColor.GetAsString() );
173 continue;
174 }
175
176 wxString text = tableCell->GetText();
177
178 // show text variable cross-references in a human-readable format
180
181 m_grid->SetCellValue( row, col, text );
182 }
183 }
184
185 CallAfter( [this]()
186 {
187 for( int row = 0; row < m_table->GetRowCount(); ++row )
188 {
189 for( int col = 0; col < m_table->GetColCount(); ++col )
190 {
191 PCB_TABLECELL* tableCell = m_table->GetCell( row, col );
192
193 if( tableCell->IsSelected() )
194 {
195 m_grid->SetGridCursor( row, col );
196 m_grid->EnableCellEditControl();
197 m_grid->ShowCellEditControl();
198 return;
199 }
200 }
201 }
202 } );
203
205
206 //
207 // Table Properties
208 //
209
211 m_cbLocked->SetValue( m_table->IsLocked() );
212
214 m_headerBorder->SetValue( m_table->StrokeHeader() );
215
216 if( m_table->GetBorderStroke().GetWidth() >= 0 )
218
219 int style = static_cast<int>( m_table->GetBorderStroke().GetLineStyle() );
220
221 if( style >= 0 && style < (int) lineTypeNames.size() )
222 m_borderStyleCombo->SetSelection( style );
223 else
224 m_borderStyleCombo->SetSelection( 0 );
225
229
230 bool rows = m_table->StrokeRows() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
231 bool cols = m_table->StrokeColumns() && m_table->GetSeparatorsStroke().GetWidth() >= 0;
232
233 m_rowSeparators->SetValue( rows );
234 m_colSeparators->SetValue( cols );
235
236 if( m_table->GetSeparatorsStroke().GetWidth() >= 0 )
238
239 style = static_cast<int>( m_table->GetSeparatorsStroke().GetLineStyle() );
240
241 if( style >= 0 && style < (int) lineTypeNames.size() )
242 m_separatorsStyleCombo->SetSelection( style );
243 else
244 m_separatorsStyleCombo->SetSelection( 0 );
245
246 m_separatorsWidth.Enable( rows || cols );
247 m_separatorsStyleLabel->Enable( rows || cols );
248 m_separatorsStyleCombo->Enable( rows || cols );
249
250 return true;
251}
252
253
254void DIALOG_TABLE_PROPERTIES::onBorderChecked( wxCommandEvent& aEvent )
255{
256 BOARD_DESIGN_SETTINGS& bds = m_frame->GetDesignSettings();
258 int defaultLineThickness = bds.GetLineThickness( currentLayer );
259
260 bool border = m_borderCheckbox->GetValue();
261
262 if( border && m_borderWidth.GetValue() < 0 )
263 m_borderWidth.SetValue( defaultLineThickness );
264
265 m_borderWidth.Enable( border );
266 m_borderStyleLabel->Enable( border );
267 m_borderStyleCombo->Enable( border );
268
269 bool row = m_rowSeparators->GetValue();
270 bool col = m_colSeparators->GetValue();
271
272 if( ( row || col ) && m_separatorsWidth.GetValue() < 0 )
273 m_separatorsWidth.SetValue( defaultLineThickness );
274
275 m_separatorsWidth.Enable( row || col );
276 m_separatorsStyleLabel->Enable( row || col );
277 m_separatorsStyleCombo->Enable( row || col );
278}
279
280
282{
284 return false;
285
286 if( !wxDialog::TransferDataFromWindow() )
287 return false;
288
289 BOARD* board = m_frame->GetBoard();
290 BOARD_COMMIT commit( m_frame );
291 commit.Modify( m_table );
292
293 // If no other command in progress, prepare undo command
294 // (for a command in progress, will be made later, at the completion of command)
295 bool pushCommit = ( m_table->GetEditFlags() == 0 );
296
297 // Set IN_EDIT flag to force undo/redo/abort proper operation and avoid new calls to
298 // SaveCopyInUndoList for the same text if is moved, and then rotated, edited, etc....
299 if( !pushCommit )
301
302 for( int row = 0; row < m_table->GetRowCount(); ++row )
303 {
304 for( int col = 0; col < m_table->GetColCount(); ++col )
305 {
306 PCB_TABLECELL* tableCell;
307
308 if( IsBackLayer( m_table->GetLayer() ) )
309 tableCell = m_table->GetCell( row, m_table->GetColCount() - 1 - col );
310 else
311 tableCell = m_table->GetCell( row, col );
312
313 wxString txt = m_grid->GetCellValue( row, col );
314
315 // convert any text variable cross-references to their UUIDs
316 txt = board->ConvertCrossReferencesToKIIDs( txt );
317
318#ifdef __WXMAC__
319 // On macOS CTRL+Enter produces '\r' instead of '\n' regardless of EOL setting.
320 // Replace it now.
321 txt.Replace( "\r", "\n" );
322#elif defined( __WINDOWS__ )
323 // On Windows, a new line is coded as \r\n. We use only \n in kicad files and in
324 // drawing routines so strip the \r char.
325 txt.Replace( "\r", "" );
326#endif
327
328 tableCell->SetText( txt );
329 }
330 }
331
333 m_table->SetLocked( m_cbLocked->GetValue() );
334
336 m_table->SetStrokeHeader( m_headerBorder->GetValue() );
337 {
339
340 if( m_borderCheckbox->GetValue() )
341 stroke.SetWidth( std::max( 0, m_borderWidth.GetIntValue() ) );
342 else
343 stroke.SetWidth( -1 );
344
345 auto it = lineTypeNames.begin();
346 std::advance( it, m_borderStyleCombo->GetSelection() );
347
348 if( it == lineTypeNames.end() )
349 stroke.SetLineStyle( LINE_STYLE::SOLID );
350 else
351 stroke.SetLineStyle( it->first );
352
353 m_table->SetBorderStroke( stroke );
354 }
355
356 m_table->SetStrokeRows( m_rowSeparators->GetValue() );
358 {
360
361 if( m_rowSeparators->GetValue() || m_colSeparators->GetValue() )
362 stroke.SetWidth( std::max( 0, m_separatorsWidth.GetIntValue() ) );
363 else
364 stroke.SetWidth( -1 );
365
366 auto it = lineTypeNames.begin();
367 std::advance( it, m_separatorsStyleCombo->GetSelection() );
368
369 if( it == lineTypeNames.end() )
370 stroke.SetLineStyle( LINE_STYLE::SOLID );
371 else
372 stroke.SetLineStyle( it->first );
373
374 m_table->SetSeparatorsStroke( stroke );
375 }
376
377 if( pushCommit )
378 commit.Push( _( "Edit Table" ), SKIP_CONNECTIVITY );
379
380 return true;
381}
382
383
385{
386 Layout(); // Make sure we get the current client size for the grid
387
388 wxSize availableGridSize = m_grid->GetClientSize();
389
390 if( availableGridSize.x == 0 || availableGridSize.y == 0 )
391 return;
392
393 BOX2I tableBBox = m_table->GetBoundingBox();
394 double scalerX = static_cast<double>( availableGridSize.x ) / tableBBox.GetWidth();
395 double scalerY = static_cast<double>( availableGridSize.y ) / tableBBox.GetHeight();
396
397 for( int row = 0; row < m_table->GetRowCount(); ++row )
398 m_grid->SetRowSize( row, std::floor( m_table->GetRowHeight( row ) * scalerY ) );
399
400 for( int col = 0; col < m_table->GetColCount(); ++col )
401 m_grid->SetColSize( col, std::floor( m_table->GetColWidth( col ) * scalerX ) );
402}
403
404
405void DIALOG_TABLE_PROPERTIES::onSize( wxSizeEvent& aEvent )
406{
407 if( m_table )
409
410 aEvent.Skip();
411}
412
413
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.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:295
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:1594
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1648
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
wxString UnescapeString(const wxString &aSource)
const std::map< LINE_STYLE, struct LINE_STYLE_DESC > lineTypeNames
Conversion map between LINE_STYLE values and style names displayed.