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 enable = !enable;
327 m_grid->Enable( enable );
328}
329
330
332{
333 // Update the UI for the elements inside the use specified values sizer
334 event.Enable( m_setToSpecifiedValues->GetValue() );
335}
336
337
339{
340 if( m_footprintDimensions->GetValue() || m_boardDimensions->GetValue() )
341 m_setToLayerDefaults->SetLabel( _( "Set to layer and dimension default values:" ) );
342 else
343 m_setToLayerDefaults->SetLabel( _( "Set to layer default values:" ) );
344}
345
346
348{
349 aCommit.Modify( aItem );
350
351 PCB_TEXT* text = dynamic_cast<PCB_TEXT*>( aItem );
352 PCB_SHAPE* shape = dynamic_cast<PCB_SHAPE*>( aItem );
353 PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem );
354 FOOTPRINT* parentFP = aItem->GetParentFootprint();
355
356 if( m_setToSpecifiedValues->GetValue() )
357 {
360
361 if( text )
362 {
364 text->SetTextSize( VECTOR2I( m_textWidth.GetValue(), text->GetTextSize().y ) );
365
367 text->SetTextSize( VECTOR2I( text->GetTextSize().x, m_textHeight.GetValue() ) );
368
370 text->SetTextThickness( m_thickness.GetValue() );
371
372 if( m_bold->Get3StateValue() != wxCHK_UNDETERMINED )
373 text->SetBold( m_bold->GetValue() );
374
375 if( m_italic->Get3StateValue() != wxCHK_UNDETERMINED )
376 text->SetItalic( m_italic->GetValue() );
377
378 // Must come after setting bold & italic
379 if( m_fontCtrl->GetStringSelection() != INDETERMINATE_ACTION )
380 {
381 text->SetFont( m_fontCtrl->GetFontSelection( text->IsBold(), text->IsItalic() ) );
382 }
383 else if(( m_italic->Get3StateValue() != wxCHK_UNDETERMINED
384 || m_bold->Get3StateValue() != wxCHK_UNDETERMINED ) )
385 {
386 wxString fontName = text->GetFontName();
387
388 if( !text->GetFontName().IsEmpty() )
389 {
390 text->SetFont( KIFONT::FONT::GetFont( text->GetFontName(), text->IsBold(),
391 text->IsItalic() ) );
392 }
393 }
394
395 if( parentFP )
396 {
397 if( m_visible->Get3StateValue() != wxCHK_UNDETERMINED )
398 text->SetVisible( m_visible->GetValue() );
399
400 if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED )
401 text->SetKeepUpright( m_keepUpright->GetValue() );
402 }
403 }
404
406 {
407 if( shape )
408 {
409 STROKE_PARAMS stroke = shape->GetStroke();
410 stroke.SetWidth( m_lineWidth.GetValue() );
411 shape->SetStroke( stroke );
412 }
413
414 if( dimension )
415 dimension->SetLineThickness( m_lineWidth.GetValue() );
416 }
417 }
418 else
419 {
420 PCB_LAYER_ID layer = aItem->GetLayer();
421
422 if( text )
423 {
424 text->SetTextSize( m_brdSettings->GetTextSize( layer ) );
425 text->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
426 text->SetItalic( m_brdSettings->GetTextItalic( layer ) );
427
428 if( parentFP )
429 text->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
430 }
431
432 if( shape )
433 {
434 STROKE_PARAMS stroke = shape->GetStroke();
435 stroke.SetWidth( m_brdSettings->GetLineThickness( layer ) );
436 shape->SetStroke( stroke );
437 }
438
439 if( dimension )
440 {
441 dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );
448 dimension->Update(); // refresh text & geometry
449 }
450 }
451}
452
453
455{
456 if( m_selectedItemsFilter->GetValue() )
457 {
458 BOARD_ITEM* candidate = aItem;
459
460 if( !candidate->IsSelected() )
461 {
462 if( candidate->GetParent() && candidate->GetParent()->Type() == PCB_FOOTPRINT_T )
463 candidate = candidate->GetParent();
464 }
465
466 if( !candidate->IsSelected() )
467 {
468 candidate = candidate->GetParentGroup();
469
470 while( candidate && !candidate->IsSelected() )
471 candidate = candidate->GetParentGroup();
472
473 if( !candidate )
474 return;
475 }
476 }
477
479 {
480 if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
481 return;
482 }
483
484 if( m_isBoardEditor )
485 {
486 if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
487 {
488 if( FOOTPRINT* fp = aItem->GetParentFootprint() )
489 {
490 if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
491 return;
492 }
493 }
494
495 if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
496 {
497 if( FOOTPRINT* fp = aItem->GetParentFootprint() )
498 {
499 if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
500 return;
501 }
502 }
503 }
504
505 processItem( aCommit, aItem );
506}
507
508
510{
511 int minTextSize = pcbIUScale.MilsToIU( TEXT_MIN_SIZE_MILS );
512 int maxTextSize = pcbIUScale.MilsToIU( TEXT_MAX_SIZE_MILS );
513
514 if( !m_textWidth.Validate( minTextSize, maxTextSize )
515 || !m_textHeight.Validate( minTextSize, maxTextSize ) )
516 {
517 return false;
518 }
519
520 BOARD_COMMIT commit( m_parent );
521
522 // Go through the footprints
523 for( FOOTPRINT* fp : m_parent->GetBoard()->Footprints() )
524 {
525 if( m_references->GetValue() )
526 visitItem( commit, &fp->Reference() );
527
528 if( m_values->GetValue() )
529 visitItem( commit, &fp->Value() );
530
531 // Go through all other footprint items
532 for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
533 {
534 KICAD_T itemType = boardItem->Type();
535
536 if( itemType == PCB_FIELD_T || itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
537 {
538 if( m_otherFields->GetValue() )
539 visitItem( commit, boardItem );
540 }
541 else if( BaseType( itemType ) == PCB_DIMENSION_T )
542 {
543 if( m_footprintDimensions->GetValue() )
544 visitItem( commit, boardItem );
545 }
546 else if( itemType == PCB_SHAPE_T )
547 {
548 if( m_footprintGraphics->GetValue() )
549 visitItem( commit, boardItem );
550 }
551 }
552 }
553
554 if( m_isBoardEditor )
555 {
556 // Go through the PCB text & graphic items
557 for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
558 {
559 KICAD_T itemType = boardItem->Type();
560
561 if( itemType == PCB_TEXT_T || itemType == PCB_TEXTBOX_T )
562 {
563 if( m_boardText->GetValue() )
564 visitItem( commit, boardItem );
565 }
566 else if( BaseType( itemType ) == PCB_DIMENSION_T )
567 {
568 if( m_boardDimensions->GetValue() )
569 visitItem( commit, boardItem );
570 }
571 else if( itemType == PCB_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
572 {
573 if( m_boardGraphics->GetValue() )
574 visitItem( commit, boardItem );
575 }
576 }
577 }
578
579 commit.Push( wxT( "Edit text and graphics properties" ) );
581
582 return true;
583}
584
585
587{
588 PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
590
591 dlg.ShowModal();
592 return 0;
593}
594
595
597{
598 FOOTPRINT_EDIT_FRAME* editFrame = getEditFrame<FOOTPRINT_EDIT_FRAME>();
600
601 dlg.ShowModal();
602 return 0;
603}
604
605
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:109
@ 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:204
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:238
FOOTPRINT * GetParentFootprint() const
Definition: board_item.cpp:247
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:182
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
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:97
bool IsSelected() const
Definition: eda_item.h:106
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:82
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: pcb_shape.h:83
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_MILS
Minimum text size in mils.
Definition: eda_text.h:42
#define TEXT_MAX_SIZE_MILS
Maximum text size in mils (10 inches)
Definition: eda_text.h:43
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:932
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:160
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 MilsToIU(int mils) const
Definition: base_units.h:94
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:252
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:92
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
@ 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:97
#define INDETERMINATE_ACTION
Definition: ui_common.h:43