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-2018 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 <kicad_string.h>
26 #include <board_commit.h>
27 #include <pcb_edit_frame.h>
28 #include <pcb_layer_box_selector.h>
29 #include <pcbnew.h>
30 #include <board.h>
31 #include <board_design_settings.h>
32 #include <footprint.h>
33 #include <pcb_dimension.h>
34 #include <fp_shape.h>
35 #include <pcb_text.h>
36 #include <widgets/unit_binder.h>
37 #include <tool/tool_manager.h>
38 #include <tools/global_edit_tool.h>
40 
41 
42 // Columns of layer classes grid
43 enum
44 {
52 };
53 
54 enum
55 {
63 };
64 
65 
66 static bool g_modifyReferences;
67 static bool g_modifyValues;
68 static bool g_modifyOtherFields;
70 static bool g_modifyBoardText;
72 static bool g_filterByLayer;
74 static bool g_filterByReference;
75 static wxString g_referenceFilter;
76 static bool g_filterByFootprint;
77 static wxString g_footprintFilter;
78 static bool g_filterSelected = false;
79 
80 
82 {
86 
91 
92 public:
95 
96 protected:
97  void onActionButtonChange( wxCommandEvent& event ) override;
98  void onSpecifiedValueUpdateUI( wxUpdateUIEvent& event ) override;
99 
100  void OnLayerFilterSelect( wxCommandEvent& event ) override
101  {
102  m_layerFilterOpt->SetValue( true );
103  }
104  void OnReferenceFilterText( wxCommandEvent& event ) override
105  {
106  m_referenceFilterOpt->SetValue( true );
107  }
108  void OnFootprintFilterText( wxCommandEvent& event ) override
109  {
110  m_footprintFilterOpt->SetValue( true );
111  }
112 
113  bool TransferDataToWindow() override;
114  bool TransferDataFromWindow() override;
115 
116  void visitItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem, FOOTPRINT* aParentItem );
117  void processItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
118 };
119 
120 
123  m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits ),
124  m_textWidth( parent, m_SizeXlabel, m_SizeXCtrl, m_SizeXunit ),
125  m_textHeight( parent, m_SizeYlabel, m_SizeYCtrl, m_SizeYunit ),
126  m_thickness( parent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnit )
127 {
128  m_parent = parent;
129  m_brdSettings = &m_parent->GetDesignSettings();
130 
134 
136  m_LayerCtrl->SetLayersHotkeys( false );
138  m_LayerCtrl->Resync();
139 
140  m_grid->SetCellHighlightPenWidth( 0 );
141  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
142  infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
143  m_grid->SetDefaultCellFont( infoFont );
144 
145  m_sdbSizerButtonsOK->SetDefault();
146 
148 }
149 
150 
152 {
153  g_modifyReferences = m_references->GetValue();
154  g_modifyValues = m_values->GetValue();
155  g_modifyOtherFields = m_otherFields->GetValue();
157  g_modifyBoardText = m_boardText->GetValue();
159 
160  g_filterByLayer = m_layerFilterOpt->GetValue();
163  g_referenceFilter = m_referenceFilter->GetValue();
165  g_footprintFilter = m_footprintFilter->GetValue();
167 }
168 
169 
171 {
173  m_selection = selTool->GetSelection();
174 
175  m_references->SetValue( g_modifyReferences );
176  m_values->SetValue( g_modifyValues );
177  m_otherFields->SetValue( g_modifyOtherFields );
179  m_boardText->SetValue( g_modifyBoardText );
181 
182  if( m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
183  m_layerFilterOpt->SetValue( g_filterByLayer );
184 
185  // SetValue() generates events, ChangeValue() does not
186  m_referenceFilter->ChangeValue( g_referenceFilter );
188  m_footprintFilter->ChangeValue( g_footprintFilter );
191 
196  m_Italic->Set3StateValue( wxCHK_UNDETERMINED );
197  m_keepUpright->Set3StateValue( wxCHK_UNDETERMINED );
198  m_Visible->Set3StateValue( wxCHK_UNDETERMINED );
200 
201 #define SET_INT_VALUE( aRow, aCol, aValue ) \
202  m_grid->SetCellValue( aRow, aCol, StringFromValue( GetUserUnits(), aValue, true ) )
203 
204 #define SET_BOOL_VALUE( aRow, aCol, aValue ) \
205  attr = new wxGridCellAttr; \
206  attr->SetRenderer( new wxGridCellBoolRenderer() ); \
207  attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); \
208  attr->SetReadOnly(); \
209  m_grid->SetAttr( aRow, aCol, attr ); \
210  m_grid->SetCellValue( aRow, aCol, ( aValue ) ? "1" : "" )
211 
212  const BOARD_DESIGN_SETTINGS& bds = m_parent->GetBoard()->GetDesignSettings();
213  wxGridCellAttr* attr;
214 
215  m_grid->SetCellValue( ROW_SILK, COL_CLASS_NAME, _( "Silk Layers" ) );
216  m_grid->SetCellValue( ROW_COPPER, COL_CLASS_NAME, _( "Copper Layers" ) );
217  m_grid->SetCellValue( ROW_EDGES, COL_CLASS_NAME, _( "Edge Cuts" ) );
218  m_grid->SetCellValue( ROW_COURTYARD, COL_CLASS_NAME, _( "Courtyards" ) );
219  m_grid->SetCellValue( ROW_FAB, COL_CLASS_NAME, _( "Fab Layers" ) );
220  m_grid->SetCellValue( ROW_OTHERS, COL_CLASS_NAME, _( "Other Layers" ) );
221 
222  m_grid->SetCellValue( ROW_HEADER, COL_LINE_THICKNESS, _( "Line Thickness" ) );
229 
230  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_WIDTH, _( "Text Width" ) );
235 
236  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_HEIGHT, _( "Text Height" ) );
241 
242  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_THICKNESS, _( "Text Thickness" ) );
247 
248  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_ITALIC, _( "Italic" ) );
253 
254  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_UPRIGHT, _( "Upright" ) );
259 
260  return true;
261 
262 #undef SET_INT_VALUE
263 #undef SET_BOOL_VALUE
264 }
265 
266 
268 {
269  // Update the UNIT_BINDER controls if the action to take is changed
270  bool enable = m_setToSpecifiedValues->GetValue();
271 
272  m_lineWidth.Enable( enable );
273  m_textWidth.Enable( enable );
274  m_textHeight.Enable( enable );
275  m_thickness.Enable( enable );
276 }
277 
278 
280 {
281  // Update the UI for the elements inside the use specified values sizer
282  event.Enable( m_setToSpecifiedValues->GetValue() );
283 }
284 
285 
287 {
288  aCommit.Modify( aItem );
289 
290  EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aItem );
291  FP_TEXT* fpTextItem = dynamic_cast<FP_TEXT*>( aItem );
292  PCB_SHAPE* drawItem = dynamic_cast<PCB_SHAPE*>( aItem );
293  PCB_DIMENSION_BASE* dimension = dynamic_cast<PCB_DIMENSION_BASE*>( aItem );
294 
295  if( dimension )
296  textItem = &dimension->Text();
297 
298  if( m_setToSpecifiedValues->GetValue() )
299  {
302 
303  if( !m_textWidth.IsIndeterminate() && textItem )
304  textItem->SetTextSize( wxSize( m_textWidth.GetValue(), textItem->GetTextSize().y ) );
305 
306  if( !m_textHeight.IsIndeterminate() && textItem )
307  textItem->SetTextSize( wxSize( textItem->GetTextSize().x, m_textHeight.GetValue() ) );
308 
309  if( !m_thickness.IsIndeterminate() && textItem )
310  textItem->SetTextThickness( m_thickness.GetValue() );
311 
312  if( m_Italic->Get3StateValue() != wxCHK_UNDETERMINED && textItem )
313  textItem->SetItalic( m_Italic->GetValue() );
314 
315  if( m_Visible->Get3StateValue() != wxCHK_UNDETERMINED && textItem )
316  textItem->SetVisible( m_Visible->GetValue() );
317 
318  if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED && fpTextItem )
319  fpTextItem->SetKeepUpright( m_keepUpright->GetValue() );
320 
322  {
323  if( drawItem )
324  drawItem->SetWidth( m_lineWidth.GetValue() );
325 
326  if( dimension )
327  dimension->SetLineThickness( m_lineWidth.GetValue() );
328  }
329  }
330  else
331  {
332  PCB_LAYER_ID layer = aItem->GetLayer();
333 
334  if( textItem )
335  {
336  textItem->SetTextSize( m_brdSettings->GetTextSize( layer ) );
337  textItem->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
338  textItem->SetItalic( m_brdSettings->GetTextItalic( layer ) );
339  }
340 
341  if( fpTextItem )
342  fpTextItem->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
343 
344  if( drawItem )
345  drawItem->SetWidth( m_brdSettings->GetLineThickness( layer ) );
346 
347  if( dimension )
348  dimension->SetLineThickness( m_brdSettings->GetLineThickness( layer ) );
349  }
350 }
351 
352 
354  FOOTPRINT* aParentItem = nullptr )
355 {
356  if( m_selectedItemsFilter->GetValue() && !m_selection.Contains( aItem )
357  && ( aParentItem == nullptr || !m_selection.Contains( aParentItem ) ) )
358  return;
359 
361  {
362  if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
363  return;
364  }
365 
366  if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
367  {
368  FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
369 
370  if( fp )
371  {
372  if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
373  return;
374  }
375  }
376 
377  if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
378  {
379  FOOTPRINT* fp = dynamic_cast<FOOTPRINT*>( aItem->GetParent() );
380 
381  if( fp )
382  {
383  if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
384  return;
385  }
386  }
387 
388  processItem( aCommit, aItem );
389 }
390 
391 
393 {
396  {
397  return false;
398  }
399 
400  BOARD_COMMIT commit( m_parent );
401 
402  // Go through the footprints
403  for( FOOTPRINT* fp : m_parent->GetBoard()->Footprints() )
404  {
405  if( m_references->GetValue() )
406  visitItem( commit, &fp->Reference(), fp );
407 
408  if( m_values->GetValue() )
409  visitItem( commit, &fp->Value(), fp );
410 
411  // Go through all other footprint items
412  for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
413  {
414  if( boardItem->Type() == PCB_FP_TEXT_T )
415  {
416  // We are guaranteed to always get an EDA_TEXT in this statement, but we must
417  // use the dynamic_cast to move through the type tree anyway.
418  const wxString text = dynamic_cast<EDA_TEXT*>( boardItem )->GetText();
419 
420  if( m_references->GetValue() && text == wxT( "${REFERENCE}" ) )
421  visitItem( commit, boardItem, fp );
422  else if( m_values->GetValue() && text == wxT( "${VALUE}" ) )
423  visitItem( commit, boardItem, fp );
424  else if( m_otherFields->GetValue() )
425  visitItem( commit, boardItem, fp );
426  }
427  else if( boardItem->Type() == PCB_FP_SHAPE_T )
428  {
429  if( m_footprintGraphics->GetValue() )
430  visitItem( commit, boardItem, fp );
431  }
432  }
433  }
434 
435  // Go through the PCB text & graphic items
436  for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
437  {
438  KICAD_T itemType = boardItem->Type();
439 
440  if( itemType == PCB_TEXT_T )
441  {
442  if( m_boardText->GetValue() )
443  visitItem( commit, boardItem );
444  }
445  else if( itemType == PCB_SHAPE_T || BaseType( itemType ) == PCB_DIMENSION_T )
446  {
447  if( m_boardGraphics->GetValue() )
448  visitItem( commit, boardItem );
449  }
450  }
451 
452  commit.Push( "Edit text and graphics properties" );
453  m_parent->GetCanvas()->Refresh();
454 
455  return true;
456 }
457 
458 
460 {
461  PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
462  DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS dlg( editFrame );
463 
464  dlg.ShowModal();
465  return 0;
466 }
467 
468 
#define SET_INT_VALUE(aRow, aCol, aValue)
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
class FP_TEXT, text in a footprint
Definition: typeinfo.h:92
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition: board_item.h:192
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
void visitItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
PCB_TEXT & Text()
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:235
void SetItalic(bool isItalic)
Definition: eda_text.h:186
void SetVisible(bool aVisible)
Definition: eda_text.h:192
class PCB_TEXT, text on a layer
Definition: typeinfo.h:91
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:93
Abstract dimension API.
Definition: pcb_dimension.h:95
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
void SetLineThickness(int aWidth)
bool GetTextUpright(PCB_LAYER_ID aLayer) const
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
bool GetTextItalic(PCB_LAYER_ID aLayer) const
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]
LAYER_NUM GetLayerSelection() const
PCB_SELECTION & GetSelection()
Return the set of currently selected items.
PCB_LAYER_ID
A quick note on layer IDs:
int m_TextThickness[LAYER_CLASS_COUNT]
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.
Definition: string.cpp:586
const wxSize & GetTextSize() const
Definition: eda_text.h:245
SCH_DRAW_PANEL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
Generic, UI-independent tool event.
Definition: tool_event.h:152
bool Contains(EDA_ITEM *aItem) const
Definition: selection.cpp:61
bool m_TextItalic[LAYER_CLASS_COUNT]
const wxString & GetReference() const
Definition: footprint.h:421
#define _(s)
int SetLayerSelection(LAYER_NUM layer)
const LIB_ID & GetFPID() const
Definition: footprint.h:185
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:32
bool SetLayersHotkeys(bool value)
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:99
int m_LineThickness[LAYER_CLASS_COUNT]
UTF8 Format() const
Definition: lib_id.cpp:233
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:31
int LAYER_NUM
This can be replaced with int and removed.
void SetUndefinedLayerName(const wxString &aName)
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void SetKeepUpright(bool aKeepUpright)
Definition: fp_text.h:115
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(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
#define SET_BOOL_VALUE(aRow, aCol, aValue)
The main frame for Pcbnew.
void SetWidth(int aWidth)
Definition: pcb_shape.h:96
The selection tool: currently supports:
virtual long long int GetValue()
Return the current value in Internal Units.
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:166
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
#define INDETERMINATE_ACTION
Definition: base_units.h:48
BOARD_ITEM_CONTAINER * GetParent() const
Definition: board_item.h:166
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:90
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:171
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
bool m_TextUpright[LAYER_CLASS_COUNT]
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
void processItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem, SCH_ITEM *aParentItem)
Container for design settings for a BOARD object.