From 0bb175a028731bfeb1c1d6e3bc6077f95cd8b593 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Thu, 13 Aug 2020 13:51:26 -0400 Subject: [PATCH] Eeschema: Add change and update symbol from library support. ADDED: Add support to to Eeschema to change and update symbols from a symbol library. Fixes: https://gitlab.com/kicad/code/kicad/-/issues/4565 --- eeschema/CMakeLists.txt | 2 + eeschema/dialogs/dialog_change_symbols.cpp | 350 ++++++ eeschema/dialogs/dialog_change_symbols.h | 63 ++ .../dialogs/dialog_change_symbols_base.cpp | 125 ++ .../dialogs/dialog_change_symbols_base.fbp | 1007 +++++++++++++++++ eeschema/dialogs/dialog_change_symbols_base.h | 79 ++ eeschema/menubar.cpp | 2 + eeschema/tools/ee_actions.cpp | 16 + eeschema/tools/ee_actions.h | 4 + eeschema/tools/sch_edit_tool.cpp | 29 + eeschema/tools/sch_edit_tool.h | 1 + 11 files changed, 1678 insertions(+) create mode 100644 eeschema/dialogs/dialog_change_symbols.cpp create mode 100644 eeschema/dialogs/dialog_change_symbols.h create mode 100644 eeschema/dialogs/dialog_change_symbols_base.cpp create mode 100644 eeschema/dialogs/dialog_change_symbols_base.fbp create mode 100644 eeschema/dialogs/dialog_change_symbols_base.h diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index afc0b72e60..a1bbc36794 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -41,6 +41,8 @@ set( EESCHEMA_DLGS dialogs/dialog_bus_manager.cpp dialogs/dialog_fields_editor_global.cpp dialogs/dialog_fields_editor_global_base.cpp + dialogs/dialog_change_symbols.cpp + dialogs/dialog_change_symbols_base.cpp dialogs/dialog_choose_component.cpp dialogs/dialog_edit_component_in_lib.cpp dialogs/dialog_edit_component_in_lib_base.cpp diff --git a/eeschema/dialogs/dialog_change_symbols.cpp b/eeschema/dialogs/dialog_change_symbols.cpp new file mode 100644 index 0000000000..9137dc98f5 --- /dev/null +++ b/eeschema/dialogs/dialog_change_symbols.cpp @@ -0,0 +1,350 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 CERN + * + * @author Wayne Stambaugh + * + * 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 // WildCompareString +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +DIALOG_CHANGE_SYMBOLS::DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_COMPONENT* aSymbol, + MODE aMode ) : + DIALOG_CHANGE_SYMBOLS_BASE( aParent ), + m_symbol( aSymbol), + m_mode( aMode ) +{ + wxASSERT( aParent ); + wxString label; + wxString verb = ( m_mode == MODE::UPDATE ) ? _( "Update" ) : _( "Change" ); + + label.Printf( m_matchAll->GetLabel(), verb ); + + if( m_mode == MODE::UPDATE ) + { + m_matchAll->SetLabel( label ); + SetTitle( _( "Update Symbol(s) from Library" ) ); + m_newIdSizer->Show( false ); + } + else + { + SetTitle( _( "Change Symbol(s)" ) ); + m_matchSizer->FindItem( m_matchAll )->Show( false ); + } + + if( m_symbol ) + { + label.Printf( m_matchBySelection->GetLabel(), verb ); + m_matchBySelection->SetLabel( label ); + m_newId->AppendText( FROM_UTF8( m_symbol->GetLibId().Format().c_str() ) ); + m_specifiedReference->ChangeValue( + m_symbol->GetRef( &aParent->Schematic().CurrentSheet() ) ); + m_specifiedValue->ChangeValue( m_symbol->GetField( VALUE )->GetText() ); + m_specifiedId->ChangeValue( FROM_UTF8( m_symbol->GetLibId().Format().c_str() ) ); + } + else + { + m_matchSizer->FindItem( m_matchBySelection )->Show( false ); + } + + m_matchIdBrowserButton->SetBitmap( KiBitmap( small_library_xpm ) ); + m_newIdBrowserButton->SetBitmap( KiBitmap( small_library_xpm ) ); + + label.Printf( m_matchByReference->GetLabel(), verb ); + m_matchByReference->SetLabel( label ); + label.Printf( m_matchByValue->GetLabel(), verb ); + m_matchByValue->SetLabel( label ); + label.Printf( m_matchById->GetLabel(), verb ); + m_matchById->SetLabel( label ); + + m_matchSizer->SetEmptyCellSize( wxSize( 0, 0 ) ); + m_matchSizer->Layout(); + + m_messagePanel->SetLazyUpdate( true ); + + if( aSymbol && aSymbol->IsSelected() ) + { + m_matchBySelection->SetValue( true ); + } + else + { + if( aMode == MODE::UPDATE ) + m_matchAll->SetValue( true ); + else + m_matchByReference->SetValue( true ); + } + + // DIALOG_SHIM needs a unique hash_key because classname is not sufficient + // because the update and change versions of this dialog have different controls. + m_hash_key = TO_UTF8( GetTitle() ); + + // Ensure m_closeButton (with id = wxID_CANCEL) has the right label + // (to fix automatic renaming of button label ) + m_sdbSizerCancel->SetLabel( _( "Close" ) ); + m_sdbSizerOK->SetLabel( verb ); + m_sdbSizerOK->SetDefault(); + + // Now all widgets have the size fixed, call FinishDialogSettings + FinishDialogSettings(); +} + + +void DIALOG_CHANGE_SYMBOLS::onMatchByReference( wxCommandEvent& aEvent ) +{ + m_specifiedReference->SetFocus(); +} + + +void DIALOG_CHANGE_SYMBOLS::onMatchByValue( wxCommandEvent& aEvent ) +{ + m_specifiedValue->SetFocus(); +} + + +void DIALOG_CHANGE_SYMBOLS::onMatchById( wxCommandEvent& aEvent ) +{ + m_specifiedId->SetFocus(); +} + + +DIALOG_CHANGE_SYMBOLS::~DIALOG_CHANGE_SYMBOLS() +{ +} + + +void DIALOG_CHANGE_SYMBOLS::launchMatchIdSymbolBrowser( wxCommandEvent& aEvent ) +{ + wxString newName = m_specifiedId->GetValue(); + + KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true ); + + if( frame->ShowModal( &newName, this ) ) + m_specifiedId->SetValue( newName ); + + frame->Destroy(); +} + + +void DIALOG_CHANGE_SYMBOLS::launchNewIdSymbolBrowser( wxCommandEvent& aEvent ) +{ + wxString newName = m_newId->GetValue(); + + KIWAY_PLAYER* frame = Kiway().Player( FRAME_SCH_VIEWER_MODAL, true ); + + if( frame->ShowModal( &newName, this ) ) + m_newId->SetValue( newName ); + + frame->Destroy(); +} + + +void DIALOG_CHANGE_SYMBOLS::onOkButtonClicked( wxCommandEvent& aEvent ) +{ + wxBusyCursor dummy; + SCH_EDIT_FRAME* parent = dynamic_cast( GetParent() ); + + wxCHECK( parent, /* void */ ); + + m_messagePanel->Clear(); + m_messagePanel->Flush( false ); + + if( processMatchingSymbols() ) + { + parent->TestDanglingEnds(); // This will also redraw the changed symbols. + parent->OnModify(); + } + + m_messagePanel->Flush( false ); +} + + +bool DIALOG_CHANGE_SYMBOLS::isMatch( SCH_COMPONENT* aSymbol, SCH_SHEET_PATH* aInstance ) +{ + LIB_ID id; + + wxCHECK( aSymbol, false ); + + SCH_EDIT_FRAME* frame = dynamic_cast( GetParent() ); + + wxCHECK( frame, false ); + + if( m_matchAll->GetValue() ) + return true; + else if( m_matchBySelection->GetValue() ) + return aSymbol == m_symbol; + else if( m_matchByReference->GetValue() ) + return WildCompareString( m_specifiedReference->GetValue(), aSymbol->GetRef( aInstance ), + false ); + else if( m_matchByValue->GetValue() ) + return WildCompareString( m_specifiedValue->GetValue(), + aSymbol->GetField( VALUE )->GetText(), false ); + else if( m_matchById ) + { + id.Parse( m_specifiedId->GetValue(), LIB_ID::ID_SCH ); + return aSymbol->GetLibId() == id; + } + + return false; +} + + +bool DIALOG_CHANGE_SYMBOLS::processMatchingSymbols() +{ + SCH_EDIT_FRAME* frame = dynamic_cast( GetParent() ); + + wxCHECK( frame, false ); + + LIB_ID newId; + bool appendToUndo = false; + bool changed = false; + SCH_SHEET_LIST hierarchy = frame->Schematic().GetSheets(); + + if( m_mode == MODE::CHANGE ) + { + newId.Parse( m_newId->GetValue(), LIB_ID::ID_SCH ); + + if( !newId.IsValid() ) + return false; + } + + // Use map as a cheap and dirty way to ensure library symbols are not updated multiple + // times in complex hierachies. + std::map symbolsToProcess; + + for( SCH_SHEET_PATH& instance : hierarchy ) + { + SCH_SCREEN* screen = instance.LastScreen(); + + wxCHECK2( screen, continue ); + + for( SCH_ITEM* item : screen->Items().OfType( SCH_COMPONENT_T ) ) + { + SCH_COMPONENT* symbol = dynamic_cast( item ); + + wxCHECK2( symbol, continue ); + + if( !isMatch( symbol, &instance ) ) + continue; + + // Shared symbols always have identical library symbols so don't add duplicates. + symbolsToProcess[symbol] = screen; + } + } + + for( auto i : symbolsToProcess ) + { + if( m_mode == MODE::UPDATE ) + { + if( processSymbol( i.first, i.second, m_symbol->GetLibId(), appendToUndo ) ) + changed = true; + } + else + { + if( processSymbol( i.first, i.second, newId, appendToUndo ) ) + changed = true; + } + + if( changed ) + appendToUndo = true; + } + + return changed; +} + + +bool DIALOG_CHANGE_SYMBOLS::processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* aScreen, + const LIB_ID& aNewId, bool aAppendToUndo ) +{ + wxCHECK( aSymbol, false ); + wxCHECK( aScreen, false ); + wxCHECK( aNewId.IsValid(), false ); + + SCH_EDIT_FRAME* frame = dynamic_cast( GetParent() ); + + wxCHECK( frame, false ); + + LIB_ID oldId = aSymbol->GetLibId(); + wxString msg; + wxString references; + + for( COMPONENT_INSTANCE_REFERENCE instance : aSymbol->GetInstanceReferences() ) + { + if( references.IsEmpty() ) + references = instance.m_Reference; + else + references += " " + instance.m_Reference; + } + + msg.Printf( _( "%s %s \"%s\" from \"%s\" to \"%s\"" ), + ( m_mode == MODE::UPDATE ) ? _( "Update" ) : _( "Change" ), + ( aSymbol->GetInstanceReferences().size() == 1 ) ? _( "symbol" ) : _( "symbols" ), + references, + oldId.Format().c_str(), + aNewId.Format().c_str() ); + + LIB_PART* libSymbol = frame->GetLibPart( aNewId ); + + if( !libSymbol ) + { + msg << ": " << _( "*** symbol not found ***" ); + m_messagePanel->Report( msg, RPT_SEVERITY_ERROR ); + return false; + } + + std::unique_ptr< LIB_PART > flattenedSymbol = libSymbol->Flatten(); + + if( flattenedSymbol->GetUnitCount() < aSymbol->GetUnit() ) + { + msg << ": " << _( "*** new symbol has too few units ***" ); + m_messagePanel->Report( msg, RPT_SEVERITY_ERROR ); + return false; + } + + // Removing the symbol needs to be done before the LIB_PART is changed to prevent stale + // library symbols in the schematic file. + aScreen->Remove( aSymbol ); + frame->SaveCopyInUndoList( aScreen, aSymbol, UR_CHANGED, aAppendToUndo ); + + if( aNewId != aSymbol->GetLibId() ) + aSymbol->SetLibId( aNewId ); + + aSymbol->SetLibSymbol( flattenedSymbol.release() ); + aScreen->Append( aSymbol ); + frame->GetCanvas()->GetView()->Update( aSymbol ); + + msg += ": OK"; + m_messagePanel->Report( msg, RPT_SEVERITY_ACTION ); + + return true; +} + + diff --git a/eeschema/dialogs/dialog_change_symbols.h b/eeschema/dialogs/dialog_change_symbols.h new file mode 100644 index 0000000000..84608f96c0 --- /dev/null +++ b/eeschema/dialogs/dialog_change_symbols.h @@ -0,0 +1,63 @@ +#ifndef _DIALOG_CHANGE_SYMBOLS_H_ +#define _DIALOG_CHANGE_SYMBOLS_H_ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 CERN + * + * @author Wayne Stambaugh + * + * 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 + +class LIB_ID; +class SCH_COMPONENT; +class SCH_EDIT_FRAME; +class SCH_SCREEN; +class SCH_SHEET_PATH; + +/** + * Dialog to update or change schematic library symbols. + */ +class DIALOG_CHANGE_SYMBOLS : public DIALOG_CHANGE_SYMBOLS_BASE +{ +public: + enum class MODE { CHANGE, UPDATE }; + + DIALOG_CHANGE_SYMBOLS( SCH_EDIT_FRAME* aParent, SCH_COMPONENT* aSymbol, + MODE aMode = MODE::UPDATE ); + ~DIALOG_CHANGE_SYMBOLS() override; + +protected: + void launchMatchIdSymbolBrowser( wxCommandEvent& aEvent ) override; + void launchNewIdSymbolBrowser( wxCommandEvent& aEvent ) override; + void onOkButtonClicked( wxCommandEvent& aEvent ) override; + void onMatchByReference( wxCommandEvent& aEvent ) override; + void onMatchByValue( wxCommandEvent& aEvent ) override; + void onMatchById( wxCommandEvent& aEvent ) override; + +private: + bool isMatch( SCH_COMPONENT* aSymbol, SCH_SHEET_PATH* aInstance ); + bool processMatchingSymbols(); + bool processSymbol( SCH_COMPONENT* aSymbol, SCH_SCREEN* aScreen, const LIB_ID& aNewId, + bool aAppendToUndo ); + + SCH_COMPONENT* m_symbol; + MODE m_mode; +}; + +#endif // _DIALOG_CHANGE_SYMBOLS_H_ diff --git a/eeschema/dialogs/dialog_change_symbols_base.cpp b/eeschema/dialogs/dialog_change_symbols_base.cpp new file mode 100644 index 0000000000..444a4fd319 --- /dev/null +++ b/eeschema/dialogs/dialog_change_symbols_base.cpp @@ -0,0 +1,125 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.9.0 Jun 3 2020) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "wx_html_report_panel.h" + +#include "dialog_change_symbols_base.h" + +/////////////////////////////////////////////////////////////////////////// + +DIALOG_CHANGE_SYMBOLS_BASE::DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + + m_mainSizer = new wxBoxSizer( wxVERTICAL ); + + m_matchSizer = new wxGridBagSizer( 5, 5 ); + m_matchSizer->SetFlexibleDirection( wxBOTH ); + m_matchSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED ); + + m_matchAll = new wxRadioButton( this, wxID_ANY, _("%s all symbols in schematic"), wxDefaultPosition, wxDefaultSize, 0 ); + m_matchSizer->Add( m_matchAll, wxGBPosition( 0, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM, 5 ); + + m_matchBySelection = new wxRadioButton( this, wxID_ANY, _("%s selected symbol"), wxDefaultPosition, wxDefaultSize, 0 ); + m_matchSizer->Add( m_matchBySelection, wxGBPosition( 1, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxBOTTOM, 3 ); + + m_matchByReference = new wxRadioButton( this, wxID_ANY, _("%s by reference:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_matchSizer->Add( m_matchByReference, wxGBPosition( 2, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + + m_specifiedReference = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 200,-1 ), wxTE_PROCESS_ENTER ); + m_matchSizer->Add( m_specifiedReference, wxGBPosition( 2, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_matchByValue = new wxRadioButton( this, wxID_ANY, _("%s by value:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_matchSizer->Add( m_matchByValue, wxGBPosition( 3, 0 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + + m_specifiedValue = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + m_matchSizer->Add( m_specifiedValue, wxGBPosition( 3, 1 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + m_matchById = new wxRadioButton( this, wxID_ANY, _("%s by library indentifier:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_matchSizer->Add( m_matchById, wxGBPosition( 4, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL, 5 ); + + m_specifiedId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + m_matchSizer->Add( m_specifiedId, wxGBPosition( 5, 0 ), wxGBSpan( 1, 2 ), wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT, 5 ); + + m_matchIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_matchSizer->Add( m_matchIdBrowserButton, wxGBPosition( 5, 2 ), wxGBSpan( 1, 1 ), wxALIGN_CENTER_VERTICAL, 5 ); + + + m_matchSizer->AddGrowableCol( 1 ); + m_matchSizer->AddGrowableRow( 1 ); + + m_mainSizer->Add( m_matchSizer, 0, wxALL|wxEXPAND, 5 ); + + m_newIdSizer = new wxBoxSizer( wxVERTICAL ); + + wxStaticText* m_newIdLabel; + m_newIdLabel = new wxStaticText( this, wxID_ANY, _("New library identifier:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_newIdLabel->Wrap( -1 ); + m_newIdSizer->Add( m_newIdLabel, 0, wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 5 ); + + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxHORIZONTAL ); + + m_newId = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); + bSizer1->Add( m_newId, 1, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 ); + + m_newIdBrowserButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer1->Add( m_newIdBrowserButton, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 ); + + + m_newIdSizer->Add( bSizer1, 0, wxEXPAND, 5 ); + + + m_mainSizer->Add( m_newIdSizer, 0, wxEXPAND|wxLEFT, 5 ); + + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxVERTICAL ); + + m_messagePanel = new WX_HTML_REPORT_PANEL( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); + m_messagePanel->SetMinSize( wxSize( -1,240 ) ); + + bSizer2->Add( m_messagePanel, 1, wxEXPAND | wxALL, 5 ); + + + m_mainSizer->Add( bSizer2, 1, wxEXPAND, 5 ); + + m_sdbSizer = new wxStdDialogButtonSizer(); + m_sdbSizerOK = new wxButton( this, wxID_OK ); + m_sdbSizer->AddButton( m_sdbSizerOK ); + m_sdbSizerCancel = new wxButton( this, wxID_CANCEL ); + m_sdbSizer->AddButton( m_sdbSizerCancel ); + m_sdbSizer->Realize(); + + m_mainSizer->Add( m_sdbSizer, 0, wxBOTTOM|wxEXPAND, 5 ); + + + this->SetSizer( m_mainSizer ); + this->Layout(); + m_mainSizer->Fit( this ); + + this->Centre( wxBOTH ); + + // Connect Events + m_matchByReference->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchByReference ), NULL, this ); + m_matchByValue->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchByValue ), NULL, this ); + m_matchById->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchById ), NULL, this ); + m_matchIdBrowserButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::launchMatchIdSymbolBrowser ), NULL, this ); + m_newIdBrowserButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::launchNewIdSymbolBrowser ), NULL, this ); + m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onOkButtonClicked ), NULL, this ); +} + +DIALOG_CHANGE_SYMBOLS_BASE::~DIALOG_CHANGE_SYMBOLS_BASE() +{ + // Disconnect Events + m_matchByReference->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchByReference ), NULL, this ); + m_matchByValue->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchByValue ), NULL, this ); + m_matchById->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onMatchById ), NULL, this ); + m_matchIdBrowserButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::launchMatchIdSymbolBrowser ), NULL, this ); + m_newIdBrowserButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::launchNewIdSymbolBrowser ), NULL, this ); + m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CHANGE_SYMBOLS_BASE::onOkButtonClicked ), NULL, this ); + +} diff --git a/eeschema/dialogs/dialog_change_symbols_base.fbp b/eeschema/dialogs/dialog_change_symbols_base.fbp new file mode 100644 index 0000000000..823ec32a78 --- /dev/null +++ b/eeschema/dialogs/dialog_change_symbols_base.fbp @@ -0,0 +1,1007 @@ + + + + + ; + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_change_symbols_base + 1000 + none + + + 1 + dialog_change_symbols_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_CHANGE_SYMBOLS_BASE + + -1,-1 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h; forward_declare + %s + + + + + + + m_mainSizer + wxVERTICAL + protected + + 5 + wxALL|wxEXPAND + 0 + + + wxBOTH + 1 + 1 + 5 + + m_matchSizer + wxFLEX_GROWMODE_SPECIFIED + protected + 5 + + 5 + 2 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM + 0 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + %s all symbols in schematic + + 0 + + + 0 + + 1 + m_matchAll + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + 3 + 1 + 0 + wxALIGN_CENTER_VERTICAL|wxBOTTOM + 1 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + %s selected symbol + + 0 + + + 0 + + 1 + m_matchBySelection + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + %s by reference: + + 0 + + + 0 + + 1 + m_matchByReference + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + onMatchByReference + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 2 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_specifiedReference + 1 + + + protected + 1 + + Resizable + 1 + 200,-1 + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 0 + wxALIGN_CENTER_VERTICAL + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + %s by value: + + 0 + + + 0 + + 1 + m_matchByValue + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + onMatchByValue + + + + 5 + 1 + 1 + wxALIGN_CENTER_VERTICAL|wxEXPAND + 3 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_specifiedValue + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 2 + 0 + wxALIGN_CENTER_VERTICAL + 4 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + %s by library indentifier: + + 0 + + + 0 + + 1 + m_matchById + 1 + + + protected + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + 0 + + + + onMatchById + + + + 5 + 2 + 0 + wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_specifiedId + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + 1 + 2 + wxALIGN_CENTER_VERTICAL + 5 + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_matchIdBrowserButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + launchMatchIdSymbolBrowser + + + + + + 5 + wxEXPAND|wxLEFT + 0 + + + m_newIdSizer + wxVERTICAL + protected + + 5 + wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + New library identifier: + 0 + + 0 + + + 0 + + 1 + m_newIdLabel + 1 + + + none + 1 + + Resizable + 1 + + + ; ; forward_declare + 0 + + + + + -1 + + + + 5 + wxEXPAND + 0 + + + bSizer1 + wxHORIZONTAL + none + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_newId + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_PROCESS_ENTER + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_newIdBrowserButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + launchNewIdSymbolBrowser + + + + + + + + 5 + wxEXPAND + 1 + + + bSizer2 + wxVERTICAL + none + + 5 + wxEXPAND | wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + -1,240 + 1 + m_messagePanel + 1 + + + protected + 1 + + Resizable + 1 + + WX_HTML_REPORT_PANEL; wx_html_report_panel.h; forward_declare + 0 + + + + wxTAB_TRAVERSAL + + + + + + 5 + wxBOTTOM|wxEXPAND + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + onOkButtonClicked + + + + + + diff --git a/eeschema/dialogs/dialog_change_symbols_base.h b/eeschema/dialogs/dialog_change_symbols_base.h new file mode 100644 index 0000000000..df6921bad6 --- /dev/null +++ b/eeschema/dialogs/dialog_change_symbols_base.h @@ -0,0 +1,79 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version 3.9.0 Jun 3 2020) +// http://www.wxformbuilder.org/ +// +// PLEASE DO *NOT* EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include +#include +class WX_HTML_REPORT_PANEL; + +#include "dialog_shim.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DIALOG_CHANGE_SYMBOLS_BASE +/////////////////////////////////////////////////////////////////////////////// +class DIALOG_CHANGE_SYMBOLS_BASE : public DIALOG_SHIM +{ + private: + + protected: + wxBoxSizer* m_mainSizer; + wxGridBagSizer* m_matchSizer; + wxRadioButton* m_matchAll; + wxRadioButton* m_matchBySelection; + wxRadioButton* m_matchByReference; + wxTextCtrl* m_specifiedReference; + wxRadioButton* m_matchByValue; + wxTextCtrl* m_specifiedValue; + wxRadioButton* m_matchById; + wxTextCtrl* m_specifiedId; + wxBitmapButton* m_matchIdBrowserButton; + wxBoxSizer* m_newIdSizer; + wxTextCtrl* m_newId; + wxBitmapButton* m_newIdBrowserButton; + WX_HTML_REPORT_PANEL* m_messagePanel; + wxStdDialogButtonSizer* m_sdbSizer; + wxButton* m_sdbSizerOK; + wxButton* m_sdbSizerCancel; + + // Virtual event handlers, overide them in your derived class + virtual void onMatchByReference( wxCommandEvent& event ) { event.Skip(); } + virtual void onMatchByValue( wxCommandEvent& event ) { event.Skip(); } + virtual void onMatchById( wxCommandEvent& event ) { event.Skip(); } + virtual void launchMatchIdSymbolBrowser( wxCommandEvent& event ) { event.Skip(); } + virtual void launchNewIdSymbolBrowser( wxCommandEvent& event ) { event.Skip(); } + virtual void onOkButtonClicked( wxCommandEvent& event ) { event.Skip(); } + + + public: + + DIALOG_CHANGE_SYMBOLS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("%s"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + ~DIALOG_CHANGE_SYMBOLS_BASE(); + +}; + diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index 8c755383e3..f055852cfc 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -157,6 +157,8 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() editMenu->AddItem( ACTIONS::deleteTool, EE_CONDITIONS::ShowAlways ); editMenu->AddItem( EE_ACTIONS::editTextAndGraphics, EE_CONDITIONS::ShowAlways ); editMenu->AddItem( EE_ACTIONS::updateFieldsFromLibrary, EE_CONDITIONS::ShowAlways ); + editMenu->AddItem( EE_ACTIONS::changeSymbols, EE_CONDITIONS::ShowAlways ); + editMenu->AddItem( EE_ACTIONS::updateSymbols, EE_CONDITIONS::ShowAlways ); editMenu->Resolve(); diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 51e95de585..ac8d8a9aef 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -396,6 +396,22 @@ TOOL_ACTION EE_ACTIONS::updateFieldsFromLibrary( "eeschema.InteractiveEdit.updat _( "Update Fields from Library..." ), _( "Sets symbol fields to original library values" ), update_fields_xpm ); +TOOL_ACTION EE_ACTIONS::changeSymbols( "eeschema.InteractiveEdit.changeSymbols", + AS_GLOBAL, 0, "", _( "Change Library Symbols..." ), + _( "Change library symbols in schematic" ), nullptr ); + +TOOL_ACTION EE_ACTIONS::updateSymbols( "eeschema.InteractiveEdit.updateSymbols", + AS_GLOBAL, 0, "", _( "Update Library Symbols..." ), + _( "Update library symbols in schematic" ), nullptr ); + +TOOL_ACTION EE_ACTIONS::changeSymbol( "eeschema.InteractiveEdit.changeSymbol", + AS_GLOBAL, 0, "", _( "Change Library Symbol..." ), + _( "Change library symbol for selected symbol" ), nullptr ); + +TOOL_ACTION EE_ACTIONS::updateSymbol( "eeschema.InteractiveEdit.updateSymbol", + AS_GLOBAL, 0, "", _( "Update Library Symbol..." ), + _( "Update library symbol for selected symbol" ), nullptr ); + TOOL_ACTION EE_ACTIONS::assignNetclass( "eeschema.InteractiveEdit.assignNetclass", AS_GLOBAL, 0, "", _( "Assign Netclass..." ), _( "Assign a netclass to the net of the selected wire" ), diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index 2c841927b6..d63e337711 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -144,6 +144,10 @@ public: static TOOL_ACTION symbolProperties; static TOOL_ACTION pinTable; static TOOL_ACTION updateFieldsFromLibrary; + static TOOL_ACTION changeSymbols; + static TOOL_ACTION updateSymbols; + static TOOL_ACTION changeSymbol; + static TOOL_ACTION updateSymbol; static TOOL_ACTION assignFootprints; static TOOL_ACTION assignNetclass; static TOOL_ACTION showBusManager; diff --git a/eeschema/tools/sch_edit_tool.cpp b/eeschema/tools/sch_edit_tool.cpp index c961e00247..1ee052afae 100644 --- a/eeschema/tools/sch_edit_tool.cpp +++ b/eeschema/tools/sch_edit_tool.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -357,6 +358,8 @@ bool SCH_EDIT_TOOL::Init() selToolMenu.AddMenu( symUnitMenu3.get(), E_C::SingleMultiUnitSymbol, 1 ); selToolMenu.AddItem( EE_ACTIONS::editWithLibEdit, singleComponentCondition && E_C::Idle, 200 ); + selToolMenu.AddItem( EE_ACTIONS::changeSymbol, E_C::SingleSymbol, 200 ); + selToolMenu.AddItem( EE_ACTIONS::updateSymbol, E_C::SingleSymbol, 200 ); selToolMenu.AddItem( EE_ACTIONS::toLabel, toLabelCondition, 200 ); selToolMenu.AddItem( EE_ACTIONS::toHLabel, toHLabelCondition, 200 ); @@ -1224,6 +1227,28 @@ int SCH_EDIT_TOOL::UpdateFields( const TOOL_EVENT& aEvent ) } +int SCH_EDIT_TOOL::ChangeSymbols( const TOOL_EVENT& aEvent ) +{ + SCH_COMPONENT* selectedSymbol = nullptr; + EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::ComponentsOnly ); + + if( !selection.Empty() ) + selectedSymbol = dynamic_cast( selection.Front() ); + + DIALOG_CHANGE_SYMBOLS::MODE mode = DIALOG_CHANGE_SYMBOLS::MODE::UPDATE; + + if( aEvent.IsAction( &EE_ACTIONS::changeSymbol ) + || aEvent.IsAction( &EE_ACTIONS::changeSymbols ) ) + mode = DIALOG_CHANGE_SYMBOLS::MODE::CHANGE; + + DIALOG_CHANGE_SYMBOLS dlg( m_frame, selectedSymbol, mode ); + + dlg.ShowModal(); + + return 0; +} + + int SCH_EDIT_TOOL::ConvertDeMorgan( const TOOL_EVENT& aEvent ) { EE_SELECTION& selection = m_selectionTool->RequestSelection( EE_COLLECTOR::ComponentsOnly ); @@ -1714,6 +1739,10 @@ void SCH_EDIT_TOOL::setTransitions() Go( &SCH_EDIT_TOOL::EditField, EE_ACTIONS::editFootprint.MakeEvent() ); Go( &SCH_EDIT_TOOL::AutoplaceFields, EE_ACTIONS::autoplaceFields.MakeEvent() ); Go( &SCH_EDIT_TOOL::UpdateFields, EE_ACTIONS::updateFieldsFromLibrary.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeSymbols, EE_ACTIONS::changeSymbols.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeSymbols, EE_ACTIONS::updateSymbols.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeSymbols, EE_ACTIONS::changeSymbol.MakeEvent() ); + Go( &SCH_EDIT_TOOL::ChangeSymbols, EE_ACTIONS::updateSymbol.MakeEvent() ); Go( &SCH_EDIT_TOOL::ConvertDeMorgan, EE_ACTIONS::toggleDeMorgan.MakeEvent() ); Go( &SCH_EDIT_TOOL::ConvertDeMorgan, EE_ACTIONS::showDeMorganStandard.MakeEvent() ); Go( &SCH_EDIT_TOOL::ConvertDeMorgan, EE_ACTIONS::showDeMorganAlternate.MakeEvent() ); diff --git a/eeschema/tools/sch_edit_tool.h b/eeschema/tools/sch_edit_tool.h index 2d2048031d..df2caf9812 100644 --- a/eeschema/tools/sch_edit_tool.h +++ b/eeschema/tools/sch_edit_tool.h @@ -52,6 +52,7 @@ public: int EditField( const TOOL_EVENT& aEvent ); int AutoplaceFields( const TOOL_EVENT& aEvent ); int UpdateFields( const TOOL_EVENT& aEvent ); + int ChangeSymbols( const TOOL_EVENT& aEvent ); int ConvertDeMorgan( const TOOL_EVENT& aEvent ); int RefreshSymbolFromLibrary( const TOOL_EVENT& aEvent );