KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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
32 m_editFrame( aParent ),
33 m_symbol( aSymbol)
34{
35 wxASSERT( aParent );
36 wxASSERT( aSymbol );
37
38 m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) );
39
40 for( FIELD_T fieldId : MANDATORY_FIELDS )
41 {
42 m_mandatoryFieldListIndexes[fieldId] = m_fieldsBox->GetCount();
43 m_fieldsBox->Append( GetDefaultFieldName( fieldId, DO_TRANSLATE ) );
44 m_fieldsBox->Check( m_fieldsBox->GetCount() - 1, true );
45 }
46
48
50
51 // Now all widgets have the size fixed, call FinishDialogSettings
53}
54
55
57{
58 // Load non-mandatory fields from the parent part
59 std::vector<SCH_FIELD*> libFields;
60 std::set<wxString> fieldNames;
61 std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
62
63 flattenedParent->GetFields( libFields );
64
65 for( SCH_FIELD* libField : libFields )
66 {
67 if( !libField->IsMandatory() )
68 fieldNames.insert( libField->GetName() );
69 }
70
71 libFields.clear(); // flattenedPart is about to go out of scope...
72
73 // Load non-mandatory fields from the editor symbol
74 m_symbol->GetFields( libFields );
75
76 for( SCH_FIELD* libField : libFields )
77 {
78 if( !libField->IsMandatory() )
79 fieldNames.insert( libField->GetName() );
80 }
81
82 auto isMandatoryField =
83 [&]( int listbox_idx )
84 {
85 for( FIELD_T fieldId : MANDATORY_FIELDS )
86 {
87 if( m_mandatoryFieldListIndexes[fieldId] == listbox_idx )
88 return true;
89 }
90
91 return false;
92 };
93
94 libFields.clear();
95
96 // Update the listbox widget
97 for( int i = (int) m_fieldsBox->GetCount() - 1; i >= 0; --i )
98 {
99 if( !isMandatoryField( i ) )
100 m_fieldsBox->Delete( i );
101 }
102
103 for( const wxString& fieldName : fieldNames )
104 m_fieldsBox->Append( fieldName );
105
106 for( int i = 0; i < (int) m_fieldsBox->GetCount(); ++i )
107 {
108 if( !isMandatoryField( i ) )
109 m_fieldsBox->Check( i, true );
110 }
111}
112
113
115{
116 for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i )
117 m_fieldsBox->Check( i, aCheck );
118}
119
120
122{
123 wxBusyCursor dummy;
124 SCH_COMMIT commit( m_editFrame );
125
126 commit.Modify( m_symbol );
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<SCH_FIELD> fields;
145 std::vector<SCH_FIELD> result;
146 m_symbol->CopyFields( fields );
147
148 for( SCH_FIELD& field : fields )
149 {
150 bool copy = true;
151 SCH_FIELD* parentField = nullptr;
152
153 if( alg::contains( m_updateFields, field.GetName() ) )
154 {
155 if( field.IsMandatory() )
156 parentField = flattenedParent->GetField( field.GetId() );
157 else
158 parentField = flattenedParent->GetField( field.GetName() );
159
160 if( parentField )
161 {
162 bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
163 : m_resetFieldText->GetValue();
164
165 if( resetText )
166 field.SetText( parentField->GetText() );
167
168 if( resetVis )
169 {
170 field.SetVisible( parentField->IsVisible() );
171 field.SetNameShown( parentField->IsNameShown() );
172 }
173
174 if( resetEffects )
175 {
176 // Careful: the visible bit and position are also set by SetAttributes()
177 bool visible = field.IsVisible();
178 VECTOR2I pos = field.GetPosition();
179
180 field.SetAttributes( *parentField );
181
182 field.SetVisible( visible );
183 field.SetPosition( pos );
184 }
185
186 if( resetPositions )
187 field.SetTextPos( parentField->GetTextPos() );
188 }
189 else if( removeExtras )
190 {
191 copy = false;
192 }
193 }
194
195 if( copy )
196 result.emplace_back( std::move( field ) );
197 }
198
199 std::vector<SCH_FIELD*> parentFields;
200
201 flattenedParent->GetFields( parentFields );
202
203 for( SCH_FIELD* parentField : parentFields )
204 {
205 if( !alg::contains( m_updateFields, parentField->GetName() ) )
206 continue;
207
208 if( !m_symbol->GetField( parentField->GetName() ) )
209 {
210 result.emplace_back( m_symbol, FIELD_T::USER );
211 SCH_FIELD* newField = &result.back();
212
213 newField->SetName( parentField->GetCanonicalName() );
214 newField->SetText( parentField->GetText() );
215 newField->SetAttributes( *parentField ); // Includes visible bit and position
216 }
217 }
218
219 m_symbol->SetFields( result );
220
221 commit.Push( _( "Update Symbol Fields" ) );
223
224 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
225}
226
227
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition: commit.h:107
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:270
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
virtual bool IsVisible() const
Definition: eda_text.h:184
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition: eda_text.cpp:433
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:999
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:489
bool IsNameShown() const
Definition: sch_field.h:202
void SetName(const wxString &aName)
Definition: sch_field.cpp:1079
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1089
The symbol library editor main window.
#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...