From 2089374f531379313148cea99ab44be48838977c Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Thu, 15 Sep 2022 23:06:23 -0400 Subject: [PATCH] ADDED: Export symbols from schematic to library Fixes https://gitlab.com/kicad/code/kicad/-/issues/11433 --- eeschema/CMakeLists.txt | 3 +- .../dialogs/dialog_lib_symbol_properties.cpp | 2 +- eeschema/menubar.cpp | 4 + eeschema/sch_base_frame.cpp | 120 ++++++++++++++++++ eeschema/sch_base_frame.h | 17 +++ .../lib_symbol_library_manager.cpp | 50 ++++++++ .../lib_symbol_library_manager.h | 63 +++++++++ eeschema/symbol_editor/symbol_edit_frame.cpp | 55 +------- eeschema/symbol_editor/symbol_edit_frame.h | 24 +--- eeschema/symbol_editor/symbol_editor.cpp | 74 +---------- .../symbol_editor_import_export.cpp | 4 +- .../symbol_editor/symbol_editor_undo_redo.cpp | 2 +- eeschema/symbol_library_common.h | 2 + .../symbol_library_manager.cpp | 33 ++--- .../symbol_library_manager.h | 31 +---- .../symbol_tree_synchronizing_adapter.cpp | 4 +- eeschema/tools/ee_actions.cpp | 14 ++ eeschema/tools/ee_actions.h | 2 + eeschema/tools/sch_editor_control.cpp | 106 ++++++++++++++++ eeschema/tools/sch_editor_control.h | 2 + eeschema/tools/symbol_editor_control.cpp | 6 +- eeschema/widgets/symbol_tree_pane.cpp | 5 +- eeschema/widgets/symbol_tree_pane.h | 10 +- 23 files changed, 423 insertions(+), 210 deletions(-) create mode 100644 eeschema/symbol_editor/lib_symbol_library_manager.cpp create mode 100644 eeschema/symbol_editor/lib_symbol_library_manager.h rename eeschema/{symbol_editor => }/symbol_library_manager.cpp (97%) rename eeschema/{symbol_editor => }/symbol_library_manager.h (94%) diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 61ba76fdc6..9b45c74fff 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -163,6 +163,7 @@ set( EESCHEMA_WIDGETS set ( EESCHEMA_LIBEDIT_SRCS symbol_editor/lib_logger.cpp + symbol_editor/lib_symbol_library_manager.cpp symbol_editor/menubar_symbol_editor.cpp symbol_editor/symbol_edit_frame.cpp symbol_editor/symbol_editor.cpp @@ -170,7 +171,6 @@ set ( EESCHEMA_LIBEDIT_SRCS symbol_editor/symbol_editor_plotter.cpp symbol_editor/symbol_editor_settings.cpp symbol_editor/symbol_editor_undo_redo.cpp - symbol_editor/symbol_library_manager.cpp symbol_editor/toolbars_symbol_editor.cpp ) @@ -248,6 +248,7 @@ set( EESCHEMA_SRCS symbol_checker.cpp symbol_lib_table.cpp symbol_library.cpp + symbol_library_manager.cpp symbol_tree_model_adapter.cpp symbol_tree_synchronizing_adapter.cpp symbol_viewer_frame.cpp diff --git a/eeschema/dialogs/dialog_lib_symbol_properties.cpp b/eeschema/dialogs/dialog_lib_symbol_properties.cpp index 8f225adfbe..bf4858fb6b 100644 --- a/eeschema/dialogs/dialog_lib_symbol_properties.cpp +++ b/eeschema/dialogs/dialog_lib_symbol_properties.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include // for KiROUND #include #include diff --git a/eeschema/menubar.cpp b/eeschema/menubar.cpp index f771385996..668cccce9e 100644 --- a/eeschema/menubar.cpp +++ b/eeschema/menubar.cpp @@ -121,6 +121,10 @@ void SCH_EDIT_FRAME::ReCreateMenuBar() submenuExport->SetIcon( BITMAPS::export_file ); submenuExport->Add( EE_ACTIONS::drawSheetOnClipboard, ACTION_MENU::NORMAL, _( "Drawing to Clipboard" ) ); submenuExport->Add( EE_ACTIONS::exportNetlist, ACTION_MENU::NORMAL, _( "Netlist..." ) ); + submenuExport->Add( EE_ACTIONS::exportSymbolsToLibrary, ACTION_MENU::NORMAL, + _( "Symbols to Library..." ) ); + submenuExport->Add( EE_ACTIONS::exportSymbolsToNewLibrary, ACTION_MENU::NORMAL, + _( "Symbols to New Library..." ) ); fileMenu->Add( submenuExport ); fileMenu->AppendSeparator(); diff --git a/eeschema/sch_base_frame.cpp b/eeschema/sch_base_frame.cpp index 159cd57b07..84745800b7 100644 --- a/eeschema/sch_base_frame.cpp +++ b/eeschema/sch_base_frame.cpp @@ -24,8 +24,11 @@ #include #include +#include #include +#include #include +#include #include #include #include @@ -41,6 +44,7 @@ #include #include #include +#include #if defined( KICAD_USE_3DCONNEXION ) #include @@ -248,6 +252,50 @@ bool SCH_BASE_FRAME::saveSymbolLibTables( bool aGlobal, bool aProject ) } +SYMBOL_LIB_TABLE* SCH_BASE_FRAME::SelectSymLibTable( bool aOptional ) +{ + // If no project is loaded, always work with the global table + if( Prj().IsNullProject() ) + { + SYMBOL_LIB_TABLE* ret = &SYMBOL_LIB_TABLE::GetGlobalLibTable(); + + if( aOptional ) + { + wxMessageDialog dlg( this, _( "Add the library to the global library table?" ), + _( "Add To Global Library Table" ), wxYES_NO ); + + if( dlg.ShowModal() != wxID_OK ) + ret = nullptr; + } + + return ret; + } + + wxArrayString libTableNames; + libTableNames.Add( _( "Global" ) ); + libTableNames.Add( _( "Project" ) ); + + wxSingleChoiceDialog dlg( this, _( "Choose the Library Table to add the library to:" ), + _( "Add To Library Table" ), libTableNames ); + + if( aOptional ) + { + dlg.FindWindow( wxID_CANCEL )->SetLabel( _( "Skip" ) ); + dlg.FindWindow( wxID_OK )->SetLabel( _( "Add" ) ); + } + + if( dlg.ShowModal() != wxID_OK ) + return nullptr; + + switch( dlg.GetSelection() ) + { + case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable(); + case 1: return Prj().SchSymbolLibTable(); + default: return nullptr; + } +} + + void SCH_BASE_FRAME::RedrawScreen( const VECTOR2I& aCenterPoint, bool aWarpPointer ) { GetCanvas()->GetView()->SetCenter( aCenterPoint ); @@ -510,3 +558,75 @@ void SCH_BASE_FRAME::handleIconizeEvent( wxIconizeEvent& aEvent ) } #endif } + + +wxString SCH_BASE_FRAME::SelectLibraryFromList() +{ + COMMON_SETTINGS* cfg = Pgm().GetCommonSettings(); + PROJECT& prj = Prj(); + + if( prj.SchSymbolLibTable()->IsEmpty() ) + { + ShowInfoBarError( _( "No symbol libraries are loaded." ) ); + return wxEmptyString; + } + + wxArrayString headers; + + headers.Add( _( "Library" ) ); + + std::vector< wxArrayString > itemsToDisplay; + std::vector< wxString > libNicknames = prj.SchSymbolLibTable()->GetLogicalLibs(); + + for( const wxString& name : libNicknames ) + { + // Exclude read only libraries. + if( !prj.SchSymbolLibTable()->IsSymbolLibWritable( name ) ) + continue; + + if( alg::contains( prj.GetProjectFile().m_PinnedSymbolLibs, name ) + || alg::contains( cfg->m_Session.pinned_symbol_libs, name ) ) + { + wxArrayString item; + + item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + name ); + itemsToDisplay.push_back( item ); + } + } + + for( const wxString& name : libNicknames ) + { + // Exclude read only libraries. + if( !prj.SchSymbolLibTable()->IsSymbolLibWritable( name ) ) + continue; + + if( !alg::contains( prj.GetProjectFile().m_PinnedSymbolLibs, name ) + && !alg::contains( cfg->m_Session.pinned_symbol_libs, name ) ) + { + wxArrayString item; + + item.Add( name ); + itemsToDisplay.push_back( item ); + } + } + + wxString oldLibName = prj.GetRString( PROJECT::SCH_LIB_SELECT ); + + EDA_LIST_DIALOG dlg( this, _( "Select Symbol Library" ), headers, itemsToDisplay, oldLibName, + false ); + + if( dlg.ShowModal() != wxID_OK ) + return wxEmptyString; + + wxString libName = dlg.GetTextSelection(); + + if( !libName.empty() ) + { + if( prj.SchSymbolLibTable()->HasLibrary( libName ) ) + prj.SetRString( PROJECT::SCH_LIB_SELECT, libName ); + else + libName = wxEmptyString; + } + + return libName; +} diff --git a/eeschema/sch_base_frame.h b/eeschema/sch_base_frame.h index eb6a4cbcc5..2ab1ec35db 100644 --- a/eeschema/sch_base_frame.h +++ b/eeschema/sch_base_frame.h @@ -191,6 +191,23 @@ public: const LIB_ID& aPreselectedLibId, int aUnit, int aConvert ); + /** + * Display a list of loaded libraries and allows the user to select a library. + * + * This list is sorted, with the library cache always at end of the list + * + * @return the library nickname used in the symbol library table. + */ + wxString SelectLibraryFromList(); + + /** + * Display a dialog asking the user to select a symbol library table. + * + * @param aOptional if set the Cancel button will be relabelled "Skip". + * @return Pointer to the selected symbol library table or nullptr if canceled. + */ + SYMBOL_LIB_TABLE* SelectSymLibTable( bool aOptional = false ); + virtual void RedrawScreen( const VECTOR2I& aCenterPoint, bool aWarpPointer ); void HardRedraw() override; diff --git a/eeschema/symbol_editor/lib_symbol_library_manager.cpp b/eeschema/symbol_editor/lib_symbol_library_manager.cpp new file mode 100644 index 0000000000..487fc748c8 --- /dev/null +++ b/eeschema/symbol_editor/lib_symbol_library_manager.cpp @@ -0,0 +1,50 @@ +/* +* This program source code file is part of KiCad, a free EDA CAD application. +* +* Copyright (C) 2022 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 + + +LIB_SYMBOL_LIBRARY_MANAGER::LIB_SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ) : + SYMBOL_LIBRARY_MANAGER( aFrame ), + m_syncHash( 0 ) +{ + m_adapter = SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Create( &aFrame, this ); + m_adapter->ShowUnits( false ); +} + + +void LIB_SYMBOL_LIBRARY_MANAGER::Sync( const wxString& aForceRefresh, + std::function aProgressCallback ) +{ + m_logger->Activate(); + { + getAdapter()->Sync( aForceRefresh, aProgressCallback ); + m_syncHash = symTable()->GetModifyHash(); + } + m_logger->Deactivate(); +} + + +void LIB_SYMBOL_LIBRARY_MANAGER::OnDataChanged() const +{ + static_cast( m_frame ).SyncLibraries( false ); +} diff --git a/eeschema/symbol_editor/lib_symbol_library_manager.h b/eeschema/symbol_editor/lib_symbol_library_manager.h new file mode 100644 index 0000000000..df6ab41846 --- /dev/null +++ b/eeschema/symbol_editor/lib_symbol_library_manager.h @@ -0,0 +1,63 @@ +/* +* This program source code file is part of KiCad, a free EDA CAD application. +* +* Copyright (C) 2022 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 . +*/ + +#ifndef KICAD_LIB_SYMBOL_LIBRARY_MANAGER_H +#define KICAD_LIB_SYMBOL_LIBRARY_MANAGER_H + +#include +#include + + +/** + * Symbol library management helper that is specific to the symbol library editor frame + * + * The base class handles library manipulation; this one also handles synchronizing the LIB_TREE. + */ +class LIB_SYMBOL_LIBRARY_MANAGER : public SYMBOL_LIBRARY_MANAGER +{ +public: + LIB_SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ); + + /** + * Updates the #SYMBOL_LIBRARY_MANAGER data to synchronize with Symbol Library Table. + */ + void Sync( const wxString& aForceRefresh, + std::function aProgressCallback ); + + /** + * Return the adapter object that provides the stored data. + */ + wxObjectDataPtr& GetAdapter() { return m_adapter; } + +protected: + void OnDataChanged() const override; + +private: + SYMBOL_TREE_SYNCHRONIZING_ADAPTER* getAdapter() + { + return static_cast( m_adapter.get() ); + } + + wxObjectDataPtr m_adapter; + + int m_syncHash; ///< Symbol lib table hash value from last synchronization +}; + + +#endif diff --git a/eeschema/symbol_editor/symbol_edit_frame.cpp b/eeschema/symbol_editor/symbol_edit_frame.cpp index d3b65caf05..74bfc224be 100644 --- a/eeschema/symbol_editor/symbol_edit_frame.cpp +++ b/eeschema/symbol_editor/symbol_edit_frame.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -71,7 +71,6 @@ #include #include #include -#include #include @@ -129,7 +128,7 @@ SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_settings = Pgm().GetSettingsManager().GetAppSettings(); LoadSettings( m_settings ); - m_libMgr = new SYMBOL_LIBRARY_MANAGER( *this ); + m_libMgr = new LIB_SYMBOL_LIBRARY_MANAGER( *this ); bool loadingCancelled = false; { @@ -820,7 +819,7 @@ void SYMBOL_EDIT_FRAME::SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom ) } -SYMBOL_LIBRARY_MANAGER& SYMBOL_EDIT_FRAME::GetLibManager() +LIB_SYMBOL_LIBRARY_MANAGER& SYMBOL_EDIT_FRAME::GetLibManager() { wxASSERT( m_libMgr ); return *m_libMgr; @@ -850,7 +849,7 @@ bool SYMBOL_EDIT_FRAME::SynchronizePins() wxString SYMBOL_EDIT_FRAME::AddLibraryFile( bool aCreateNew ) { // Select the target library table (global/project) - SYMBOL_LIB_TABLE* libTable = selectSymLibTable(); + SYMBOL_LIB_TABLE* libTable = SelectSymLibTable(); if( !libTable ) return wxEmptyString; @@ -909,7 +908,7 @@ wxString SYMBOL_EDIT_FRAME::AddLibraryFile( bool aCreateNew ) void SYMBOL_EDIT_FRAME::DdAddLibrary( wxString aLibFile ) { // Select the target library table (global/project) - SYMBOL_LIB_TABLE* libTable = selectSymLibTable(); + SYMBOL_LIB_TABLE* libTable = SelectSymLibTable(); if( !libTable ) return; @@ -1104,50 +1103,6 @@ void SYMBOL_EDIT_FRAME::UpdateLibraryTree( const wxDataViewItem& aTreeItem, LIB_ } -SYMBOL_LIB_TABLE* SYMBOL_EDIT_FRAME::selectSymLibTable( bool aOptional ) -{ - // If no project is loaded, always work with the global table - if( Prj().IsNullProject() ) - { - SYMBOL_LIB_TABLE* ret = &SYMBOL_LIB_TABLE::GetGlobalLibTable(); - - if( aOptional ) - { - wxMessageDialog dlg( this, _( "Add the library to the global library table?" ), - _( "Add To Global Library Table" ), wxYES_NO ); - - if( dlg.ShowModal() != wxID_OK ) - ret = nullptr; - } - - return ret; - } - - wxArrayString libTableNames; - libTableNames.Add( _( "Global" ) ); - libTableNames.Add( _( "Project" ) ); - - wxSingleChoiceDialog dlg( this, _( "Choose the Library Table to add the library to:" ), - _( "Add To Library Table" ), libTableNames ); - - if( aOptional ) - { - dlg.FindWindow( wxID_CANCEL )->SetLabel( _( "Skip" ) ); - dlg.FindWindow( wxID_OK )->SetLabel( _( "Add" ) ); - } - - if( dlg.ShowModal() != wxID_OK ) - return nullptr; - - switch( dlg.GetSelection() ) - { - case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable(); - case 1: return Prj().SchSymbolLibTable(); - default: return nullptr; - } -} - - bool SYMBOL_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt ) { if( aOriginalFile.FileExists() ) diff --git a/eeschema/symbol_editor/symbol_edit_frame.h b/eeschema/symbol_editor/symbol_edit_frame.h index 5b9292e90c..2a6e05a7a4 100644 --- a/eeschema/symbol_editor/symbol_edit_frame.h +++ b/eeschema/symbol_editor/symbol_edit_frame.h @@ -42,7 +42,7 @@ class DIALOG_LIB_TEXT_PROPERTIES; class SYMBOL_TREE_PANE; class LIB_TREE_NODE; class LIB_ID; -class SYMBOL_LIBRARY_MANAGER; +class LIB_SYMBOL_LIBRARY_MANAGER; class SYMBOL_EDITOR_SETTINGS; class EDA_LIST_DIALOG; @@ -114,7 +114,7 @@ public: */ void SetCurSymbol( LIB_SYMBOL* aSymbol, bool aUpdateZoom ); - SYMBOL_LIBRARY_MANAGER& GetLibManager(); + LIB_SYMBOL_LIBRARY_MANAGER& GetLibManager(); SELECTION& GetCurrentSelection() override; @@ -427,16 +427,6 @@ private: */ void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString ); - /** - * Display a list of loaded libraries in the symbol library and allows the user to select - * a library. - * - * This list is sorted, with the library cache always at end of the list - * - * @return the library nickname used in the symbol library table. - */ - wxString SelectLibraryFromList(); - /** * Load a symbol from the current active library, optionally setting the selected unit * and convert. @@ -461,14 +451,6 @@ private: bool LoadOneLibrarySymbolAux( LIB_SYMBOL* aLibEntry, const wxString& aLibrary, int aUnit, int aConvert ); - /** - * Display a dialog asking the user to select a symbol library table. - * - * @param aOptional if set the Cancel button will be relabelled "Skip". - * @return Pointer to the selected symbol library table or nullptr if canceled. - */ - SYMBOL_LIB_TABLE* selectSymLibTable( bool aOptional = false ); - ///< Create a backup copy of a file with requested extension. bool backupFile( const wxFileName& aOriginalFile, const wxString& aBackupExt ); @@ -562,7 +544,7 @@ private: wxComboBox* m_unitSelectBox; // a ComboBox to select a unit to edit (if the // symbol has multiple units) SYMBOL_TREE_PANE* m_treePane; // symbol search tree widget - SYMBOL_LIBRARY_MANAGER* m_libMgr; // manager taking care of temporary modifications + LIB_SYMBOL_LIBRARY_MANAGER* m_libMgr; // manager taking care of temporary modifications SYMBOL_EDITOR_SETTINGS* m_settings; // Handle to the settings LIB_ID m_centerItemOnIdle; diff --git a/eeschema/symbol_editor/symbol_editor.cpp b/eeschema/symbol_editor/symbol_editor.cpp index ca64ceb52d..dd22037dac 100644 --- a/eeschema/symbol_editor/symbol_editor.cpp +++ b/eeschema/symbol_editor/symbol_editor.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -102,78 +102,6 @@ void SYMBOL_EDIT_FRAME::SelectActiveLibrary( const wxString& aLibrary ) } -wxString SYMBOL_EDIT_FRAME::SelectLibraryFromList() -{ - COMMON_SETTINGS* cfg = Pgm().GetCommonSettings(); - PROJECT& prj = Prj(); - - if( prj.SchSymbolLibTable()->IsEmpty() ) - { - ShowInfoBarError( _( "No symbol libraries are loaded." ) ); - return wxEmptyString; - } - - wxArrayString headers; - - headers.Add( _( "Library" ) ); - - std::vector< wxArrayString > itemsToDisplay; - std::vector< wxString > libNicknames = prj.SchSymbolLibTable()->GetLogicalLibs(); - - for( const wxString& name : libNicknames ) - { - // Exclude read only libraries. - if( m_libMgr->IsLibraryReadOnly( name ) ) - continue; - - if( alg::contains( prj.GetProjectFile().m_PinnedSymbolLibs, name ) - || alg::contains( cfg->m_Session.pinned_symbol_libs, name ) ) - { - wxArrayString item; - - item.Add( LIB_TREE_MODEL_ADAPTER::GetPinningSymbol() + name ); - itemsToDisplay.push_back( item ); - } - } - - for( const wxString& name : libNicknames ) - { - // Exclude read only libraries. - if( m_libMgr->IsLibraryReadOnly( name ) ) - continue; - - if( !alg::contains( prj.GetProjectFile().m_PinnedSymbolLibs, name ) - && !alg::contains( cfg->m_Session.pinned_symbol_libs, name ) ) - { - wxArrayString item; - - item.Add( name ); - itemsToDisplay.push_back( item ); - } - } - - wxString oldLibName = prj.GetRString( PROJECT::SCH_LIB_SELECT ); - - EDA_LIST_DIALOG dlg( this, _( "Select Symbol Library" ), headers, itemsToDisplay, oldLibName, - false ); - - if( dlg.ShowModal() != wxID_OK ) - return wxEmptyString; - - wxString libName = dlg.GetTextSelection(); - - if( !libName.empty() ) - { - if( prj.SchSymbolLibTable()->HasLibrary( libName ) ) - prj.SetRString( PROJECT::SCH_LIB_SELECT, libName ); - else - libName = wxEmptyString; - } - - return libName; -} - - bool SYMBOL_EDIT_FRAME::saveCurrentSymbol() { if( GetCurSymbol() ) diff --git a/eeschema/symbol_editor/symbol_editor_import_export.cpp b/eeschema/symbol_editor/symbol_editor_import_export.cpp index 1eaa803770..e5e9c09b6f 100644 --- a/eeschema/symbol_editor/symbol_editor_import_export.cpp +++ b/eeschema/symbol_editor/symbol_editor_import_export.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -204,7 +204,7 @@ void SYMBOL_EDIT_FRAME::ExportSymbol() SetStatusText( msg ); // See if the user wants it added to a library table (global or project) - SYMBOL_LIB_TABLE* libTable = selectSymLibTable( true ); + SYMBOL_LIB_TABLE* libTable = SelectSymLibTable( true ); if( libTable ) { diff --git a/eeschema/symbol_editor/symbol_editor_undo_redo.cpp b/eeschema/symbol_editor/symbol_editor_undo_redo.cpp index 9e49bee6a9..78ef608f9c 100644 --- a/eeschema/symbol_editor/symbol_editor_undo_redo.cpp +++ b/eeschema/symbol_editor/symbol_editor_undo_redo.cpp @@ -23,7 +23,7 @@ */ #include -#include +#include #include #include #include diff --git a/eeschema/symbol_library_common.h b/eeschema/symbol_library_common.h index 09c44fc6dc..8d55ccf333 100644 --- a/eeschema/symbol_library_common.h +++ b/eeschema/symbol_library_common.h @@ -26,6 +26,8 @@ class LIB_SYMBOL; +class SCH_BASE_FRAME; +class SYMBOL_LIB_TABLE; enum class SCH_LIB_TYPE diff --git a/eeschema/symbol_editor/symbol_library_manager.cpp b/eeschema/symbol_library_manager.cpp similarity index 97% rename from eeschema/symbol_editor/symbol_library_manager.cpp rename to eeschema/symbol_library_manager.cpp index 9c48d5da85..3f5775bc9c 100644 --- a/eeschema/symbol_editor/symbol_library_manager.cpp +++ b/eeschema/symbol_library_manager.cpp @@ -44,12 +44,9 @@ #include "lib_logger.h" -SYMBOL_LIBRARY_MANAGER::SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ) : - m_frame( aFrame ), - m_syncHash( 0 ) +SYMBOL_LIBRARY_MANAGER::SYMBOL_LIBRARY_MANAGER( SCH_BASE_FRAME& aFrame ) : + m_frame( aFrame ) { - m_adapter = SYMBOL_TREE_SYNCHRONIZING_ADAPTER::Create( &m_frame, this ); - m_adapter->ShowUnits( false ); m_logger = new LIB_LOGGER(); } @@ -60,19 +57,6 @@ SYMBOL_LIBRARY_MANAGER::~SYMBOL_LIBRARY_MANAGER() } -void SYMBOL_LIBRARY_MANAGER::Sync( const wxString& aForceRefresh, - std::function aProgressCallback ) -{ - m_logger->Activate(); - { - getAdapter()->Sync( aForceRefresh, aProgressCallback ); - m_syncHash = symTable()->GetModifyHash(); - } - m_logger->Deactivate(); -} - - void SYMBOL_LIBRARY_MANAGER::Preload( PROGRESS_REPORTER& aReporter ) { SYMBOL_ASYNC_LOADER loader( symTable()->GetLogicalLibs(), symTable(), false, nullptr, @@ -210,8 +194,7 @@ bool SYMBOL_LIBRARY_MANAGER::SaveLibrary( const wxString& aLibrary, const wxStri if( row ) { - original = row->GetFullURI( true ); - original.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ); + } destination.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ); @@ -508,7 +491,7 @@ bool SYMBOL_LIBRARY_MANAGER::UpdateSymbolAfterRename( LIB_SYMBOL* aSymbol, const wxCHECK( symbolBuf, false ); libBuf.UpdateBuffer( symbolBuf, aSymbol ); - m_frame.SyncLibraries( false ); + OnDataChanged(); return true; } @@ -546,7 +529,7 @@ LIB_ID SYMBOL_LIBRARY_MANAGER::RevertSymbol( const wxString& aAlias, const wxStr else { symbolBuf->SetSymbol( new LIB_SYMBOL( original ) ); - m_frame.SyncLibraries( false ); + OnDataChanged(); } return LIB_ID( aLibrary, original.GetName() ); @@ -561,7 +544,7 @@ bool SYMBOL_LIBRARY_MANAGER::RevertLibrary( const wxString& aLibrary ) return false; m_libs.erase( it ); - m_frame.SyncLibraries( false ); + OnDataChanged(); return true; } @@ -602,7 +585,7 @@ bool SYMBOL_LIBRARY_MANAGER::RemoveSymbol( const wxString& aAlias, const wxStrin bool retv = true; retv &= libBuf.DeleteBuffer( symbolBuf ); - m_frame.SyncLibraries( false ); + OnDataChanged(); return retv; } @@ -754,7 +737,7 @@ bool SYMBOL_LIBRARY_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate } } - m_frame.SyncLibraries( false ); + OnDataChanged(); return true; } diff --git a/eeschema/symbol_editor/symbol_library_manager.h b/eeschema/symbol_library_manager.h similarity index 94% rename from eeschema/symbol_editor/symbol_library_manager.h rename to eeschema/symbol_library_manager.h index 1850274c39..288630bdad 100644 --- a/eeschema/symbol_editor/symbol_library_manager.h +++ b/eeschema/symbol_library_manager.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -41,7 +40,7 @@ class LIB_SYMBOL; class SYMBOL_LIB; class PROGRESS_REPORTER; class SCH_PLUGIN; -class SYMBOL_EDIT_FRAME; +class SCH_BASE_FRAME; class SYMBOL_LIB_TABLE; class SYMBOL_LIB_TABLE_ROW; class LIB_LOGGER; @@ -53,15 +52,9 @@ class LIB_LOGGER; class SYMBOL_LIBRARY_MANAGER { public: - SYMBOL_LIBRARY_MANAGER( SYMBOL_EDIT_FRAME& aFrame ); + SYMBOL_LIBRARY_MANAGER( SCH_BASE_FRAME& aFrame ); ~SYMBOL_LIBRARY_MANAGER(); - /** - * Updates the #SYMBOL_LIBRARY_MANAGER data to synchronize with Symbol Library Table. - */ - void Sync( const wxString& aForceRefresh, - std::function aProgressCallback ); - /** * Preloads all symbol libraries in the symbol library table using SYMBOL_ASYNC_LOADER. * Call before the first call to Sync() to get better performance. @@ -240,11 +233,6 @@ public: */ wxString GetUniqueLibraryName() const; - /** - * Return the adapter object that provides the stored data. - */ - wxObjectDataPtr& GetAdapter() { return m_adapter; } - void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames ); /** @@ -257,21 +245,19 @@ public: size_t GetLibraryCount() const; -private: +protected: + virtual void OnDataChanged() const {} + ///< Extract library name basing on the file name. static wxString getLibraryName( const wxString& aFilePath ); ///< Helper function to add either existing or create new library bool addLibrary( const wxString& aFilePath, bool aCreate, SYMBOL_LIB_TABLE* aTable ); + ///< Return the current Symbol Library Table. SYMBOL_LIB_TABLE* symTable() const; - SYMBOL_TREE_SYNCHRONIZING_ADAPTER* getAdapter() - { - return static_cast( m_adapter.get() ); - } - ///< Class to store a working copy of a LIB_SYMBOL object and editor context. class SYMBOL_BUFFER { @@ -423,11 +409,8 @@ private: ///< The library buffers std::map m_libs; - SYMBOL_EDIT_FRAME& m_frame; ///< Parent frame + SCH_BASE_FRAME& m_frame; ///< Parent frame LIB_LOGGER* m_logger; - int m_syncHash; ///< Symbol lib table hash value from last synchronization - - wxObjectDataPtr m_adapter; }; #endif /* SYMBOL_LIBRARY_MANAGER_H */ diff --git a/eeschema/symbol_tree_synchronizing_adapter.cpp b/eeschema/symbol_tree_synchronizing_adapter.cpp index ba1701de55..27288ffe43 100644 --- a/eeschema/symbol_tree_synchronizing_adapter.cpp +++ b/eeschema/symbol_tree_synchronizing_adapter.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -252,7 +252,7 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::GetValue( wxVariant& aVariant, wxDataVie } else if( node->m_Type == LIB_TREE_NODE::LIB ) { - SYMBOL_LIBRARY_MANAGER& libMgr = m_frame->GetLibManager(); + LIB_SYMBOL_LIBRARY_MANAGER& libMgr = m_frame->GetLibManager(); SYMBOL_LIB_TABLE_ROW* lib = libMgr.GetLibrary( node->m_LibId.GetLibNickname() ); if( lib ) diff --git a/eeschema/tools/ee_actions.cpp b/eeschema/tools/ee_actions.cpp index 2ab43e86ca..1213d526f9 100644 --- a/eeschema/tools/ee_actions.cpp +++ b/eeschema/tools/ee_actions.cpp @@ -676,6 +676,20 @@ TOOL_ACTION EE_ACTIONS::generateBOM( "eeschema.EditorControl.generateBOM", _( "Generate BOM..." ), _( "Generate a bill of materials for the current schematic" ), BITMAPS::post_bom ); +TOOL_ACTION EE_ACTIONS::exportSymbolsToLibrary( "eeschema.EditorControl.exportSymbolsToLibrary", + AS_GLOBAL, 0, "", + _( "Export Symbols to Library..." ), + _( "Add symbols used in schematic to an existing symbol library\n" + "(does not remove other symbols from this library)" ), + BITMAPS::library_archive ); + +TOOL_ACTION EE_ACTIONS::exportSymbolsToNewLibrary( "eeschema.EditorControl.exportSymbolsToNewLibrary", + AS_GLOBAL, 0, "", + _( "Export Symbols to New Library..." ), + _( "Create a new symbol library using the symbols used in the schematic\n" + "(if the library already exists it will be replaced)" ), + BITMAPS::library_archive_as ); + TOOL_ACTION EE_ACTIONS::selectOnPCB( "eeschema.EditorControl.selectOnPCB", AS_GLOBAL, 0, "", _( "Select on PCB" ), diff --git a/eeschema/tools/ee_actions.h b/eeschema/tools/ee_actions.h index cb1f9ca6fc..9cc5da381e 100644 --- a/eeschema/tools/ee_actions.h +++ b/eeschema/tools/ee_actions.h @@ -177,6 +177,8 @@ public: static TOOL_ACTION exportNetlist; static TOOL_ACTION generateBOM; static TOOL_ACTION addSymbolToSchematic; + static TOOL_ACTION exportSymbolsToLibrary; + static TOOL_ACTION exportSymbolsToNewLibrary; // Library management static TOOL_ACTION saveLibraryAs; diff --git a/eeschema/tools/sch_editor_control.cpp b/eeschema/tools/sch_editor_control.cpp index 2da394ca4b..5e9cbb3aff 100644 --- a/eeschema/tools/sch_editor_control.cpp +++ b/eeschema/tools/sch_editor_control.cpp @@ -33,11 +33,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -51,6 +53,7 @@ #include #include #include +#include "symbol_library_manager.h" #include #include #include @@ -743,6 +746,106 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF } +int SCH_EDITOR_CONTROL::ExportSymbolsToLibrary( const TOOL_EVENT& aEvent ) +{ + bool createNew = aEvent.IsAction( &EE_ACTIONS::exportSymbolsToNewLibrary ); + + SCH_REFERENCE_LIST symbols; + m_frame->Schematic().GetSheets().GetSymbols( symbols, false ); + + std::map libSymbols; + std::map> symbolMap; + + for( size_t i = 0; i < symbols.GetCount(); ++i ) + { + SCH_SYMBOL* symbol = symbols[i].GetSymbol(); + LIB_SYMBOL* libSymbol = symbol->GetLibSymbolRef().get(); + LIB_ID id = libSymbol->GetLibId(); + + if( libSymbols.count( id ) ) + { + wxASSERT_MSG( libSymbols[id]->Compare( *libSymbol, LIB_ITEM::COMPARE_FLAGS::ERC ) == 0, + "Two symbols have the same LIB_ID but are different!" ); + } + else + { + libSymbols[id] = libSymbol; + } + + symbolMap[id].emplace_back( symbol ); + } + + SYMBOL_LIBRARY_MANAGER mgr( *m_frame ); + + wxString targetLib; + + if( createNew ) + { + wxFileName fn; + SYMBOL_LIB_TABLE* libTable = m_frame->SelectSymLibTable(); + + if( !m_frame->LibraryFileBrowser( false, fn, KiCadSymbolLibFileWildcard(), + KiCadSymbolLibFileExtension, false, + ( libTable == &SYMBOL_LIB_TABLE::GetGlobalLibTable() ), + PATHS::GetDefaultUserSymbolsPath() ) ) + { + return 0; + } + + targetLib = fn.GetName(); + + if( libTable->HasLibrary( targetLib, false ) ) + { + DisplayError( m_frame, wxString::Format( _( "Library '%s' already exists." ), + targetLib ) ); + return 0; + } + + if( !mgr.CreateLibrary( fn.GetFullPath(), libTable ) ) + { + DisplayError( m_frame, wxString::Format( _( "Could not add library '%s'." ), + targetLib ) ); + return 0; + } + } + else + { + targetLib = m_frame->SelectLibraryFromList(); + } + + if( targetLib.IsEmpty() ) + return 0; + + bool map = IsOK( m_frame, _( "Update symbols in schematic to refer to new library?" ) ); + + SYMBOL_LIB_TABLE_ROW* row = mgr.GetLibrary( targetLib ); + SCH_IO_MGR::SCH_FILE_T type = SCH_IO_MGR::EnumFromStr( row->GetType() ); + SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( type ) ); + + wxFileName dest = row->GetFullURI( true ); + dest.Normalize( FN_NORMALIZE_FLAGS | wxPATH_NORM_ENV_VARS ); + + for( const std::pair& it : libSymbols ) + { + LIB_SYMBOL* origSym = it.second; + LIB_SYMBOL* newSym = origSym->Flatten().release(); + + pi->SaveSymbol( dest.GetFullPath(), newSym ); + + if( map ) + { + LIB_ID id = it.first; + id.SetLibNickname( targetLib ); + + for( SCH_SYMBOL* symbol : symbolMap[it.first] ) + symbol->SetLibId( id ); + } + } + + return 0; +} + + #ifdef KICAD_SPICE #define HITTEST_THRESHOLD_PIXELS 5 @@ -2475,4 +2578,7 @@ void SCH_EDITOR_CONTROL::setTransitions() Go( &SCH_EDITOR_CONTROL::TogglePythonConsole, EE_ACTIONS::showPythonConsole.MakeEvent() ); Go( &SCH_EDITOR_CONTROL::RepairSchematic, EE_ACTIONS::repairSchematic.MakeEvent() ); + + Go( &SCH_EDITOR_CONTROL::ExportSymbolsToLibrary, EE_ACTIONS::exportSymbolsToLibrary.MakeEvent() ); + Go( &SCH_EDITOR_CONTROL::ExportSymbolsToLibrary, EE_ACTIONS::exportSymbolsToNewLibrary.MakeEvent() ); } diff --git a/eeschema/tools/sch_editor_control.h b/eeschema/tools/sch_editor_control.h index 49a240542e..5fbca30bd0 100644 --- a/eeschema/tools/sch_editor_control.h +++ b/eeschema/tools/sch_editor_control.h @@ -90,6 +90,8 @@ public: ///< Equivalent to the above, but initiated by the user. int ExplicitCrossProbeToPcb( const TOOL_EVENT& aEvent ); + int ExportSymbolsToLibrary( const TOOL_EVENT& aEvent ); + #ifdef KICAD_SPICE int SimProbe( const TOOL_EVENT& aEvent ); int SimTune( const TOOL_EVENT& aEvent ); diff --git a/eeschema/tools/symbol_editor_control.cpp b/eeschema/tools/symbol_editor_control.cpp index 4d19c7e10f..5a394d25fe 100644 --- a/eeschema/tools/symbol_editor_control.cpp +++ b/eeschema/tools/symbol_editor_control.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -314,8 +314,8 @@ int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent ) { if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) ) { - SYMBOL_EDIT_FRAME* editFrame = static_cast( m_frame ); - SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager(); + SYMBOL_EDIT_FRAME* editFrame = static_cast( m_frame ); + LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager(); LIB_ID libId = editFrame->GetTreeLIBID(); wxString libName = libId.GetLibNickname(); diff --git a/eeschema/widgets/symbol_tree_pane.cpp b/eeschema/widgets/symbol_tree_pane.cpp index a500ce5f91..873225e309 100644 --- a/eeschema/widgets/symbol_tree_pane.cpp +++ b/eeschema/widgets/symbol_tree_pane.cpp @@ -25,13 +25,14 @@ #include "symbol_tree_pane.h" #include -#include +#include #include #include #include #include -SYMBOL_TREE_PANE::SYMBOL_TREE_PANE( SYMBOL_EDIT_FRAME* aParent, SYMBOL_LIBRARY_MANAGER* aLibMgr ) +SYMBOL_TREE_PANE::SYMBOL_TREE_PANE( SYMBOL_EDIT_FRAME* aParent, + LIB_SYMBOL_LIBRARY_MANAGER* aLibMgr ) : wxPanel( aParent ), m_symbolEditFrame( aParent ), m_tree( nullptr ), diff --git a/eeschema/widgets/symbol_tree_pane.h b/eeschema/widgets/symbol_tree_pane.h index 00dbf3674f..876865e58f 100644 --- a/eeschema/widgets/symbol_tree_pane.h +++ b/eeschema/widgets/symbol_tree_pane.h @@ -32,7 +32,7 @@ class LIB_TREE; class SYMBOL_EDIT_FRAME; -class SYMBOL_LIBRARY_MANAGER; +class LIB_SYMBOL_LIBRARY_MANAGER; class wxBoxSizer; /** @@ -41,7 +41,7 @@ class wxBoxSizer; class SYMBOL_TREE_PANE : public wxPanel { public: - SYMBOL_TREE_PANE( SYMBOL_EDIT_FRAME* aParent, SYMBOL_LIBRARY_MANAGER* aLibMgr ); + SYMBOL_TREE_PANE( SYMBOL_EDIT_FRAME* aParent, LIB_SYMBOL_LIBRARY_MANAGER* aLibMgr ); ~SYMBOL_TREE_PANE(); LIB_TREE* GetLibTree() const @@ -53,9 +53,9 @@ protected: void onSymbolSelected( wxCommandEvent& aEvent ); void onUpdateUI( wxUpdateUIEvent& aEvent ); - SYMBOL_EDIT_FRAME* m_symbolEditFrame; - LIB_TREE* m_tree; ///< symbol search tree widget - SYMBOL_LIBRARY_MANAGER* m_libMgr; + SYMBOL_EDIT_FRAME* m_symbolEditFrame; + LIB_TREE* m_tree; ///< symbol search tree widget + LIB_SYMBOL_LIBRARY_MANAGER* m_libMgr; }; #endif /* SYM_TREE_PANE_H */