KiCad PCB EDA Suite
dialog_update_symbol_fields.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) 2020 CERN
5  * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software: you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the
9  * Free Software Foundation, either version 3 of the License, or (at your
10  * option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <algorithm>
22 
23 #include <core/kicad_algo.h>
25 #include <lib_symbol.h>
26 #include <symbol_edit_frame.h>
27 #include <template_fieldnames.h>
28 
29 
31 bool g_resetEmptyLibFields = false;
32 bool g_resetLibFieldText = true;
36 
37 
39  LIB_PART* aSymbol ) :
41  m_editFrame( aParent ),
42  m_symbol( aSymbol)
43 {
44  wxASSERT( aParent );
45  wxASSERT( aSymbol );
46 
47  m_parentSymbolReadOnly->SetValue( m_symbol->GetParent().lock()->GetName() );
48 
49  for( int i = 0; i < MANDATORY_FIELDS; ++i )
50  {
52  m_fieldsBox->Check( i, true );
53  }
54 
56 
63 
64  m_sdbSizerOK->SetDefault();
65 
66  // Now all widgets have the size fixed, call FinishDialogSettings
68 }
69 
70 
72 {
79 }
80 
81 
83 {
84  // Load non-mandatory fields from the parent part
85  std::vector<LIB_FIELD*> libFields;
86  std::set<wxString> fieldNames;
87  std::unique_ptr<LIB_PART> flattenedParent = m_symbol->GetParent().lock()->Flatten();
88 
89  flattenedParent->GetFields( libFields );
90 
91  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
92  fieldNames.insert( libFields[i]->GetName() );
93 
94  libFields.clear(); // flattenedPart is about to go out of scope...
95 
96  // Load non-mandatory fields from the editor symbol
97  m_symbol->GetFields( libFields );
98 
99  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
100  fieldNames.insert( libFields[i]->GetName() );
101 
102  libFields.clear();
103 
104  // Update the listbox widget
105  for( unsigned i = m_fieldsBox->GetCount() - 1; i >= MANDATORY_FIELDS; --i )
106  m_fieldsBox->Delete( i );
107 
108  for( const wxString& fieldName : fieldNames )
109  m_fieldsBox->Append( fieldName );
110 
111  for( unsigned i = MANDATORY_FIELDS; i < m_fieldsBox->GetCount(); ++i )
112  m_fieldsBox->Check( i, true );
113 }
114 
115 
117 {
118  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
119  m_fieldsBox->Check( i, aCheck );
120 }
121 
122 
124 {
125  wxBusyCursor dummy;
126 
128 
129  // Create the set of fields to be updated
130  m_updateFields.clear();
131 
132  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
133  {
134  if( m_fieldsBox->IsChecked( i ) )
135  m_updateFields.insert( m_fieldsBox->GetString( i ) );
136  }
137 
138  std::unique_ptr<LIB_PART> flattenedParent = m_symbol->GetParent().lock()->Flatten();
139 
140  bool removeExtras = m_removeExtraBox->GetValue();
141  bool resetVis = m_resetFieldVisibilities->GetValue();
142  bool resetEffects = m_resetFieldEffects->GetValue();
143  bool resetPositions = m_resetFieldPositions->GetValue();
144 
145  std::vector<LIB_FIELD> fields;
146  std::vector<LIB_FIELD> result;
147  m_symbol->GetFields( fields );
148 
149  for( LIB_FIELD& field : fields )
150  {
151  bool copy = true;
152  LIB_FIELD* parentField = nullptr;
153 
154  if( alg::contains( m_updateFields, field.GetName() ) )
155  {
156  parentField = flattenedParent->FindField( field.GetName() );
157 
158  if( parentField )
159  {
160  bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
161  : m_resetFieldText->GetValue();
162 
163  if( resetText )
164  field.SetText( parentField->GetText() );
165 
166  if( resetVis )
167  field.SetVisible( parentField->IsVisible() );
168 
169  if( resetEffects )
170  {
171  // Careful: the visible bit and position are also in Effects
172  bool visible = field.IsVisible();
173  wxPoint pos = field.GetPosition();
174 
175  field.SetEffects( *parentField );
176 
177  field.SetVisible( visible );
178  field.SetPosition( pos );
179  }
180 
181  if( resetPositions )
182  field.SetTextPos( parentField->GetTextPos() );
183  }
184  else if( removeExtras )
185  {
186  copy = false;
187  }
188  }
189 
190  if( copy )
191  result.emplace_back( std::move( field ) );
192  }
193 
194  std::vector<LIB_FIELD*> parentFields;
195  int idx = result.size();
196 
197  flattenedParent->GetFields( parentFields );
198 
199  for( LIB_FIELD* parentField : parentFields )
200  {
201  if( !alg::contains( m_updateFields, parentField->GetName() ) )
202  continue;
203 
204  if( !m_symbol->FindField( parentField->GetName() ) )
205  {
206  result.emplace_back( m_symbol, idx++ );
207  LIB_FIELD* newField = &result.back();
208 
209  newField->SetName( parentField->GetCanonicalName() );
210  newField->SetText( parentField->GetText() );
211  newField->SetEffects( *parentField ); // Includes visible bit and position
212  }
213  }
214 
215  m_symbol->SetFields( result );
216 
219  EndModal( wxID_OK );
220 }
221 
222 
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
DIALOG_UPDATE_SYMBOL_FIELDS(SYMBOL_EDIT_FRAME *aParent, LIB_PART *aPart)
bool g_resetLibFieldVisibilities
Class DIALOG_UPDATE_SYMBOL_FIELDS_BASE.
bool IsVisible() const
Definition: eda_text.h:193
void SetEffects(const EDA_TEXT &aSrc)
Set the text effects from another instance.
Definition: eda_text.cpp:137
Field object used in symbol libraries.
Definition: lib_field.h:59
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
Definition: sch_symbol.cpp:69
bool g_resetLibFieldPositions
void SetName(const wxString &aName)
Set a user definable field name to aName.
Definition: lib_field.cpp:387
bool g_removeExtraLibFields
bool g_resetLibFieldText
void onOkButtonClicked(wxCommandEvent &aEvent) override
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this part matching aFieldName and returns it or NULL if not found.
Definition: lib_symbol.cpp:951
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:121
LIB_PART * m_symbol
Set of field names that should have values updated.
void SaveCopyInUndoList(EDA_ITEM *aItem, UNDO_REDO aUndoType=UNDO_REDO::LIBEDIT, bool aAppend=false)
Create a copy of the current symbol, and save it in the undo list.
PART_REF & GetParent()
Definition: lib_symbol.h:120
Define a library symbol object.
Definition: lib_symbol.h:93
bool g_resetLibFieldEffects
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this part.
Definition: lib_symbol.cpp:903
static const wxString GetDefaultFieldName(int aFieldNdx, bool aTranslate=true)
Return a default symbol field name for field aFieldNdx for all components.
bool g_resetEmptyLibFields
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:81
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
const wxPoint & GetTextPos() const
Definition: eda_text.h:254
void SetFields(const std::vector< LIB_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
Definition: lib_symbol.cpp:886
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
The symbol library editor main window.