Library Manager: logic
This commit is contained in:
parent
769c6a8d51
commit
a789b735e9
|
@ -83,6 +83,7 @@ set( EESCHEMA_DLGS
|
||||||
)
|
)
|
||||||
|
|
||||||
set( EESCHEMA_WIDGETS
|
set( EESCHEMA_WIDGETS
|
||||||
|
widgets/cmp_tree_pane.cpp
|
||||||
widgets/component_tree.cpp
|
widgets/component_tree.cpp
|
||||||
widgets/widget_eeschema_color_config.cpp
|
widgets/widget_eeschema_color_config.cpp
|
||||||
widgets/pin_shape_combobox.cpp
|
widgets/pin_shape_combobox.cpp
|
||||||
|
@ -143,6 +144,8 @@ set( EESCHEMA_SRCS
|
||||||
lib_draw_item.cpp
|
lib_draw_item.cpp
|
||||||
lib_export.cpp
|
lib_export.cpp
|
||||||
lib_field.cpp
|
lib_field.cpp
|
||||||
|
lib_manager.cpp
|
||||||
|
lib_manager_adapter.cpp
|
||||||
lib_pin.cpp
|
lib_pin.cpp
|
||||||
lib_polyline.cpp
|
lib_polyline.cpp
|
||||||
lib_rectangle.cpp
|
lib_rectangle.cpp
|
||||||
|
|
|
@ -185,32 +185,22 @@ enum id_eeschema_frm
|
||||||
/* Library editor main menubar IDs. */
|
/* Library editor main menubar IDs. */
|
||||||
ID_LIBEDIT_DIMENSIONS,
|
ID_LIBEDIT_DIMENSIONS,
|
||||||
|
|
||||||
|
/* Library editor: library edit events */
|
||||||
|
ID_LIBEDIT_NEW_LIBRARY,
|
||||||
|
ID_LIBEDIT_ADD_LIBRARY,
|
||||||
|
ID_LIBEDIT_SAVE_LIBRARY,
|
||||||
|
ID_LIBEDIT_SAVE_LIBRARY_AS,
|
||||||
|
ID_LIBEDIT_SAVE_ALL_LIBS,
|
||||||
|
ID_LIBEDIT_REVERT_LIBRARY,
|
||||||
|
|
||||||
/* Library editor: part edit events */
|
/* Library editor: part edit events */
|
||||||
ID_LIBEDIT_NEW_PART,
|
ID_LIBEDIT_NEW_PART,
|
||||||
ID_LIBEDIT_EDIT_PART,
|
ID_LIBEDIT_EDIT_PART,
|
||||||
ID_LIBEDIT_IMPORT_PART,
|
ID_LIBEDIT_IMPORT_PART,
|
||||||
ID_LIBEDIT_EXPORT_PART,
|
ID_LIBEDIT_EXPORT_PART,
|
||||||
ID_LIBEDIT_SAVE_PART,
|
ID_LIBEDIT_SAVE_PART,
|
||||||
ID_LIBEDIT_SAVE_CURRENT_PART,
|
|
||||||
ID_LIBEDIT_REMOVE_PART,
|
|
||||||
ID_LIBEDIT_CUT_PART,
|
|
||||||
ID_LIBEDIT_COPY_PART,
|
|
||||||
ID_LIBEDIT_PASTE_PART,
|
|
||||||
ID_LIBEDIT_RENAME_PART,
|
|
||||||
ID_LIBEDIT_REVERT_PART,
|
ID_LIBEDIT_REVERT_PART,
|
||||||
ID_LIBEDIT_DELETE_PART,
|
ID_LIBEDIT_REMOVE_PART,
|
||||||
|
|
||||||
/* Library editor: library edit events */
|
|
||||||
|
|
||||||
ID_LIBEDIT_NEW_LIBRARY,
|
|
||||||
ID_LIBEDIT_ADD_LIBRARY,
|
|
||||||
ID_LIBEDIT_SAVE_LIBRARY,
|
|
||||||
ID_LIBEDIT_SAVE_LIBRARY_AS,
|
|
||||||
ID_LIBEDIT_SAVE_CURRENT_LIB, // TODO merge with save_library?
|
|
||||||
ID_LIBEDIT_SAVE_CURRENT_LIB_AS,
|
|
||||||
ID_LIBEDIT_SAVE_ALL_LIBS,
|
|
||||||
ID_LIBEDIT_REVERT_LIBRARY,
|
|
||||||
ID_LIBEDIT_REMOVE_LIBRARY,
|
|
||||||
|
|
||||||
/* Library editor horizontal toolbar IDs. */
|
/* Library editor horizontal toolbar IDs. */
|
||||||
ID_DE_MORGAN_NORMAL_BUTT,
|
ID_DE_MORGAN_NORMAL_BUTT,
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include <class_library.h>
|
#include <class_library.h>
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
#include <eeschema_id.h>
|
#include <eeschema_id.h>
|
||||||
|
#include <lib_manager.h>
|
||||||
|
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
m_lastDrawItem = NULL;
|
m_lastDrawItem = NULL;
|
||||||
|
wxString libName = getTargetLib();
|
||||||
|
|
||||||
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath,
|
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath,
|
||||||
wxEmptyString, SchematicLibraryFileWildcard(),
|
wxEmptyString, SchematicLibraryFileWildcard(),
|
||||||
|
@ -55,12 +57,12 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wxFileName fn = dlg.GetPath();
|
wxFileName fn = dlg.GetPath();
|
||||||
|
|
||||||
m_mruPath = fn.GetPath();
|
m_mruPath = fn.GetPath();
|
||||||
|
|
||||||
wxArrayString symbols;
|
wxArrayString symbols;
|
||||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||||
|
|
||||||
|
// TODO dialog to select the part to be imported if there is more than one
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pi->EnumerateSymbolLib( symbols, fn.GetFullPath() );
|
pi->EnumerateSymbolLib( symbols, fn.GetFullPath() );
|
||||||
|
@ -79,25 +81,25 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbols[0] );
|
wxString symbolName = symbols[0];
|
||||||
|
LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbolName );
|
||||||
|
|
||||||
if( LoadOneLibraryPartAux( entry, fn.GetFullPath() ) )
|
if( m_libMgr->PartExists( symbols[0], libName ) )
|
||||||
{
|
{
|
||||||
DisplayLibInfos();
|
msg.Printf( _( "Symbol '%s' already exists in library '%s'." ), symbolName, libName );
|
||||||
GetScreen()->ClearUndoRedoList();
|
DisplayError( this, msg );
|
||||||
Zoom_Automatique( false );
|
return;
|
||||||
|
|
||||||
// This effectively adds a new symbol to the library. Set the modified flag so the
|
|
||||||
// save library toolbar button and menu entry are enabled.
|
|
||||||
OnModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_libMgr->UpdatePart( entry->GetPart(), libName );
|
||||||
|
loadPart( symbolName, libName, 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
wxString msg, title;
|
wxString msg, title;
|
||||||
LIB_PART* part = GetCurPart();
|
LIB_PART* part = getTargetPart();
|
||||||
|
|
||||||
if( !part )
|
if( !part )
|
||||||
{
|
{
|
||||||
|
@ -173,12 +175,6 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mruPath = fn.GetPath();
|
m_mruPath = fn.GetPath();
|
||||||
|
|
||||||
/// @todo Give the user a choice to add the new library to the symbol library table.
|
|
||||||
DisplayInfoMessage( this, _( "This library will not be available until it is added to the "
|
|
||||||
"symbol library table." ) );
|
|
||||||
|
|
||||||
GetScreen()->ClrModify();
|
|
||||||
m_drawItem = m_lastDrawItem = NULL;
|
m_drawItem = m_lastDrawItem = NULL;
|
||||||
|
|
||||||
msg.Printf( _( "Symbol '%s' saved in library '%s'" ), part->GetName(), fn.GetFullPath() );
|
msg.Printf( _( "Symbol '%s' saved in library '%s'" ), part->GetName(), fn.GetFullPath() );
|
||||||
|
|
|
@ -0,0 +1,658 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lib_manager.h>
|
||||||
|
#include <class_libentry.h>
|
||||||
|
#include <class_library.h>
|
||||||
|
#include <libeditframe.h>
|
||||||
|
|
||||||
|
#include <kiway.h>
|
||||||
|
#include <profile.h>
|
||||||
|
#include <symbol_lib_table.h>
|
||||||
|
#include <sch_legacy_plugin.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MANAGER::LIB_MANAGER( LIB_EDIT_FRAME& aFrame )
|
||||||
|
: m_frame( aFrame ), m_symbolTable( aFrame.Prj().SchSymbolLibTable() )
|
||||||
|
{
|
||||||
|
m_adapter = LIB_MANAGER_ADAPTER::Create( this );
|
||||||
|
m_adapter->ShowUnits( true );
|
||||||
|
Sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER::Sync()
|
||||||
|
{
|
||||||
|
// TODO handle renaming libraries in the sym-lib-table dialog
|
||||||
|
// TODO using filepath as the key?
|
||||||
|
// TODO should not be compared with symboltable, but between the adapter and manager
|
||||||
|
// TODO move to treepane?
|
||||||
|
getAdapter()->Sync();
|
||||||
|
|
||||||
|
//int libTableHash = m_symbolTable->GetModifyHash();
|
||||||
|
|
||||||
|
//if( m_syncHash != libTableHash )
|
||||||
|
//{
|
||||||
|
//getAdapter()->Sync();
|
||||||
|
//m_syncHash = libTableHash;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_MANAGER::GetHash() const
|
||||||
|
{
|
||||||
|
int hash = m_symbolTable->GetModifyHash();
|
||||||
|
|
||||||
|
for( const auto& libBuf : m_libs )
|
||||||
|
hash += libBuf.second.GetHash();
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int LIB_MANAGER::GetLibraryHash( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
const auto libBufIt = m_libs.find( aLibrary );
|
||||||
|
return libBufIt != m_libs.end() ? libBufIt->second.GetHash() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxArrayString LIB_MANAGER::GetLibraryNames() const
|
||||||
|
{
|
||||||
|
wxArrayString res;
|
||||||
|
|
||||||
|
for( const auto& libName : m_symbolTable->GetLogicalLibs() )
|
||||||
|
res.Add( libName );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::FlushAll()
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
|
||||||
|
for( auto& libBuf : m_libs )
|
||||||
|
result &= FlushLibrary( libBuf.first );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::FlushLibrary( const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it == m_libs.end() ) // no changes to flush
|
||||||
|
return true;
|
||||||
|
|
||||||
|
LIB_BUFFER& libBuf = it->second;
|
||||||
|
wxArrayString aliases;
|
||||||
|
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
|
||||||
|
|
||||||
|
// TODO probably this could be implemented more efficiently
|
||||||
|
for( const auto& alias : aliases )
|
||||||
|
m_symbolTable->DeleteAlias( aLibrary, alias );
|
||||||
|
|
||||||
|
// Assume all libraries are successfully saved
|
||||||
|
bool res = true;
|
||||||
|
|
||||||
|
for( const auto& partBuf : libBuf.GetBuffers() )
|
||||||
|
{
|
||||||
|
if( !libBuf.SaveBuffer( partBuf, m_symbolTable ) )
|
||||||
|
{
|
||||||
|
// Something went wrong but try to save other libraries
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( res )
|
||||||
|
libBuf.ClearDeletedBuffer();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::IsLibraryModified( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), false );
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
return it != m_libs.end() ? it->second.IsModified() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::IsPartModified( const wxString& aAlias, const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), false );
|
||||||
|
auto libIt = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( libIt == m_libs.end() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const LIB_BUFFER& buf = libIt->second;
|
||||||
|
auto partBuf = buf.GetBuffer( aAlias );
|
||||||
|
return partBuf ? partBuf->IsModified() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), true );
|
||||||
|
wxFileName fn( m_symbolTable->GetFullURI( aLibrary ) );
|
||||||
|
return !fn.IsFileWritable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxArrayString LIB_MANAGER::GetAliasNames( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
wxArrayString names;
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), names );
|
||||||
|
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it == m_libs.end() )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_symbolTable->EnumerateSymbolLib( aLibrary, names );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR& e )
|
||||||
|
{
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
names = it->second.GetAliasNames();
|
||||||
|
}
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::list<LIB_ALIAS*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
std::list<LIB_ALIAS*> ret;
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), ret );
|
||||||
|
|
||||||
|
auto libIt = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( libIt != m_libs.end() )
|
||||||
|
{
|
||||||
|
for( auto& partBuf : libIt->second.GetBuffers() )
|
||||||
|
{
|
||||||
|
for( int i = 0; i < partBuf->GetPart()->GetAliasCount(); ++i )
|
||||||
|
ret.push_back( partBuf->GetPart()->GetAlias( i ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxArrayString symbols;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
m_symbolTable->EnumerateSymbolLib( aLibrary, symbols );
|
||||||
|
}
|
||||||
|
catch( IO_ERROR& e )
|
||||||
|
{
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( const auto& symbol : symbols )
|
||||||
|
ret.push_back( m_symbolTable->LoadSymbol( aLibrary, symbol ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_PART* LIB_MANAGER::GetBufferedPart( const wxString& aAlias, const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), nullptr );
|
||||||
|
|
||||||
|
// try the library buffers first
|
||||||
|
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
|
||||||
|
LIB_PART* bufferedPart = libBuf.GetPart( aAlias );
|
||||||
|
|
||||||
|
if( !bufferedPart ) // no buffer part found
|
||||||
|
{
|
||||||
|
// create a partCopy
|
||||||
|
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aAlias );
|
||||||
|
wxCHECK( alias, nullptr );
|
||||||
|
bufferedPart = new LIB_PART( *alias->GetPart(), nullptr );
|
||||||
|
libBuf.CreateBuffer( bufferedPart, new SCH_SCREEN( &m_frame.Kiway() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return bufferedPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SCH_SCREEN* LIB_MANAGER::GetScreen( const wxString& aAlias, const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), nullptr );
|
||||||
|
wxCHECK( !aAlias.IsEmpty(), nullptr );
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
wxCHECK( it != m_libs.end(), nullptr );
|
||||||
|
|
||||||
|
LIB_BUFFER& buf = it->second;
|
||||||
|
auto partBuf = buf.GetBuffer( aAlias );
|
||||||
|
return partBuf ? partBuf->GetScreen() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::UpdatePart( LIB_PART* aPart, const wxString& aLibrary, wxString aOldName )
|
||||||
|
{
|
||||||
|
wxCHECK( LibraryExists( aLibrary ), false );
|
||||||
|
wxCHECK( aPart, false );
|
||||||
|
const wxString partName = aOldName.IsEmpty() ? aPart->GetName() : aOldName;
|
||||||
|
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
|
||||||
|
auto partBuf = libBuf.GetBuffer( partName );
|
||||||
|
LIB_PART* partCopy = new LIB_PART( *aPart, nullptr );
|
||||||
|
|
||||||
|
if( partBuf )
|
||||||
|
{
|
||||||
|
libBuf.UpdateBuffer( partBuf, partCopy );
|
||||||
|
}
|
||||||
|
else // New entry
|
||||||
|
{
|
||||||
|
SCH_SCREEN* screen = new SCH_SCREEN( &m_frame.Kiway() );
|
||||||
|
libBuf.CreateBuffer( partCopy, screen );
|
||||||
|
screen->SetModify();
|
||||||
|
}
|
||||||
|
|
||||||
|
Sync(); // TODO update only the changed part
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::FlushPart( const wxString& aAlias, const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it == m_libs.end() ) // no items to flush
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto partBuf = it->second.GetBuffer( aAlias );
|
||||||
|
wxCHECK( partBuf, false );
|
||||||
|
|
||||||
|
return it->second.SaveBuffer( partBuf, m_symbolTable );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::RevertPart( const wxString& aAlias, const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it == m_libs.end() ) // no items to flush
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto partBuf = it->second.GetBuffer( aAlias );
|
||||||
|
wxCHECK( partBuf, false );
|
||||||
|
|
||||||
|
partBuf->GetScreen()->ClrModify();
|
||||||
|
partBuf->SetPart( new LIB_PART( *partBuf->GetOriginal() ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::RevertLibrary( const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it == m_libs.end() ) // nothing to reverse
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_libs.erase( it );
|
||||||
|
getAdapter()->UpdateLibrary( aLibrary );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::RemovePart( const wxString& aAlias, const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
|
||||||
|
auto partBuf = libBuf.GetBuffer( aAlias );
|
||||||
|
wxCHECK( partBuf, false );
|
||||||
|
|
||||||
|
bool res = libBuf.DeleteBuffer( partBuf );
|
||||||
|
getAdapter()->UpdateLibrary( aLibrary );
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_ALIAS* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
// Try the library buffers first
|
||||||
|
auto libIt = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( libIt != m_libs.end() )
|
||||||
|
{
|
||||||
|
LIB_PART* part = libIt->second.GetPart( aAlias );
|
||||||
|
|
||||||
|
if( part )
|
||||||
|
return part->GetAlias( aAlias );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the original part
|
||||||
|
return m_symbolTable->LoadSymbol( aLibrary, aAlias );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::PartExists( const wxString& aAlias, const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
auto libBufIt = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( libBufIt != m_libs.end() )
|
||||||
|
return !!libBufIt->second.GetBuffer( aAlias );
|
||||||
|
|
||||||
|
return !!m_symbolTable->LoadSymbol( aLibrary, aAlias );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LibraryExists( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
if( m_libs.count( aLibrary ) > 0 )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return m_symbolTable->HasLibrary( aLibrary );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString LIB_MANAGER::ValidateName( const wxString& aName )
|
||||||
|
{
|
||||||
|
wxString name( aName );
|
||||||
|
name.Replace( " ", "_" );
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString LIB_MANAGER::GetUniqueLibraryName() const
|
||||||
|
{
|
||||||
|
wxString name = "New_Library";
|
||||||
|
|
||||||
|
if( !LibraryExists( name ) )
|
||||||
|
return name;
|
||||||
|
|
||||||
|
name += "_";
|
||||||
|
|
||||||
|
for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
|
||||||
|
{
|
||||||
|
if( !LibraryExists( name + wxString::Format( "%u", i ) ) )
|
||||||
|
return name + wxString::Format( "%u", i );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFAIL;
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString LIB_MANAGER::GetUniqueComponentName( const wxString& aLibrary ) const
|
||||||
|
{
|
||||||
|
wxString name = "New_Component";
|
||||||
|
|
||||||
|
if( !PartExists( name, aLibrary ) )
|
||||||
|
return name;
|
||||||
|
|
||||||
|
name += "_";
|
||||||
|
|
||||||
|
for( unsigned int i = 0; i < std::numeric_limits<unsigned int>::max(); ++i )
|
||||||
|
{
|
||||||
|
if( !PartExists( name + wxString::Format( "%u", i ), aLibrary ) )
|
||||||
|
return name + wxString::Format( "%u", i );
|
||||||
|
}
|
||||||
|
|
||||||
|
wxFAIL;
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString LIB_MANAGER::getLibraryName( const wxString& aFilePath )
|
||||||
|
{
|
||||||
|
wxFileName fn( aFilePath );
|
||||||
|
return fn.GetName();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::addLibrary( const wxString& aFilePath, bool aCreate )
|
||||||
|
{
|
||||||
|
wxString libName = getLibraryName( aFilePath );
|
||||||
|
wxCHECK( !LibraryExists( libName ), false ); // either create or add an existing one
|
||||||
|
|
||||||
|
// Select the target library table (global/project)
|
||||||
|
SYMBOL_LIB_TABLE* libTable = m_frame.SelectSymLibTable();
|
||||||
|
wxCHECK( libTable, false );
|
||||||
|
|
||||||
|
SYMBOL_LIB_TABLE_ROW* libRow = new SYMBOL_LIB_TABLE_ROW( libName, aFilePath,
|
||||||
|
SCH_IO_MGR::ShowType( SCH_IO_MGR::SCH_LEGACY ) );
|
||||||
|
libTable->InsertRow( libRow );
|
||||||
|
|
||||||
|
if( aCreate )
|
||||||
|
libTable->CreateSymbolLib( libName );
|
||||||
|
|
||||||
|
getAdapter()->AddLibrary( libName );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary )
|
||||||
|
{
|
||||||
|
auto it = m_libs.find( aLibrary );
|
||||||
|
|
||||||
|
if( it != m_libs.end() )
|
||||||
|
return it->second;
|
||||||
|
|
||||||
|
wxArrayString aliases;
|
||||||
|
auto ret = m_libs.emplace( aLibrary, LIB_BUFFER( aLibrary ) );
|
||||||
|
LIB_BUFFER& buf = ret.first->second;
|
||||||
|
m_symbolTable->EnumerateSymbolLib( aLibrary, aliases );
|
||||||
|
// set collecting the processed LIB_PARTs
|
||||||
|
std::set<LIB_PART*> processed;
|
||||||
|
|
||||||
|
for( const auto& aliasName : aliases )
|
||||||
|
{
|
||||||
|
LIB_ALIAS* alias = m_symbolTable->LoadSymbol( aLibrary, aliasName );
|
||||||
|
LIB_PART* part = alias->GetPart();
|
||||||
|
|
||||||
|
if( !processed.count( part ) )
|
||||||
|
{
|
||||||
|
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
|
||||||
|
processed.insert( part );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MANAGER::PART_BUFFER::PART_BUFFER( LIB_PART* aPart, SCH_SCREEN* aScreen )
|
||||||
|
: m_screen( aScreen ), m_part( aPart )
|
||||||
|
{
|
||||||
|
m_original = new LIB_PART( *aPart );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MANAGER::PART_BUFFER::~PART_BUFFER()
|
||||||
|
{
|
||||||
|
delete m_screen;
|
||||||
|
delete m_part;
|
||||||
|
delete m_original;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER::PART_BUFFER::SetPart( LIB_PART* aPart )
|
||||||
|
{
|
||||||
|
wxCHECK( m_part != aPart, /* void */ );
|
||||||
|
wxASSERT( aPart );
|
||||||
|
delete m_part;
|
||||||
|
m_part = aPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER::PART_BUFFER::SetOriginal( LIB_PART* aPart )
|
||||||
|
{
|
||||||
|
wxCHECK( m_original != aPart, /* void */ );
|
||||||
|
wxASSERT( aPart );
|
||||||
|
delete m_original;
|
||||||
|
m_original = aPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::PART_BUFFER::IsModified() const
|
||||||
|
{
|
||||||
|
return m_screen && m_screen->IsModify();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxArrayString LIB_MANAGER::LIB_BUFFER::GetAliasNames() const
|
||||||
|
{
|
||||||
|
wxArrayString ret;
|
||||||
|
|
||||||
|
for( const auto& alias : m_aliases )
|
||||||
|
ret.push_back( alias.first );
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen )
|
||||||
|
{
|
||||||
|
wxASSERT( m_aliases.count( aCopy->GetName() ) == 0 ); // only for new parts
|
||||||
|
wxASSERT( aCopy->GetLib() == nullptr );
|
||||||
|
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, aScreen );
|
||||||
|
m_parts.push_back( partBuf );
|
||||||
|
addAliases( partBuf );
|
||||||
|
|
||||||
|
// Set the parent library name,
|
||||||
|
// otherwise it is empty as no library has been given as the owner during object construction
|
||||||
|
LIB_ID libId = aCopy->GetLibId();
|
||||||
|
libId.SetLibNickname( m_libName );
|
||||||
|
aCopy->SetLibId( libId );
|
||||||
|
++m_hash;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::UpdateBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf, LIB_PART* aCopy )
|
||||||
|
{
|
||||||
|
bool ret = true;
|
||||||
|
|
||||||
|
ret &= removeAliases( aPartBuf );
|
||||||
|
aPartBuf->SetPart( aCopy );
|
||||||
|
ret &= addAliases( aPartBuf );
|
||||||
|
++m_hash;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::DeleteBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf )
|
||||||
|
{
|
||||||
|
auto partBufIt = std::find( m_parts.begin(), m_parts.end(), aPartBuf );
|
||||||
|
wxCHECK( partBufIt != m_parts.end(), false );
|
||||||
|
m_deleted.emplace_back( *partBufIt );
|
||||||
|
m_parts.erase( partBufIt );
|
||||||
|
++m_hash;
|
||||||
|
|
||||||
|
return removeAliases( aPartBuf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf,
|
||||||
|
SYMBOL_LIB_TABLE* aLibTable )
|
||||||
|
{
|
||||||
|
wxCHECK( aPartBuf, false );
|
||||||
|
|
||||||
|
LIB_PART* part = aPartBuf->GetPart();
|
||||||
|
wxCHECK( part, false );
|
||||||
|
|
||||||
|
// TODO Enable buffering to avoid to disable too frequent file saves
|
||||||
|
//PROPERTIES properties;
|
||||||
|
//properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
|
||||||
|
|
||||||
|
if( aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) ) == SYMBOL_LIB_TABLE::SAVE_OK )
|
||||||
|
{
|
||||||
|
aPartBuf->GetScreen()->ClrModify();
|
||||||
|
aPartBuf->SetOriginal( new LIB_PART( *part ) );
|
||||||
|
++m_hash;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::addAliases( PART_BUFFER::PTR aPartBuf )
|
||||||
|
{
|
||||||
|
LIB_PART* part = aPartBuf->GetPart();
|
||||||
|
wxCHECK( part, false );
|
||||||
|
bool ret = true; // Assume everything is ok
|
||||||
|
|
||||||
|
for( int i = 0; i < part->GetAliasCount(); ++i )
|
||||||
|
{
|
||||||
|
bool newAlias;
|
||||||
|
std::tie( std::ignore, newAlias ) = m_aliases.emplace( part->GetAlias( i )->GetName(), aPartBuf );
|
||||||
|
|
||||||
|
if( !newAlias ) // Overwrite check
|
||||||
|
{
|
||||||
|
wxFAIL;
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER::LIB_BUFFER::removeAliases( PART_BUFFER::PTR aPartBuf )
|
||||||
|
{
|
||||||
|
LIB_PART* part = aPartBuf->GetPart();
|
||||||
|
wxCHECK( part, false );
|
||||||
|
bool ret = true; // Assume everything is ok
|
||||||
|
|
||||||
|
for( int i = 0; i < part->GetAliasCount(); ++i )
|
||||||
|
{
|
||||||
|
auto aliasIt = m_aliases.find( part->GetAlias( i )->GetName() );
|
||||||
|
|
||||||
|
if( aliasIt == m_aliases.end() )
|
||||||
|
{
|
||||||
|
wxFAIL;
|
||||||
|
ret = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Be sure the alias belongs to the assigned owner
|
||||||
|
wxASSERT( aliasIt->second.lock() == aPartBuf );
|
||||||
|
|
||||||
|
m_aliases.erase( aliasIt );
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,347 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIB_MANAGER_H
|
||||||
|
#define LIB_MANAGER_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <list>
|
||||||
|
#include <deque>
|
||||||
|
#include <set>
|
||||||
|
#include <memory>
|
||||||
|
#include <wx/arrstr.h>
|
||||||
|
#include <lib_manager_adapter.h>
|
||||||
|
|
||||||
|
class LIB_ALIAS;
|
||||||
|
class LIB_PART;
|
||||||
|
class LIB_BUFFER;
|
||||||
|
class PART_LIB;
|
||||||
|
class SCH_SCREEN;
|
||||||
|
class LIB_EDIT_FRAME;
|
||||||
|
class SYMBOL_LIB_TABLE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to handle modifications to the symbol libraries.
|
||||||
|
*/
|
||||||
|
class LIB_MANAGER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIB_MANAGER( LIB_EDIT_FRAME& aFrame );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the LIB_MANAGER data to account for the changes introduced to the project libraries.
|
||||||
|
* @see PROJECT::SchLibs()
|
||||||
|
*/
|
||||||
|
void Sync();
|
||||||
|
|
||||||
|
int GetHash() const;
|
||||||
|
|
||||||
|
int GetLibraryHash( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the array of library names.
|
||||||
|
*/
|
||||||
|
wxArrayString GetLibraryNames() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a set containing all part names for a specific library.
|
||||||
|
*/
|
||||||
|
wxArrayString GetAliasNames( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
std::list<LIB_ALIAS*> GetAliases( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an empty library and adds it to the library table. The library file is created.
|
||||||
|
*/
|
||||||
|
bool CreateLibrary( const wxString& aFilePath )
|
||||||
|
{
|
||||||
|
return addLibrary( aFilePath, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an existing library. The library is added to the library table as well.
|
||||||
|
*/
|
||||||
|
bool AddLibrary( const wxString& aFilePath )
|
||||||
|
{
|
||||||
|
return addLibrary( aFilePath, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the part buffer with a new version of the part.
|
||||||
|
* It is required to save the library to use the updated part in the schematic editor.
|
||||||
|
*/
|
||||||
|
bool UpdatePart( LIB_PART* aPart, const wxString& aLibrary, wxString aOldName = wxEmptyString );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the part from the part buffer.
|
||||||
|
* It is required to save the library to have the part removed in the schematic editor.
|
||||||
|
*/
|
||||||
|
bool RemovePart( const wxString& aName, const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns either an alias of a working LIB_PART copy, or alias of the original part if there
|
||||||
|
* is no working copy.
|
||||||
|
*/
|
||||||
|
LIB_ALIAS* GetAlias( const wxString& aAlias, const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the part copy from the buffer. In case it does not exist yet, the copy is created.
|
||||||
|
* LIB_MANAGER retains the ownership.
|
||||||
|
*/
|
||||||
|
LIB_PART* GetBufferedPart( const wxString& aAlias, const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the screen used to edit a specific part. LIB_MANAGER retains the ownership.
|
||||||
|
*/
|
||||||
|
SCH_SCREEN* GetScreen( const wxString& aAlias, const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if part with a specific alias exists in library (either original one or buffered).
|
||||||
|
*/
|
||||||
|
bool PartExists( const wxString& aAlias, const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if library exists.
|
||||||
|
*/
|
||||||
|
bool LibraryExists( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if library has unsaved modifications.
|
||||||
|
*/
|
||||||
|
bool IsLibraryModified( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if part has unsaved modifications.
|
||||||
|
*/
|
||||||
|
bool IsPartModified( const wxString& aAlias, const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the library is stored in a read-only file.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool IsLibraryReadOnly( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves part changes to the library copy used by the schematic editor. Not it is not
|
||||||
|
* necessarily saved to the file.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool FlushPart( const wxString& aAlias, const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves changes to the library copy used by the schematic editor. Note it is not
|
||||||
|
* necessarily saved to the file.
|
||||||
|
* @param aLibrary is the library name.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool FlushLibrary( const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves all changes to libraries.
|
||||||
|
* @return True if all changes have been flushed successfully, false otherwise.
|
||||||
|
*/
|
||||||
|
bool FlushAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts unsaved changes for a particular part.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool RevertPart( const wxString& aAlias, const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts unsaved changes for a particular library.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
|
*/
|
||||||
|
bool RevertLibrary( const wxString& aLibrary );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces all characters considered illegal in library/part names with underscores.
|
||||||
|
*/
|
||||||
|
static wxString ValidateName( const wxString& aName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a library name that is not currently in use.
|
||||||
|
* Used for generating names for new libraries.
|
||||||
|
*/
|
||||||
|
wxString GetUniqueLibraryName() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a component name that is not stored in a library.
|
||||||
|
* Used for generating names for new components.
|
||||||
|
*/
|
||||||
|
wxString GetUniqueComponentName( const wxString& aLibrary ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the adapter object that provides the stored data.
|
||||||
|
*/
|
||||||
|
CMP_TREE_MODEL_ADAPTER_BASE::PTR& GetAdapter() { return m_adapter; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
///> Parent frame
|
||||||
|
LIB_EDIT_FRAME& m_frame;
|
||||||
|
|
||||||
|
///> Extracts 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* m_symbolTable;
|
||||||
|
|
||||||
|
///> Class to store a working copy of a LIB_PART object and editor context.
|
||||||
|
class PART_BUFFER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PART_BUFFER( LIB_PART* aPart = nullptr, SCH_SCREEN* aScreen = nullptr );
|
||||||
|
~PART_BUFFER();
|
||||||
|
|
||||||
|
LIB_PART* GetPart() const { return m_part; }
|
||||||
|
void SetPart( LIB_PART* aPart );
|
||||||
|
|
||||||
|
LIB_PART* GetOriginal() const { return m_original; }
|
||||||
|
void SetOriginal( LIB_PART* aPart );
|
||||||
|
|
||||||
|
bool IsModified() const;
|
||||||
|
SCH_SCREEN* GetScreen() const { return m_screen; }
|
||||||
|
|
||||||
|
typedef std::shared_ptr<PART_BUFFER> PTR;
|
||||||
|
typedef std::weak_ptr<PART_BUFFER> WEAK_PTR;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SCH_SCREEN* m_screen;
|
||||||
|
|
||||||
|
///> Working copy
|
||||||
|
LIB_PART* m_part;
|
||||||
|
|
||||||
|
///> Initial state of the part
|
||||||
|
LIB_PART* m_original;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///> Class to store a working copy of a library
|
||||||
|
class LIB_BUFFER
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LIB_BUFFER( const wxString& aLibrary )
|
||||||
|
: m_libName( aLibrary ), m_hash( 1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsModified() const
|
||||||
|
{
|
||||||
|
if( !m_deleted.empty() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for( const auto& partBuf : m_parts )
|
||||||
|
{
|
||||||
|
if( partBuf->IsModified() )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetHash() const
|
||||||
|
{
|
||||||
|
return m_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Returns all alias names for stored parts
|
||||||
|
wxArrayString GetAliasNames() const;
|
||||||
|
|
||||||
|
///> Returns the working copy of a LIB_PART object with specified alias
|
||||||
|
LIB_PART* GetPart( const wxString& aAlias ) const
|
||||||
|
{
|
||||||
|
auto buf = GetBuffer( aAlias );
|
||||||
|
return buf ? buf->GetPart() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Creates a new buffer to store a part. LIB_BUFFER takes ownership of aCopy.
|
||||||
|
bool CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen );
|
||||||
|
|
||||||
|
///> Updates the stored part. LIB_BUFFER takes ownership of aCopy.
|
||||||
|
bool UpdateBuffer( PART_BUFFER::PTR aPartBuf, LIB_PART* aCopy );
|
||||||
|
|
||||||
|
bool DeleteBuffer( PART_BUFFER::PTR aPartBuf );
|
||||||
|
|
||||||
|
void ClearDeletedBuffer()
|
||||||
|
{
|
||||||
|
m_deleted.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Saves stored modifications to a Symbol Library Table
|
||||||
|
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SYMBOL_LIB_TABLE* aLibTable );
|
||||||
|
|
||||||
|
///> Returns a part buffer with LIB_PART holding a particular alias
|
||||||
|
PART_BUFFER::PTR GetBuffer( const wxString& aAlias ) const
|
||||||
|
{
|
||||||
|
auto it = m_aliases.find( aAlias );
|
||||||
|
return it != m_aliases.end() ? it->second.lock() : PART_BUFFER::PTR( nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Returns all buffered parts
|
||||||
|
const std::deque<PART_BUFFER::PTR>& GetBuffers() const
|
||||||
|
{
|
||||||
|
return m_parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Returns all aliases of buffered parts
|
||||||
|
const std::map<wxString, PART_BUFFER::WEAK_PTR>& GetAliases() const
|
||||||
|
{
|
||||||
|
return m_aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
///> Creates alias entries for a particular part buffer
|
||||||
|
bool addAliases( PART_BUFFER::PTR aPartBuf );
|
||||||
|
|
||||||
|
///> Removes alias entries for a particular part buffer
|
||||||
|
bool removeAliases( PART_BUFFER::PTR aPartBuf );
|
||||||
|
|
||||||
|
std::map<wxString, PART_BUFFER::WEAK_PTR> m_aliases;
|
||||||
|
std::deque<PART_BUFFER::PTR> m_parts;
|
||||||
|
|
||||||
|
///> Buffer to keep deleted parts until the library is saved
|
||||||
|
std::deque<PART_BUFFER::PTR> m_deleted;
|
||||||
|
|
||||||
|
/// Buffered library name
|
||||||
|
const wxString m_libName;
|
||||||
|
|
||||||
|
int m_hash;
|
||||||
|
|
||||||
|
friend class PART_BUFFER;
|
||||||
|
};
|
||||||
|
|
||||||
|
///> Returns an existing library buffer or creates one to using
|
||||||
|
///> Symbol Library Table to get the original data.
|
||||||
|
LIB_BUFFER& getLibraryBuffer( const wxString& aLibrary );
|
||||||
|
|
||||||
|
///> The library buffers
|
||||||
|
std::map<wxString, LIB_BUFFER> m_libs;
|
||||||
|
|
||||||
|
LIB_MANAGER_ADAPTER::PTR m_adapter;
|
||||||
|
LIB_MANAGER_ADAPTER* getAdapter() { return static_cast<LIB_MANAGER_ADAPTER*>( m_adapter.get() ); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIB_MANAGER_H */
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <lib_manager_adapter.h>
|
||||||
|
#include <lib_manager.h>
|
||||||
|
#include <class_libentry.h>
|
||||||
|
|
||||||
|
|
||||||
|
CMP_TREE_MODEL_ADAPTER_BASE::PTR LIB_MANAGER_ADAPTER::Create( LIB_MANAGER* aLibMgr )
|
||||||
|
{
|
||||||
|
auto adapter = new LIB_MANAGER_ADAPTER( aLibMgr );
|
||||||
|
auto container = CMP_TREE_MODEL_ADAPTER_BASE::PTR( adapter );
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::AddLibrary( const wxString& aLibNickname )
|
||||||
|
{
|
||||||
|
auto& lib_node = m_tree.AddLib( aLibNickname );
|
||||||
|
ItemAdded( wxDataViewItem( nullptr ), ToItem( &lib_node ) );
|
||||||
|
updateLibrary( lib_node );
|
||||||
|
lib_node.AssignIntrinsicRanks();
|
||||||
|
m_tree.AssignIntrinsicRanks();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::RemoveLibrary( const wxString& aLibNickname )
|
||||||
|
{
|
||||||
|
auto it = std::find_if( m_tree.Children.begin(), m_tree.Children.end(),
|
||||||
|
[&] ( std::unique_ptr<CMP_TREE_NODE>& node ) { return node->Name == aLibNickname; } );
|
||||||
|
|
||||||
|
if( it != m_tree.Children.end() )
|
||||||
|
{
|
||||||
|
ItemDeleted( wxDataViewItem( nullptr ), ToItem( it->get() ) );
|
||||||
|
m_tree.Children.erase( it );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::UpdateLibrary( const wxString& aLibraryName )
|
||||||
|
{
|
||||||
|
CMP_TREE_NODE* node = findLibrary( aLibraryName );
|
||||||
|
|
||||||
|
if( !node )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemChanged( ToItem( node ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::AddAliasList( const wxString& aNodeName,
|
||||||
|
const wxArrayString& aAliasNameList )
|
||||||
|
{
|
||||||
|
wxASSERT( false ); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER_ADAPTER::IsContainer( const wxDataViewItem& aItem ) const
|
||||||
|
{
|
||||||
|
const CMP_TREE_NODE* node = ToNode( aItem );
|
||||||
|
return node && node->Type == CMP_TREE_NODE::LIB;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::Sync()
|
||||||
|
{
|
||||||
|
if( getSyncHash() == m_libMgr->GetHash() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxDataViewItem root( nullptr );
|
||||||
|
|
||||||
|
// Process already stored libraries
|
||||||
|
for( auto it = m_tree.Children.begin(); it != m_tree.Children.end(); /* iteration inside */ )
|
||||||
|
{
|
||||||
|
int mgrHash = m_libMgr->GetLibraryHash( it->get()->Name );
|
||||||
|
|
||||||
|
if( mgrHash < 0 )
|
||||||
|
{
|
||||||
|
deleteLibrary( * (CMP_TREE_NODE_LIB*) it->get() );
|
||||||
|
it = m_tree.Children.erase( it );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if( mgrHash != m_libHashes[it->get()->Name] )
|
||||||
|
{
|
||||||
|
updateLibrary( * (CMP_TREE_NODE_LIB*) it->get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for new libraries
|
||||||
|
for( const auto& libName : m_libMgr->GetLibraryNames() )
|
||||||
|
{
|
||||||
|
if( m_libHashes.count( libName ) == 0 )
|
||||||
|
{
|
||||||
|
auto& libNode = m_tree.AddLib( libName ); // Use AddLibrary?
|
||||||
|
ItemAdded( root, ToItem( &libNode ) );
|
||||||
|
updateLibrary( libNode );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Resort();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::updateLibrary( CMP_TREE_NODE_LIB& aLibNode )
|
||||||
|
{
|
||||||
|
wxDataViewItem parent = ToItem( &aLibNode );
|
||||||
|
aLibNode.Children.clear();
|
||||||
|
|
||||||
|
for( auto alias : m_libMgr->GetAliases( aLibNode.Name ) )
|
||||||
|
{
|
||||||
|
auto& aliasNode = aLibNode.AddAlias( alias );
|
||||||
|
ItemAdded( parent, ToItem( &aliasNode ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO faster?
|
||||||
|
/*
|
||||||
|
wxDataViewItemArray aliasItems;
|
||||||
|
aliasItems.reserve( aLibNode.Children.size() );
|
||||||
|
|
||||||
|
for( const auto& child : aLibNode.Children )
|
||||||
|
aliasItems.Add( ToItem( child.get() ) );
|
||||||
|
|
||||||
|
ItemsAdded( parent, aliasItems );
|
||||||
|
*/
|
||||||
|
|
||||||
|
m_libHashes[aLibNode.Name] = m_libMgr->GetLibraryHash( aLibNode.Name );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_MANAGER_ADAPTER::deleteLibrary( CMP_TREE_NODE_LIB& aLibNode )
|
||||||
|
{
|
||||||
|
wxASSERT( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CMP_TREE_NODE* LIB_MANAGER_ADAPTER::findLibrary( const wxString& aLibNickName )
|
||||||
|
{
|
||||||
|
for( auto& lib : m_tree.Children )
|
||||||
|
{
|
||||||
|
if( lib->Name == aLibNickName )
|
||||||
|
return lib.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_MANAGER_ADAPTER::GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
|
||||||
|
wxDataViewItemAttr& aAttr ) const
|
||||||
|
{
|
||||||
|
// change attributes only for the name field
|
||||||
|
if( aCol != 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto node = ToNode( aItem );
|
||||||
|
wxCHECK( node, false );
|
||||||
|
|
||||||
|
switch( node->Type )
|
||||||
|
{
|
||||||
|
case CMP_TREE_NODE::LIB:
|
||||||
|
// mark modified libs with bold font
|
||||||
|
aAttr.SetBold( m_libMgr->IsLibraryModified( node->Name ) );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CMP_TREE_NODE::LIBID:
|
||||||
|
// mark modified part with bold font
|
||||||
|
aAttr.SetBold( m_libMgr->IsPartModified( node->Name, node->Parent->Name ) );
|
||||||
|
|
||||||
|
// mark aliases with italic font
|
||||||
|
aAttr.SetItalic( !node->IsRoot );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_MANAGER_ADAPTER::LIB_MANAGER_ADAPTER( LIB_MANAGER* aLibMgr )
|
||||||
|
: m_libMgr( aLibMgr )
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIB_MANAGER_ADAPTER_H
|
||||||
|
#define LIB_MANAGER_ADAPTER_H
|
||||||
|
|
||||||
|
#include <cmp_tree_model_adapter_base.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
class LIB_MANAGER;
|
||||||
|
|
||||||
|
class LIB_MANAGER_ADAPTER : public CMP_TREE_MODEL_ADAPTER_BASE
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static PTR Create( LIB_MANAGER* aLibs );
|
||||||
|
|
||||||
|
void AddLibrary( const wxString& aLibNickname ) override;
|
||||||
|
|
||||||
|
void RemoveLibrary( const wxString& aLibNickname );
|
||||||
|
|
||||||
|
void AddAliasList( const wxString& aNodeName, const wxArrayString& aAliasNameList ) override;
|
||||||
|
|
||||||
|
bool IsContainer( const wxDataViewItem& aItem ) const override;
|
||||||
|
|
||||||
|
void UpdateLibrary( const wxString& aLibraryName );
|
||||||
|
|
||||||
|
void Sync();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateLibrary( CMP_TREE_NODE_LIB& aLibNode );
|
||||||
|
|
||||||
|
void deleteLibrary( CMP_TREE_NODE_LIB& aLibNode );
|
||||||
|
|
||||||
|
CMP_TREE_NODE* findLibrary( const wxString& aLibNickName );
|
||||||
|
|
||||||
|
bool GetAttr( wxDataViewItem const& aItem, unsigned int aCol,
|
||||||
|
wxDataViewItemAttr& aAttr ) const override;
|
||||||
|
|
||||||
|
LIB_MANAGER_ADAPTER( LIB_MANAGER* aLibMgr );
|
||||||
|
|
||||||
|
LIB_MANAGER* m_libMgr;
|
||||||
|
|
||||||
|
// TODO? use hashes to determine whcih libraries to update?
|
||||||
|
std::map<wxString, int> m_libHashes;
|
||||||
|
|
||||||
|
int getSyncHash() const
|
||||||
|
{
|
||||||
|
int hash = 0;
|
||||||
|
|
||||||
|
for( const auto& h : m_libHashes )
|
||||||
|
hash += h.second;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* LIB_MANAGER_ADAPTER_H */
|
|
@ -46,6 +46,9 @@
|
||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
#include <schframe.h>
|
#include <schframe.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
|
#include <lib_manager.h>
|
||||||
|
#include <cmp_tree_pane.h>
|
||||||
|
#include <component_tree.h>
|
||||||
|
|
||||||
#include <dialog_choose_component.h>
|
#include <dialog_choose_component.h>
|
||||||
#include <cmp_tree_model_adapter.h>
|
#include <cmp_tree_model_adapter.h>
|
||||||
|
@ -201,25 +204,19 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString cmpName = m_aliasName = aEntry->GetName();
|
|
||||||
|
|
||||||
LIB_PART* lib_part = aEntry->GetPart();
|
|
||||||
|
|
||||||
wxASSERT( lib_part );
|
|
||||||
|
|
||||||
LIB_PART* part = new LIB_PART( *lib_part ); // clone it and own it.
|
|
||||||
SetCurPart( part );
|
|
||||||
m_aliasName = aEntry->GetName();
|
m_aliasName = aEntry->GetName();
|
||||||
|
|
||||||
|
LIB_PART* lib_part = m_libMgr->GetBufferedPart( m_aliasName, aLibrary );
|
||||||
|
wxASSERT( lib_part );
|
||||||
|
SetScreen( m_libMgr->GetScreen( lib_part->GetName(), aLibrary ) );
|
||||||
|
SetCurPart( new LIB_PART( *lib_part ) );
|
||||||
|
SetCurLib( aLibrary );
|
||||||
|
|
||||||
m_unit = 1;
|
m_unit = 1;
|
||||||
m_convert = 1;
|
m_convert = 1;
|
||||||
|
SetShowDeMorgan( GetCurPart()->HasConversion() );
|
||||||
|
|
||||||
m_showDeMorgan = false;
|
Zoom_Automatique( false );
|
||||||
|
|
||||||
if( part->HasConversion() )
|
|
||||||
m_showDeMorgan = true;
|
|
||||||
|
|
||||||
GetScreen()->ClrModify();
|
|
||||||
DisplayLibInfos();
|
DisplayLibInfos();
|
||||||
UpdateAliasSelectList();
|
UpdateAliasSelectList();
|
||||||
UpdatePartSelectList();
|
UpdatePartSelectList();
|
||||||
|
@ -282,13 +279,181 @@ void LIB_EDIT_FRAME::RedrawActiveWindow( wxDC* DC, bool EraseBg )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnSaveActiveLibrary( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnSaveLibrary( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
SaveActiveLibrary( event.GetId() == ID_LIBEDIT_SAVE_CURRENT_LIB_AS );
|
saveLibrary( getTargetLib(), event.GetId() == ID_LIBEDIT_SAVE_LIBRARY_AS );
|
||||||
|
m_treePane->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
void LIB_EDIT_FRAME::OnSaveAllLibraries( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
wxASSERT( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnRevertLibrary( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
wxString libName = getTargetLib();
|
||||||
|
bool currentLib = ( libName == GetCurLib() );
|
||||||
|
|
||||||
|
// Save the current part name/unit to reload after revert
|
||||||
|
wxString alias = m_aliasName;
|
||||||
|
int unit = m_unit;
|
||||||
|
|
||||||
|
if( !IsOK( this, _( "The revert operation cannot be undone!\n\nRevert changes?" ) ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( currentLib )
|
||||||
|
emptyScreen();
|
||||||
|
|
||||||
|
m_libMgr->RevertLibrary( libName );
|
||||||
|
|
||||||
|
if( currentLib && m_libMgr->PartExists( alias, libName ) )
|
||||||
|
loadPart( alias, libName, unit );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnCreateNewPart( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
|
||||||
|
m_drawItem = NULL;
|
||||||
|
|
||||||
|
DIALOG_LIB_NEW_COMPONENT dlg( this );
|
||||||
|
dlg.SetMinSize( dlg.GetSize() );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_CANCEL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( dlg.GetName().IsEmpty() )
|
||||||
|
{
|
||||||
|
wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString name = dlg.GetName();
|
||||||
|
name.Replace( " ", "_" );
|
||||||
|
|
||||||
|
wxString lib = getTargetLib();
|
||||||
|
|
||||||
|
// Test if there is a component with this name already.
|
||||||
|
if( !lib.empty() && m_libMgr->PartExists( name, lib ) )
|
||||||
|
{
|
||||||
|
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
|
||||||
|
name, lib );
|
||||||
|
DisplayError( this, msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIB_PART* new_part = new LIB_PART( name );
|
||||||
|
m_aliasName = new_part->GetName();
|
||||||
|
|
||||||
|
new_part->GetReferenceField().SetText( dlg.GetReference() );
|
||||||
|
new_part->SetUnitCount( dlg.GetUnitCount() );
|
||||||
|
|
||||||
|
// Initialize new_part->m_TextInside member:
|
||||||
|
// if 0, pin text is outside the body (on the pin)
|
||||||
|
// if > 0, pin text is inside the body
|
||||||
|
new_part->SetConversion( dlg.GetAlternateBodyStyle() );
|
||||||
|
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
|
||||||
|
|
||||||
|
if( dlg.GetPinNameInside() )
|
||||||
|
{
|
||||||
|
new_part->SetPinNameOffset( dlg.GetPinTextPosition() );
|
||||||
|
|
||||||
|
if( new_part->GetPinNameOffset() == 0 )
|
||||||
|
new_part->SetPinNameOffset( 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_part->SetPinNameOffset( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
( dlg.GetPowerSymbol() ) ? new_part->SetPower() : new_part->SetNormal();
|
||||||
|
new_part->SetShowPinNumbers( dlg.GetShowPinNumber() );
|
||||||
|
new_part->SetShowPinNames( dlg.GetShowPinName() );
|
||||||
|
new_part->LockUnits( dlg.GetLockItems() );
|
||||||
|
|
||||||
|
if( dlg.GetUnitCount() < 2 )
|
||||||
|
new_part->LockUnits( false );
|
||||||
|
|
||||||
|
m_libMgr->UpdatePart( new_part, lib );
|
||||||
|
loadPart( name, lib, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnEditPart( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
int unit = 0;
|
||||||
|
LIB_ID partId = m_treePane->GetCmpTree()->GetSelectedLibId( &unit );
|
||||||
|
loadPart( partId.GetLibItemName(), partId.GetLibNickname(), unit );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnSavePart( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
LIB_ID libId = getTargetLibId();
|
||||||
|
m_libMgr->FlushPart( libId.GetLibItemName(), libId.GetLibNickname() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnRemovePart( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
LIB_ID libId = getTargetLibId();
|
||||||
|
|
||||||
|
if( m_libMgr->IsPartModified( libId.GetLibItemName(), libId.GetLibNickname() )
|
||||||
|
&& !IsOK( this, _( wxString::Format( "Component %s has been modified\n"
|
||||||
|
"Do you want to remove it from the library?", libId.GetLibItemName().c_str() ) ) ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isCurrentPart( libId ) )
|
||||||
|
emptyScreen();
|
||||||
|
|
||||||
|
m_libMgr->RemovePart( libId.GetLibItemName(), libId.GetLibNickname() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnRevertPart( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
LIB_ID libId = getTargetLibId();
|
||||||
|
bool currentPart = isCurrentPart( libId );
|
||||||
|
int unit = m_unit;
|
||||||
|
|
||||||
|
if( currentPart )
|
||||||
|
emptyScreen();
|
||||||
|
|
||||||
|
m_libMgr->RevertPart( libId.GetLibItemName(), libId.GetLibNickname() );
|
||||||
|
|
||||||
|
if( currentPart && m_libMgr->PartExists( libId.GetLibItemName(), libId.GetLibNickname() ) )
|
||||||
|
loadPart( libId.GetLibItemName(), libId.GetLibNickname(), unit );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::loadPart( const wxString& aAlias, const wxString& aLibrary, int aUnit )
|
||||||
|
{
|
||||||
|
wxCHECK( m_libMgr->PartExists( aAlias, aLibrary ), /* void */ );
|
||||||
|
LIB_PART* part = m_libMgr->GetBufferedPart( aAlias, aLibrary );
|
||||||
|
LIB_ALIAS* alias = part ? part->GetAlias( aAlias ) : nullptr;
|
||||||
|
|
||||||
|
if( !alias )
|
||||||
|
{
|
||||||
|
wxString msg = wxString::Format( _( "Part name '%s' not found in library '%s'" ),
|
||||||
|
GetChars( aAlias ), GetChars( aLibrary ) );
|
||||||
|
DisplayError( this, msg );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastDrawItem = m_drawItem = nullptr;
|
||||||
|
m_aliasName = aAlias;
|
||||||
|
m_unit = ( aUnit <= part->GetUnitCount() ? aUnit : 1 );
|
||||||
|
|
||||||
|
LoadOneLibraryPartAux( alias, aLibrary );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
|
||||||
{
|
{
|
||||||
wxFileName fn;
|
wxFileName fn;
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
@ -296,18 +461,15 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
||||||
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
|
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
|
||||||
|
|
||||||
wxString lib = GetCurLib();
|
wxString lib = getTargetLib();
|
||||||
|
|
||||||
if( !newFile && ( lib.empty() || !prj.SchSymbolLibTable()->HasLibrary( lib ) ) )
|
if( !aNewFile && ( lib.empty() || !prj.SchSymbolLibTable()->HasLibrary( lib ) ) )
|
||||||
{
|
{
|
||||||
DisplayError( this, _( "No library specified." ) );
|
DisplayError( this, _( "No library specified." ) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( GetScreen()->IsModify() && !IsOK( this, _( "Include current symbol changes?" ) ) )
|
if( aNewFile )
|
||||||
return false;
|
|
||||||
|
|
||||||
if( newFile )
|
|
||||||
{
|
{
|
||||||
SEARCH_STACK* search = prj.SchSearchS();
|
SEARCH_STACK* search = prj.SchSearchS();
|
||||||
|
|
||||||
|
@ -392,7 +554,7 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the library and document files to the new destination library files.
|
// Copy the library and document files to the new destination library files.
|
||||||
if( newFile )
|
if( aNewFile )
|
||||||
{
|
{
|
||||||
wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() );
|
wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() );
|
||||||
|
|
||||||
|
@ -417,21 +579,13 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
||||||
// Update symbol changes in library.
|
// Update symbol changes in library.
|
||||||
if( GetScreen()->IsModify() )
|
if( GetScreen()->IsModify() )
|
||||||
{
|
{
|
||||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
if( !m_libMgr->FlushLibrary( lib ) )
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *GetCurPart() ) );
|
|
||||||
}
|
|
||||||
catch( const IO_ERROR& ioe )
|
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
|
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
|
||||||
libFileName.GetFullPath() );
|
libFileName.GetFullPath() );
|
||||||
DisplayErrorMessage( this, msg, ioe.What() );
|
DisplayErrorMessage( this, _( "Error saving library" ), msg );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetScreen()->ClrModify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Printf( _( "Symbol library file '%s' saved" ), libFileName.GetFullPath() );
|
msg.Printf( _( "Symbol library file '%s' saved" ), libFileName.GetFullPath() );
|
||||||
|
@ -493,197 +647,3 @@ void LIB_EDIT_FRAME::DisplayCmpDoc()
|
||||||
AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
|
AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
|
||||||
AppendMsgPanel( _( "Datasheet" ), alias->GetDocFileName(), DARKDARKGRAY );
|
AppendMsgPanel( _( "Datasheet" ), alias->GetDocFileName(), DARKDARKGRAY );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::DeleteOnePart( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
wxString cmp_name;
|
|
||||||
wxArrayString nameList;
|
|
||||||
wxString msg;
|
|
||||||
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
|
|
||||||
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
m_drawItem = NULL;
|
|
||||||
|
|
||||||
LIB_PART *part = GetCurPart();
|
|
||||||
wxString lib = GetCurLib();
|
|
||||||
|
|
||||||
if( lib.empty() )
|
|
||||||
{
|
|
||||||
SelectActiveLibrary();
|
|
||||||
|
|
||||||
lib = GetCurLib();
|
|
||||||
|
|
||||||
if( !lib )
|
|
||||||
{
|
|
||||||
DisplayError( this, _( "Please select a symbol library." ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto adapter( CMP_TREE_MODEL_ADAPTER::Create( Prj().SchSymbolLibTable() ) );
|
|
||||||
|
|
||||||
wxString name = part ? part->GetName() : wxString( wxEmptyString );
|
|
||||||
adapter->SetPreselectNode( name, /* aUnit */ 0 );
|
|
||||||
adapter->ShowUnits( false );
|
|
||||||
adapter->AddLibrary( lib );
|
|
||||||
|
|
||||||
wxString dialogTitle;
|
|
||||||
dialogTitle.Printf( _( "Delete Symbol (%u items loaded)" ), adapter->GetComponentsCount() );
|
|
||||||
|
|
||||||
DIALOG_CHOOSE_COMPONENT dlg( this, dialogTitle, adapter, m_convert, false );
|
|
||||||
|
|
||||||
if( dlg.ShowQuasiModal() == wxID_CANCEL )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIB_ID id;
|
|
||||||
|
|
||||||
id = dlg.GetSelectedLibId();
|
|
||||||
|
|
||||||
if( !id.IsValid() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
LIB_ALIAS* alias = Prj().SchSymbolLibTable()->LoadSymbol( id );
|
|
||||||
|
|
||||||
if( !alias )
|
|
||||||
return;
|
|
||||||
|
|
||||||
msg.Printf( _( "Delete symbol '%s' from library '%s'?" ),
|
|
||||||
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
|
|
||||||
|
|
||||||
if( !IsOK( this, msg ) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part || !part->HasAlias( id.GetLibItemName() ) )
|
|
||||||
{
|
|
||||||
Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() );
|
|
||||||
m_canvas->Refresh();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If deleting the current entry or removing one of the aliases for
|
|
||||||
// the current entry, sync the changes in the current entry as well.
|
|
||||||
|
|
||||||
if( GetScreen()->IsModify() && !IsOK( this, _(
|
|
||||||
"The symbol being deleted has been modified."
|
|
||||||
" All changes will be lost. Discard changes?" ) ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Prj().SchSymbolLibTable()->DeleteAlias( id.GetLibNickname(), id.GetLibItemName() );
|
|
||||||
}
|
|
||||||
catch( ... /* IO_ERROR ioe */ )
|
|
||||||
{
|
|
||||||
msg.Printf( _( "Error occurred deleting symbol '%s' from library '%s'" ),
|
|
||||||
id.GetLibItemName().wx_str(), id.GetLibNickname().wx_str() );
|
|
||||||
DisplayError( this, msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetCurPart( NULL ); // delete CurPart
|
|
||||||
m_aliasName.Empty();
|
|
||||||
m_canvas->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::CreateNewLibraryPart( wxCommandEvent& event )
|
|
||||||
{
|
|
||||||
wxString name;
|
|
||||||
|
|
||||||
if( GetCurPart() && GetScreen()->IsModify() && !IsOK( this, _(
|
|
||||||
"All changes to the current symbol will be lost!\n\n"
|
|
||||||
"Clear the current symbol from the screen?" ) ) )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->EndMouseCapture( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor() );
|
|
||||||
|
|
||||||
m_drawItem = NULL;
|
|
||||||
|
|
||||||
DIALOG_LIB_NEW_COMPONENT dlg( this );
|
|
||||||
|
|
||||||
dlg.SetMinSize( dlg.GetSize() );
|
|
||||||
|
|
||||||
if( dlg.ShowModal() == wxID_CANCEL )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( dlg.GetName().IsEmpty() )
|
|
||||||
{
|
|
||||||
wxMessageBox( _( "This new symbol has no name and cannot be created." ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = dlg.GetName();
|
|
||||||
name.Replace( " ", "_" );
|
|
||||||
|
|
||||||
wxString lib = GetCurLib();
|
|
||||||
|
|
||||||
// Test if there a component with this name already.
|
|
||||||
if( !lib.empty() && Prj().SchSymbolLibTable()->LoadSymbol( lib, name ) != NULL )
|
|
||||||
{
|
|
||||||
wxString msg = wxString::Format( _( "Symbol '%s' already exists in library '%s'" ),
|
|
||||||
name, lib );
|
|
||||||
DisplayError( this, msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LIB_PART* new_part = new LIB_PART( name );
|
|
||||||
|
|
||||||
SetCurPart( new_part );
|
|
||||||
m_aliasName = new_part->GetName();
|
|
||||||
|
|
||||||
new_part->GetReferenceField().SetText( dlg.GetReference() );
|
|
||||||
new_part->SetUnitCount( dlg.GetUnitCount() );
|
|
||||||
|
|
||||||
// Initialize new_part->m_TextInside member:
|
|
||||||
// if 0, pin text is outside the body (on the pin)
|
|
||||||
// if > 0, pin text is inside the body
|
|
||||||
new_part->SetConversion( dlg.GetAlternateBodyStyle() );
|
|
||||||
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
|
|
||||||
|
|
||||||
if( dlg.GetPinNameInside() )
|
|
||||||
{
|
|
||||||
new_part->SetPinNameOffset( dlg.GetPinTextPosition() );
|
|
||||||
|
|
||||||
if( new_part->GetPinNameOffset() == 0 )
|
|
||||||
new_part->SetPinNameOffset( 1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
new_part->SetPinNameOffset( 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
( dlg.GetPowerSymbol() ) ? new_part->SetPower() : new_part->SetNormal();
|
|
||||||
new_part->SetShowPinNumbers( dlg.GetShowPinNumber() );
|
|
||||||
new_part->SetShowPinNames( dlg.GetShowPinName() );
|
|
||||||
new_part->LockUnits( dlg.GetLockItems() );
|
|
||||||
|
|
||||||
if( dlg.GetUnitCount() < 2 )
|
|
||||||
new_part->LockUnits( false );
|
|
||||||
|
|
||||||
m_unit = 1;
|
|
||||||
m_convert = 1;
|
|
||||||
|
|
||||||
DisplayLibInfos();
|
|
||||||
DisplayCmpDoc();
|
|
||||||
UpdateAliasSelectList();
|
|
||||||
UpdatePartSelectList();
|
|
||||||
|
|
||||||
m_editPinsPerPartOrConvert = new_part->UnitsLocked() ? true : false;
|
|
||||||
m_lastDrawItem = NULL;
|
|
||||||
|
|
||||||
GetScreen()->ClearUndoRedoList();
|
|
||||||
OnModify();
|
|
||||||
|
|
||||||
m_canvas->Refresh();
|
|
||||||
m_mainToolBar->Refresh();
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <gr_basic.h>
|
#include <gr_basic.h>
|
||||||
#include <schframe.h>
|
#include <schframe.h>
|
||||||
#include <msgpanel.h>
|
#include <msgpanel.h>
|
||||||
|
#include <confirm.h>
|
||||||
|
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
#include <eeschema_id.h>
|
#include <eeschema_id.h>
|
||||||
|
@ -44,6 +45,10 @@
|
||||||
#include <class_library.h>
|
#include <class_library.h>
|
||||||
#include <lib_polyline.h>
|
#include <lib_polyline.h>
|
||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
|
|
||||||
|
#include <lib_manager.h>
|
||||||
|
#include <widgets/cmp_tree_pane.h>
|
||||||
|
#include <widgets/component_tree.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
|
|
||||||
#include <kicad_device_context.h>
|
#include <kicad_device_context.h>
|
||||||
|
@ -53,7 +58,7 @@
|
||||||
#include <dialogs/dialog_edit_component_in_lib.h>
|
#include <dialogs/dialog_edit_component_in_lib.h>
|
||||||
#include <dialogs/dialog_lib_edit_pin_table.h>
|
#include <dialogs/dialog_lib_edit_pin_table.h>
|
||||||
|
|
||||||
#include <widgets/component_tree.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
#include <menus_helpers.h>
|
#include <menus_helpers.h>
|
||||||
|
|
||||||
|
@ -82,12 +87,25 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_SIZE( LIB_EDIT_FRAME::OnSize )
|
EVT_SIZE( LIB_EDIT_FRAME::OnSize )
|
||||||
EVT_ACTIVATE( LIB_EDIT_FRAME::OnActivate )
|
EVT_ACTIVATE( LIB_EDIT_FRAME::OnActivate )
|
||||||
|
|
||||||
// Main horizontal toolbar.
|
// Library actions
|
||||||
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnSaveActiveLibrary )
|
EVT_TOOL( ID_LIBEDIT_NEW_LIBRARY, LIB_EDIT_FRAME::OnCreateNewLibrary )
|
||||||
EVT_TOOL( ID_LIBEDIT_DELETE_PART, LIB_EDIT_FRAME::DeleteOnePart )
|
EVT_TOOL( ID_LIBEDIT_ADD_LIBRARY, LIB_EDIT_FRAME::OnAddLibrary )
|
||||||
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
|
EVT_TOOL( ID_LIBEDIT_SAVE_LIBRARY, LIB_EDIT_FRAME::OnSaveLibrary )
|
||||||
EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::CreateNewLibraryPart )
|
EVT_MENU( ID_LIBEDIT_SAVE_LIBRARY_AS, LIB_EDIT_FRAME::OnSaveLibrary )
|
||||||
|
EVT_MENU( ID_LIBEDIT_SAVE_ALL_LIBS, LIB_EDIT_FRAME::OnSaveAllLibraries )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_REVERT_LIBRARY, LIB_EDIT_FRAME::OnRevertLibrary )
|
||||||
|
|
||||||
|
// Part actions
|
||||||
|
EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::OnCreateNewPart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_EDIT_PART, LIB_EDIT_FRAME::OnEditPart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_IMPORT_PART, LIB_EDIT_FRAME::OnImportPart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnExportPart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_SAVE_PART, LIB_EDIT_FRAME::OnSavePart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_REVERT_PART, LIB_EDIT_FRAME::OnRevertPart )
|
||||||
|
EVT_TOOL( ID_LIBEDIT_REMOVE_PART, LIB_EDIT_FRAME::OnRemovePart )
|
||||||
|
|
||||||
|
// Main horizontal toolbar.
|
||||||
|
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
|
||||||
EVT_TOOL( wxID_UNDO, LIB_EDIT_FRAME::GetComponentFromUndoList )
|
EVT_TOOL( wxID_UNDO, LIB_EDIT_FRAME::GetComponentFromUndoList )
|
||||||
EVT_TOOL( wxID_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
|
EVT_TOOL( wxID_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
|
||||||
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnEditComponentProperties )
|
EVT_TOOL( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnEditComponentProperties )
|
||||||
|
@ -98,9 +116,6 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
EVT_TOOL( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnViewEntryDoc )
|
EVT_TOOL( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnViewEntryDoc )
|
||||||
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::Process_Special_Functions )
|
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::Process_Special_Functions )
|
||||||
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
|
EVT_TOOL( ID_LIBEDIT_EDIT_PIN_BY_TABLE, LIB_EDIT_FRAME::OnOpenPinTable )
|
||||||
EVT_TOOL( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnExportPart )
|
|
||||||
EVT_TOOL( ID_LIBEDIT_IMPORT_PART, LIB_EDIT_FRAME::OnImportPart )
|
|
||||||
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnSaveCurrentPart )
|
|
||||||
|
|
||||||
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart )
|
EVT_COMBOBOX( ID_LIBEDIT_SELECT_PART_NUMBER, LIB_EDIT_FRAME::OnSelectPart )
|
||||||
EVT_COMBOBOX( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnSelectAlias )
|
EVT_COMBOBOX( ID_LIBEDIT_SELECT_ALIAS, LIB_EDIT_FRAME::OnSelectAlias )
|
||||||
|
@ -117,7 +132,6 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
|
|
||||||
// menubar commands
|
// menubar commands
|
||||||
EVT_MENU( wxID_EXIT, LIB_EDIT_FRAME::CloseWindow )
|
EVT_MENU( wxID_EXIT, LIB_EDIT_FRAME::CloseWindow )
|
||||||
EVT_MENU( ID_LIBEDIT_SAVE_CURRENT_LIB_AS, LIB_EDIT_FRAME::OnSaveActiveLibrary )
|
|
||||||
EVT_MENU( ID_LIBEDIT_GEN_PNG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
|
EVT_MENU( ID_LIBEDIT_GEN_PNG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
|
||||||
EVT_MENU( ID_LIBEDIT_GEN_SVG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
|
EVT_MENU( ID_LIBEDIT_GEN_SVG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
|
||||||
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
|
EVT_MENU( wxID_HELP, EDA_DRAW_FRAME::GetKicadHelp )
|
||||||
|
@ -149,13 +163,13 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
||||||
|
|
||||||
// Update user interface elements.
|
// Update user interface elements.
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
EVT_UPDATE_UI( ID_LIBEDIT_EXPORT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_FIELDS, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
EVT_UPDATE_UI( ID_LIBEDIT_CHECK_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
EVT_UPDATE_UI( ID_LIBEDIT_GET_FRAME_EDIT_PART, LIB_EDIT_FRAME::OnUpdateEditingPart )
|
||||||
EVT_UPDATE_UI( wxID_UNDO, LIB_EDIT_FRAME::OnUpdateUndo )
|
EVT_UPDATE_UI( wxID_UNDO, LIB_EDIT_FRAME::OnUpdateUndo )
|
||||||
EVT_UPDATE_UI( wxID_REDO, LIB_EDIT_FRAME::OnUpdateRedo )
|
EVT_UPDATE_UI( wxID_REDO, LIB_EDIT_FRAME::OnUpdateRedo )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib )
|
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_LIBRARY, LIB_EDIT_FRAME::OnUpdateSaveCurrentLib )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_LIBRARY_AS, LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs )
|
EVT_UPDATE_UI( ID_LIBEDIT_SAVE_LIBRARY_AS, LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc )
|
EVT_UPDATE_UI( ID_LIBEDIT_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc )
|
||||||
EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::OnUpdatePinByPin )
|
EVT_UPDATE_UI( ID_LIBEDIT_EDIT_PIN_BY_PIN, LIB_EDIT_FRAME::OnUpdatePinByPin )
|
||||||
|
@ -189,7 +203,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
|
|
||||||
m_my_part = NULL;
|
m_my_part = NULL;
|
||||||
m_tempCopyComponent = NULL;
|
m_tempCopyComponent = NULL;
|
||||||
m_componentTree = nullptr;
|
m_treePane = nullptr;
|
||||||
|
m_libMgr = nullptr;
|
||||||
|
|
||||||
// Delayed initialization
|
// Delayed initialization
|
||||||
if( m_textSize == -1 )
|
if( m_textSize == -1 )
|
||||||
|
@ -204,7 +219,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
|
|
||||||
LoadSettings( config() );
|
LoadSettings( config() );
|
||||||
|
|
||||||
SetScreen( new SCH_SCREEN( aKiway ) );
|
m_dummyScreen = new SCH_SCREEN( aKiway );
|
||||||
|
SetScreen( m_dummyScreen );
|
||||||
GetScreen()->m_Center = true;
|
GetScreen()->m_Center = true;
|
||||||
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
|
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
|
||||||
|
|
||||||
|
@ -224,7 +240,9 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
if( m_canvas )
|
if( m_canvas )
|
||||||
m_canvas->SetEnableBlockCommands( true );
|
m_canvas->SetEnableBlockCommands( true );
|
||||||
|
|
||||||
createComponentTree();
|
m_libMgr = new LIB_MANAGER( *this );
|
||||||
|
m_treePane = new CMP_TREE_PANE( this, m_libMgr );
|
||||||
|
|
||||||
ReCreateMenuBar();
|
ReCreateMenuBar();
|
||||||
ReCreateHToolbar();
|
ReCreateHToolbar();
|
||||||
ReCreateVToolbar();
|
ReCreateVToolbar();
|
||||||
|
@ -280,8 +298,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||||
m_auimgr.AddPane( m_messagePanel,
|
m_auimgr.AddPane( m_messagePanel,
|
||||||
wxAuiPaneInfo( mesg ).Name( "MsgPanel" ).Bottom().Layer( 10 ) );
|
wxAuiPaneInfo( mesg ).Name( "MsgPanel" ).Bottom().Layer( 10 ) );
|
||||||
|
|
||||||
m_auimgr.AddPane( m_componentTree,
|
m_auimgr.AddPane( m_treePane,
|
||||||
wxAuiPaneInfo( vert ).Name( "ComponentTree" ).Left().Row( 1 ) );
|
wxAuiPaneInfo( vert ).Name( "ComponentTree" ).Left().Row( 1 ).Resizable().MinSize( 300, 400 ) );
|
||||||
|
|
||||||
m_auimgr.Update();
|
m_auimgr.Update();
|
||||||
|
|
||||||
|
@ -301,12 +319,14 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
|
||||||
Unbind( wxEVT_COMMAND_MENU_SELECTED, &LIB_EDIT_FRAME::OnEditSymbolLibTable, this,
|
Unbind( wxEVT_COMMAND_MENU_SELECTED, &LIB_EDIT_FRAME::OnEditSymbolLibTable, this,
|
||||||
ID_EDIT_SYM_LIB_TABLE );
|
ID_EDIT_SYM_LIB_TABLE );
|
||||||
|
|
||||||
|
// current screen is destroyed in EDA_DRAW_FRAME
|
||||||
|
SetScreen( m_dummyScreen );
|
||||||
|
|
||||||
m_drawItem = m_lastDrawItem = NULL;
|
m_drawItem = m_lastDrawItem = NULL;
|
||||||
|
|
||||||
delete m_tempCopyComponent;
|
delete m_tempCopyComponent;
|
||||||
|
delete m_libMgr;
|
||||||
delete m_my_part;
|
delete m_my_part;
|
||||||
m_my_part = NULL;
|
|
||||||
m_tempCopyComponent = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,6 +338,7 @@ void LIB_EDIT_FRAME::SetDrawItem( LIB_ITEM* drawItem )
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
{
|
{
|
||||||
|
// TODO check all libraries for modifications
|
||||||
if( GetScreen()->IsModify() )
|
if( GetScreen()->IsModify() )
|
||||||
{
|
{
|
||||||
int ii = DisplayExitDialog( this, _( "Save the changes in the library before closing?" ) );
|
int ii = DisplayExitDialog( this, _( "Save the changes in the library before closing?" ) );
|
||||||
|
@ -328,7 +349,7 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case wxID_YES:
|
case wxID_YES:
|
||||||
if( SaveActiveLibrary( false ) )
|
if( saveLibrary( GetCurLib(), false ) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// fall through: cancel the close because of an error
|
// fall through: cancel the close because of an error
|
||||||
|
@ -458,15 +479,21 @@ void LIB_EDIT_FRAME::OnShowElectricalType( wxCommandEvent& event )
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnToggleSearchTree( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnToggleSearchTree( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
auto& treePane = m_auimgr.GetPane( m_componentTree );
|
auto& treePane = m_auimgr.GetPane( m_treePane );
|
||||||
treePane.Show( !IsSearchTreeShown() );
|
treePane.Show( !IsSearchTreeShown() );
|
||||||
m_auimgr.Update();
|
m_auimgr.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
SCH_BASE_FRAME::OnEditSymbolLibTable( aEvent );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LIB_EDIT_FRAME::IsSearchTreeShown()
|
bool LIB_EDIT_FRAME::IsSearchTreeShown()
|
||||||
{
|
{
|
||||||
return m_auimgr.GetPane( m_componentTree ).IsShown();
|
return m_auimgr.GetPane( m_treePane ).IsShown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -515,17 +542,17 @@ void LIB_EDIT_FRAME::OnUpdateRedo( wxUpdateUIEvent& event )
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event )
|
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLib( wxUpdateUIEvent& event )
|
||||||
{
|
{
|
||||||
wxString lib = GetCurLib();
|
wxString lib = getTargetLib();
|
||||||
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
||||||
|
|
||||||
event.Enable( !lib.empty() && table->HasLibrary( lib ) && table->IsSymbolLibWritable( lib ) &&
|
event.Enable( !lib.empty() && table->HasLibrary( lib ) && table->IsSymbolLibWritable( lib ) &&
|
||||||
GetScreen()->IsModify() );
|
m_libMgr->IsLibraryModified( lib ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event )
|
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event )
|
||||||
{
|
{
|
||||||
wxString lib = GetCurLib();
|
wxString lib = getTargetLib();
|
||||||
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
||||||
|
|
||||||
event.Enable( !lib.empty() && table->HasLibrary( lib ) );
|
event.Enable( !lib.empty() && table->HasLibrary( lib ) );
|
||||||
|
@ -685,46 +712,6 @@ void LIB_EDIT_FRAME::OnSelectBodyStyle( wxCommandEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::OnSaveCurrentPart( wxCommandEvent& aEvent )
|
|
||||||
{
|
|
||||||
LIB_PART* part = GetCurPart();
|
|
||||||
|
|
||||||
if( !part )
|
|
||||||
{
|
|
||||||
DisplayError( this, _( "No part to save." ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString libNickname = GetCurLib();
|
|
||||||
|
|
||||||
if( libNickname.empty() )
|
|
||||||
SelectActiveLibrary();
|
|
||||||
|
|
||||||
libNickname = GetCurLib();
|
|
||||||
|
|
||||||
if( !libNickname )
|
|
||||||
{
|
|
||||||
DisplayError( this, _( "No valid library specified." ) );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Prj().SchSymbolLibTable()->SaveSymbol( libNickname, new LIB_PART( *part ) );
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
|
||||||
wxString msg;
|
|
||||||
msg.Printf( _( "Unexpected error occured saving symbol '%s' to symbol library '%s'." ),
|
|
||||||
part->GetName(), libNickname );
|
|
||||||
DisplayError( this, msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshSchematic();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
int id = event.GetId();
|
int id = event.GetId();
|
||||||
|
@ -973,7 +960,7 @@ void LIB_EDIT_FRAME::OnActivate( wxActivateEvent& event )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString LIB_EDIT_FRAME::GetCurLib()
|
wxString LIB_EDIT_FRAME::GetCurLib() const
|
||||||
{
|
{
|
||||||
wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
|
wxString libNickname = Prj().GetRString( PROJECT::SCH_LIBEDIT_CUR_LIB );
|
||||||
|
|
||||||
|
@ -1003,16 +990,15 @@ wxString LIB_EDIT_FRAME::SetCurLib( const wxString& aLibNickname )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LIB_PART* LIB_EDIT_FRAME::GetCurPart()
|
|
||||||
{
|
|
||||||
return m_my_part;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
|
void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
|
||||||
|
{
|
||||||
|
wxASSERT( m_my_part != aPart );
|
||||||
|
|
||||||
|
if( m_my_part != aPart )
|
||||||
{
|
{
|
||||||
delete m_my_part;
|
delete m_my_part;
|
||||||
m_my_part = aPart; // take ownership here
|
m_my_part = aPart;
|
||||||
|
}
|
||||||
|
|
||||||
// retain in case this wxFrame is re-opened later on the same PROJECT
|
// retain in case this wxFrame is re-opened later on the same PROJECT
|
||||||
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, aPart ? aPart->GetName() : wxString() );
|
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, aPart ? aPart->GetName() : wxString() );
|
||||||
|
@ -1075,6 +1061,7 @@ void LIB_EDIT_FRAME::EditSymbolText( wxDC* DC, LIB_ITEM* DrawItem )
|
||||||
void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
||||||
{
|
{
|
||||||
bool partLocked = GetCurPart()->UnitsLocked();
|
bool partLocked = GetCurPart()->UnitsLocked();
|
||||||
|
wxString oldName = GetCurPart()->GetName();
|
||||||
|
|
||||||
DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this );
|
DIALOG_EDIT_COMPONENT_IN_LIBRARY dlg( this );
|
||||||
|
|
||||||
|
@ -1088,6 +1075,8 @@ void LIB_EDIT_FRAME::OnEditComponentProperties( wxCommandEvent& event )
|
||||||
m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false;
|
m_editPinsPerPartOrConvert = GetCurPart()->UnitsLocked() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_libMgr->UpdatePart( GetCurPart(), GetCurLib(), oldName );
|
||||||
|
|
||||||
UpdateAliasSelectList();
|
UpdateAliasSelectList();
|
||||||
UpdatePartSelectList();
|
UpdatePartSelectList();
|
||||||
DisplayLibInfos();
|
DisplayLibInfos();
|
||||||
|
@ -1391,50 +1380,11 @@ void LIB_EDIT_FRAME::deleteItem( wxDC* aDC )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LIB_EDIT_FRAME::createComponentTree()
|
void LIB_EDIT_FRAME::OnModify()
|
||||||
{
|
{
|
||||||
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
GetScreen()->SetModify();
|
||||||
auto adapter( CMP_TREE_MODEL_ADAPTER::Create( table ) );
|
storeCurrentPart();
|
||||||
|
m_treePane->GetCmpTree()->Refresh();
|
||||||
for( const wxString& lib : table->GetLogicalLibs() )
|
|
||||||
adapter->AddLibrary( lib );
|
|
||||||
|
|
||||||
adapter->ShowUnits( true );
|
|
||||||
m_componentTree = new COMPONENT_TREE( this, table, adapter, COMPONENT_TREE::SEARCH );
|
|
||||||
m_libMgr = new LIB_MANAGER( *this );
|
|
||||||
|
|
||||||
std::unique_ptr<wxMenu> menuLibrary = std::make_unique<wxMenu>();
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_NEW_LIBRARY, _( "New library..." ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_ADD_LIBRARY, _( "Add existing library..." ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY, _( "Save library" ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY_AS, _( "Save library as..." ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_REVERT_LIBRARY, _( "Revert library" ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_REMOVE_LIBRARY, _( "Remove library" ) );
|
|
||||||
menuLibrary->AppendSeparator();
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_NEW_PART, _( "New component..." ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_PASTE_PART, _( "Paste component" ) );
|
|
||||||
menuLibrary->Append( ID_LIBEDIT_IMPORT_PART, _( "Import component..." ) );
|
|
||||||
|
|
||||||
std::unique_ptr<wxMenu> menuPart = std::make_unique<wxMenu>();
|
|
||||||
menuPart->Append( ID_LIBEDIT_EDIT_PART, _( "Edit" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_CUT_PART, _( "Cut" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_COPY_PART, _( "Copy" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_RENAME_PART, _( "Rename" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_REMOVE_PART, _( "Remove" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_EXPORT_PART, _( "Export..." ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_SAVE_PART, _( "Save" ) );
|
|
||||||
menuPart->Append( ID_LIBEDIT_REVERT_PART, _( "Revert" ) );
|
|
||||||
menuPart->AppendSeparator();
|
|
||||||
|
|
||||||
// Append the library menu to the component menu
|
|
||||||
for( size_t i = 0; i < menuLibrary->GetMenuItemCount(); ++i )
|
|
||||||
{
|
|
||||||
wxMenuItem* menuItem = menuLibrary->FindItemByPosition( i );
|
|
||||||
menuPart->Append( menuItem->GetId(), menuItem->GetItemLabel() );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_componentTree->SetMenu( CMP_TREE_NODE::ALIAS, std::move( menuPart ) );
|
|
||||||
m_componentTree->SetMenu( CMP_TREE_NODE::LIB, std::move( menuLibrary ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1490,3 +1440,137 @@ void LIB_EDIT_FRAME::refreshSchematic()
|
||||||
// in case any symbols have changed.
|
// in case any symbols have changed.
|
||||||
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, std::string( "" ), this );
|
Kiway().ExpressMail( FRAME_SCH, MAIL_SCH_REFRESH, std::string( "" ), this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_EDIT_FRAME::addLibraryFile( bool aCreateNew )
|
||||||
|
{
|
||||||
|
wxFileName fileName = getLibraryFileName( !aCreateNew );
|
||||||
|
wxString libName = fileName.GetName();
|
||||||
|
|
||||||
|
if( libName.IsEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if( m_libMgr->LibraryExists( libName ) )
|
||||||
|
{
|
||||||
|
DisplayError( this,
|
||||||
|
wxString::Format( _( "Library '%s' already exists" ), GetChars( libName ) ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_libMgr->AddLibrary( fileName.GetFullPath() );
|
||||||
|
|
||||||
|
if( aCreateNew )
|
||||||
|
Prj().SchSymbolLibTable()->CreateSymbolLib( libName );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxFileName LIB_EDIT_FRAME::getLibraryFileName( bool aExisting )
|
||||||
|
{
|
||||||
|
wxFileName fn = m_libMgr->GetUniqueLibraryName();
|
||||||
|
fn.SetExt( SchematicLibraryFileExtension );
|
||||||
|
|
||||||
|
wxFileDialog dlg( this,
|
||||||
|
aExisting ? _( "Select Library" ) : _( "New Library" ),
|
||||||
|
Prj().GetProjectPath(),
|
||||||
|
aExisting ? wxString( wxEmptyString ) : fn.GetFullName() ,
|
||||||
|
SchematicLibraryFileWildcard(),
|
||||||
|
aExisting ? wxFD_OPEN | wxFD_FILE_MUST_EXIST :
|
||||||
|
wxFD_SAVE | wxFD_CHANGE_DIR | wxFD_OVERWRITE_PROMPT );
|
||||||
|
|
||||||
|
if( dlg.ShowModal() == wxID_CANCEL )
|
||||||
|
return wxFileName();
|
||||||
|
|
||||||
|
fn = dlg.GetPath();
|
||||||
|
fn.SetExt( SchematicLibraryFileExtension );
|
||||||
|
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_PART* LIB_EDIT_FRAME::getTargetPart() const
|
||||||
|
{
|
||||||
|
LIB_ALIAS* alias = nullptr;
|
||||||
|
|
||||||
|
if( m_treePane->GetCmpTree()->IsMenuActive() )
|
||||||
|
{
|
||||||
|
LIB_ID libId = m_treePane->GetCmpTree()->GetSelectedLibId();
|
||||||
|
alias = m_libMgr->GetAlias( libId.GetLibItemName(), libId.GetLibNickname() );
|
||||||
|
}
|
||||||
|
else if( LIB_PART* part = GetCurPart() )
|
||||||
|
{
|
||||||
|
alias = part->GetAlias( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return alias ? alias->GetPart() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LIB_ID LIB_EDIT_FRAME::getTargetLibId() const
|
||||||
|
{
|
||||||
|
if( m_treePane->GetCmpTree()->IsMenuActive() )
|
||||||
|
return m_treePane->GetCmpTree()->GetSelectedLibId();
|
||||||
|
|
||||||
|
if( LIB_PART* part = GetCurPart() )
|
||||||
|
return part->GetLibId();
|
||||||
|
|
||||||
|
return LIB_ID();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wxString LIB_EDIT_FRAME::getTargetLib() const
|
||||||
|
{
|
||||||
|
if( m_treePane->GetCmpTree()->IsMenuActive() )
|
||||||
|
{
|
||||||
|
LIB_ID libId = m_treePane->GetCmpTree()->GetSelectedLibId();
|
||||||
|
return libId.GetLibNickname();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GetCurLib();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SYMBOL_LIB_TABLE* LIB_EDIT_FRAME::SelectSymLibTable()
|
||||||
|
{
|
||||||
|
wxArrayString libTableNames;
|
||||||
|
libTableNames.Add( _( "Global Symbol Library Table" ) );
|
||||||
|
libTableNames.Add( _( "Project Symbol Library Table" ) );
|
||||||
|
|
||||||
|
switch( SelectSingleOption( this, _( "Select target symbol library table" ),
|
||||||
|
wxEmptyString, libTableNames ) )
|
||||||
|
{
|
||||||
|
case 0: return &SYMBOL_LIB_TABLE::GetGlobalLibTable();
|
||||||
|
case 1: return Prj().SchSymbolLibTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::storeCurrentPart()
|
||||||
|
{
|
||||||
|
if( m_my_part && !GetCurLib().IsEmpty() && GetScreen()->IsModify() )
|
||||||
|
m_libMgr->UpdatePart( m_my_part, GetCurLib() ); // UpdatePart() makes a copy
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LIB_EDIT_FRAME::isCurrentPart( const LIB_ID& aLibId ) const
|
||||||
|
{
|
||||||
|
return ( GetCurPart() && aLibId == GetCurPart()->GetLibId() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void LIB_EDIT_FRAME::emptyScreen()
|
||||||
|
{
|
||||||
|
SetCurLib( wxEmptyString );
|
||||||
|
SetCurPart( nullptr );
|
||||||
|
m_aliasName.Empty();
|
||||||
|
m_drawItem = m_lastDrawItem = nullptr;
|
||||||
|
SetScreen( m_dummyScreen );
|
||||||
|
m_dummyScreen->ClearUndoRedoList();
|
||||||
|
Zoom_Automatique( false );
|
||||||
|
Refresh();
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
* Copyright (C) 2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
|
||||||
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||||
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -39,12 +41,14 @@
|
||||||
|
|
||||||
|
|
||||||
class SCH_EDIT_FRAME;
|
class SCH_EDIT_FRAME;
|
||||||
|
class SYMBOL_LIB_TABLE;
|
||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class LIB_ALIAS;
|
class LIB_ALIAS;
|
||||||
class LIB_FIELD;
|
class LIB_FIELD;
|
||||||
class DIALOG_LIB_EDIT_TEXT;
|
class DIALOG_LIB_EDIT_TEXT;
|
||||||
class COMPONENT_TREE;
|
class CMP_TREE_PANE;
|
||||||
class LIB_ID;
|
class LIB_ID;
|
||||||
|
class LIB_MANAGER;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,7 +61,8 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME
|
||||||
LIB_COLLECTOR m_collectedItems; ///< Used for hit testing.
|
LIB_COLLECTOR m_collectedItems; ///< Used for hit testing.
|
||||||
wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
|
wxComboBox* m_partSelectBox; ///< a Box to select a part to edit (if any)
|
||||||
wxComboBox* m_aliasSelectBox; ///< a box to select the alias to edit (if any)
|
wxComboBox* m_aliasSelectBox; ///< a box to select the alias to edit (if any)
|
||||||
COMPONENT_TREE* m_componentTree; ///< component search tree widget
|
CMP_TREE_PANE* m_treePane; ///< component search tree widget
|
||||||
|
LIB_MANAGER* m_libMgr; ///< manager taking care of temporary modificatoins
|
||||||
|
|
||||||
/** Convert of the item currently being drawn. */
|
/** Convert of the item currently being drawn. */
|
||||||
bool m_drawSpecificConvert;
|
bool m_drawSpecificConvert;
|
||||||
|
@ -132,8 +137,6 @@ class LIB_EDIT_FRAME : public SCH_BASE_FRAME
|
||||||
|
|
||||||
LIB_ITEM* locateItem( const wxPoint& aPosition, const KICAD_T aFilterList[] );
|
LIB_ITEM* locateItem( const wxPoint& aPosition, const KICAD_T aFilterList[] );
|
||||||
|
|
||||||
void createComponentTree();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||||
|
@ -141,7 +144,7 @@ public:
|
||||||
~LIB_EDIT_FRAME();
|
~LIB_EDIT_FRAME();
|
||||||
|
|
||||||
/** The nickname of the current library being edited and empty string if none. */
|
/** The nickname of the current library being edited and empty string if none. */
|
||||||
wxString GetCurLib();
|
wxString GetCurLib() const;
|
||||||
|
|
||||||
/** Sets the current library nickname and returns the old library nickname. */
|
/** Sets the current library nickname and returns the old library nickname. */
|
||||||
wxString SetCurLib( const wxString& aLibNickname );
|
wxString SetCurLib( const wxString& aLibNickname );
|
||||||
|
@ -151,7 +154,10 @@ public:
|
||||||
*
|
*
|
||||||
* This is a LIB_PART that I own, it is at best a copy of one in a library.
|
* This is a LIB_PART that I own, it is at best a copy of one in a library.
|
||||||
*/
|
*/
|
||||||
LIB_PART* GetCurPart();
|
LIB_PART* GetCurPart() const
|
||||||
|
{
|
||||||
|
return m_my_part;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take ownership of aPart and notes that it is the one currently being edited.
|
* Take ownership of aPart and notes that it is the one currently being edited.
|
||||||
|
@ -208,6 +214,50 @@ public:
|
||||||
void Process_Special_Functions( wxCommandEvent& event );
|
void Process_Special_Functions( wxCommandEvent& event );
|
||||||
void OnSelectTool( wxCommandEvent& aEvent );
|
void OnSelectTool( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new library. The library is added to the project libraries table.
|
||||||
|
*/
|
||||||
|
void OnCreateNewLibrary( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
addLibraryFile( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an existing library. The library is added to the project libraries table.
|
||||||
|
*/
|
||||||
|
void OnAddLibrary( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
addLibraryFile( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The command event handler to save the changes to the current library.
|
||||||
|
*
|
||||||
|
* A backup file of the current library is saved with the .bak extension before the
|
||||||
|
* changes made to the library are saved.
|
||||||
|
*/
|
||||||
|
void OnSaveLibrary( wxCommandEvent& event );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves all changes in modified libraries.
|
||||||
|
*/
|
||||||
|
void OnSaveAllLibraries( wxCommandEvent& event );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts unsaved changes in a library.
|
||||||
|
*/
|
||||||
|
void OnRevertLibrary( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new part in the selected library.
|
||||||
|
*/
|
||||||
|
void OnCreateNewPart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the selected part for editing.
|
||||||
|
*/
|
||||||
|
void OnEditPart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Routine to read one part.
|
* Routine to read one part.
|
||||||
* The format is that of libraries, but it loads only 1 component.
|
* The format is that of libraries, but it loads only 1 component.
|
||||||
|
@ -217,12 +267,27 @@ public:
|
||||||
void OnImportPart( wxCommandEvent& event );
|
void OnImportPart( wxCommandEvent& event );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function OnExportPart
|
* Creates a new library and backup the current component in this library or exports
|
||||||
* creates a new library and backup the current component in this library or export
|
|
||||||
* the component of the current library.
|
* the component of the current library.
|
||||||
*/
|
*/
|
||||||
void OnExportPart( wxCommandEvent& event );
|
void OnExportPart( wxCommandEvent& event );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves a single part in the selected library. The library file is updated without including
|
||||||
|
* the remaining unsaved changes.
|
||||||
|
*/
|
||||||
|
void OnSavePart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverts unsaved changes in a part, restoring to the last saved state.
|
||||||
|
*/
|
||||||
|
void OnRevertPart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a part from the working copy of a library.
|
||||||
|
*/
|
||||||
|
void OnRemovePart( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
void OnSelectAlias( wxCommandEvent& event );
|
void OnSelectAlias( wxCommandEvent& event );
|
||||||
void OnSelectPart( wxCommandEvent& event );
|
void OnSelectPart( wxCommandEvent& event );
|
||||||
|
|
||||||
|
@ -233,29 +298,10 @@ public:
|
||||||
|
|
||||||
void OnToggleSearchTree( wxCommandEvent& event );
|
void OnToggleSearchTree( wxCommandEvent& event );
|
||||||
|
|
||||||
|
void OnEditSymbolLibTable( wxCommandEvent& aEvent ) override;
|
||||||
|
|
||||||
bool IsSearchTreeShown();
|
bool IsSearchTreeShown();
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a symbol from the current library.
|
|
||||||
*
|
|
||||||
* The deleted entry can be an alias or a component. If the entry is an alias,
|
|
||||||
* it is removed from the component and the list of alias is updated. If the
|
|
||||||
* entry is a component and the list of aliases is empty, the component and all
|
|
||||||
* it drawable items are deleted. Otherwise the first alias in the alias list
|
|
||||||
* becomes the new component name and the other aliases become dependent on
|
|
||||||
* renamed component.
|
|
||||||
*
|
|
||||||
* @note This only deletes the entry in memory. The file does not change.
|
|
||||||
*/
|
|
||||||
void DeleteOnePart( wxCommandEvent& event );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new library symbol.
|
|
||||||
*
|
|
||||||
* If an old component is currently in edit, it is deleted.
|
|
||||||
*/
|
|
||||||
void CreateNewLibraryPart( wxCommandEvent& event );
|
|
||||||
|
|
||||||
void OnEditComponentProperties( wxCommandEvent& event );
|
void OnEditComponentProperties( wxCommandEvent& event );
|
||||||
void InstallFieldsEditorDialog( wxCommandEvent& event );
|
void InstallFieldsEditorDialog( wxCommandEvent& event );
|
||||||
|
|
||||||
|
@ -276,11 +322,12 @@ public:
|
||||||
|
|
||||||
void OnOpenPinTable( wxCommandEvent& aEvent );
|
void OnOpenPinTable( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
void OnSaveCurrentPart( wxCommandEvent& aEvent );
|
|
||||||
|
|
||||||
void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
|
void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateEditingPart( wxUpdateUIEvent& event );
|
void OnUpdateEditingPart( wxUpdateUIEvent& event );
|
||||||
void OnUpdateNotEditingPart( wxUpdateUIEvent& event );
|
void OnUpdateNotEditingPart( wxUpdateUIEvent& event ); // TODO?
|
||||||
|
void OnUpdatePartModified( wxUpdateUIEvent& aEvent );
|
||||||
|
void OnUpdateLibModified( wxUpdateUIEvent& aEvent );
|
||||||
|
void OnUpdateClipboardNotEmpty( wxUpdateUIEvent& aEvent );
|
||||||
void OnUpdateUndo( wxUpdateUIEvent& event );
|
void OnUpdateUndo( wxUpdateUIEvent& event );
|
||||||
void OnUpdateRedo( wxUpdateUIEvent& event );
|
void OnUpdateRedo( wxUpdateUIEvent& event );
|
||||||
void OnUpdateSaveCurrentLib( wxUpdateUIEvent& event );
|
void OnUpdateSaveCurrentLib( wxUpdateUIEvent& event );
|
||||||
|
@ -357,10 +404,7 @@ public:
|
||||||
* Must be called after a schematic change in order to set the "modify" flag of the
|
* Must be called after a schematic change in order to set the "modify" flag of the
|
||||||
* current screen.
|
* current screen.
|
||||||
*/
|
*/
|
||||||
void OnModify()
|
void OnModify();
|
||||||
{
|
|
||||||
GetScreen()->SetModify();
|
|
||||||
}
|
|
||||||
|
|
||||||
const wxString& GetAliasName() { return m_aliasName; }
|
const wxString& GetAliasName() { return m_aliasName; }
|
||||||
|
|
||||||
|
@ -427,6 +471,18 @@ public:
|
||||||
bool IsEditingDrawItem() { return m_drawItem && m_drawItem->InEditMode(); }
|
bool IsEditingDrawItem() { return m_drawItem && m_drawItem->InEditMode(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void loadPart( const wxString& aLibrary, const wxString& aPart, int Unit );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the changes to the current library.
|
||||||
|
*
|
||||||
|
* A backup file of the current library is saved with the .bak extension before the
|
||||||
|
* changes made to the library are saved.
|
||||||
|
* @param aLibrary is the library name.
|
||||||
|
* @param aNewFile Ask for a new file name to save the library.
|
||||||
|
* @return True if the library was successfully saved.
|
||||||
|
*/
|
||||||
|
bool saveLibrary( const wxString& aLibrary, bool aNewFile );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the frame is activated. Tests if the current library exists.
|
* Called when the frame is activated. Tests if the current library exists.
|
||||||
|
@ -445,24 +501,6 @@ private:
|
||||||
*/
|
*/
|
||||||
void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString );
|
void SelectActiveLibrary( const wxString& aLibrary = wxEmptyString );
|
||||||
|
|
||||||
/**
|
|
||||||
* The command event handler to save the changes to the current library.
|
|
||||||
*
|
|
||||||
* A backup file of the current library is saved with the .bak extension before the
|
|
||||||
* changes made to the library are saved.
|
|
||||||
*/
|
|
||||||
void OnSaveActiveLibrary( wxCommandEvent& event );
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves the changes to the current library.
|
|
||||||
*
|
|
||||||
* A backup file of the current library is saved with the .bak extension before the
|
|
||||||
* changes made to the library are saved.
|
|
||||||
* @param newFile Ask for a new file name to save the library.
|
|
||||||
* @return True if the library was successfully saved.
|
|
||||||
*/
|
|
||||||
bool SaveActiveLibrary( bool newFile );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a symbol from the current active library, optionally setting the selected
|
* Loads a symbol from the current active library, optionally setting the selected
|
||||||
* unit and convert.
|
* unit and convert.
|
||||||
|
@ -653,6 +691,33 @@ public:
|
||||||
*/
|
*/
|
||||||
void SVG_PlotComponent( const wxString& aFullFileName );
|
void SVG_PlotComponent( const wxString& aFullFileName );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays a dialog asking the user to select a symbol library table.
|
||||||
|
* @return Pointer to the selected symbol library table or nullptr if cancelled.
|
||||||
|
*/
|
||||||
|
SYMBOL_LIB_TABLE* SelectSymLibTable();
|
||||||
|
|
||||||
|
///> Helper screen used when no part is loaded
|
||||||
|
SCH_SCREEN* m_dummyScreen;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// TODO move to tree pane?
|
||||||
|
LIB_PART* getTargetPart() const;
|
||||||
|
|
||||||
|
LIB_ID getTargetLibId() const;
|
||||||
|
|
||||||
|
wxString getTargetLib() const;
|
||||||
|
|
||||||
|
bool addLibraryFile( bool aCreateNew );
|
||||||
|
|
||||||
|
wxFileName getLibraryFileName( bool aExisting );
|
||||||
|
|
||||||
|
void storeCurrentPart();
|
||||||
|
|
||||||
|
bool isCurrentPart( const LIB_ID& aLibId ) const;
|
||||||
|
|
||||||
|
void emptyScreen();
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE()
|
DECLARE_EVENT_TABLE()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ public:
|
||||||
const LIB_ID* aHighlight = nullptr,
|
const LIB_ID* aHighlight = nullptr,
|
||||||
bool aAllowFields = true );
|
bool aAllowFields = true );
|
||||||
|
|
||||||
void OnEditSymbolLibTable( wxCommandEvent& aEvent );
|
virtual void OnEditSymbolLibTable( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load symbol from symbol library table.
|
* Load symbol from symbol library table.
|
||||||
|
|
|
@ -107,7 +107,7 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
|
||||||
KiBitmap( new_library_xpm ),
|
KiBitmap( new_library_xpm ),
|
||||||
_( "Create a new library" ) );
|
_( "Create a new library" ) );
|
||||||
|
|
||||||
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_LIB, wxEmptyString,
|
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_LIBRARY, wxEmptyString,
|
||||||
KiBitmap( save_library_xpm ),
|
KiBitmap( save_library_xpm ),
|
||||||
_( "Save current library" ) );
|
_( "Save current library" ) );
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
|
||||||
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART, wxEmptyString, KiBitmap( new_component_xpm ),
|
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART, wxEmptyString, KiBitmap( new_component_xpm ),
|
||||||
_( "Create new component" ) );
|
_( "Create new component" ) );
|
||||||
|
|
||||||
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_CURRENT_PART, wxEmptyString,
|
m_mainToolBar->AddTool( ID_LIBEDIT_SAVE_PART, wxEmptyString,
|
||||||
KiBitmap( save_part_in_mem_xpm ), // TODO change icon
|
KiBitmap( save_part_in_mem_xpm ), // TODO change icon
|
||||||
_( "Save component" ) );
|
_( "Save component" ) );
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cmp_tree_pane.h"
|
||||||
|
|
||||||
|
#include <component_tree.h>
|
||||||
|
#include <eeschema_id.h>
|
||||||
|
#include <lib_manager.h>
|
||||||
|
#include <libeditframe.h>
|
||||||
|
#include <symbol_lib_table.h>
|
||||||
|
|
||||||
|
CMP_TREE_PANE::CMP_TREE_PANE( LIB_EDIT_FRAME* aParent, LIB_MANAGER* aLibMgr )
|
||||||
|
: wxPanel( aParent ),
|
||||||
|
m_libEditFrame( aParent ),
|
||||||
|
m_libMgr( aLibMgr )
|
||||||
|
{
|
||||||
|
// Create widgets
|
||||||
|
wxBoxSizer* boxSizer = new wxBoxSizer( wxVERTICAL );
|
||||||
|
|
||||||
|
m_tree = new COMPONENT_TREE( this, &SYMBOL_LIB_TABLE::GetGlobalLibTable(),
|
||||||
|
m_libMgr->GetAdapter(), COMPONENT_TREE::SEARCH );
|
||||||
|
boxSizer->Add( m_tree, 1, wxEXPAND | wxALL, 5 );
|
||||||
|
|
||||||
|
SetSizer( boxSizer );
|
||||||
|
Layout();
|
||||||
|
boxSizer->Fit( this );
|
||||||
|
|
||||||
|
// Setup right click-context menus
|
||||||
|
std::unique_ptr<wxMenu> menuLibrary = std::make_unique<wxMenu>();
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_NEW_LIBRARY, _( "New library..." ) );
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_ADD_LIBRARY, _( "Add existing library..." ) );
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY, _( "Save library" ) );
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_SAVE_LIBRARY_AS, _( "Save library as..." ) );
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_REVERT_LIBRARY, _( "Revert library" ) );
|
||||||
|
menuLibrary->AppendSeparator();
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_NEW_PART, _( "New component..." ) );
|
||||||
|
menuLibrary->Append( ID_LIBEDIT_IMPORT_PART, _( "Import component..." ) );
|
||||||
|
|
||||||
|
std::unique_ptr<wxMenu> menuPart = std::make_unique<wxMenu>();
|
||||||
|
menuPart->Append( ID_LIBEDIT_EDIT_PART, _( "Edit" ) );
|
||||||
|
menuPart->Append( ID_LIBEDIT_REMOVE_PART, _( "Remove" ) );
|
||||||
|
menuPart->Append( ID_LIBEDIT_EXPORT_PART, _( "Export..." ) );
|
||||||
|
menuPart->Append( ID_LIBEDIT_SAVE_PART, _( "Save" ) );
|
||||||
|
menuPart->Append( ID_LIBEDIT_REVERT_PART, _( "Revert" ) );
|
||||||
|
menuPart->AppendSeparator();
|
||||||
|
|
||||||
|
// Append the library menu to the component menu
|
||||||
|
for( size_t i = 0; i < menuLibrary->GetMenuItemCount(); ++i )
|
||||||
|
{
|
||||||
|
wxMenuItem* menuItem = menuLibrary->FindItemByPosition( i );
|
||||||
|
menuPart->Append( menuItem->GetId(), menuItem->GetItemLabel() );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<wxMenu> menuNoSelection = std::make_unique<wxMenu>();
|
||||||
|
menuNoSelection->Append( ID_LIBEDIT_NEW_LIBRARY, _( "New library..." ) );
|
||||||
|
menuNoSelection->Append( ID_LIBEDIT_ADD_LIBRARY, _( "Add existing library..." ) );
|
||||||
|
|
||||||
|
m_tree->SetMenu( CMP_TREE_NODE::LIBID, std::move( menuPart ) );
|
||||||
|
m_tree->SetMenu( CMP_TREE_NODE::LIB, std::move( menuLibrary ) );
|
||||||
|
m_tree->SetMenu( CMP_TREE_NODE::INVALID, std::move( menuNoSelection ) );
|
||||||
|
|
||||||
|
// Event handlers
|
||||||
|
Bind( COMPONENT_SELECTED, &CMP_TREE_PANE::onComponentSelected, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CMP_TREE_PANE::~CMP_TREE_PANE()
|
||||||
|
{
|
||||||
|
delete m_tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CMP_TREE_PANE::onComponentSelected( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
// Repost the event
|
||||||
|
wxCommandEvent evt( ID_LIBEDIT_EDIT_PART );
|
||||||
|
// I cannot figure out why the two methods below do not work..
|
||||||
|
//wxPostEvent( libEditFrame, evt );
|
||||||
|
//wxQueueEvent( m_libEditFrame, new wxCommandEvent( ID_LIBEDIT_EDIT_PART ) );
|
||||||
|
m_libEditFrame->OnEditPart( evt );
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2017 CERN
|
||||||
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
|
*
|
||||||
|
* 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, you may find one here:
|
||||||
|
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CMP_TREE_PANE_H
|
||||||
|
#define CMP_TREE_PANE_H
|
||||||
|
|
||||||
|
#include <wx/panel.h>
|
||||||
|
|
||||||
|
class COMPONENT_TREE;
|
||||||
|
class LIB_EDIT_FRAME;
|
||||||
|
class LIB_MANAGER;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Library Editor pane with component tree and symbol library table selector.
|
||||||
|
*/
|
||||||
|
class CMP_TREE_PANE : public wxPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMP_TREE_PANE( LIB_EDIT_FRAME* aParent, LIB_MANAGER* aLibMgr );
|
||||||
|
~CMP_TREE_PANE();
|
||||||
|
|
||||||
|
COMPONENT_TREE* GetCmpTree() const
|
||||||
|
{
|
||||||
|
return m_tree;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void onSymLibTableSelected( wxCommandEvent& aEvent );
|
||||||
|
void onComponentSelected( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
LIB_EDIT_FRAME* m_libEditFrame;
|
||||||
|
COMPONENT_TREE* m_tree; ///< component search tree widget
|
||||||
|
LIB_MANAGER* m_libMgr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CMP_TREE_PANE_H */
|
Loading…
Reference in New Issue