KiCad PCB EDA Suite
pcbnew/dialogs/dialog_global_edit_text_and_graphics.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) 2012 Jean-Pierre Charras, jp.charras at wanadoo.fr
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, you may find one here:
19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20 * or you may search the http://www.gnu.org website for the version 2 license,
21 * or you may write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 */
24
25#include <string_utils.h>
26#include <board_commit.h>
27#include <pcb_edit_frame.h>
30#include <pcbnew.h>
31#include <board.h>
33#include <footprint.h>
34#include <pcb_group.h>
35#include <pcb_dimension.h>
36#include <fp_shape.h>
37#include <pcb_text.h>
38#include <widgets/unit_binder.h>
39#include <widgets/font_choice.h>
40#include <tool/tool_manager.h>
45
46// Columns of layer classes grid
47enum
48{
56};
57
58enum
59{
67};
68
69
71static bool g_modifyValues;
76static bool g_filterByLayer;
77static int g_layerFilter;
79static wxString g_referenceFilter;
81static wxString g_footprintFilter;
82static bool g_filterSelected = false;
83
84
86{
91
96
97public:
100
101protected:
102 void onActionButtonChange( wxCommandEvent& event ) override;
103 void onSpecifiedValueUpdateUI( wxUpdateUIEvent& event ) override;
104
105 void OnLayerFilterSelect( wxCommandEvent& event ) override
106 {
107 m_layerFilterOpt->SetValue( true );
108 }
109 void OnReferenceFilterText( wxCommandEvent& event ) override
110 {
111 m_referenceFilterOpt->SetValue( true );
112 }
113 void OnFootprintFilterText( wxCommandEvent& event ) override
114 {
115 m_footprintFilterOpt->SetValue( true );
116 }
117
118 bool TransferDataToWindow() override;
119 bool TransferDataFromWindow() override;
120
121 void visitItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
122 void processItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
123};
124
125
128 m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits ),
129 m_textWidth( parent, m_SizeXlabel, m_SizeXCtrl, m_SizeXunit ),
130 m_textHeight( parent, m_SizeYlabel, m_SizeYCtrl, m_SizeYunit ),
131 m_thickness( parent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnit )
132{
133 m_parent = parent;
134 m_brdSettings = &m_parent->GetDesignSettings();
135 m_isBoardEditor = dynamic_cast<PCB_EDIT_FRAME*>( m_parent ) != nullptr;
136
137 if( !m_isBoardEditor )
138 {
139 m_otherFields->SetLabel( _( "Other text items" ) );
140 m_footprintGraphics->SetLabel( _( "Graphic items" ) );
141
142 m_boardText->Show( false );
143 m_boardGraphics->Show( false );
144
145 m_referenceFilterOpt->Show( false );
146 m_referenceFilter->Show( false );
147 m_footprintFilterOpt->Show( false );
148 m_footprintFilter->Show( false );
149 }
150
154
159
160 m_grid->SetCellHighlightPenWidth( 0 );
161 m_grid->SetDefaultCellFont( KIUI::GetInfoFont( this ) );
162
164
166}
167
168
170{
171 g_modifyReferences = m_references->GetValue();
172 g_modifyValues = m_values->GetValue();
175
176 if( m_isBoardEditor )
177 {
178 g_modifyBoardText = m_boardText->GetValue();
180 }
181
182 g_filterByLayer = m_layerFilterOpt->GetValue();
184
185 if( m_isBoardEditor )
186 {
191 }
192
194}
195
196
198{
200 m_selection = selTool->GetSelection();
201
202 m_references->SetValue( g_modifyReferences );
203 m_values->SetValue( g_modifyValues );
206
207 if( m_isBoardEditor )
208 {
209 m_boardText->SetValue( g_modifyBoardText );
211 }
212
213 if( m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
215
216 if( m_isBoardEditor )
217 {
218 // SetValue() generates events, ChangeValue() does not
219 m_referenceFilter->ChangeValue( g_referenceFilter );
221 m_footprintFilter->ChangeValue( g_footprintFilter );
223 }
224
226
228
230 m_fontCtrl->SetStringSelection( INDETERMINATE_ACTION );
231
235 m_bold->Set3StateValue( wxCHK_UNDETERMINED );
236 m_italic->Set3StateValue( wxCHK_UNDETERMINED );
237 m_keepUpright->Set3StateValue( wxCHK_UNDETERMINED );
238 m_visible->Set3StateValue( wxCHK_UNDETERMINED );
240
241#define SET_INT_VALUE( aRow, aCol, aValue ) \
242 m_grid->SetCellValue( aRow, aCol, m_parent->StringFromValue( aValue, true ) )
243
244#define SET_BOOL_VALUE( aRow, aCol, aValue ) \
245 attr = new wxGridCellAttr; \
246 attr->SetRenderer( new wxGridCellBoolRenderer() ); \
247 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); \
248 attr->SetReadOnly(); \
249 m_grid->SetAttr( aRow, aCol, attr ); \
250 m_grid->SetCellValue( aRow, aCol, ( aValue ) ? wxT( "1" ) : wxT( "" ) )
251
252 const BOARD_DESIGN_SETTINGS& bds = m_parent->GetBoard()->GetDesignSettings();
253 wxGridCellAttr* attr;
254
255 m_grid->SetCellValue( ROW_SILK, COL_CLASS_NAME, _( "Silk Layers" ) );
256 m_grid->SetCellValue( ROW_COPPER, COL_CLASS_NAME, _( "Copper Layers" ) );
257 m_grid->SetCellValue( ROW_EDGES, COL_CLASS_NAME, _( "Edge Cuts" ) );
258 m_grid->SetCellValue( ROW_COURTYARD, COL_CLASS_NAME, _( "Courtyards" ) );
259 m_grid->SetCellValue( ROW_FAB, COL_CLASS_NAME, _( "Fab Layers" ) );
260 m_grid->SetCellValue( ROW_OTHERS, COL_CLASS_NAME, _( "Other Layers" ) );
261
262 m_grid->SetCellValue( ROW_HEADER, COL_LINE_THICKNESS, _( "Line Thickness" ) );
269
270 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_WIDTH, _( "Text Width" ) );
275
276 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_HEIGHT, _( "Text Height" ) );
281
282 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_THICKNESS, _( "Text Thickness" ) );
287
288 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_ITALIC, _( "Italic" ) );
293
294 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_UPRIGHT, _( "Upright" ) );
299
300 return true;
301
302#undef SET_INT_VALUE
303#undef SET_BOOL_VALUE
304}
305
306
308{
309 // Update the UNIT_BINDER controls if the action to take is changed
310 bool enable = m_setToSpecifiedValues->GetValue();
311
312 m_lineWidth.Enable( enable );
313 m_textWidth.Enable( enable );
314 m_textHeight.Enable( enable );
315 m_thickness.Enable( enable );
316}
317
318
320{
321 // Update the UI for the elements inside the use specified values sizer
322 event.Enable( m_setToSpecifiedValues->GetValue() );
323}
324
325
327{
328 aCommit.Modify( aItem );
329
330 EDA_TEXT* edaText = dynamic_cast<EDA_TEXT*>( aItem );
331 FP_TEXT* fpText = dynamic_cast<FP_TEXT*>( aItem );
332 PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem );
333 PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem );
334
335 if( dimension )
336 edaText = &dimension->Text();
337
338 if( m_setToSpecifiedValues->GetValue() )
339 {
342
343 if( edaText )
344 {
346 edaText->SetTextSize( wxSize( m_textWidth.GetValue(), edaText->GetTextSize().y ) );
347
349 edaText->SetTextSize( wxSize( edaText->GetTextSize().x, m_textHeight.GetValue() ) );
350
353
354 if( m_bold->Get3StateValue() != wxCHK_UNDETERMINED )
355 edaText->SetBold( m_bold->GetValue() );
356
357 if( m_italic->Get3StateValue() != wxCHK_UNDETERMINED )
358 edaText->SetItalic( m_italic->GetValue() );
359
360 // Must come after setting bold & italic
361 if( m_fontCtrl->GetStringSelection() != INDETERMINATE_ACTION )
362 {
363 edaText->SetFont( m_fontCtrl->GetFontSelection( edaText->IsBold(),
364 edaText->IsItalic() ) );
365 }
366 else if(( m_italic->Get3StateValue() != wxCHK_UNDETERMINED
367 || m_bold->Get3StateValue() != wxCHK_UNDETERMINED ) )
368 {
369 wxString fontName = edaText->GetFontName();
370
371 if( !edaText->GetFontName().IsEmpty() )
372 {
373 edaText->SetFont( KIFONT::FONT::GetFont( edaText->GetFontName(),
374 edaText->IsBold(),
375 edaText->IsItalic() ) );
376 }
377 }
378
379 if( m_visible->Get3StateValue() != wxCHK_UNDETERMINED )
380 edaText->SetVisible( m_visible->GetValue() );
381 }
382
383 if( fpText )
384 {
385 if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED )
386 fpText->SetKeepUpright( m_keepUpright->GetValue() );
387 }
388
390 {
391 if( shape )
392 {
393 STROKE_PARAMS stroke = shape->GetStroke();
394 stroke.SetWidth( m_lineWidth.GetValue() );
395 shape->SetStroke( stroke );
396 }
397
398 if( dimension )
399 dimension->SetLineThickness( m_lineWidth.GetValue() );
400 }
401 }
402 else
403 {
404 PCB_LAYER_ID layer = aItem->GetLayer();
405
406 if( edaText )
407 {
408 edaText->SetTextSize( m_brdSettings->GetTextSize( layer ) );
409 edaText->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
410 edaText->SetItalic( m_brdSettings->GetTextItalic( layer ) );
411 }
412
413 if( fpText )
414 fpText->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
415
416 if( shape )
417 {
418 STROKE_PARAMS stroke = shape->GetStroke();
419 stroke.SetWidth( m_brdSettings->GetLineThickness( layer ) );
420 shape->SetStroke( stroke );
421 }
422
423 if( dimension )
424 dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );
425 }
426}
427
428
430{
431 if( m_selectedItemsFilter->GetValue() )
432 {
433 BOARD_ITEM* candidate = aItem;
434
435 if( !candidate->IsSelected() )
436 {
437 if( candidate->GetParent() && candidate->GetParent()->Type() == PCB_FOOTPRINT_T )
438 candidate = candidate->GetParent();
439 }
440
441 if( !candidate->IsSelected() )
442 {
443 candidate = candidate->GetParentGroup();
444
445 while( candidate && !candidate->IsSelected() )
446 candidate = candidate->GetParentGroup();
447
448 if( !candidate )
449 return;
450 }
451 }
452
454 {
455 if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
456 return;
457 }
458
459 if( m_isBoardEditor )
460 {
461 if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
462 {
463 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
464
465 if( fp )
466 {
467 if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
468 return;
469 }
470 }
471
472 if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
473 {
474 FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
475
476 if( fp )
477 {
478 if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
479 return;
480 }
481 }
482 }
483
484 processItem( aCommit, aItem );
485}
486
487
489{
492 {
493 return false;
494 }
495
496 BOARD_COMMIT commit( m_parent );
497
498 // Go through the footprints
499 for( FOOTPRINT* fp : m_parent->GetBoard()->Footprints() )
500 {
501 if( m_references->GetValue() )
502 visitItem( commit, &fp->Reference() );
503
504 if( m_values->GetValue() )
505 visitItem( commit, &fp->Value() );
506
507 // Go through all other footprint items
508 for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
509 {
510 KICAD_T itemType = boardItem->Type();
511
512 if( itemType == PCB_FP_TEXT_T || itemType == PCB_FP_TEXTBOX_T )
513 {
514 if( m_otherFields->GetValue() )
515 visitItem( commit, boardItem );
516 }
517 else if( itemType == PCB_FP_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
518 {
519 if( m_footprintGraphics->GetValue() )
520 visitItem( commit, boardItem );
521 }
522 }
523 }
524
525 if( m_isBoardEditor )
526 {
527 // Go through the PCB text & graphic items
528 for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
529 {
530 KICAD_T itemType = boardItem->Type();
531
532 if( itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
533 {
534 if( m_boardText->GetValue() )
535 visitItem( commit, boardItem );
536 }
537 else if( itemType == PCB_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
538 {
539 if( m_boardGraphics->GetValue() )
540 visitItem( commit, boardItem );
541 }
542 }
543 }
544
545 commit.Push( wxT( "Edit text and graphics properties" ) );
547
548 return true;
549}
550
551
553{
554 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
556
557 dlg.ShowModal();
558 return 0;
559}
560
561
563{
564 FOOTPRINT_EDIT_FRAME* editFrame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
566
567 dlg.ShowModal();
568 return 0;
569}
570
571
@ LAYER_CLASS_OTHERS
@ LAYER_CLASS_FAB
@ LAYER_CLASS_COURTYARD
@ LAYER_CLASS_SILK
@ LAYER_CLASS_COPPER
@ LAYER_CLASS_EDGES
Container for design settings for a BOARD object.
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
bool GetTextUpright(PCB_LAYER_ID aLayer) const
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
bool m_TextUpright[LAYER_CLASS_COUNT]
bool GetTextItalic(PCB_LAYER_ID aLayer) const
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
wxSize m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:58
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:180
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:72
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:214
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:163
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
void visitItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
void processItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
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...
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:97
bool IsSelected() const
Definition: eda_item.h:107
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:72
wxString GetFontName() const
Definition: eda_text.cpp:757
bool IsItalic() const
Definition: eda_text.h:130
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:217
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.cpp:185
void SetBold(bool aBold)
Definition: eda_text.cpp:209
bool IsBold() const
Definition: eda_text.h:133
void SetKeepUpright(bool aKeepUpright)
Definition: eda_text.cpp:256
void SetTextSize(const VECTOR2I &aNewSize)
Definition: eda_text.cpp:347
void SetItalic(bool aItalic)
Definition: eda_text.cpp:201
void SetFont(KIFONT::FONT *aFont)
Definition: eda_text.cpp:331
VECTOR2I GetTextSize() const
Definition: eda_text.h:196
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic) const
const LIB_ID & GetFPID() const
Definition: footprint.h:212
const wxString & GetReference() const
Definition: footprint.h:519
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:65
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
UTF8 Format() const
Definition: lib_id.cpp:117
Common, abstract interface for edit frames.
Abstract dimension API.
Definition: pcb_dimension.h:96
PCB_TEXT & Text()
void SetLineThickness(int aWidth)
The main frame for Pcbnew.
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
void SetUndefinedLayerName(const wxString &aName)
The selection tool: currently supports:
PCB_SELECTION & GetSelection()
STROKE_PARAMS GetStroke() const override
Definition: pcb_shape.h:71
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:72
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Simple container to manage line stroke parameters.
Definition: stroke_params.h:88
void SetWidth(int aWidth)
Definition: stroke_params.h:99
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
Generic, UI-independent tool event.
Definition: tool_event.h:156
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
#define _(s)
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:59
@ UNDEFINED_LAYER
Definition: layer_ids.h:60
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:932
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:144
#define SET_INT_VALUE(aRow, aCol, aValue)
#define SET_BOOL_VALUE(aRow, aCol, aValue)
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:32
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:31
bool WildCompareString(const wxString &pattern, const wxString &string_to_tst, bool case_sensitive)
Compare a string against wild card (* and ?) pattern using the usual rules.
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:253
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:88
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
@ PCB_FP_TEXTBOX_T
class FP_TEXTBOX, wrapped text in a footprint
Definition: typeinfo.h:93
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:91
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:90
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_FP_TEXT_T
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:105
#define INDETERMINATE_ACTION
Definition: ui_common.h:43