KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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 <board.h>
32#include <footprint.h>
33#include <pcb_group.h>
34#include <pcb_dimension.h>
35#include <pcb_shape.h>
36#include <pcb_text.h>
37#include <widgets/unit_binder.h>
38#include <widgets/font_choice.h>
39#include <tool/tool_manager.h>
43
44// Columns of layer classes grid
45enum
46{
54};
55
56enum
57{
65};
66
67
69static bool g_modifyValues;
74static bool g_filterByLayer;
75static int g_layerFilter;
77static wxString g_referenceFilter;
79static wxString g_footprintFilter;
80static bool g_filterSelected = false;
81
82
84{
89
94
95public:
98
99protected:
100 void onActionButtonChange( wxCommandEvent& event ) override;
101 void onSpecifiedValueUpdateUI( wxUpdateUIEvent& event ) override;
102 void onDimensionItemCheckbox( wxCommandEvent& aEvent ) override;
103
104 void OnLayerFilterSelect( wxCommandEvent& event ) override
105 {
106 m_layerFilterOpt->SetValue( true );
107 }
108 void OnReferenceFilterText( wxCommandEvent& event ) override
109 {
110 m_referenceFilterOpt->SetValue( true );
111 }
112 void OnFootprintFilterText( wxCommandEvent& event ) override
113 {
114 m_footprintFilterOpt->SetValue( true );
115 }
116
117 bool TransferDataToWindow() override;
118 bool TransferDataFromWindow() override;
119
120 void visitItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
121 void processItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
122};
123
124
127 m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits ),
128 m_textWidth( parent, m_SizeXlabel, m_SizeXCtrl, m_SizeXunit ),
129 m_textHeight( parent, m_SizeYlabel, m_SizeYCtrl, m_SizeYunit ),
130 m_thickness( parent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnit )
131{
132 m_parent = parent;
133 m_brdSettings = &m_parent->GetDesignSettings();
134 m_isBoardEditor = dynamic_cast<PCB_EDIT_FRAME*>( m_parent ) != nullptr;
135
136 if( !m_isBoardEditor )
137 {
138 m_otherFields->SetLabel( _( "Other text items" ) );
139 m_footprintGraphics->SetLabel( _( "Graphic items" ) );
140 m_footprintDimensions->SetLabel( _( "Dimension 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 wxCommandEvent dummy;
243
244#define SET_INT_VALUE( aRow, aCol, aValue ) \
245 m_grid->SetCellValue( aRow, aCol, m_parent->StringFromValue( aValue, true ) )
246
247#define SET_BOOL_VALUE( aRow, aCol, aValue ) \
248 attr = new wxGridCellAttr; \
249 attr->SetRenderer( new wxGridCellBoolRenderer() ); \
250 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); \
251 attr->SetReadOnly(); \
252 m_grid->SetAttr( aRow, aCol, attr ); \
253 m_grid->SetCellValue( aRow, aCol, ( aValue ) ? wxT( "1" ) : wxT( "" ) )
254
255 const BOARD_DESIGN_SETTINGS& bds = m_parent->GetBoard()->GetDesignSettings();
256 wxGridCellAttr* attr;
257
258 m_grid->SetCellValue( ROW_SILK, COL_CLASS_NAME, _( "Silk Layers" ) );
259 m_grid->SetCellValue( ROW_COPPER, COL_CLASS_NAME, _( "Copper Layers" ) );
260 m_grid->SetCellValue( ROW_EDGES, COL_CLASS_NAME, _( "Edge Cuts" ) );
261 m_grid->SetCellValue( ROW_COURTYARD, COL_CLASS_NAME, _( "Courtyards" ) );
262 m_grid->SetCellValue( ROW_FAB, COL_CLASS_NAME, _( "Fab Layers" ) );
263 m_grid->SetCellValue( ROW_OTHERS, COL_CLASS_NAME, _( "Other Layers" ) );
264
265 m_grid->SetCellValue( ROW_HEADER, COL_LINE_THICKNESS, _( "Line Thickness" ) );
272
273 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_WIDTH, _( "Text Width" ) );
278
279 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_HEIGHT, _( "Text Height" ) );
284
285 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_THICKNESS, _( "Text Thickness" ) );
290
291 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_ITALIC, _( "Italic" ) );
296
297 m_grid->SetCellValue( ROW_HEADER, COL_TEXT_UPRIGHT, _( "Upright" ) );
302
303 return true;
304
305#undef SET_INT_VALUE
306#undef SET_BOOL_VALUE
307}
308
309
311{
312 // Update the UNIT_BINDER controls if the action to take is changed
313 bool enable = m_setToSpecifiedValues->GetValue();
314
315 m_LayerLabel->Enable( enable );
316 m_LayerCtrl->Enable( enable );
317
318 m_lineWidth.Enable( enable );
319 m_textWidth.Enable( enable );
320 m_textHeight.Enable( enable );
321 m_thickness.Enable( enable );
322
323 m_fontLabel->Enable( enable );
324 m_fontCtrl->Enable( enable );
325
326 m_centerOnFP->Enable( enable );
327
328 enable = !enable;
329 m_grid->Enable( enable );
330}
331
332
334{
335 // Update the UI for the elements inside the use specified values sizer
336 event.Enable( m_setToSpecifiedValues->GetValue() );
337}
338
339
341{
342 if( m_footprintDimensions->GetValue() || m_boardDimensions->GetValue() )
343 m_setToLayerDefaults->SetLabel( _( "Set to layer and dimension default values:" ) );
344 else
345 m_setToLayerDefaults->SetLabel( _( "Set to layer default values:" ) );
346}
347
348
350{
351 aCommit.Modify( aItem );
352
353 PCB_TEXT* text = dynamic_cast<PCB_TEXT*>( aItem );
354 PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem );
355 PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem );
356 FOOTPRINT* parentFP = aItem->GetParentFootprint();
357
358 if( m_setToSpecifiedValues->GetValue() )
359 {
362
363 if( text )
364 {
366 text->SetTextSize( VECTOR2I( m_textWidth.GetValue(), text->GetTextSize().y ) );
367
369 text->SetTextSize( VECTOR2I( text->GetTextSize().x, m_textHeight.GetValue() ) );
370
372 text->SetTextThickness( m_thickness.GetValue() );
373
374 // Must be after SetTextSize()
375 if( m_bold->Get3StateValue() != wxCHK_UNDETERMINED )
376 text->SetBold( m_bold->GetValue() );
377
378 if( m_italic->Get3StateValue() != wxCHK_UNDETERMINED )
379 text->SetItalic( m_italic->GetValue() );
380
381 // Must come after setting bold & italic
382 if( m_fontCtrl->GetStringSelection() != INDETERMINATE_ACTION )
383 {
384 text->SetFont( m_fontCtrl->GetFontSelection( text->IsBold(), text->IsItalic() ) );
385 }
386 else if(( m_italic->Get3StateValue() != wxCHK_UNDETERMINED
387 || m_bold->Get3StateValue() != wxCHK_UNDETERMINED ) )
388 {
389 wxString fontName = text->GetFontName();
390
391 if( !text->GetFontName().IsEmpty() )
392 {
393 text->SetFont( KIFONT::FONT::GetFont( text->GetFontName(), text->IsBold(),
394 text->IsItalic() ) );
395 }
396 }
397
398 if( parentFP )
399 {
400 if( m_visible->Get3StateValue() != wxCHK_UNDETERMINED )
401 text->SetVisible( m_visible->GetValue() );
402
403 if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED )
404 text->SetKeepUpright( m_keepUpright->GetValue() );
405
406 if( m_centerOnFP->GetValue() == wxCHK_CHECKED )
407 text->SetTextPos( text->GetParent()->GetCenter() );
408 }
409 }
410
412 {
413 if( shape )
414 {
415 STROKE_PARAMS stroke = shape->GetStroke();
416 stroke.SetWidth( m_lineWidth.GetValue() );
417 shape->SetStroke( stroke );
418 }
419
420 if( dimension )
421 dimension->SetLineThickness( m_lineWidth.GetValue() );
422 }
423 }
424 else
425 {
426 PCB_LAYER_ID layer = aItem->GetLayer();
427
428 if( text )
429 {
430 text->SetTextSize( m_brdSettings->GetTextSize( layer ) );
431 text->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
432 text->SetItalic( m_brdSettings->GetTextItalic( layer ) );
433
434 if( parentFP )
435 text->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
436 }
437
438 if( shape )
439 {
440 STROKE_PARAMS stroke = shape->GetStroke();
441 stroke.SetWidth( m_brdSettings->GetLineThickness( layer ) );
442 shape->SetStroke( stroke );
443 }
444
445 if( dimension )
446 {
447 dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );
454 dimension->Update(); // refresh text & geometry
455 }
456 }
457}
458
459
461{
462 if( m_selectedItemsFilter->GetValue() )
463 {
464 BOARD_ITEM* candidate = aItem;
465
466 if( !candidate->IsSelected() )
467 {
468 if( candidate->GetParent() && candidate->GetParent()->Type() == PCB_FOOTPRINT_T )
469 candidate = candidate->GetParent();
470 }
471
472 if( !candidate->IsSelected() )
473 {
474 candidate = candidate->GetParentGroup();
475
476 while( candidate && !candidate->IsSelected() )
477 candidate = candidate->GetParentGroup();
478
479 if( !candidate )
480 return;
481 }
482 }
483
485 {
486 if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
487 return;
488 }
489
490 if( m_isBoardEditor )
491 {
492 if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
493 {
494 if( FOOTPRINT* fp = aItem->GetParentFootprint() )
495 {
496 if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
497 return;
498 }
499 }
500
501 if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
502 {
503 if( FOOTPRINT* fp = aItem->GetParentFootprint() )
504 {
505 if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
506 return;
507 }
508 }
509 }
510
511 processItem( aCommit, aItem );
512}
513
514
516{
517 int minTextSize = pcbIUScale.mmToIU( TEXT_MIN_SIZE_MM );
518 int maxTextSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
519
520 if( !m_textWidth.Validate( minTextSize, maxTextSize )
521 || !m_textHeight.Validate( minTextSize, maxTextSize ) )
522 {
523 return false;
524 }
525
526 BOARD_COMMIT commit( m_parent );
527
528 // Go through the footprints
529 for( FOOTPRINT* fp : m_parent->GetBoard()->Footprints() )
530 {
531 if( m_references->GetValue() )
532 visitItem( commit, &fp->Reference() );
533
534 if( m_values->GetValue() )
535 visitItem( commit, &fp->Value() );
536
537 // Go through all other footprint items
538 for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
539 {
540 KICAD_T itemType = boardItem->Type();
541
542 if( itemType == PCB_FIELD_T || itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
543 {
544 if( m_otherFields->GetValue() )
545 visitItem( commit, boardItem );
546 }
547 else if( BaseType( itemType ) == PCB_DIMENSION_T )
548 {
549 if( m_footprintDimensions->GetValue() )
550 visitItem( commit, boardItem );
551 }
552 else if( itemType == PCB_SHAPE_T )
553 {
554 if( m_footprintGraphics->GetValue() )
555 visitItem( commit, boardItem );
556 }
557 }
558 }
559
560 if( m_isBoardEditor )
561 {
562 // Go through the PCB text & graphic items
563 for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
564 {
565 KICAD_T itemType = boardItem->Type();
566
567 if( itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
568 {
569 if( m_boardText->GetValue() )
570 visitItem( commit, boardItem );
571 }
572 else if( BaseType( itemType ) == PCB_DIMENSION_T )
573 {
574 if( m_boardDimensions->GetValue() )
575 visitItem( commit, boardItem );
576 }
577 else if( itemType == PCB_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
578 {
579 if( m_boardGraphics->GetValue() )
580 visitItem( commit, boardItem );
581 }
582 }
583 }
584
585 commit.Push( wxT( "Edit text and graphics properties" ) );
587
588 return true;
589}
590
591
593{
594 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
596
597 dlg.ShowModal();
598 return 0;
599}
600
601
603{
604 FOOTPRINT_EDIT_FRAME* editFrame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
606
607 dlg.ShowModal();
608 return 0;
609}
610
611
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
@ 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.
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
DIM_UNITS_FORMAT m_DimensionUnitsFormat
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]
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
DIM_TEXT_POSITION m_DimensionTextPosition
DIM_UNITS_MODE m_DimensionUnitsMode
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:77
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:226
PCB_GROUP * GetParentGroup() const
Definition: board_item.h:91
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:260
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:248
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:204
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
void processItem(SCH_COMMIT *aCommit, const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
void visitItem(SCH_COMMIT *aCommit, 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
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:100
bool IsSelected() const
Definition: eda_item.h:109
KIFONT::FONT * GetFontSelection(bool aBold, bool aItalic) const
static FONT * GetFont(const wxString &aFontName=wxEmptyString, bool aBold=false, bool aItalic=false)
Definition: font.cpp:146
int SetLayerSelection(int layer)
bool SetLayersHotkeys(bool value)
Common, abstract interface for edit frames.
Abstract dimension API.
void Update()
Update the dimension's cached text and geometry.
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
void SetSuppressZeroes(bool aSuppress)
void SetTextPositionMode(DIM_TEXT_POSITION aMode)
void SetLineThickness(int aWidth)
void SetPrecision(DIM_PRECISION aPrecision)
void SetUnitsMode(DIM_UNITS_MODE aMode)
void SetKeepTextAligned(bool aKeepAligned)
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:85
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:86
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:81
void SetWidth(int aWidth)
Definition: stroke_params.h:92
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
Generic, UI-independent tool event.
Definition: tool_event.h:167
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)
#define TEXT_MIN_SIZE_MM
Minimum text size (1 micron).
Definition: eda_text.h:45
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition: eda_text.h:46
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ UNDEFINED_LAYER
Definition: layer_ids.h:61
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:1022
KICOMMON_API wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:154
Class to handle a set of BOARD_ITEMs.
#define SET_INT_VALUE(aRow, aCol, aValue)
#define SET_BOOL_VALUE(aRow, aCol, aValue)
std::vector< FAB_LAYER_COLOR > dummy
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 int mmToIU(double mm) const
Definition: base_units.h:88
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:248
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_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition: typeinfo.h:93
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
Definition: typeinfo.h:90
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
Definition: typeinfo.h:86
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:100
#define INDETERMINATE_ACTION
Definition: ui_common.h:46