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 <class_board.h>
30 #include <class_module.h>
31 #include <fp_shape.h>
32 #include <pcb_text.h>
33 #include <widgets/unit_binder.h>
34 #include <tools/global_edit_tool.h>
36 
37 
38 // Columns of layer classes grid
39 enum
40 {
48 };
49 
50 enum
51 {
59 };
60 
61 
62 static bool g_modifyReferences;
63 static bool g_modifyValues;
64 static bool g_modifyOtherFields;
66 static bool g_modifyBoardText;
68 static bool g_filterByLayer;
70 static bool g_filterByReference;
71 static wxString g_referenceFilter;
72 static bool g_filterByFootprint;
73 static wxString g_footprintFilter;
74 
75 
77 {
80 
85 
86 public:
89 
90 protected:
91  void OnUpdateUI( wxUpdateUIEvent& event ) override;
92  void OnLayerFilterSelect( wxCommandEvent& event ) override
93  {
94  m_layerFilterOpt->SetValue( true );
95  }
96  void OnReferenceFilterText( wxCommandEvent& event ) override
97  {
98  m_referenceFilterOpt->SetValue( true );
99  }
100  void OnFootprintFilterText( wxCommandEvent& event ) override
101  {
102  m_footprintFilterOpt->SetValue( true );
103  }
104 
105  bool TransferDataToWindow() override;
106  bool TransferDataFromWindow() override;
107 
108  void visitItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
109  void processItem( BOARD_COMMIT& aCommit, BOARD_ITEM* aItem );
110 };
111 
112 
115  m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits, true ),
116  m_textWidth( parent, m_SizeXlabel, m_SizeXCtrl, m_SizeXunit, true ),
117  m_textHeight( parent, m_SizeYlabel, m_SizeYCtrl, m_SizeYunit, true ),
118  m_thickness( parent, m_ThicknessLabel, m_ThicknessCtrl, m_ThicknessUnit, true )
119 {
120  m_parent = parent;
121  m_brdSettings = &m_parent->GetDesignSettings();
122 
126 
128  m_LayerCtrl->SetLayersHotkeys( false );
130  m_LayerCtrl->Resync();
131 
132  m_grid->SetCellHighlightPenWidth( 0 );
133  wxFont infoFont = wxSystemSettings::GetFont( wxSYS_DEFAULT_GUI_FONT );
134  infoFont.SetSymbolicSize( wxFONTSIZE_SMALL );
135  m_grid->SetDefaultCellFont( infoFont );
136 
137  m_sdbSizerButtonsOK->SetDefault();
138 
140 }
141 
142 
144 {
145  g_modifyReferences = m_references->GetValue();
146  g_modifyValues = m_values->GetValue();
147  g_modifyOtherFields = m_otherFields->GetValue();
149  g_modifyBoardText = m_boardText->GetValue();
151 
152  g_filterByLayer = m_layerFilterOpt->GetValue();
155  g_referenceFilter = m_referenceFilter->GetValue();
157  g_footprintFilter = m_footprintFilter->GetValue();
158 }
159 
160 
162 {
163  m_references->SetValue( g_modifyReferences );
164  m_values->SetValue( g_modifyValues );
165  m_otherFields->SetValue( g_modifyOtherFields );
167  m_boardText->SetValue( g_modifyBoardText );
169 
170  if( m_layerFilter->SetLayerSelection( g_layerFilter ) != wxNOT_FOUND )
171  m_layerFilterOpt->SetValue( g_filterByLayer );
172 
173  // SetValue() generates events, ChangeValue() does not
174  m_referenceFilter->ChangeValue( g_referenceFilter );
176  m_footprintFilter->ChangeValue( g_footprintFilter );
178 
183  m_Italic->Set3StateValue( wxCHK_UNDETERMINED );
184  m_keepUpright->Set3StateValue( wxCHK_UNDETERMINED );
185  m_Visible->Set3StateValue( wxCHK_UNDETERMINED );
187 
188 #define SET_INT_VALUE( aRow, aCol, aValue ) \
189  m_grid->SetCellValue( aRow, aCol, StringFromValue( GetUserUnits(), aValue, true ) )
190 
191 #define SET_BOOL_VALUE( aRow, aCol, aValue ) \
192  attr = new wxGridCellAttr; \
193  attr->SetRenderer( new wxGridCellBoolRenderer() ); \
194  attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); \
195  attr->SetReadOnly(); \
196  m_grid->SetAttr( aRow, aCol, attr ); \
197  m_grid->SetCellValue( aRow, aCol, ( aValue ) ? "1" : "" )
198 
199  const BOARD_DESIGN_SETTINGS& bds = m_parent->GetBoard()->GetDesignSettings();
200  wxGridCellAttr* attr;
201 
202  m_grid->SetCellValue( ROW_SILK, COL_CLASS_NAME, _( "Silk Layers" ) );
203  m_grid->SetCellValue( ROW_COPPER, COL_CLASS_NAME, _( "Copper Layers" ) );
204  m_grid->SetCellValue( ROW_EDGES, COL_CLASS_NAME, _( "Edge Cuts" ) );
205  m_grid->SetCellValue( ROW_COURTYARD, COL_CLASS_NAME, _( "Courtyards" ) );
206  m_grid->SetCellValue( ROW_FAB, COL_CLASS_NAME, _( "Fab Layers" ) );
207  m_grid->SetCellValue( ROW_OTHERS, COL_CLASS_NAME, _( "Other Layers" ) );
208 
209  m_grid->SetCellValue( ROW_HEADER, COL_LINE_THICKNESS, _( "Line Thickness" ) );
216 
217  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_WIDTH, _( "Text Width" ) );
222 
223  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_HEIGHT, _( "Text Height" ) );
228 
229  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_THICKNESS, _( "Text Thickness" ) );
234 
235  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_ITALIC, _( "Italic" ) );
240 
241  m_grid->SetCellValue( ROW_HEADER, COL_TEXT_UPRIGHT, _( "Upright" ) );
246 
247  return true;
248 
249 #undef SET_INT_VALUE
250 #undef SET_BOOL_VALUE
251 }
252 
253 
255 {
260  m_Italic->Enable( m_setToSpecifiedValues->GetValue() );
261  m_Visible->Enable( m_setToSpecifiedValues->GetValue() );
262  m_LayerLabel->Enable( m_setToSpecifiedValues->GetValue() );
263  m_LayerCtrl->Enable( m_setToSpecifiedValues->GetValue() );
264  m_keepUpright->Enable( m_setToSpecifiedValues->GetValue() );
265 }
266 
267 
269 {
270  aCommit.Modify( aItem );
271 
272  EDA_TEXT* textItem = dynamic_cast<EDA_TEXT*>( aItem );
273  PCB_SHAPE* drawItem = dynamic_cast<PCB_SHAPE*>( aItem );
274  FP_TEXT* fpTextItem = dynamic_cast<FP_TEXT*>( aItem );
275 
276  if( m_setToSpecifiedValues->GetValue() )
277  {
280 
281  if( !m_textWidth.IsIndeterminate() && textItem )
282  textItem->SetTextSize( wxSize( m_textWidth.GetValue(), textItem->GetTextSize().y ) );
283 
284  if( !m_textHeight.IsIndeterminate() && textItem )
285  textItem->SetTextSize( wxSize( textItem->GetTextSize().x, m_textHeight.GetValue() ) );
286 
287  if( !m_thickness.IsIndeterminate() && textItem )
288  textItem->SetTextThickness( m_thickness.GetValue() );
289 
290  if( m_Italic->Get3StateValue() != wxCHK_UNDETERMINED && textItem )
291  textItem->SetItalic( m_Italic->GetValue() );
292 
293  if( m_Visible->Get3StateValue() != wxCHK_UNDETERMINED && textItem )
294  textItem->SetVisible( m_Visible->GetValue() );
295 
296  if( m_keepUpright->Get3StateValue() != wxCHK_UNDETERMINED && fpTextItem )
297  fpTextItem->SetKeepUpright( m_keepUpright->GetValue() );
298 
299  if( !m_lineWidth.IsIndeterminate() && drawItem )
300  drawItem->SetWidth( m_lineWidth.GetValue() );
301  }
302  else
303  {
304  PCB_LAYER_ID layer = aItem->GetLayer();
305 
306  if( textItem )
307  {
308  textItem->SetTextSize( m_brdSettings->GetTextSize( layer ) );
309  textItem->SetTextThickness( m_brdSettings->GetTextThickness( layer ) );
310  textItem->SetItalic( m_brdSettings->GetTextItalic( layer ) );
311  }
312 
313  if( fpTextItem )
314  fpTextItem->SetKeepUpright( m_brdSettings->GetTextUpright( layer ) );
315 
316  if( drawItem )
317  drawItem->SetWidth( m_brdSettings->GetLineThickness( layer ) );
318  }
319 }
320 
321 
323 {
325  {
326  if( aItem->GetLayer() != m_layerFilter->GetLayerSelection() )
327  return;
328  }
329 
330  if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
331  {
332  MODULE* fp = dynamic_cast<MODULE*>( aItem->GetParent() );
333 
334  if( fp )
335  {
336  if( !WildCompareString( m_referenceFilter->GetValue(), fp->GetReference(), false ) )
337  return;
338  }
339  }
340 
341  if( m_footprintFilterOpt->GetValue() && !m_footprintFilter->GetValue().IsEmpty() )
342  {
343  MODULE* fp = dynamic_cast<MODULE*>( aItem->GetParent() );
344 
345  if( fp )
346  {
347  if( !WildCompareString( m_footprintFilter->GetValue(), fp->GetFPID().Format(), false ) )
348  return;
349  }
350  }
351 
352  processItem( aCommit, aItem );
353 }
354 
355 
357 {
360  {
361  return false;
362  }
363 
364  BOARD_COMMIT commit( m_parent );
365 
366  // Go through the footprints
367  for( MODULE* fp : m_parent->GetBoard()->Modules() )
368  {
369  if( m_references->GetValue() )
370  visitItem( commit, &fp->Reference() );
371 
372  if( m_values->GetValue() )
373  visitItem( commit, &fp->Value() );
374 
375  // Go through all other footprint items
376  for( BOARD_ITEM* boardItem : fp->GraphicalItems() )
377  {
378  if( boardItem->Type() == PCB_FP_TEXT_T )
379  {
380  // We are guaranteed to always get an EDA_TEXT in this statement, but we must
381  // use the dynamic_cast to move through the type tree anyway.
382  const wxString text = dynamic_cast<EDA_TEXT*>( boardItem )->GetText();
383 
384  if( m_references->GetValue() && text == wxT( "${REFERENCE}" ) )
385  visitItem( commit, boardItem );
386  else if( m_values->GetValue() && text == wxT( "${VALUE}" ) )
387  visitItem( commit, boardItem );
388  else if( m_otherFields->GetValue() )
389  visitItem( commit, boardItem );
390  }
391  else if( boardItem->Type() == PCB_FP_SHAPE_T )
392  {
393  if( m_footprintGraphics->GetValue() )
394  visitItem( commit, boardItem );
395  }
396  }
397  }
398 
399  // Go through the PCB text & graphic items
400  for( BOARD_ITEM* boardItem : m_parent->GetBoard()->Drawings() )
401  {
402  if( boardItem->Type() == PCB_TEXT_T )
403  {
404  if( m_boardText->GetValue() )
405  visitItem( commit, boardItem );
406  }
407  else if( boardItem->Type() == PCB_SHAPE_T )
408  {
409  if( m_boardGraphics->GetValue() )
410  visitItem( commit, boardItem );
411  }
412  }
413 
414  commit.Push( "Edit text and graphics properties" );
415  m_parent->GetCanvas()->Refresh();
416 
417  return true;
418 }
419 
420 
422 {
423  PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
424  DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS dlg( editFrame );
425 
426  dlg.ShowModal();
427  return 0;
428 }
429 
430 
#define SET_INT_VALUE(aRow, aCol, aValue)
COMMIT & Modify(EDA_ITEM *aItem)
Modifies a given item in the model.
Definition: commit.h:103
class FP_TEXT, text in a footprint
Definition: typeinfo.h:93
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
void visitItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
void SetItalic(bool isItalic)
Definition: eda_text.h:185
void FinishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
void SetVisible(bool aVisible)
Definition: eda_text.h:191
class PCB_TEXT, text on a layer
Definition: typeinfo.h:92
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
const LIB_ID & GetFPID() const
Definition: class_module.h:210
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:244
bool IsIndeterminate() const
Function IsIndeterminate Returns true if the control holds the indeterminate value (for instance,...
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
int GetTextThickness(PCB_LAYER_ID aLayer) const
Function GetTextThickness Returns the default text thickness from the layer class for the given layer...
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:435
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
Function GetLineThickness Returns the default graphic segment thickness from the layer class for the ...
wxSize m_TextSize[LAYER_CLASS_COUNT]
LAYER_NUM GetLayerSelection() const
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:488
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.
TOOL_EVENT.
Definition: tool_event.h:171
bool m_TextItalic[LAYER_CLASS_COUNT]
int SetLayerSelection(LAYER_NUM layer)
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:32
bool SetLayersHotkeys(bool value)
int m_LineThickness[LAYER_CLASS_COUNT]
UTF8 Format() const
Definition: lib_id.cpp:237
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 SetKeepUpright(bool aKeepUpright)
Definition: fp_text.h:117
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Function Validate Validates the control against the given range, informing the user of any errors fou...
#define _(s)
Definition: 3d_actions.cpp:33
virtual void SetValue(int aValue)
Function SetValue Sets new value (in Internal Units) for the text field, taking care of units convers...
#define SET_BOOL_VALUE(aRow, aCol, aValue)
PCB_EDIT_FRAME is the main frame for Pcbnew.
void SetWidth(int aWidth)
Definition: pcb_shape.h:99
void processItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
virtual long long int GetValue()
Function GetValue Returns the current value in Internal Units.
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition: eda_text.h:164
#define INDETERMINATE_ACTION
Definition: base_units.h:49
BOARD_ITEM_CONTAINER * GetParent() const
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:91
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:897
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Function GetTextSize Returns the default text size from the layer class for the given layer.
bool m_TextUpright[LAYER_CLASS_COUNT]
void Enable(bool aEnable)
Function Enable Enables/diasables the label, widget and units label.
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.