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 <core/kicad_algo.h>
23 #include <lib_symbol.h>
24 #include <symbol_edit_frame.h>
25 #include <template_fieldnames.h>
26 #include <string_utils.h>
27 
28 
30 bool g_resetEmptyLibFields = false;
31 bool g_resetLibFieldText = true;
35 
36 
38  LIB_SYMBOL* aSymbol ) :
40  m_editFrame( aParent ),
41  m_symbol( aSymbol)
42 {
43  wxASSERT( aParent );
44  wxASSERT( aSymbol );
45 
46  m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) );
47 
48  for( int i = 0; i < MANDATORY_FIELDS; ++i )
49  {
51  m_fieldsBox->Check( i, true );
52  }
53 
55 
62 
63  m_sdbSizerOK->SetDefault();
64 
65  // Now all widgets have the size fixed, call FinishDialogSettings
67 }
68 
69 
71 {
78 }
79 
80 
82 {
83  // Load non-mandatory fields from the parent part
84  std::vector<LIB_FIELD*> libFields;
85  std::set<wxString> fieldNames;
86  std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
87 
88  flattenedParent->GetFields( libFields );
89 
90  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
91  fieldNames.insert( libFields[i]->GetName() );
92 
93  libFields.clear(); // flattenedPart is about to go out of scope...
94 
95  // Load non-mandatory fields from the editor symbol
96  m_symbol->GetFields( libFields );
97 
98  for( unsigned i = MANDATORY_FIELDS; i < libFields.size(); ++i )
99  fieldNames.insert( libFields[i]->GetName() );
100 
101  libFields.clear();
102 
103  // Update the listbox widget
104  for( unsigned i = m_fieldsBox->GetCount() - 1; i >= MANDATORY_FIELDS; --i )
105  m_fieldsBox->Delete( i );
106 
107  for( const wxString& fieldName : fieldNames )
108  m_fieldsBox->Append( fieldName );
109 
110  for( unsigned i = MANDATORY_FIELDS; i < m_fieldsBox->GetCount(); ++i )
111  m_fieldsBox->Check( i, true );
112 }
113 
114 
116 {
117  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
118  m_fieldsBox->Check( i, aCheck );
119 }
120 
121 
123 {
124  wxBusyCursor dummy;
125 
127 
128  // Create the set of fields to be updated
129  m_updateFields.clear();
130 
131  for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
132  {
133  if( m_fieldsBox->IsChecked( i ) )
134  m_updateFields.insert( m_fieldsBox->GetString( i ) );
135  }
136 
137  std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
138 
139  bool removeExtras = m_removeExtraBox->GetValue();
140  bool resetVis = m_resetFieldVisibilities->GetValue();
141  bool resetEffects = m_resetFieldEffects->GetValue();
142  bool resetPositions = m_resetFieldPositions->GetValue();
143 
144  std::vector<LIB_FIELD> fields;
145  std::vector<LIB_FIELD> result;
146  m_symbol->GetFields( fields );
147 
148  for( LIB_FIELD& field : fields )
149  {
150  bool copy = true;
151  LIB_FIELD* parentField = nullptr;
152 
153  if( alg::contains( m_updateFields, field.GetName() ) )
154  {
155  parentField = flattenedParent->FindField( field.GetName() );
156 
157  if( parentField )
158  {
159  bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
160  : m_resetFieldText->GetValue();
161 
162  if( resetText )
163  field.SetText( parentField->GetText() );
164 
165  if( resetVis )
166  field.SetVisible( parentField->IsVisible() );
167 
168  if( resetEffects )
169  {
170  // Careful: the visible bit and position are also in Effects
171  bool visible = field.IsVisible();
172  wxPoint pos = field.GetPosition();
173 
174  field.SetEffects( *parentField );
175 
176  field.SetVisible( visible );
177  field.SetPosition( pos );
178  }
179 
180  if( resetPositions )
181  field.SetTextPos( parentField->GetTextPos() );
182  }
183  else if( removeExtras )
184  {
185  copy = false;
186  }
187  }
188 
189  if( copy )
190  result.emplace_back( std::move( field ) );
191  }
192 
193  std::vector<LIB_FIELD*> parentFields;
194  int idx = result.size();
195 
196  flattenedParent->GetFields( parentFields );
197 
198  for( LIB_FIELD* parentField : parentFields )
199  {
200  if( !alg::contains( m_updateFields, parentField->GetName() ) )
201  continue;
202 
203  if( !m_symbol->FindField( parentField->GetName() ) )
204  {
205  result.emplace_back( m_symbol, idx++ );
206  LIB_FIELD* newField = &result.back();
207 
208  newField->SetName( parentField->GetCanonicalName() );
209  newField->SetText( parentField->GetText() );
210  newField->SetEffects( *parentField ); // Includes visible bit and position
211  }
212  }
213 
214  m_symbol->SetFields( result );
215 
218  wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
219 }
220 
221 
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:978
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:913
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:385
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:930
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:72
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:99
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.