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 #include <string_utils.h>
29 
30 
32 bool g_resetEmptyLibFields = false;
33 bool g_resetLibFieldText = true;
37 
38 
40  LIB_SYMBOL* aSymbol ) :
42  m_editFrame( aParent ),
43  m_symbol( aSymbol)
44 {
45  wxASSERT( aParent );
46  wxASSERT( aSymbol );
47 
48  m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) );
49 
50  for( int i = 0; i < MANDATORY_FIELDS; ++i )
51  {
53  m_fieldsBox->Check( i, true );
54  }
55 
57 
64 
65  m_sdbSizerOK->SetDefault();
66 
67  // Now all widgets have the size fixed, call FinishDialogSettings
69 }
70 
71 
73 {
80 }
81 
82 
84 {
85  // Load non-mandatory fields from the parent part
86  std::vector<LIB_FIELD*> libFields;
87  std::set<wxString> fieldNames;
88  std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
89 
90  flattenedParent->GetFields( libFields );
91 
92  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
93  fieldNames.insert( libFields[i]->GetName() );
94 
95  libFields.clear(); // flattenedPart is about to go out of scope...
96 
97  // Load non-mandatory fields from the editor symbol
98  m_symbol->GetFields( libFields );
99 
100  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
101  fieldNames.insert( libFields[i]->GetName() );
102 
103  libFields.clear();
104 
105  // Update the listbox widget
106  for( unsigned i = m_fieldsBox->GetCount() - 1; i >= MANDATORY_FIELDS; --i )
107  m_fieldsBox->Delete( i );
108 
109  for( const wxString& fieldName : fieldNames )
110  m_fieldsBox->Append( fieldName );
111 
112  for( unsigned i = MANDATORY_FIELDS; i < m_fieldsBox->GetCount(); ++i )
113  m_fieldsBox->Check( i, true );
114 }
115 
116 
118 {
119  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
120  m_fieldsBox->Check( i, aCheck );
121 }
122 
123 
125 {
126  wxBusyCursor dummy;
127 
129 
130  // Create the set of fields to be updated
131  m_updateFields.clear();
132 
133  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
134  {
135  if( m_fieldsBox->IsChecked( i ) )
136  m_updateFields.insert( m_fieldsBox->GetString( i ) );
137  }
138 
139  std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
140 
141  bool removeExtras = m_removeExtraBox->GetValue();
142  bool resetVis = m_resetFieldVisibilities->GetValue();
143  bool resetEffects = m_resetFieldEffects->GetValue();
144  bool resetPositions = m_resetFieldPositions->GetValue();
145 
146  std::vector<LIB_FIELD> fields;
147  std::vector<LIB_FIELD> result;
148  m_symbol->GetFields( fields );
149 
150  for( LIB_FIELD& field : fields )
151  {
152  bool copy = true;
153  LIB_FIELD* parentField = nullptr;
154 
155  if( alg::contains( m_updateFields, field.GetName() ) )
156  {
157  parentField = flattenedParent->FindField( field.GetName() );
158 
159  if( parentField )
160  {
161  bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
162  : m_resetFieldText->GetValue();
163 
164  if( resetText )
165  field.SetText( parentField->GetText() );
166 
167  if( resetVis )
168  field.SetVisible( parentField->IsVisible() );
169 
170  if( resetEffects )
171  {
172  // Careful: the visible bit and position are also in Effects
173  bool visible = field.IsVisible();
174  wxPoint pos = field.GetPosition();
175 
176  field.SetEffects( *parentField );
177 
178  field.SetVisible( visible );
179  field.SetPosition( pos );
180  }
181 
182  if( resetPositions )
183  field.SetTextPos( parentField->GetTextPos() );
184  }
185  else if( removeExtras )
186  {
187  copy = false;
188  }
189  }
190 
191  if( copy )
192  result.emplace_back( std::move( field ) );
193  }
194 
195  std::vector<LIB_FIELD*> parentFields;
196  int idx = result.size();
197 
198  flattenedParent->GetFields( parentFields );
199 
200  for( LIB_FIELD* parentField : parentFields )
201  {
202  if( !alg::contains( m_updateFields, parentField->GetName() ) )
203  continue;
204 
205  if( !m_symbol->FindField( parentField->GetName() ) )
206  {
207  result.emplace_back( m_symbol, idx++ );
208  LIB_FIELD* newField = &result.back();
209 
210  newField->SetName( parentField->GetCanonicalName() );
211  newField->SetText( parentField->GetText() );
212  newField->SetEffects( *parentField ); // Includes visible bit and position
213  }
214  }
215 
216  m_symbol->SetFields( result );
217 
220  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
221 }
222 
223 
void OnModify() override
Must be called after a schematic change in order to set the "modify" flag of the current symbol.
LIB_FIELD * FindField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName and returns it or NULL if not found.
Definition: lib_symbol.cpp:953
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:124
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:888
bool g_resetLibFieldVisibilities
Class DIALOG_UPDATE_SYMBOL_FIELDS_BASE.
void SetEffects(const EDA_TEXT &aSrc)
Set the text effects from another instance.
Definition: eda_text.cpp:129
Field object used in symbol libraries.
Definition: lib_field.h:59
bool g_resetLibFieldPositions
void SetName(const wxString &aName)
Set a user definable field name to aName.
Definition: lib_field.cpp:386
Define a library symbol object.
Definition: lib_symbol.h:96
void GetFields(std::vector< LIB_FIELD * > &aList)
Return a list of fields within this symbol.
Definition: lib_symbol.cpp:905
bool g_removeExtraLibFields
bool g_resetLibFieldText
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:71
void onOkButtonClicked(wxCommandEvent &aEvent) override
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:114
virtual bool IsVisible() const
Definition: eda_text.h:186
LIB_SYMBOL * 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.
bool g_resetLibFieldEffects
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:98
wxString UnescapeString(const wxString &aSource)
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...
DIALOG_UPDATE_SYMBOL_FIELDS(SYMBOL_EDIT_FRAME *aParent, LIB_SYMBOL *aSymbol)
const wxPoint & GetTextPos() const
Definition: eda_text.h:247
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:133
The symbol library editor main window.