Library Manager: logic
This commit is contained in:
parent
769c6a8d51
commit
a789b735e9
|
@ -83,6 +83,7 @@ set( EESCHEMA_DLGS
|
|||
)
|
||||
|
||||
set( EESCHEMA_WIDGETS
|
||||
widgets/cmp_tree_pane.cpp
|
||||
widgets/component_tree.cpp
|
||||
widgets/widget_eeschema_color_config.cpp
|
||||
widgets/pin_shape_combobox.cpp
|
||||
|
@ -143,6 +144,8 @@ set( EESCHEMA_SRCS
|
|||
lib_draw_item.cpp
|
||||
lib_export.cpp
|
||||
lib_field.cpp
|
||||
lib_manager.cpp
|
||||
lib_manager_adapter.cpp
|
||||
lib_pin.cpp
|
||||
lib_polyline.cpp
|
||||
lib_rectangle.cpp
|
||||
|
|
|
@ -185,32 +185,22 @@ enum id_eeschema_frm
|
|||
/* Library editor main menubar IDs. */
|
||||
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 */
|
||||
ID_LIBEDIT_NEW_PART,
|
||||
ID_LIBEDIT_EDIT_PART,
|
||||
ID_LIBEDIT_IMPORT_PART,
|
||||
ID_LIBEDIT_EXPORT_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_DELETE_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,
|
||||
ID_LIBEDIT_REMOVE_PART,
|
||||
|
||||
/* Library editor horizontal toolbar IDs. */
|
||||
ID_DE_MORGAN_NORMAL_BUTT,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <class_library.h>
|
||||
#include <wildcards_and_files_ext.h>
|
||||
#include <eeschema_id.h>
|
||||
#include <lib_manager.h>
|
||||
|
||||
#include <wx/filename.h>
|
||||
|
||||
|
@ -46,6 +47,7 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
|||
{
|
||||
wxString msg;
|
||||
m_lastDrawItem = NULL;
|
||||
wxString libName = getTargetLib();
|
||||
|
||||
wxFileDialog dlg( this, _( "Import Symbol" ), m_mruPath,
|
||||
wxEmptyString, SchematicLibraryFileWildcard(),
|
||||
|
@ -55,12 +57,12 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
|||
return;
|
||||
|
||||
wxFileName fn = dlg.GetPath();
|
||||
|
||||
m_mruPath = fn.GetPath();
|
||||
|
||||
wxArrayString symbols;
|
||||
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
|
||||
{
|
||||
pi->EnumerateSymbolLib( symbols, fn.GetFullPath() );
|
||||
|
@ -79,25 +81,25 @@ void LIB_EDIT_FRAME::OnImportPart( wxCommandEvent& event )
|
|||
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();
|
||||
GetScreen()->ClearUndoRedoList();
|
||||
Zoom_Automatique( false );
|
||||
|
||||
// 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();
|
||||
msg.Printf( _( "Symbol '%s' already exists in library '%s'." ), symbolName, libName );
|
||||
DisplayError( this, msg );
|
||||
return;
|
||||
}
|
||||
|
||||
m_libMgr->UpdatePart( entry->GetPart(), libName );
|
||||
loadPart( symbolName, libName, 1 );
|
||||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
||||
{
|
||||
wxString msg, title;
|
||||
LIB_PART* part = GetCurPart();
|
||||
LIB_PART* part = getTargetPart();
|
||||
|
||||
if( !part )
|
||||
{
|
||||
|
@ -173,12 +175,6 @@ void LIB_EDIT_FRAME::OnExportPart( wxCommandEvent& event )
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
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 <schframe.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 <cmp_tree_model_adapter.h>
|
||||
|
@ -201,25 +204,19 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
|
|||
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();
|
||||
|
||||
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_convert = 1;
|
||||
SetShowDeMorgan( GetCurPart()->HasConversion() );
|
||||
|
||||
m_showDeMorgan = false;
|
||||
|
||||
if( part->HasConversion() )
|
||||
m_showDeMorgan = true;
|
||||
|
||||
GetScreen()->ClrModify();
|
||||
Zoom_Automatique( false );
|
||||
DisplayLibInfos();
|
||||
UpdateAliasSelectList();
|
||||
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;
|
||||
wxString msg;
|
||||
|
@ -296,18 +461,15 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
|||
|
||||
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." ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( GetScreen()->IsModify() && !IsOK( this, _( "Include current symbol changes?" ) ) )
|
||||
return false;
|
||||
|
||||
if( newFile )
|
||||
if( aNewFile )
|
||||
{
|
||||
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.
|
||||
if( newFile )
|
||||
if( aNewFile )
|
||||
{
|
||||
wxFileName src = prj.SchSymbolLibTable()->GetFullURI( GetCurLib() );
|
||||
|
||||
|
@ -417,21 +579,13 @@ bool LIB_EDIT_FRAME::SaveActiveLibrary( bool newFile )
|
|||
// Update symbol changes in library.
|
||||
if( GetScreen()->IsModify() )
|
||||
{
|
||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||
|
||||
try
|
||||
{
|
||||
pi->SaveSymbol( fn.GetFullPath(), new LIB_PART( *GetCurPart() ) );
|
||||
}
|
||||
catch( const IO_ERROR& ioe )
|
||||
if( !m_libMgr->FlushLibrary( lib ) )
|
||||
{
|
||||
msg.Printf( _( "Failed to save changes to symbol library file '%s'" ),
|
||||
libFileName.GetFullPath() );
|
||||
DisplayErrorMessage( this, msg, ioe.What() );
|
||||
DisplayErrorMessage( this, _( "Error saving library" ), msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
GetScreen()->ClrModify();
|
||||
}
|
||||
|
||||
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( _( "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 <schframe.h>
|
||||
#include <msgpanel.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#include <general.h>
|
||||
#include <eeschema_id.h>
|
||||
|
@ -44,6 +45,10 @@
|
|||
#include <class_library.h>
|
||||
#include <lib_polyline.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 <kicad_device_context.h>
|
||||
|
@ -53,7 +58,7 @@
|
|||
#include <dialogs/dialog_edit_component_in_lib.h>
|
||||
#include <dialogs/dialog_lib_edit_pin_table.h>
|
||||
|
||||
#include <widgets/component_tree.h>
|
||||
#include <wildcards_and_files_ext.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_ACTIVATE( LIB_EDIT_FRAME::OnActivate )
|
||||
|
||||
// Main horizontal toolbar.
|
||||
EVT_TOOL( ID_LIBEDIT_SAVE_CURRENT_LIB, LIB_EDIT_FRAME::OnSaveActiveLibrary )
|
||||
EVT_TOOL( ID_LIBEDIT_DELETE_PART, LIB_EDIT_FRAME::DeleteOnePart )
|
||||
EVT_TOOL( ID_TO_LIBVIEW, LIB_EDIT_FRAME::OnOpenLibraryViewer )
|
||||
EVT_TOOL( ID_LIBEDIT_NEW_PART, LIB_EDIT_FRAME::CreateNewLibraryPart )
|
||||
// Library actions
|
||||
EVT_TOOL( ID_LIBEDIT_NEW_LIBRARY, LIB_EDIT_FRAME::OnCreateNewLibrary )
|
||||
EVT_TOOL( ID_LIBEDIT_ADD_LIBRARY, LIB_EDIT_FRAME::OnAddLibrary )
|
||||
EVT_TOOL( ID_LIBEDIT_SAVE_LIBRARY, LIB_EDIT_FRAME::OnSaveLibrary )
|
||||
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_REDO, LIB_EDIT_FRAME::GetComponentFromRedoList )
|
||||
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_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_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_ALIAS, LIB_EDIT_FRAME::OnSelectAlias )
|
||||
|
@ -117,7 +132,6 @@ BEGIN_EVENT_TABLE( LIB_EDIT_FRAME, EDA_DRAW_FRAME )
|
|||
|
||||
// menubar commands
|
||||
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_SVG_FILE, LIB_EDIT_FRAME::OnPlotCurrentComponent )
|
||||
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.
|
||||
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_CHECK_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_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_VIEW_DOC, LIB_EDIT_FRAME::OnUpdateViewDoc )
|
||||
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_tempCopyComponent = NULL;
|
||||
m_componentTree = nullptr;
|
||||
m_treePane = nullptr;
|
||||
m_libMgr = nullptr;
|
||||
|
||||
// Delayed initialization
|
||||
if( m_textSize == -1 )
|
||||
|
@ -204,7 +219,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
|
||||
LoadSettings( config() );
|
||||
|
||||
SetScreen( new SCH_SCREEN( aKiway ) );
|
||||
m_dummyScreen = new SCH_SCREEN( aKiway );
|
||||
SetScreen( m_dummyScreen );
|
||||
GetScreen()->m_Center = true;
|
||||
GetScreen()->SetMaxUndoItems( m_UndoRedoCountMax );
|
||||
|
||||
|
@ -224,7 +240,9 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
if( m_canvas )
|
||||
m_canvas->SetEnableBlockCommands( true );
|
||||
|
||||
createComponentTree();
|
||||
m_libMgr = new LIB_MANAGER( *this );
|
||||
m_treePane = new CMP_TREE_PANE( this, m_libMgr );
|
||||
|
||||
ReCreateMenuBar();
|
||||
ReCreateHToolbar();
|
||||
ReCreateVToolbar();
|
||||
|
@ -280,8 +298,8 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
|||
m_auimgr.AddPane( m_messagePanel,
|
||||
wxAuiPaneInfo( mesg ).Name( "MsgPanel" ).Bottom().Layer( 10 ) );
|
||||
|
||||
m_auimgr.AddPane( m_componentTree,
|
||||
wxAuiPaneInfo( vert ).Name( "ComponentTree" ).Left().Row( 1 ) );
|
||||
m_auimgr.AddPane( m_treePane,
|
||||
wxAuiPaneInfo( vert ).Name( "ComponentTree" ).Left().Row( 1 ).Resizable().MinSize( 300, 400 ) );
|
||||
|
||||
m_auimgr.Update();
|
||||
|
||||
|
@ -301,12 +319,14 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
|
|||
Unbind( wxEVT_COMMAND_MENU_SELECTED, &LIB_EDIT_FRAME::OnEditSymbolLibTable, this,
|
||||
ID_EDIT_SYM_LIB_TABLE );
|
||||
|
||||
// current screen is destroyed in EDA_DRAW_FRAME
|
||||
SetScreen( m_dummyScreen );
|
||||
|
||||
m_drawItem = m_lastDrawItem = NULL;
|
||||
|
||||
delete m_tempCopyComponent;
|
||||
delete m_libMgr;
|
||||
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 )
|
||||
{
|
||||
// TODO check all libraries for modifications
|
||||
if( GetScreen()->IsModify() )
|
||||
{
|
||||
int ii = DisplayExitDialog( this, _( "Save the changes in the library before closing?" ) );
|
||||
|
@ -328,7 +349,7 @@ void LIB_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
|
|||
break;
|
||||
|
||||
case wxID_YES:
|
||||
if( SaveActiveLibrary( false ) )
|
||||
if( saveLibrary( GetCurLib(), false ) )
|
||||
break;
|
||||
|
||||
// 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 )
|
||||
{
|
||||
auto& treePane = m_auimgr.GetPane( m_componentTree );
|
||||
auto& treePane = m_auimgr.GetPane( m_treePane );
|
||||
treePane.Show( !IsSearchTreeShown() );
|
||||
m_auimgr.Update();
|
||||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::OnEditSymbolLibTable( wxCommandEvent& aEvent )
|
||||
{
|
||||
SCH_BASE_FRAME::OnEditSymbolLibTable( aEvent );
|
||||
}
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
wxString lib = GetCurLib();
|
||||
wxString lib = getTargetLib();
|
||||
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
||||
|
||||
event.Enable( !lib.empty() && table->HasLibrary( lib ) && table->IsSymbolLibWritable( lib ) &&
|
||||
GetScreen()->IsModify() );
|
||||
m_libMgr->IsLibraryModified( lib ) );
|
||||
}
|
||||
|
||||
|
||||
void LIB_EDIT_FRAME::OnUpdateSaveCurrentLibAs( wxUpdateUIEvent& event )
|
||||
{
|
||||
wxString lib = GetCurLib();
|
||||
wxString lib = getTargetLib();
|
||||
SYMBOL_LIB_TABLE* table = Prj().SchSymbolLibTable();
|
||||
|
||||
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 )
|
||||
{
|
||||
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 );
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
wxASSERT( m_my_part != aPart );
|
||||
|
||||
if( m_my_part != aPart )
|
||||
{
|
||||
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
|
||||
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 )
|
||||
{
|
||||
bool partLocked = GetCurPart()->UnitsLocked();
|
||||
wxString oldName = GetCurPart()->GetName();
|
||||
|
||||
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_libMgr->UpdatePart( GetCurPart(), GetCurLib(), oldName );
|
||||
|
||||
UpdateAliasSelectList();
|
||||
UpdatePartSelectList();
|
||||
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();
|
||||
auto adapter( CMP_TREE_MODEL_ADAPTER::Create( table ) );
|
||||
|
||||
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 ) );
|
||||
GetScreen()->SetModify();
|
||||
storeCurrentPart();
|
||||
m_treePane->GetCmpTree()->Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1490,3 +1440,137 @@ void LIB_EDIT_FRAME::refreshSchematic()
|
|||
// in case any symbols have changed.
|
||||
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) 2008 Wayne Stambaugh <stambaughw@gmail.com>
|
||||
* 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
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -39,12 +41,14 @@
|
|||
|
||||
|
||||
class SCH_EDIT_FRAME;
|
||||
class SYMBOL_LIB_TABLE;
|
||||
class LIB_PART;
|
||||
class LIB_ALIAS;
|
||||
class LIB_FIELD;
|
||||
class DIALOG_LIB_EDIT_TEXT;
|
||||
class COMPONENT_TREE;
|
||||
class CMP_TREE_PANE;
|
||||
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.
|
||||
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)
|
||||
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. */
|
||||
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[] );
|
||||
|
||||
void createComponentTree();
|
||||
|
||||
public:
|
||||
|
||||
LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent );
|
||||
|
@ -141,7 +144,7 @@ public:
|
|||
~LIB_EDIT_FRAME();
|
||||
|
||||
/** 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. */
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
|
@ -208,6 +214,50 @@ public:
|
|||
void Process_Special_Functions( wxCommandEvent& event );
|
||||
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.
|
||||
* The format is that of libraries, but it loads only 1 component.
|
||||
|
@ -217,12 +267,27 @@ public:
|
|||
void OnImportPart( wxCommandEvent& event );
|
||||
|
||||
/**
|
||||
* Function OnExportPart
|
||||
* creates a new library and backup the current component in this library or export
|
||||
* Creates a new library and backup the current component in this library or exports
|
||||
* the component of the current library.
|
||||
*/
|
||||
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 OnSelectPart( wxCommandEvent& event );
|
||||
|
||||
|
@ -233,29 +298,10 @@ public:
|
|||
|
||||
void OnToggleSearchTree( wxCommandEvent& event );
|
||||
|
||||
void OnEditSymbolLibTable( wxCommandEvent& aEvent ) override;
|
||||
|
||||
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 InstallFieldsEditorDialog( wxCommandEvent& event );
|
||||
|
||||
|
@ -276,11 +322,12 @@ public:
|
|||
|
||||
void OnOpenPinTable( wxCommandEvent& aEvent );
|
||||
|
||||
void OnSaveCurrentPart( wxCommandEvent& aEvent );
|
||||
|
||||
void OnUpdateSelectTool( wxUpdateUIEvent& aEvent );
|
||||
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 OnUpdateRedo( 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
|
||||
* current screen.
|
||||
*/
|
||||
void OnModify()
|
||||
{
|
||||
GetScreen()->SetModify();
|
||||
}
|
||||
void OnModify();
|
||||
|
||||
const wxString& GetAliasName() { return m_aliasName; }
|
||||
|
||||
|
@ -427,6 +471,18 @@ public:
|
|||
bool IsEditingDrawItem() { return m_drawItem && m_drawItem->InEditMode(); }
|
||||
|
||||
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.
|
||||
|
@ -445,24 +501,6 @@ private:
|
|||
*/
|
||||
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
|
||||
* unit and convert.
|
||||
|
@ -653,6 +691,33 @@ public:
|
|||
*/
|
||||
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()
|
||||
};
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ public:
|
|||
const LIB_ID* aHighlight = nullptr,
|
||||
bool aAllowFields = true );
|
||||
|
||||
void OnEditSymbolLibTable( wxCommandEvent& aEvent );
|
||||
virtual void OnEditSymbolLibTable( wxCommandEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Load symbol from symbol library table.
|
||||
|
|
|
@ -107,7 +107,7 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
|
|||
KiBitmap( new_library_xpm ),
|
||||
_( "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 ),
|
||||
_( "Save current library" ) );
|
||||
|
||||
|
@ -115,7 +115,7 @@ void LIB_EDIT_FRAME::ReCreateHToolbar()
|
|||
m_mainToolBar->AddTool( ID_LIBEDIT_NEW_PART, wxEmptyString, KiBitmap( new_component_xpm ),
|
||||
_( "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
|
||||
_( "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