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 if( std::shared_ptr<LIB_SYMBOL> parent = m_symbol->GetParent().lock() )
39 m_parentSymbolReadOnly->SetValue( UnescapeString( parent->GetName() ) );
40
41 for( FIELD_T fieldId : MANDATORY_FIELDS )
42 {
43 m_mandatoryFieldListIndexes[fieldId] = m_fieldsBox->GetCount();
44 m_fieldsBox->Append( GetDefaultFieldName( fieldId, DO_TRANSLATE ) );
45 m_fieldsBox->Check( m_fieldsBox->GetCount() - 1, true );
46 }
47
49
51
52 // Now all widgets have the size fixed, call FinishDialogSettings
54}
55
56
58{
59 // Load non-mandatory fields from the parent part
60 std::vector<SCH_FIELD*> libFields;
61 std::set<wxString> fieldNames;
62 std::unique_ptr<LIB_SYMBOL> flattenedParent = m_symbol->GetParent().lock()->Flatten();
63
64 flattenedParent->GetFields( libFields );
65
66 for( SCH_FIELD* libField : libFields )
67 {
68 if( !libField->IsMandatory() )
69 fieldNames.insert( libField->GetName() );
70 }
71
72 libFields.clear(); // flattenedPart is about to go out of scope...
73
74 // Load non-mandatory fields from the editor symbol
75 m_symbol->GetFields( libFields );
76
77 for( SCH_FIELD* libField : libFields )
78 {
79 if( !libField->IsMandatory() )
80 fieldNames.insert( libField->GetName() );
81 }
82
83 auto isMandatoryField =
84 [&]( int listbox_idx )
85 {
86 for( FIELD_T fieldId : MANDATORY_FIELDS )
87 {
88 if( m_mandatoryFieldListIndexes[fieldId] == listbox_idx )
89 return true;
90 }
91
92 return false;
93 };
94
95 libFields.clear();
96
97 // Update the listbox widget
98 for( int i = (int) m_fieldsBox->GetCount() - 1; i >= 0; --i )
99 {
100 if( !isMandatoryField( i ) )
101 m_fieldsBox->Delete( i );
102 }
103
104 for( const wxString& fieldName : fieldNames )
105 m_fieldsBox->Append( fieldName );
106
107 for( int i = 0; i < (int) m_fieldsBox->GetCount(); ++i )
108 {
109 if( !isMandatoryField( i ) )
110 m_fieldsBox->Check( i, true );
111 }
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 SCH_COMMIT commit( m_editFrame );
126
127 commit.Modify( m_symbol, m_editFrame->GetScreen() );
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_SYMBOL> 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<SCH_FIELD> fields;
146 std::vector<SCH_FIELD> result;
147 m_symbol->CopyFields( fields );
148
149 for( SCH_FIELD& field : fields )
150 {
151 bool copy = true;
152 SCH_FIELD* parentField = nullptr;
153
154 if( alg::contains( m_updateFields, field.GetName() ) )
155 {
156 if( field.IsMandatory() )
157 parentField = flattenedParent->GetField( field.GetId() );
158 else
159 parentField = flattenedParent->GetField( field.GetName() );
160
161 if( parentField )
162 {
163 bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue()
164 : m_resetFieldText->GetValue();
165
166 if( resetText )
167 field.SetText( parentField->GetText() );
168
169 if( resetVis )
170 {
171 field.SetVisible( parentField->IsVisible() );
172 field.SetNameShown( parentField->IsNameShown() );
173 }
174
175 if( resetEffects )
176 {
177 // Careful: the visible bit and position are also set by SetAttributes()
178 bool visible = field.IsVisible();
179 VECTOR2I pos = field.GetPosition();
180
181 field.SetAttributes( *parentField );
182
183 field.SetVisible( visible );
184 field.SetPosition( pos );
185 }
186
187 if( resetPositions )
188 field.SetTextPos( parentField->GetTextPos() );
189 }
190 else if( removeExtras )
191 {
192 copy = false;
193 }
194 }
195
196 if( copy )
197 result.emplace_back( std::move( field ) );
198 }
199
200 std::vector<SCH_FIELD*> parentFields;
201
202 flattenedParent->GetFields( parentFields );
203
204 for( SCH_FIELD* parentField : parentFields )
205 {
206 if( !alg::contains( m_updateFields, parentField->GetName() ) )
207 continue;
208
209 if( !m_symbol->GetField( parentField->GetName() ) )
210 {
211 result.emplace_back( m_symbol, FIELD_T::USER );
212 SCH_FIELD* newField = &result.back();
213
214 newField->SetName( parentField->GetCanonicalName() );
215 newField->SetText( parentField->GetText() );
216 newField->SetAttributes( *parentField ); // Includes visible bit and position
217 }
218 }
219
220 m_symbol->SetFields( result );
221
222 commit.Push( _( "Update Symbol Fields" ) );
223 m_editFrame->RebuildView();
224
225 wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) );
226}
227
228
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:106
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...
DIALOG_UPDATE_SYMBOL_FIELDS_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Update Symbol Fields"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER)
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:273
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:187
void SetAttributes(const EDA_TEXT &aSrc, bool aSetPosition=true)
Set the text attributes from another instance.
Definition eda_text.cpp:444
Define a library symbol object.
Definition lib_symbol.h:85
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Execute the changes.
bool IsNameShown() const
Definition sch_field.h:201
void SetName(const wxString &aName)
void SetText(const wxString &aText) override
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...
@ USER
The field ID hasn't been set yet; field is invalid.
wxString result
Test unit parsing edge cases and error handling.
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695