KiCad PCB EDA Suite
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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 The 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 <sch_commit.h>
26#include <template_fieldnames.h>
27#include <string_utils.h>
28
29
36
37
39 LIB_SYMBOL* aSymbol ) :
41 m_editFrame( aParent ),
42 m_symbol( aSymbol)
43{
44 wxASSERT( aParent );
45 wxASSERT( aSymbol );
46
47 m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) );
48
49 for( FIELD_T fieldId : MANDATORY_FIELDS )
50 {
51 m_mandatoryFieldListIndexes[fieldId] = m_fieldsBox->GetCount();
52 m_fieldsBox->Append( GetDefaultFieldName( fieldId, DO_TRANSLATE ) );
53 m_fieldsBox->Check( m_fieldsBox->GetCount() - 1, true );
54 }
55
57
64
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<SCH_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( SCH_FIELD* libField : libFields )
93 {
94 if( !libField->IsMandatory() )
95 fieldNames.insert( libField->GetName() );
96 }
97
98 libFields.clear(); // flattenedPart is about to go out of scope...
99
100 // Load non-mandatory fields from the editor symbol
101 m_symbol->GetFields( libFields );
102
103 for( SCH_FIELD* libField : libFields )
104 {
105 if( !libField->IsMandatory() )
106 fieldNames.insert( libField->GetName() );
107 }
108
109 auto isMandatoryField =
110 [&]( int listbox_idx )
111 {
112 for( FIELD_T fieldId : MANDATORY_FIELDS )
113 {
114 if( m_mandatoryFieldListIndexes[fieldId] == listbox_idx )
115 return true;
116 }
117
118 return false;
119 };
120
121 libFields.clear();
122
123 // Update the listbox widget
124 for( int i = (int) m_fieldsBox->GetCount() - 1; i >= 0; --i )
125 {
126 if( !isMandatoryField( i ) )
127 m_fieldsBox->Delete( i );
128 }
129
130 for( const wxString& fieldName : fieldNames )
131 m_fieldsBox->Append( fieldName );
132
133 for( int i = 0; i < (int) m_fieldsBox->GetCount(); ++i )
134 {
135 if( !isMandatoryField( i ) )
136 m_fieldsBox->Check( i, true );
137 }
138}
139
140
142{
143 for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
144 m_fieldsBox->Check( i, aCheck );
145}
146
147
149{
150 wxBusyCursor dummy;
151 SCH_COMMIT commit( m_editFrame );
152
153 commit.Modify( m_symbol );
154
155 // Create the set of fields to be updated
156 m_updateFields.clear();
157
158 for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
159 {
160 if( m_fieldsBox->IsChecked( i ) )
161 m_updateFields.insert( m_fieldsBox->GetString( i ) );
162 }
163
164 std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
165
166 bool removeExtras = m_removeExtraBox->GetValue();
167 bool resetVis = m_resetFieldVisibilities->GetValue();
168 bool resetEffects = m_resetFieldEffects->GetValue();
169 bool resetPositions = m_resetFieldPositions->GetValue();
170
171 std::vector<SCH_FIELD> fields;
172 std::vector<SCH_FIELD> result;
173 m_symbol->CopyFields( fields );
174
175 for( SCH_FIELD& field : fields )
176 {
177 bool copy = true;
178 SCH_FIELD* parentField = nullptr;
179
180 if( alg::contains( m_updateFields, field.GetName() ) )
181 {
182 if( field.IsMandatory() )
183 parentField = flattenedParent->GetField( field.GetId() );
184 else
185 parentField = flattenedParent->GetField( field.GetName() );
186
187 if( parentField )
188 {
189 bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
190 : m_resetFieldText->GetValue();
191
192 if( resetText )
193 field.SetText( parentField->GetText() );
194
195 if( resetVis )
196 {
197 field.SetVisible( parentField->IsVisible() );
198 field.SetNameShown( parentField->IsNameShown() );
199 }
200
201 if( resetEffects )
202 {
203 // Careful: the visible bit and position are also set by SetAttributes()
204 bool visible = field.IsVisible();
205 VECTOR2I pos = field.GetPosition();
206
207 field.SetAttributes( *parentField );
208
209 field.SetVisible( visible );
210 field.SetPosition( pos );
211 }
212
213 if( resetPositions )
214 field.SetTextPos( parentField->GetTextPos() );
215 }
216 else if( removeExtras )
217 {
218 copy = false;
219 }
220 }
221
222 if( copy )
223 result.emplace_back( std::move( field ) );
224 }
225
226 std::vector<SCH_FIELD*> parentFields;
227
228 flattenedParent->GetFields( parentFields );
229
230 for( SCH_FIELD* parentField : parentFields )
231 {
232 if( !alg::contains( m_updateFields, parentField->GetName() ) )
233 continue;
234
235 if( !m_symbol->GetField( parentField->GetName() ) )
236 {
237 result.emplace_back( m_symbol, FIELD_T::USER );
238 SCH_FIELD* newField = &result.back();
239
240 newField->SetName( parentField->GetCanonicalName() );
241 newField->SetText( parentField->GetText() );
242 newField->SetAttributes( *parentField ); // Includes visible bit and position
243 }
244 }
245
246 m_symbol->SetFields( result );
247
248 commit.Push( _( "Update Symbol Fields" ) );
250
251 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
252}
253
254
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr)
Modify a given item in the model.
Definition: commit.h:108
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Class DIALOG_UPDATE_SYMBOL_FIELDS_BASE.
void checkAll(bool aCheck)
Select or deselect all fields in the listbox widget.
void onOkButtonClicked(wxCommandEvent &aEvent) override
DIALOG_UPDATE_SYMBOL_FIELDS(SYMBOL_EDIT_FRAME *aParent, LIB_SYMBOL *aSymbol)
std::set< wxString > m_updateFields
Set of field names that should have values updated.
std::map< FIELD_T, int > m_mandatoryFieldListIndexes
Index in the list control for each MANDATORY_FIELD type.
const VECTOR2I & GetTextPos() const
Definition: eda_text.h:260
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:98
virtual bool IsVisible() const
Definition: eda_text.h:174
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:426
Define a library symbol object.
Definition: lib_symbol.h:85
void GetFields(std::vector< SCH_FIELD * > &aList, bool aVisibleOnly=false) const override
Populate a std::vector with SCH_FIELDs, sorted in ordinal order.
void SetFields(const std::vector< SCH_FIELD > &aFieldsList)
Overwrite all the existing fields in this symbol with fields supplied in aFieldsList.
Definition: lib_symbol.cpp:997
SCH_FIELD * GetField(const wxString &aFieldName)
Find a field within this symbol matching aFieldName; return nullptr if not found.
void CopyFields(std::vector< SCH_FIELD > &aList)
Create a copy of the SCH_FIELDs, sorted in ordinal order.
LIB_SYMBOL_REF & GetParent()
Definition: lib_symbol.h:118
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
Definition: sch_commit.cpp:435
bool IsNameShown() const
Definition: sch_field.h:208
void SetName(const wxString &aName)
Definition: sch_field.cpp:1059
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1069
The symbol library editor main window.
bool g_removeExtraLibFields
bool g_resetLibFieldEffects
bool g_resetLibFieldVisibilities
bool g_resetLibFieldText
bool g_resetLibFieldPositions
bool g_resetEmptyLibFields
#define _(s)
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition: kicad_algo.h:100
std::vector< FAB_LAYER_COLOR > dummy
wxString UnescapeString(const wxString &aSource)
wxString GetDefaultFieldName(FIELD_T aFieldId, bool aTranslateForHI)
Return a default symbol field name for a mandatory field type.
#define DO_TRANSLATE
#define MANDATORY_FIELDS
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...