KiCad PCB EDA Suite
eeschema/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) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <connection_graph.h>
26 #include <kicad_string.h>
27 #include <sch_symbol.h>
28 #include <sch_connection.h>
29 #include <sch_edit_frame.h>
30 #include <sch_line.h>
31 #include <sch_junction.h>
32 #include <sch_sheet.h>
33 #include <schematic.h>
34 #include <advanced_config.h>
35 #include <tool/tool_manager.h>
37 #include <tools/sch_edit_tool.h>
38 #include <widgets/unit_binder.h>
39 
40 static bool g_modifyReferences;
41 static bool g_modifyValues;
42 static bool g_modifyOtherFields;
43 static bool g_modifyWires;
44 static bool g_modifyBuses;
46 static bool g_modifyHierLabels;
47 static bool g_modifySheetTitles;
49 static bool g_modifySheetPins;
52 
53 static bool g_filterByFieldname;
54 static wxString g_fieldnameFilter;
55 static bool g_filterByReference;
56 static wxString g_referenceFilter;
57 static bool g_filterBySymbol;
58 static wxString g_symbolFilter;
59 static bool g_filterByType;
60 static bool g_typeFilterIsPower;
61 static bool g_filterByNet;
62 static wxString g_netFilter;
63 static bool g_filterSelected;
64 
65 
66 #define DEFAULT_STYLE _( "Default" )
67 
69 {
72 
75 
77 
78 public:
81 
82 protected:
83  void OnUpdateUI( wxUpdateUIEvent& event ) override;
84  void OnReferenceFilterText( wxCommandEvent& event ) override
85  {
86  m_referenceFilterOpt->SetValue( true );
87  }
88  void OnSymbolFilterText( wxCommandEvent& event ) override
89  {
90  m_symbolFilterOpt->SetValue( true );
91  }
92 
93  bool TransferDataToWindow() override;
94  bool TransferDataFromWindow() override;
95 
96  void visitItem( const SCH_SHEET_PATH& aSheetPath, SCH_ITEM* aItem );
97  void processItem( const SCH_SHEET_PATH& aSheetPath, SCH_ITEM* aItem, SCH_ITEM* aParentItem );
98 };
99 
100 
103  m_textSize( parent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, true ),
104  m_lineWidth( parent, m_lineWidthLabel, m_LineWidthCtrl, m_lineWidthUnits, true )
105 {
106  m_parent = parent;
107  m_appendUndo = false;
108 
109  // TODO(JE) remove once real-time connectivity is a given
110  if( !ADVANCED_CFG::GetCfg().m_RealTimeConnectivity || !CONNECTION_GRAPH::m_allowRealTime )
112 
113  m_lineStyle->Append( DEFAULT_STYLE );
115 
116  m_colorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
117  m_colorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
118  m_bgColorSwatch->SetSwatchColor( COLOR4D::UNSPECIFIED, false );
119  m_bgColorSwatch->SetDefaultColor( COLOR4D::UNSPECIFIED );
120 
121  m_sdbSizerButtonsOK->SetDefault();
122 
124 }
125 
126 
128 {
129  g_modifyReferences = m_references->GetValue();
130  g_modifyValues = m_values->GetValue();
131  g_modifyOtherFields = m_otherFields->GetValue();
132  g_modifyWires = m_wires->GetValue();
133  g_modifyBuses = m_buses->GetValue();
134  g_modifyGlobalLabels = m_globalLabels->GetValue();
135  g_modifyHierLabels = m_hierLabels->GetValue();
136  g_modifySheetTitles = m_sheetTitles->GetValue();
138  g_modifySheetPins = m_sheetPins->GetValue();
139  g_modifySheetBorders = m_sheetBorders->GetValue();
141 
143  g_fieldnameFilter = m_fieldnameFilter->GetValue();
145  g_referenceFilter = m_referenceFilter->GetValue();
146  g_filterBySymbol = m_symbolFilterOpt->GetValue();
147  g_symbolFilter = m_symbolFilter->GetValue();
148  g_filterByType = m_typeFilterOpt->GetValue();
149  g_typeFilterIsPower = m_typeFilter->GetSelection() == 1;
150  g_filterByNet = m_netFilterOpt->GetValue();
151  g_netFilter = m_netFilter->GetValue();
153 }
154 
155 
157 {
159  m_selection = selectionTool->GetSelection();
160 
161  m_references->SetValue( g_modifyReferences );
162  m_values->SetValue( g_modifyValues );
163  m_otherFields->SetValue( g_modifyOtherFields );
164  m_wires->SetValue( g_modifyWires );
165  m_buses->SetValue( g_modifyBuses );
167  m_hierLabels->SetValue( g_modifyHierLabels );
168  m_sheetTitles->SetValue( g_modifySheetTitles );
170  m_sheetPins->SetValue( g_modifySheetPins );
173 
174  // SetValue() generates events, ChangeValue() does not
175  m_fieldnameFilter->ChangeValue( g_fieldnameFilter );
177  m_referenceFilter->ChangeValue( g_referenceFilter );
179  m_symbolFilter->ChangeValue( g_symbolFilter );
180  m_symbolFilterOpt->SetValue( g_filterBySymbol );
181  m_typeFilter->SetSelection( g_typeFilterIsPower ? 1 : 0 );
182  m_typeFilterOpt->SetValue( g_filterByType );
184 
185  if( g_filterByNet && !g_netFilter.IsEmpty() )
186  {
187  m_netFilter->SetValue( g_netFilter );
188  m_netFilterOpt->SetValue( true );
189  }
190  else if( m_parent->GetHighlightedConnection() )
191  {
193  }
194  else if( m_selection.GetSize() )
195  {
196  SCH_ITEM* sch_item = (SCH_ITEM*) m_selection.Front();
197  SCH_CONNECTION* connection = sch_item->Connection();
198 
199  if( connection )
200  m_netFilter->SetValue( connection->Name() );
201  }
202 
203  m_netFilterOpt->SetValue( g_filterByNet );
204 
206  m_orientation->SetStringSelection( INDETERMINATE_ACTION );
207  m_hAlign->SetStringSelection( INDETERMINATE_ACTION );
208  m_vAlign->SetStringSelection( INDETERMINATE_ACTION );
209  m_Italic->Set3StateValue( wxCHK_UNDETERMINED );
210  m_Bold->Set3StateValue( wxCHK_UNDETERMINED );
211  m_Visible->Set3StateValue( wxCHK_UNDETERMINED );
213  m_lineStyle->SetStringSelection( INDETERMINATE_ACTION );
214  m_setColor->SetValue( false );
215  m_setBgColor->SetValue( false );
216 
217  return true;
218 }
219 
220 
222 {
223 }
224 
225 
227  SCH_ITEM* aItem,
228  SCH_ITEM* aParentItem = nullptr )
229 {
230  if( m_selectedFilterOpt->GetValue() && !m_selection.Contains( aItem )
231  && ( aParentItem == nullptr || !m_selection.Contains( aParentItem ) ) )
232  {
233  return;
234  }
235 
236  EDA_TEXT* eda_text = dynamic_cast<EDA_TEXT*>( aItem );
237  SCH_TEXT* sch_text = dynamic_cast<SCH_TEXT*>( aItem );
238  SCH_LINE* lineItem = dynamic_cast<SCH_LINE*>( aItem );
239 
241  m_appendUndo = true;
242 
243  if( eda_text )
244  {
245  if( !m_textSize.IsIndeterminate() )
246  eda_text->SetTextSize( wxSize( m_textSize.GetValue(), m_textSize.GetValue() ) );
247 
248  if( m_hAlign->GetStringSelection() != INDETERMINATE_ACTION )
249  eda_text->SetHorizJustify( EDA_TEXT::MapHorizJustify( m_hAlign->GetSelection() - 1 ) );
250 
251  if( m_vAlign->GetStringSelection() != INDETERMINATE_ACTION )
252  eda_text->SetVertJustify( EDA_TEXT::MapVertJustify( m_vAlign->GetSelection() - 1 ) );
253 
254  if( m_Visible->Get3StateValue() != wxCHK_UNDETERMINED )
255  eda_text->SetVisible( m_Visible->GetValue() );
256 
257  if( m_Italic->Get3StateValue() != wxCHK_UNDETERMINED )
258  eda_text->SetItalic( m_Italic->GetValue() );
259 
260  if( m_Bold->Get3StateValue() != wxCHK_UNDETERMINED )
261  eda_text->SetBold( m_Bold->GetValue() );
262  }
263 
264  // No else! Labels are both.
265  if( sch_text )
266  {
267  if( m_orientation->GetStringSelection() != INDETERMINATE_ACTION )
268  sch_text->SetLabelSpinStyle( (LABEL_SPIN_STYLE::SPIN) m_orientation->GetSelection() );
269  }
270 
271  if( lineItem )
272  {
274  lineItem->SetLineWidth( m_lineWidth.GetValue() );
275 
276  if( m_lineStyle->GetStringSelection() != INDETERMINATE_ACTION )
277  {
278  if( m_lineStyle->GetStringSelection() == DEFAULT_STYLE )
280  else
281  lineItem->SetLineStyle( m_lineStyle->GetSelection() );
282  }
283 
284  if( m_setColor->GetValue() )
285  lineItem->SetLineColor( m_colorSwatch->GetSwatchColor() );
286  }
287 }
288 
290  SCH_ITEM* aItem )
291 {
292  if( m_netFilterOpt->GetValue() && !m_netFilter->GetValue().IsEmpty() )
293  {
294  SCH_CONNECTION* connection = aItem->Connection( &aSheetPath );
295 
296  if( !connection )
297  return;
298 
299  if( !WildCompareString( m_netFilter->GetValue(), connection->Name(), false ) )
300  return;
301  }
302 
303  if( m_referenceFilterOpt->GetValue() && !m_referenceFilter->GetValue().IsEmpty() )
304  {
305  if( aItem->Type() == SCH_SYMBOL_T )
306  {
307  wxString ref = static_cast<SCH_SYMBOL*>( aItem )->GetRef( &aSheetPath );
308 
309  if( !WildCompareString( m_referenceFilter->GetValue(), ref, false ) )
310  return;
311  }
312  }
313 
314  if( m_symbolFilterOpt->GetValue() && !m_symbolFilter->GetValue().IsEmpty() )
315  {
316  if( aItem->Type() == SCH_SYMBOL_T )
317  {
318  wxString id = static_cast<SCH_SYMBOL*>( aItem )->GetLibId().Format();
319 
320  if( !WildCompareString( m_symbolFilter->GetValue(), id, false ) )
321  return;
322  }
323  }
324 
325  if( m_typeFilterOpt->GetValue() )
326  {
327  if( aItem->Type() == SCH_SYMBOL_T )
328  {
329  bool isPower = static_cast<SCH_SYMBOL*>( aItem )->GetLibSymbolRef()->IsPower();
330 
331  if( isPower != ( m_typeFilter->GetSelection() == 1 ) )
332  return;
333  }
334  }
335 
336  static KICAD_T wireTypes[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LABEL_LOCATE_WIRE_T, EOT };
337  static KICAD_T busTypes[] = { SCH_LINE_LOCATE_BUS_T, SCH_LABEL_LOCATE_BUS_T, EOT };
338  static KICAD_T schTextAndGraphics[] = { SCH_TEXT_T, SCH_LINE_LOCATE_GRAPHIC_LINE_T, EOT };
339 
340  if( aItem->Type() == SCH_SYMBOL_T )
341  {
342  SCH_SYMBOL* symbol = (SCH_SYMBOL*) aItem;
343 
344  if( m_references->GetValue() )
345  processItem( aSheetPath, symbol->GetField( REFERENCE_FIELD ), aItem );
346 
347  if( m_values->GetValue() )
348  processItem( aSheetPath, symbol->GetField( VALUE_FIELD ), aItem );
349 
350  if( m_otherFields->GetValue() )
351  {
352  for( int i = 2; i < symbol->GetFieldCount(); ++i )
353  {
354  SCH_FIELD& field = symbol->GetFields()[i];
355  const wxString& fieldName = field.GetName();
356 
357  if( !m_fieldnameFilterOpt->GetValue() || m_fieldnameFilter->GetValue().IsEmpty()
358  || WildCompareString( m_fieldnameFilter->GetValue(), fieldName, false ) )
359  {
360  processItem( aSheetPath, &field, aItem );
361  }
362  }
363  }
364  }
365  else if( aItem->Type() == SCH_SHEET_T )
366  {
367  SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
368 
369  if( m_sheetTitles->GetValue() )
370  processItem( aSheetPath, &sheet->GetFields()[SHEETNAME], aItem );
371 
372  if( m_sheetFields->GetValue() )
373  {
374  for( SCH_FIELD& field : sheet->GetFields() )
375  {
376  if( field.GetId() == SHEETNAME )
377  continue;
378 
379  const wxString& fieldName = field.GetName();
380 
381  if( !m_fieldnameFilterOpt->GetValue() || m_fieldnameFilter->GetValue().IsEmpty()
382  || WildCompareString( m_fieldnameFilter->GetValue(), fieldName, false ) )
383  {
384  processItem( aSheetPath, &field, aItem );
385  }
386  }
387  }
388 
389  if( m_sheetBorders->GetValue() )
390  {
392  sheet->SetBorderWidth( m_lineWidth.GetValue() );
393 
394  if( m_setColor->GetValue() )
396 
397  if( m_setBgColor->GetValue() )
399  }
400  }
401  else if( aItem->Type() == SCH_JUNCTION_T )
402  {
403  SCH_JUNCTION* junction = static_cast<SCH_JUNCTION*>( aItem );
404 
405  for( SCH_ITEM* item : junction->ConnectedItems( aSheetPath ) )
406  {
407  if( item->GetLayer() == LAYER_BUS )
408  {
409  if( m_buses->GetValue() && m_setColor->GetValue() )
410  junction->SetColor( m_colorSwatch->GetSwatchColor() );
411 
412  break;
413  }
414  else if( item->GetLayer() == LAYER_WIRE )
415  {
416  if( m_wires->GetValue() && m_setColor->GetValue() )
417  junction->SetColor( m_colorSwatch->GetSwatchColor() );
418 
419  break;
420  }
421  }
422  }
423  else if( m_wires->GetValue() && aItem->IsType( wireTypes ) )
424  processItem( aSheetPath, aItem );
425  else if( m_buses->GetValue() && aItem->IsType( busTypes ) )
426  processItem( aSheetPath, aItem );
427  else if( m_globalLabels->GetValue() && aItem->Type() == SCH_GLOBAL_LABEL_T )
428  processItem( aSheetPath, aItem );
429  else if( m_hierLabels->GetValue() && aItem->Type() == SCH_HIER_LABEL_T )
430  processItem( aSheetPath, aItem );
431  else if( m_sheetPins->GetValue() && aItem->Type() == SCH_SHEET_PIN_T )
432  processItem( aSheetPath, aItem );
433  else if( m_schTextAndGraphics->GetValue() && aItem->IsType( schTextAndGraphics ) )
434  processItem( aSheetPath, aItem );
435 }
436 
437 
439 {
440  if( !m_textSize.Validate( 1.0, 10000.0, EDA_UNITS::MILS ) ) // 1 mil .. 10 inches
441  return false;
442 
443  SCH_SHEET_PATH currentSheet = m_parent->GetCurrentSheet();
444  m_appendUndo = false;
445 
446  // Go through sheets
447  for( const SCH_SHEET_PATH& sheetPath : m_parent->Schematic().GetSheets() )
448  {
449  SCH_SCREEN* screen = sheetPath.LastScreen();
450 
451  if( screen )
452  {
453  m_parent->SetCurrentSheet( sheetPath );
454 
455  for( SCH_ITEM* item : screen->Items() )
456  visitItem( sheetPath, item );
457  }
458  }
459 
460  if( m_appendUndo )
461  {
462  m_parent->OnModify();
463  m_parent->HardRedraw();
464  }
465 
466  // Reset the view to where we left the user
467  m_parent->SetCurrentSheet( currentSheet );
468 
469  return true;
470 }
471 
472 
474 {
476  dlg.ShowModal();
477  return 0;
478 }
479 
480 
Field Reference of part, i.e. "IC21".
void SetCurrentSheet(const SCH_SHEET_PATH &aSheet)
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:49
void SetSwatchColor(KIGFX::COLOR4D aColor, bool aSendEvent)
Set the current swatch color directly.
KIGFX::COLOR4D GetSwatchColor() const
void RecalculateConnections(SCH_CLEANUP_FLAGS aCleanupFlags)
Generate the connection data for the entire schematic hierarchy.
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:666
const SCH_CONNECTION * GetHighlightedConnection() const
void visitItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem)
void SetDefaultColor(KIGFX::COLOR4D aColor)
Sets the color that will be chosen with the "Reset to Default" button in the chooser.
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:271
void SetItalic(bool isItalic)
Definition: eda_text.h:179
void SetColor(const COLOR4D &aColor)
Definition: sch_junction.h:103
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
Definition: sch_symbol.cpp:702
Schematic editor (Eeschema) main window.
void SetTextSize(const wxSize &aNewSize)
Definition: eda_text.h:237
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
search types array terminator (End Of Types)
Definition: typeinfo.h:81
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:77
void SetBorderWidth(int aWidth)
Definition: sch_sheet.h:109
SCH_CONNECTION * Connection(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve the connection associated with this object in the given sheet.
Definition: sch_item.cpp:131
EE_SELECTION & GetSelection()
Return the set of currently selected items.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:119
std::vector< SCH_FIELD > & GetFields()
Definition: sch_sheet.h:88
virtual void SetVisible(bool aVisible)
Definition: eda_text.h:185
int GlobalEdit(const TOOL_EVENT &aEvent)
Delete the selected items, or the item under the cursor.
void SetLineStyle(const PLOT_DASH_TYPE aStyle)
Definition: sch_line.cpp:239
void SetBackgroundColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:115
wxString Name(bool aIgnoreSheet=false) const
Field Value of part, i.e. "3.3K".
static EDA_TEXT_HJUSTIFY_T MapHorizJustify(int aHorizJustify)
Definition: eda_text.cpp:63
void HardRedraw() override
Rebuild the GAL and redraw the screen.
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:597
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:202
int GetFieldCount() const
Return the number of fields in this symbol.
Definition: sch_symbol.h:421
Generic, UI-independent tool event.
Definition: tool_event.h:152
bool Contains(EDA_ITEM *aItem) const
Definition: selection.cpp:61
SCHEMATIC & Schematic() const
void SetBorderColor(KIGFX::COLOR4D aColor)
Definition: sch_sheet.h:112
virtual bool IsType(const KICAD_T aScanTypes[]) const
Check whether the item is one of the listed types.
Definition: eda_item.h:183
void SetLineColor(const COLOR4D &aColor)
Definition: sch_line.cpp:189
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
static EDA_TEXT_VJUSTIFY_T MapVertJustify(int aVertJustify)
Definition: eda_text.cpp:77
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:54
virtual unsigned int GetSize() const override
Return the number of stored items.
Definition: selection.h:87
static bool m_allowRealTime
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
SCH_SHEET_LIST GetSheets() const override
Builds and returns an updated schematic hierarchy TODO: can this be cached?
Definition: schematic.h:87
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.
Schematic symbol object.
Definition: sch_symbol.h:78
SCH_SCREEN * LastScreen()
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:37
SCH_ITEM_SET & ConnectedItems(const SCH_SHEET_PATH &aPath)
Retrieve the set of items connected to this item on the given sheet.
Definition: sch_item.cpp:164
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:201
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
void SaveCopyInUndoList(SCH_SCREEN *aScreen, SCH_ITEM *aItemToCopy, UNDO_REDO aTypeCommand, bool aAppend)
Create a copy of the current schematic item, and put it in the undo list.
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
wxString GetName(bool aUseDefaultName=true) const
Return the field name.
Definition: sch_field.cpp:545
EE_RTREE & Items()
Definition: sch_screen.h:102
virtual long long int GetValue()
Return the current value in Internal Units.
SCH_SHEET_PATH & GetCurrentSheet() const
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:54
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current screen and u...
virtual void SetLabelSpinStyle(LABEL_SPIN_STYLE aSpinStyle)
Set a spin or rotation angle, along with specific horizontal and vertical justification styles with e...
Definition: sch_text.cpp:318
#define INDETERMINATE_ACTION
Definition: base_units.h:48
void SetBold(bool aBold)
Definition: eda_text.h:182
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:197
EDA_ITEM * Front() const
Definition: selection.h:144
void processItem(const SCH_SHEET_PATH &aSheetPath, SCH_ITEM *aItem, SCH_ITEM *aParentItem)
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113