/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 CERN * Copyright The KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or (at your * option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include #include #include #include #include #include #include DIALOG_UPDATE_SYMBOL_FIELDS::DIALOG_UPDATE_SYMBOL_FIELDS( SYMBOL_EDIT_FRAME* aParent, LIB_SYMBOL* aSymbol ) : DIALOG_UPDATE_SYMBOL_FIELDS_BASE( aParent ), m_editFrame( aParent ), m_symbol( aSymbol) { wxASSERT( aParent ); wxASSERT( aSymbol ); m_parentSymbolReadOnly->SetValue( UnescapeString( m_symbol->GetParent().lock()->GetName() ) ); for( FIELD_T fieldId : MANDATORY_FIELDS ) { m_mandatoryFieldListIndexes[fieldId] = m_fieldsBox->GetCount(); m_fieldsBox->Append( GetDefaultFieldName( fieldId, DO_TRANSLATE ) ); m_fieldsBox->Check( m_fieldsBox->GetCount() - 1, true ); } updateFieldsList(); SetupStandardButtons(); // Now all widgets have the size fixed, call FinishDialogSettings finishDialogSettings(); } void DIALOG_UPDATE_SYMBOL_FIELDS::updateFieldsList() { // Load non-mandatory fields from the parent part std::vector libFields; std::set fieldNames; std::unique_ptr flattenedParent = m_symbol->GetParent().lock()->Flatten(); flattenedParent->GetFields( libFields ); for( SCH_FIELD* libField : libFields ) { if( !libField->IsMandatory() ) fieldNames.insert( libField->GetName() ); } libFields.clear(); // flattenedPart is about to go out of scope... // Load non-mandatory fields from the editor symbol m_symbol->GetFields( libFields ); for( SCH_FIELD* libField : libFields ) { if( !libField->IsMandatory() ) fieldNames.insert( libField->GetName() ); } auto isMandatoryField = [&]( int listbox_idx ) { for( FIELD_T fieldId : MANDATORY_FIELDS ) { if( m_mandatoryFieldListIndexes[fieldId] == listbox_idx ) return true; } return false; }; libFields.clear(); // Update the listbox widget for( int i = (int) m_fieldsBox->GetCount() - 1; i >= 0; --i ) { if( !isMandatoryField( i ) ) m_fieldsBox->Delete( i ); } for( const wxString& fieldName : fieldNames ) m_fieldsBox->Append( fieldName ); for( int i = 0; i < (int) m_fieldsBox->GetCount(); ++i ) { if( !isMandatoryField( i ) ) m_fieldsBox->Check( i, true ); } } void DIALOG_UPDATE_SYMBOL_FIELDS::checkAll( bool aCheck ) { for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i ) m_fieldsBox->Check( i, aCheck ); } void DIALOG_UPDATE_SYMBOL_FIELDS::onOkButtonClicked( wxCommandEvent& aEvent ) { wxBusyCursor dummy; SCH_COMMIT commit( m_editFrame ); commit.Modify( m_symbol, m_editFrame->GetScreen() ); // Create the set of fields to be updated m_updateFields.clear(); for( unsigned i = 0; i < m_fieldsBox->GetCount(); ++i ) { if( m_fieldsBox->IsChecked( i ) ) m_updateFields.insert( m_fieldsBox->GetString( i ) ); } std::unique_ptr flattenedParent = m_symbol->GetParent().lock()->Flatten(); bool removeExtras = m_removeExtraBox->GetValue(); bool resetVis = m_resetFieldVisibilities->GetValue(); bool resetEffects = m_resetFieldEffects->GetValue(); bool resetPositions = m_resetFieldPositions->GetValue(); std::vector fields; std::vector result; m_symbol->CopyFields( fields ); for( SCH_FIELD& field : fields ) { bool copy = true; SCH_FIELD* parentField = nullptr; if( alg::contains( m_updateFields, field.GetName() ) ) { if( field.IsMandatory() ) parentField = flattenedParent->GetField( field.GetId() ); else parentField = flattenedParent->GetField( field.GetName() ); if( parentField ) { bool resetText = parentField->GetText().IsEmpty() ? m_resetEmptyFields->GetValue() : m_resetFieldText->GetValue(); if( resetText ) field.SetText( parentField->GetText() ); if( resetVis ) { field.SetVisible( parentField->IsVisible() ); field.SetNameShown( parentField->IsNameShown() ); } if( resetEffects ) { // Careful: the visible bit and position are also set by SetAttributes() bool visible = field.IsVisible(); VECTOR2I pos = field.GetPosition(); field.SetAttributes( *parentField ); field.SetVisible( visible ); field.SetPosition( pos ); } if( resetPositions ) field.SetTextPos( parentField->GetTextPos() ); } else if( removeExtras ) { copy = false; } } if( copy ) result.emplace_back( std::move( field ) ); } std::vector parentFields; flattenedParent->GetFields( parentFields ); for( SCH_FIELD* parentField : parentFields ) { if( !alg::contains( m_updateFields, parentField->GetName() ) ) continue; if( !m_symbol->GetField( parentField->GetName() ) ) { result.emplace_back( m_symbol, FIELD_T::USER ); SCH_FIELD* newField = &result.back(); newField->SetName( parentField->GetCanonicalName() ); newField->SetText( parentField->GetText() ); newField->SetAttributes( *parentField ); // Includes visible bit and position } } m_symbol->SetFields( result ); commit.Push( _( "Update Symbol Fields" ) ); m_editFrame->RebuildView(); wxPostEvent( this, wxCommandEvent( wxEVT_COMMAND_BUTTON_CLICKED, wxID_OK ) ); }