ADDED: Export symbols from schematic to library

Fixes https://gitlab.com/kicad/code/kicad/-/issues/11433
This commit is contained in:
Jon Evans 2022-09-15 23:06:23 -04:00
parent b8ef9ec178
commit 2089374f53
23 changed files with 423 additions and 210 deletions

View File

@ -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

View File

@ -26,7 +26,7 @@
#include <dialogs/dialog_text_entry.h>
#include <kiway.h>
#include <symbol_edit_frame.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <math/util.h> // for KiROUND
#include <sch_symbol.h>
#include <kiplatform/ui.h>

View File

@ -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();

View File

@ -24,8 +24,11 @@
#include <base_units.h>
#include <kiway.h>
#include <lib_tree_model_adapter.h>
#include <pgm_base.h>
#include <eda_list_dialog.h>
#include <eeschema_settings.h>
#include <project/project_file.h>
#include <symbol_editor/symbol_editor_settings.h>
#include <sch_draw_panel.h>
#include <sch_view.h>
@ -41,6 +44,7 @@
#include <tool/tool_dispatcher.h>
#include <tools/ee_actions.h>
#include <tools/ee_selection_tool.h>
#include <wx/choicdlg.h>
#if defined( KICAD_USE_3DCONNEXION )
#include <navlib/nl_schematic_plugin.h>
@ -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;
}

View File

@ -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;

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <lib_logger.h>
#include <lib_symbol_library_manager.h>
#include <symbol_edit_frame.h>
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<void( int, int,
const wxString& )> aProgressCallback )
{
m_logger->Activate();
{
getAdapter()->Sync( aForceRefresh, aProgressCallback );
m_syncHash = symTable()->GetModifyHash();
}
m_logger->Deactivate();
}
void LIB_SYMBOL_LIBRARY_MANAGER::OnDataChanged() const
{
static_cast<SYMBOL_EDIT_FRAME&>( m_frame ).SyncLibraries( false );
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_LIB_SYMBOL_LIBRARY_MANAGER_H
#define KICAD_LIB_SYMBOL_LIBRARY_MANAGER_H
#include <symbol_library_manager.h>
#include <symbol_tree_synchronizing_adapter.h>
/**
* 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<void( int, int, const wxString& )> aProgressCallback );
/**
* Return the adapter object that provides the stored data.
*/
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER>& GetAdapter() { return m_adapter; }
protected:
void OnDataChanged() const override;
private:
SYMBOL_TREE_SYNCHRONIZING_ADAPTER* getAdapter()
{
return static_cast<SYMBOL_TREE_SYNCHRONIZING_ADAPTER*>( m_adapter.get() );
}
wxObjectDataPtr<LIB_TREE_MODEL_ADAPTER> m_adapter;
int m_syncHash; ///< Symbol lib table hash value from last synchronization
};
#endif

View File

@ -36,7 +36,7 @@
#include <kiplatform/app.h>
#include <kiway_express.h>
#include <symbol_edit_frame.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <lib_text.h>
#include <symbol_editor_settings.h>
#include <paths.h>
@ -71,7 +71,6 @@
#include <widgets/symbol_tree_pane.h>
#include <wildcards_and_files_ext.h>
#include <panel_sym_lib_table.h>
#include <wx/choicdlg.h>
#include <string_utils.h>
@ -129,7 +128,7 @@ SYMBOL_EDIT_FRAME::SYMBOL_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_settings = Pgm().GetSettingsManager().GetAppSettings<SYMBOL_EDITOR_SETTINGS>();
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() )

View File

@ -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;

View File

@ -34,7 +34,7 @@
#include <template_fieldnames.h>
#include <wildcards_and_files_ext.h>
#include <symbol_lib_table.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <symbol_tree_pane.h>
#include <project/project_file.h>
#include <widgets/lib_tree.h>
@ -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() )

View File

@ -28,7 +28,7 @@
#include <symbol_edit_frame.h>
#include <symbol_library.h>
#include <wildcards_and_files_ext.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <wx/filename.h>
#include <wx/filedlg.h>
#include <string_utils.h>
@ -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 )
{

View File

@ -23,7 +23,7 @@
*/
#include <symbol_edit_frame.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <widgets/lib_tree.h>
#include <symbol_tree_pane.h>
#include <tool/tool_manager.h>

View File

@ -26,6 +26,8 @@
class LIB_SYMBOL;
class SCH_BASE_FRAME;
class SYMBOL_LIB_TABLE;
enum class SCH_LIB_TYPE

View File

@ -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<void( int, int,
const wxString& )> 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;
}

View File

@ -33,7 +33,6 @@
#include <set>
#include <memory>
#include <wx/arrstr.h>
#include <symbol_tree_synchronizing_adapter.h>
#include <sch_io_mgr.h>
#include <sch_screen.h>
@ -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<void( int, int, const wxString& )> 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<LIB_TREE_MODEL_ADAPTER>& 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<SYMBOL_TREE_SYNCHRONIZING_ADAPTER*>( 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<wxString, LIB_BUFFER> 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<LIB_TREE_MODEL_ADAPTER> m_adapter;
};
#endif /* SYMBOL_LIBRARY_MANAGER_H */

View File

@ -26,7 +26,7 @@
#include <pgm_base.h>
#include <project/project_file.h>
#include <symbol_tree_synchronizing_adapter.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <symbol_lib_table.h>
#include <tools/symbol_editor_control.h>
#include <string_utils.h>
@ -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 )

View File

@ -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" ),

View File

@ -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;

View File

@ -33,11 +33,13 @@
#include <dialogs/dialog_assign_netclass.h>
#include <project_rescue.h>
#include <erc.h>
#include <fmt.h>
#include <invoke_sch_dialog.h>
#include <string_utils.h>
#include <kiway.h>
#include <kiway_player.h>
#include <netlist_exporters/netlist_exporter_spice.h>
#include <paths.h>
#include <project/project_file.h>
#include <project/net_settings.h>
#include <sch_edit_frame.h>
@ -51,6 +53,7 @@
#include <advanced_config.h>
#include <sim/sim_plot_frame.h>
#include <sim/spice_generator.h>
#include "symbol_library_manager.h"
#include <symbol_viewer_frame.h>
#include <status_popup.h>
#include <tool/picker_tool.h>
@ -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<LIB_ID, LIB_SYMBOL*> libSymbols;
std::map<LIB_ID, std::vector<SCH_SYMBOL*>> 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<const LIB_ID, LIB_SYMBOL*>& 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() );
}

View File

@ -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 );

View File

@ -29,7 +29,7 @@
#include <tools/ee_actions.h>
#include <tools/symbol_editor_control.h>
#include <symbol_edit_frame.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <symbol_viewer_frame.h>
#include <symbol_tree_model_adapter.h>
#include <wildcards_and_files_ext.h>
@ -315,7 +315,7 @@ int SYMBOL_EDITOR_CONTROL::RenameSymbol( const TOOL_EVENT& aEvent )
if( m_frame->IsType( FRAME_SCH_SYMBOL_EDITOR ) )
{
SYMBOL_EDIT_FRAME* editFrame = static_cast<SYMBOL_EDIT_FRAME*>( m_frame );
SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
LIB_SYMBOL_LIBRARY_MANAGER& libMgr = editFrame->GetLibManager();
LIB_ID libId = editFrame->GetTreeLIBID();
wxString libName = libId.GetLibNickname();

View File

@ -25,13 +25,14 @@
#include "symbol_tree_pane.h"
#include <widgets/lib_tree.h>
#include <symbol_library_manager.h>
#include <lib_symbol_library_manager.h>
#include <symbol_edit_frame.h>
#include <symbol_lib_table.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
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 ),

View File

@ -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
@ -55,7 +55,7 @@ protected:
SYMBOL_EDIT_FRAME* m_symbolEditFrame;
LIB_TREE* m_tree; ///< symbol search tree widget
SYMBOL_LIBRARY_MANAGER* m_libMgr;
LIB_SYMBOL_LIBRARY_MANAGER* m_libMgr;
};
#endif /* SYM_TREE_PANE_H */