Implement simple inheritance for library symbols.

This change completely removes the LIB_ALIAS design pattern an replaces
it by allowing LIB_PART objects to inherit from other LIB_PART objects.
The initial implementation only allows for single inheritance and only
supports the mandatory fields in the derived part because that is all
that the current symbol library file format will support.  Once the new
file format is implemented and saving to the old file format is deprecated,
more complex inheritance will be added.  The LIB_ALIAS information saved
in the document files was move into the LIB_PART object.  This change
impacts virtually every part of the schematic and symbol library editor
code so this commit message is woefully incomplete.

REMOVE: Removed the symbol aliases concept from the schematic and symbol
editors and the symbol viewer.

NEW: Replace the symbol alias concept with simple inheritance that allows
a library symbol to be derived from another library symbol.
This commit is contained in:
Wayne Stambaugh 2019-11-06 14:15:42 -05:00
parent 9f896312ee
commit 54f066fed7
80 changed files with 2697 additions and 4449 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -113,7 +113,7 @@ DIALOG_SHIM::DIALOG_SHIM( wxWindow* aParent, wxWindowID id, const wxString& titl
Bind( wxEVT_BUTTON, &DIALOG_SHIM::OnButton, this );
#ifdef __WINDOWS__
// On Windows, the app top windows can be brought to the foreground (at least temporarily)
// On Windows, the app top windows can be brought to the foreground (at least temporarily)
// in certain circumstances such as when calling an external tool in Eeschema BOM generation.
// So set the parent frame (if exists) to top window to avoid this annoying behavior.
if( kiwayHolder && kiwayHolder->GetType() == KIWAY_HOLDER::FRAME )
@ -235,6 +235,31 @@ bool DIALOG_SHIM::Show( bool show )
}
void DIALOG_SHIM::ResetSize()
{
const char* hash_key;
if( m_hash_key.size() )
{
// a special case like EDA_LIST_DIALOG, which has multiple uses.
hash_key = m_hash_key.c_str();
}
else
{
hash_key = typeid(*this).name();
}
RECT_MAP::iterator it = class_map.find( hash_key );
if( it == class_map.end() )
return;
EDA_RECT rect = it->second;
rect.SetSize( 0, 0 );
class_map[ hash_key ] = rect;
}
bool DIALOG_SHIM::Enable( bool enable )
{
// so we can do logging of this state change:
@ -406,7 +431,8 @@ void DIALOG_SHIM::EndQuasiModal( int retCode )
if( !IsQuasiModal() )
{
wxFAIL_MSG( wxT( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal wasn't called" ) );
wxFAIL_MSG( "either DIALOG_SHIM::EndQuasiModal called twice or ShowQuasiModal"
"wasn't called" );
return;
}
@ -535,7 +561,6 @@ void DIALOG_SHIM::OnCharHook( wxKeyEvent& aEvt )
}
void DIALOG_SHIM::OnGridEditorShown( wxGridEvent& event )
{
SetEscapeId( wxID_NONE );

View File

@ -51,155 +51,30 @@ int LIB_PART::m_subpartIdSeparator = 0;
int LIB_PART::m_subpartFirstId = 'A';
LIB_ALIAS::LIB_ALIAS( const wxString& aName, LIB_PART* aRootPart ) :
EDA_ITEM( LIB_ALIAS_T ),
shared( aRootPart )
{
SetName( aName );
}
LIB_ALIAS::LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootPart ) :
EDA_ITEM( aAlias ),
shared( aRootPart )
{
name = aAlias.name;
description = aAlias.description;
keyWords = aAlias.keyWords;
docFileName = aAlias.docFileName;
}
LIB_ALIAS::~LIB_ALIAS()
{
wxLogTrace( traceSchLibMem, wxT( "%s: destroying alias:'%s'" ),
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ), GetChars( GetName() ) );
wxCHECK_RET( shared, wxT( "~LIB_ALIAS() without a LIB_PART" ) );
if( shared )
shared->RemoveAlias( this );
}
wxString LIB_ALIAS::GetLibNickname() const
{
wxASSERT_MSG( shared, wxT( "LIB_ALIAS without a LIB_PART" ) );
if( shared )
return shared->GetLibraryName();
return wxEmptyString;
}
bool LIB_ALIAS::IsRoot() const
{
return name == shared->GetName();
}
LIB_ID LIB_ALIAS::GetLibId() const
{
LIB_ID id = shared->GetLibId();
id.SetLibItemName( name );
return id;
}
PART_LIB* LIB_ALIAS::GetLib()
{
return shared->GetLib();
}
void LIB_ALIAS::SetName( const wxString& aName )
{
name = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
}
int LIB_ALIAS::GetUnitCount()
{
return shared->GetUnitCount();
}
wxString LIB_ALIAS::GetUnitReference( int aUnit )
{
return LIB_PART::SubReference( aUnit, false );
}
const EDA_RECT LIB_ALIAS::GetBoundingBox() const
{
// a LIB_ALIAS does not really have a bounding box.
// return a 0 size rect.
EDA_RECT dummy;
return dummy;
};
const BOX2I LIB_ALIAS::ViewBBox() const
{
// LIB_ALIAS may be displayed in preview windows, so ensure that it is always
// selected for drawing.
BOX2I bbox;
bbox.SetMaximum();
return bbox;
}
wxString LIB_ALIAS::GetSearchText()
wxString LIB_PART::GetSearchText()
{
// Matches are scored by offset from front of string, so inclusion of this spacer
// discounts matches found after it.
static const wxString discount( wxT( " " ) );
wxString text = GetKeyWords() + discount + GetDescription();
wxString text = GetKeyWords() + discount + GetDescription();
wxString footprint = GetFootprintField().GetText();
// If a footprint is defined for the part, add it to the serach string
if( shared )
if( !footprint.IsEmpty() )
{
wxString footprint = shared->GetFootprintField().GetText();
if( !footprint.IsEmpty() )
text += discount + footprint;
text += discount + footprint;
}
return text;
}
bool LIB_ALIAS::operator==( const wxChar* aName ) const
{
return name == aName;
}
bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 )
bool operator<( const LIB_PART& aItem1, const LIB_PART& aItem2 )
{
return aItem1.GetName() < aItem2.GetName();
}
void LIB_ALIAS::ViewGetLayers( int aLayers[], int& aCount ) const
{
// An alias's fields don't know how to fetch their parent's values so we don't let
// them draw themselves. This means the alias always has to draw them, which means
// it has to "own" their layers as well.
aCount = 6;
aLayers[0] = LAYER_DEVICE;
aLayers[1] = LAYER_DEVICE_BACKGROUND;
aLayers[2] = LAYER_REFERENCEPART;
aLayers[3] = LAYER_VALUEPART;
aLayers[4] = LAYER_FIELDS;
aLayers[5] = LAYER_SELECTION_SHADOWS;
}
/// http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
struct null_deleter
{
@ -209,7 +84,7 @@ struct null_deleter
};
LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
LIB_PART::LIB_PART( const wxString& aName, LIB_PART* aParent, PART_LIB* aLibrary ) :
EDA_ITEM( LIB_PART_T ),
m_me( this, null_deleter() )
{
@ -221,6 +96,9 @@ LIB_PART::LIB_PART( const wxString& aName, PART_LIB* aLibrary ) :
m_showPinNumbers = true;
m_showPinNames = true;
if( aParent )
m_parent = aParent->SharedPtr();
// Add the MANDATORY_FIELDS in RAM only. These are assumed to be present
// when the field editors are invoked.
m_drawings[LIB_FIELD_T].reserve( 4 );
@ -241,7 +119,9 @@ LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
LIB_ITEM* newItem;
m_library = aLibrary;
m_FootprintList = aPart.m_FootprintList;
m_name = aPart.m_name;
m_parent = aPart.m_parent;
m_FootprintList = wxArrayString( aPart.m_FootprintList );
m_unitCount = aPart.m_unitCount;
m_unitsLocked = aPart.m_unitsLocked;
m_pinNameOffset = aPart.m_pinNameOffset;
@ -250,41 +130,197 @@ LIB_PART::LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary ) :
m_dateLastEdition = aPart.m_dateLastEdition;
m_options = aPart.m_options;
m_libId = aPart.m_libId;
m_description = aPart.m_description;
m_keyWords = aPart.m_keyWords;
m_docFileName = aPart.m_docFileName;
for( LIB_ITEM& oldItem : aPart.m_drawings )
{
if( oldItem.HasFlag( IS_NEW ) || oldItem.HasFlag( STRUCT_DELETED ) )
if( ( oldItem.GetFlags() & ( IS_NEW | STRUCT_DELETED ) ) != 0 )
continue;
newItem = (LIB_ITEM*) oldItem.Clone();
newItem->SetParent( this );
m_drawings.push_back( newItem );
}
for( LIB_ALIAS* alias : aPart.m_aliases )
m_aliases.emplace_back( new LIB_ALIAS( *alias, this ) );
}
LIB_PART::~LIB_PART()
{
wxLogTrace( traceSchLibMem,
wxT( "%s: destroying symbol with alias list count of %llu" ),
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
(long long unsigned) m_aliases.size() );
// If the part is being deleted directly rather than through the library,
// delete all of the aliases.
while( m_aliases.size() )
{
LIB_ALIAS* alias = m_aliases.back();
m_aliases.pop_back();
delete alias;
}
}
const wxString LIB_PART::GetLibraryName()
int LIB_PART::Compare( const LIB_PART& aRhs ) const
{
if( m_me == aRhs.m_me )
return 0;
int retv = m_name.Cmp( aRhs.m_name );
if( retv )
return retv;
retv = m_libId.compare( aRhs.m_libId );
if( retv )
return retv;
if( m_parent.lock() < aRhs.m_parent.lock() )
return -1;
if( m_parent.lock() > aRhs.m_parent.lock() )
return 1;
if( m_options != aRhs.m_options )
return ( m_options == ENTRY_NORMAL ) ? -1 : 1;
if( m_unitCount != aRhs.m_unitCount )
return m_unitCount - aRhs.m_unitCount;
if( m_drawings.size() != aRhs.m_drawings.size() )
return m_drawings.size() - aRhs.m_drawings.size();
LIB_ITEMS_CONTAINER::CONST_ITERATOR lhsItem = m_drawings.begin();
LIB_ITEMS_CONTAINER::CONST_ITERATOR rhsItem = aRhs.m_drawings.begin();
while( lhsItem != m_drawings.end() )
{
if( lhsItem->Type() != rhsItem->Type() )
return lhsItem->Type() - rhsItem->Type();
retv = lhsItem->compare( *rhsItem );
if( retv )
return retv;
++lhsItem;
++rhsItem;
}
if( m_FootprintList.GetCount() != aRhs.m_FootprintList.GetCount() )
return m_FootprintList.GetCount() - aRhs.m_FootprintList.GetCount();
for( size_t i = 0; i < m_FootprintList.GetCount(); i++ )
{
retv = m_FootprintList[i].Cmp( aRhs.m_FootprintList[i] );
if( retv )
return retv;
}
retv = m_description.Cmp( aRhs.m_description );
if( retv )
return retv;
retv = m_keyWords.Cmp( aRhs.m_keyWords );
if( retv )
return retv;
retv = m_docFileName.Cmp( aRhs.m_docFileName );
if( retv )
return retv;
if( m_pinNameOffset != aRhs.m_pinNameOffset )
return m_pinNameOffset - aRhs.m_pinNameOffset;
if( m_unitsLocked != aRhs.m_unitsLocked )
return ( m_unitsLocked ) ? 1 : -1;
if( m_showPinNames != aRhs.m_showPinNames )
return ( m_showPinNames ) ? 1 : -1;
if( m_showPinNumbers != aRhs.m_showPinNumbers )
return ( m_showPinNumbers ) ? 1 : -1;
return 0;
}
wxString LIB_PART::GetUnitReference( int aUnit )
{
return LIB_PART::SubReference( aUnit, false );
}
void LIB_PART::SetName( const wxString& aName )
{
wxString validatedName = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
m_name = validatedName;
m_libId.SetLibItemName( validatedName, false );
GetValueField().SetText( validatedName );
}
void LIB_PART::SetParent( LIB_PART* aParent )
{
if( aParent )
m_parent = aParent->SharedPtr();
else
m_parent.reset();
}
std::unique_ptr< LIB_PART > LIB_PART::Flatten() const
{
std::unique_ptr< LIB_PART > retv;
if( IsAlias() )
{
PART_SPTR parent = m_parent.lock();
wxCHECK_MSG( parent, retv,
wxString::Format( "Parent of derived symbol '%s' undefined", m_name ) );
retv.reset( new LIB_PART( *const_cast< LIB_PART* >( this ) ) );
// Flattened symbols have no inheritance.
retv->SetParent( nullptr );
// Flatten parent information into the derived symbol.
retv->SetUnitCount( parent->GetUnitCount() );
LIB_ITEM* newItem;
for( LIB_ITEM& item : parent->GetDrawItems() )
{
// Only add fields from the parent that are not present in the child. The child
// symbol fields are already set.
if( item.Type() == LIB_FIELD_T )
{
LIB_FIELD* field = (LIB_FIELD*) &item;
if( retv->GetField( field->GetId() ) )
continue;
}
newItem = (LIB_ITEM*) item.Clone();
newItem->SetParent( retv.get() );
retv->GetDrawItems().push_back( newItem );
}
if( parent->IsPower() )
retv->SetPower();
else
retv->SetNormal();
retv->LockUnits( parent->UnitsLocked() );
}
else
{
retv.reset( new LIB_PART( *const_cast< LIB_PART* >( this ) ) );
}
return retv;
}
const wxString LIB_PART::GetLibraryName() const
{
if( m_library )
return m_library->GetName();
@ -325,31 +361,6 @@ wxString LIB_PART::SubReference( int aUnit, bool aAddSeparator )
}
const wxString& LIB_PART::GetName() const
{
static wxString dummy;
wxCHECK_MSG( m_aliases.size(), dummy, "no aliases defined for symbol" );
return m_aliases[0]->GetName();
}
void LIB_PART::SetName( const wxString& aName )
{
// The LIB_ALIAS that is the LIB_PART name has to be created so create it.
if( m_aliases.empty() )
m_aliases.push_back( new LIB_ALIAS( aName, this ) );
else
m_aliases[0]->SetName( aName );
wxString validatedName = LIB_ID::FixIllegalChars( aName, LIB_ID::ID_SCH );
m_libId.SetLibItemName( validatedName, false );
GetValueField().SetText( validatedName );
}
void LIB_PART::Print( wxDC* aDc, const wxPoint& aOffset, int aMulti, int aConvert,
const PART_DRAW_OPTIONS& aOpts )
{
@ -457,7 +468,8 @@ void LIB_PART::Plot( PLOTTER* aPlotter, int aUnit, int aConvert,
if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
continue;
item.Plot( aPlotter, aOffset, fill && ( item.m_Fill != FILLED_WITH_BG_BODYCOLOR ), aTransform );
item.Plot( aPlotter, aOffset, fill && ( item.m_Fill != FILLED_WITH_BG_BODYCOLOR ),
aTransform );
}
}
@ -481,15 +493,18 @@ void LIB_PART::PlotLibFields( PLOTTER* aPlotter, int aUnit, int aConvert,
if( aConvert && item.m_Convert && ( item.m_Convert != aConvert ) )
continue;
LIB_FIELD& field = (LIB_FIELD&) item;
// The reference is a special case: we should change the basic text
// to add '?' and the part id
LIB_FIELD& field = (LIB_FIELD&) item;
wxString tmp = field.GetShownText();
if( field.GetId() == REFERENCE )
{
wxString text = field.GetFullText( aUnit );
field.SetText( text );
}
item.Plot( aPlotter, aOffset, fill, aTransform );
field.SetText( tmp );
}
@ -541,11 +556,12 @@ void LIB_PART::AddDrawItem( LIB_ITEM* aItem )
LIB_ITEM* LIB_PART::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType )
{
if( m_drawings.empty( aType ) )
return NULL;
if( aItem == NULL )
return &( *( m_drawings.begin( aType ) ) );
{
LIB_ITEMS_CONTAINER::ITERATOR it1 = m_drawings.begin( aType );
return (it1 != m_drawings.end( aType ) ) ? &( *( m_drawings.begin( aType ) ) ) : nullptr;
}
// Search for the last item, assume aItem is of type aType
wxASSERT( ( aType == TYPE_NOT_INIT ) || ( aType == aItem->Type() ) );
@ -569,9 +585,6 @@ LIB_ITEM* LIB_PART::GetNextDrawItem( LIB_ITEM* aItem, KICAD_T aType )
void LIB_PART::GetPins( LIB_PINS& aList, int aUnit, int aConvert )
{
if( m_drawings.empty( LIB_PIN_T ) )
return;
/* Notes:
* when aUnit == 0: no unit filtering
* when aConvert == 0: no convert (shape selection) filtering
@ -632,23 +645,24 @@ bool LIB_PART::PinsConflictWith( LIB_PART& aOtherPart, bool aTestNums, bool aTes
continue;
// Same number?
if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ))
if( aTestNums && ( eachThisPin->GetNumber() != eachOtherPin->GetNumber() ) )
continue;
// Same name?
if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ))
if( aTestNames && ( eachThisPin->GetName() != eachOtherPin->GetName() ) )
continue;
// Same electrical type?
if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ))
if( aTestType && ( eachThisPin->GetType() != eachOtherPin->GetType() ) )
continue;
// Same orientation?
if( aTestOrientation && ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ))
if( aTestOrientation
&& ( eachThisPin->GetOrientation() != eachOtherPin->GetOrientation() ) )
continue;
// Same length?
if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ))
if( aTestLength && ( eachThisPin->GetLength() != eachOtherPin->GetLength() ) )
continue;
foundMatch = true;
@ -699,10 +713,13 @@ const EDA_RECT LIB_PART::GetUnitBoundingBox( int aUnit, int aConvert ) const
void LIB_PART::ViewGetLayers( int aLayers[], int& aCount ) const
{
aCount = 3;
aCount = 6;
aLayers[0] = LAYER_DEVICE;
aLayers[1] = LAYER_DEVICE_BACKGROUND;
aLayers[2] = LAYER_SELECTION_SHADOWS;
aLayers[2] = LAYER_REFERENCEPART;
aLayers[3] = LAYER_VALUEPART;
aLayers[4] = LAYER_FIELDS;
aLayers[5] = LAYER_SELECTION_SHADOWS;
}
@ -862,18 +879,21 @@ bool LIB_PART::HasConversion() const
return false;
}
void LIB_PART::ClearTempFlags()
{
for( LIB_ITEM& item : m_drawings )
item.ClearTempFlags();
}
void LIB_PART::ClearEditFlags()
{
for( LIB_ITEM& item : m_drawings )
item.ClearEditFlags();
}
LIB_ITEM* LIB_PART::LocateDrawItem( int aUnit, int aConvert,
KICAD_T aType, const wxPoint& aPoint )
{
@ -976,6 +996,15 @@ void LIB_PART::SetUnitCount( int aCount )
}
int LIB_PART::GetUnitCount() const
{
if( PART_SPTR parent = m_parent.lock() )
return parent->GetUnitCount();
return m_unitCount;
}
void LIB_PART::SetConversion( bool aSetConvert )
{
if( aSetConvert == HasConversion() )
@ -1021,142 +1050,6 @@ void LIB_PART::SetConversion( bool aSetConvert )
}
wxArrayString LIB_PART::GetAliasNames( bool aIncludeRoot ) const
{
wxArrayString names;
LIB_ALIASES::const_iterator it;
for( it=m_aliases.begin(); it != m_aliases.end(); ++it )
{
if( !aIncludeRoot && (*it)->IsRoot() )
continue;
names.Add( (*it)->GetName() );
}
return names;
}
bool LIB_PART::HasAlias( const wxString& aName ) const
{
wxCHECK2_MSG( !aName.IsEmpty(), return false,
wxT( "Cannot get alias with an empty name, bad programmer." ) );
for( size_t i = 0; i < m_aliases.size(); i++ )
{
if( aName == m_aliases[i]->GetName() )
return true;
}
return false;
}
void LIB_PART::RemoveAlias( const wxString& aName )
{
LIB_ALIAS* a = GetAlias( aName );
if( a )
RemoveAlias( a );
}
LIB_ALIAS* LIB_PART::RemoveAlias( LIB_ALIAS* aAlias )
{
wxCHECK_MSG( aAlias, NULL, wxT( "Cannot remove alias by NULL pointer." ) );
LIB_ALIAS* nextAlias = NULL;
LIB_ALIASES::iterator it = find( m_aliases.begin(), m_aliases.end(), aAlias );
if( it != m_aliases.end() )
{
bool rename = aAlias->IsRoot();
wxLogTrace( traceSchLibMem,
wxT( "%s: symbol:'%s', alias:'%s', alias count %llu, reference count %ld." ),
GetChars( wxString::FromAscii( __WXFUNCTION__ ) ),
GetChars( GetName() ),
GetChars( aAlias->GetName() ),
(long long unsigned) m_aliases.size(),
m_me.use_count() );
it = m_aliases.erase( it );
if( !m_aliases.empty() )
{
if( it == m_aliases.end() )
it = m_aliases.begin();
nextAlias = *it;
if( rename )
SetName( nextAlias->GetName() );
}
}
return nextAlias;
}
void LIB_PART::RemoveAllAliases()
{
// Remove all of the aliases except the root alias.
while( m_aliases.size() > 1 )
m_aliases.pop_back();
}
LIB_ALIAS* LIB_PART::GetAlias( const wxString& aName ) const
{
wxCHECK2_MSG( !aName.IsEmpty(), return NULL,
wxT( "Cannot get alias with an empty name. Bad programmer!" ) );
for( LIB_ALIAS* alias : m_aliases)
{
if( alias->GetName() == aName )
return alias;
}
return NULL;
}
LIB_ALIAS* LIB_PART::GetRootAlias() const
{
for( LIB_ALIAS* alias : m_aliases )
{
if( alias->IsRoot() )
return alias;
}
return NULL;
}
LIB_ALIAS* LIB_PART::GetAlias( size_t aIndex ) const
{
wxCHECK2_MSG( aIndex < m_aliases.size(), return NULL,
wxT( "Illegal alias list index, bad programmer." ) );
return m_aliases[aIndex];
}
void LIB_PART::AddAlias( const wxString& aName )
{
m_aliases.push_back( new LIB_ALIAS( aName, this ) );
}
void LIB_PART::AddAlias( LIB_ALIAS* aAlias )
{
m_aliases.push_back( aAlias );
}
void LIB_PART::SetSubpartIdNotation( int aSep, int aFirstId )
{
m_subpartFirstId = 'A';

View File

@ -41,12 +41,11 @@ class EDA_RECT;
class LINE_READER;
class OUTPUTFORMATTER;
class PART_LIB;
class LIB_ALIAS;
class LIB_PART;
class LIB_FIELD;
class TEST_LIB_PART_FIXTURE;
typedef std::vector<LIB_ALIAS*> LIB_ALIASES;
typedef std::shared_ptr<LIB_PART> PART_SPTR; ///< shared pointer to LIB_PART
typedef std::weak_ptr<LIB_PART> PART_REF; ///< weak pointer to LIB_PART
typedef MULTIVECTOR<LIB_ITEM, LIB_ARC_T, LIB_FIELD_T> LIB_ITEMS_CONTAINER;
@ -61,135 +60,7 @@ enum LIBRENTRYOPTIONS
};
/**
* Part library alias object definition.
*
* Part aliases are not really parts. An alias uses the part definition
* (graphic, pins...) but has its own name, keywords and documentation. Therefore, when
* the part is modified, alias of this part are modified. This is a simple
* method to create parts that have the same physical layout with different names
* such as 74LS00, 74HC00 ... and many op amps.
*/
class LIB_ALIAS : public EDA_ITEM, public LIB_TREE_ITEM
{
/**
* Actual LIB_PART referenced by [multiple] aliases.
*
* @note - Do not delete the shared part. The shared part is shared by
* all of the aliases associated with it. A shared LIB_PART will
* be deleted when all LIB_ALIASes pointing to it are deleted.
*/
LIB_PART* shared;
protected:
wxString name;
wxString description; ///< documentation for info
wxString keyWords; ///< keyword list (used for search for parts by keyword)
wxString docFileName; ///< Associate doc file name
public:
LIB_ALIAS( const wxString& aName, LIB_PART* aRootComponent );
LIB_ALIAS( const LIB_ALIAS& aAlias, LIB_PART* aRootComponent = NULL );
virtual ~LIB_ALIAS();
virtual wxString GetClass() const override
{
return wxT( "LIB_ALIAS" );
}
// a LIB_ALIAS does not really have a bounding box.
// But because it is derived from EDA_ITEM, returns a dummy bounding box
// to avoid useless messages in debug mode
const EDA_RECT GetBoundingBox() const override;
/**
* Returns a default bounding box for the alias. This will be set to the full
* bounding size, ensuring that the alias is always drawn when it is used on screen.
*
* N.B. This is acceptable only because there is typically only a single LIB_ALIAS
* element being drawn (e.g. in the symbol browser)
* @return a maximum size view bounding box
*/
virtual const BOX2I ViewBBox() const override;
/**
* Get the shared LIB_PART.
*
* @return LIB_PART* - the LIB_PART shared by
* this LIB_ALIAS with possibly other LIB_ALIASes.
*/
LIB_PART* GetPart() const
{
return shared;
}
PART_LIB* GetLib();
LIB_ID GetLibId() const override;
wxString GetLibNickname() const override;
const wxString& GetName() const override { return name; }
void SetName( const wxString& aName );
void SetDescription( const wxString& aDescription )
{
description = aDescription;
}
const wxString& GetDescription() override { return description; }
void SetKeyWords( const wxString& aKeyWords )
{
keyWords = aKeyWords;
}
const wxString& GetKeyWords() const { return keyWords; }
void SetDocFileName( const wxString& aDocFileName )
{
docFileName = aDocFileName;
}
const wxString& GetDocFileName() const { return docFileName; }
wxString GetSearchText() override;
/**
* For symbols having aliases, IsRoot() indicates the principal item.
*/
bool IsRoot() const override;
/**
* For symbols with units, return the number of units.
*/
int GetUnitCount() override;
/**
* For symbols with units, return an identifier for unit x.
*/
wxString GetUnitReference( int aUnit ) override;
/**
* KEEPCASE sensitive comparison of the part entry name.
*/
bool operator==( const wxChar* aName ) const;
bool operator!=( const wxChar* aName ) const
{
return !( *this == aName );
}
bool operator==( const LIB_ALIAS* aAlias ) const { return this == aAlias; }
void ViewGetLayers( int aLayers[], int& aCount ) const override;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
#endif
};
extern bool operator<( const LIB_ALIAS& aItem1, const LIB_ALIAS& aItem2 );
extern bool operator<( const LIB_PART& aItem1, const LIB_PART& aItem2 );
struct PART_DRAW_OPTIONS
@ -217,10 +88,14 @@ struct PART_DRAW_OPTIONS
* A library symbol object is typically saved and loaded in a part library file (.lib).
* Library symbols are different from schematic symbols.
*/
class LIB_PART : public EDA_ITEM
class LIB_PART : public EDA_ITEM, public LIB_TREE_ITEM
{
PART_SPTR m_me; ///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
///< http://www.boost.org/doc/libs/1_55_0/libs/smart_ptr/sp_techniques.html#weak_without_shared
PART_SPTR m_me;
PART_REF m_parent; ///< Use for inherited symbols.
LIB_ID m_libId;
int m_pinNameOffset; ///< The offset in mils to draw the pin name. Set to 0
///< to draw the pin name above the pin.
bool m_unitsLocked; ///< True if part has multiple units and changing
@ -233,31 +108,35 @@ class LIB_PART : public EDA_ITEM
LIB_ITEMS_CONTAINER m_drawings; ///< Drawing items of this part.
wxArrayString m_FootprintList; /**< List of suitable footprint names for the
part (wild card names accepted). */
LIB_ALIASES m_aliases; ///< List of alias object pointers associated with the
///< part.
PART_LIB* m_library; ///< Library the part belongs to if any.
wxString m_name; ///< Symbol name.
wxString m_description; ///< documentation for info
wxString m_keyWords; ///< keyword list (used for search for parts by keyword)
wxString m_docFileName; ///< Associate doc file name
static int m_subpartIdSeparator; ///< the separator char between
///< the subpart id and the reference
///< like U1A ( m_subpartIdSeparator = 0 ) or U1.A or U1-A
static int m_subpartFirstId; ///< the ascii char value to calculate the subpart symbol id
///< from the part number: only 'A', 'a' or '1' can be used,
///< other values have no sense.
private:
///< the subpart id and the reference like U1A
///< ( m_subpartIdSeparator = 0 ) or U1.A or U1-A
static int m_subpartFirstId; ///< the ASCII char value to calculate the subpart
///< symbol id from the part number: only 'A', 'a'
///< or '1' can be used, other values have no sense.
void deleteAllFields();
public:
LIB_PART( const wxString& aName, PART_LIB* aLibrary = NULL );
LIB_PART( const wxString& aName, LIB_PART* aParent = nullptr, PART_LIB* aLibrary = nullptr );
/**
* Copy constructor.
*/
LIB_PART( LIB_PART& aPart, PART_LIB* aLibrary = NULL );
virtual ~LIB_PART();
PART_SPTR SharedPtr()
{
// clone a shared pointer
return m_me;
}
PART_SPTR SharedPtr() { return m_me; }
void SetParent( LIB_PART* aParent = nullptr );
PART_REF& GetParent() { return m_parent; }
virtual wxString GetClass() const override
{
@ -265,56 +144,54 @@ public:
}
virtual void SetName( const wxString& aName );
const wxString& GetName() const;
const wxString GetName() const override { return m_name; }
const LIB_ID& GetLibId() const { return m_libId; }
LIB_ID GetLibId() const override { return m_libId; }
void SetLibId( const LIB_ID& aLibId ) { m_libId = aLibId; }
const wxString GetLibraryName();
wxString GetLibNickname() const override { return GetLibraryName(); }
void SetDescription( const wxString& aDescription )
{
m_description = aDescription;
}
const wxString GetDescription() override { return m_description; }
void SetKeyWords( const wxString& aKeyWords )
{
m_keyWords = aKeyWords;
}
const wxString GetKeyWords() const { return m_keyWords; }
void SetDocFileName( const wxString& aDocFileName )
{
m_docFileName = aDocFileName;
}
const wxString GetDocFileName() const { return m_docFileName; }
wxString GetSearchText() override;
/**
* For symbols derived from other symbols, IsRoot() indicates no derivation.
*/
bool IsRoot() const override { return m_parent.use_count() == 0; }
bool IsAlias() const { return !IsRoot(); }
const wxString GetLibraryName() const;
PART_LIB* GetLib() { return m_library; }
void SetLib( PART_LIB* aLibrary ) { m_library = aLibrary; }
wxArrayString GetAliasNames( bool aIncludeRoot = true ) const;
LIB_ALIASES GetAliases() const { return m_aliases; }
size_t GetAliasCount() const { return m_aliases.size(); }
LIB_ALIAS* GetAlias( size_t aIndex ) const;
LIB_ALIAS* GetAlias( const wxString& aName ) const;
LIB_ALIAS* GetRootAlias() const;
timestamp_t GetDateLastEdition() const { return m_dateLastEdition; }
/**
* Add an alias \a aName to the part.
*
* Duplicate alias names are not added to the alias list. Debug builds will raise an
* assertion. Release builds will fail silently.
*
* @param aName - Name of alias to add.
*/
void AddAlias( const wxString& aName );
void AddAlias( LIB_ALIAS* aAlias );
/**
* Test if alias \a aName is in part alias list.
*
* Alias name comparisons are case insensitive.
*
* @param aName - Name of alias.
* @return True if alias name in alias list.
*/
bool HasAlias( const wxString& aName ) const;
void RemoveAlias( const wxString& aName );
LIB_ALIAS* RemoveAlias( LIB_ALIAS* aAlias );
void RemoveAllAliases();
wxArrayString& GetFootprints() { return m_FootprintList; }
wxArrayString GetFootprints() const { return m_FootprintList; }
void SetFootprintFilters( const wxArrayString& aFootprintFilters )
{
m_FootprintList = aFootprintFilters;
}
void ViewGetLayers( int aLayers[], int& aCount ) const override;
@ -384,7 +261,7 @@ public:
void GetFields( LIB_FIELDS& aList );
/**
* Findd a field within this part matching \a aFieldName and returns it or NULL if not found.
* Find a field within this part matching \a aFieldName and returns it or NULL if not found.
*/
LIB_FIELD* FindField( const wxString& aFieldName );
@ -579,10 +456,7 @@ public:
*
* @return LIB_ITEMS_CONTAINER& - Reference to the draw item object container.
*/
LIB_ITEMS_CONTAINER& GetDrawItems()
{
return m_drawings;
}
LIB_ITEMS_CONTAINER& GetDrawItems() { return m_drawings; }
SEARCH_RESULT Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] ) override;
@ -597,7 +471,12 @@ public:
* @param count - Number of units per package.
*/
void SetUnitCount( int count );
int GetUnitCount() const { return m_unitCount; }
int GetUnitCount() const override;
/**
* Return an identifier for \a aUnit for symbols with units.
*/
wxString GetUnitReference( int aUnit ) override;
/**
* @return true if the part has multiple units per part.
@ -609,7 +488,7 @@ public:
* @return the sub reference for part having multiple units per part.
* The sub reference identify the part (or unit)
* @param aUnit = the part identifier ( 1 to max count)
* @param aAddSeparator = true (default) to prpebd the sub ref
* @param aAddSeparator = true (default) to prepend the sub ref
* by the separator symbol (if any)
* Note: this is a static function.
*/
@ -679,7 +558,28 @@ public:
void SetShowPinNumbers( bool aShow ) { m_showPinNumbers = aShow; }
bool ShowPinNumbers() { return m_showPinNumbers; }
bool operator==( const LIB_PART* aPart ) const { return this == aPart; }
/**
* Comparison test that can be used for operators.
*
* @param aRhs is the right hand side symbol used for comparison.
*
* @return -1 if this symbol is less than \a aRhs
* 1 if this symbol is greater than \a aRhs
* 0 if this symbol is the same as \a aRhs
*/
int Compare( const LIB_PART& aRhs ) const;
bool operator==( const LIB_PART* aPart ) const { return this == aPart; }
bool operator==( const LIB_PART& aPart ) const { return Compare( aPart ) == 0; }
/**
* Return a flattened symbol inheritance to the caller.
*
* If the symbol does not inherit from another symbol, a copy of the symbol is returned.
*
* @return a flattened symbol on the heap
*/
std::unique_ptr< LIB_PART > Flatten() const;
#if defined(DEBUG)
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2004-2016 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) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -146,7 +146,7 @@ void PART_LIB::EnableBuffering( bool aEnable )
}
void PART_LIB::GetAliasNames( wxArrayString& aNames ) const
void PART_LIB::GetPartNames( wxArrayString& aNames ) const
{
m_plugin->EnumerateSymbolLib( aNames, fileName.GetFullPath(), m_properties.get() );
@ -154,44 +154,27 @@ void PART_LIB::GetAliasNames( wxArrayString& aNames ) const
}
void PART_LIB::GetAliases( std::vector<LIB_ALIAS*>& aAliases ) const
void PART_LIB::GetParts( std::vector<LIB_PART*>& aSymbols ) const
{
m_plugin->EnumerateSymbolLib( aAliases, fileName.GetFullPath(), m_properties.get() );
m_plugin->EnumerateSymbolLib( aSymbols, fileName.GetFullPath(), m_properties.get() );
std::sort( aAliases.begin(), aAliases.end(),
[](LIB_ALIAS *lhs, LIB_ALIAS *rhs) -> bool
std::sort( aSymbols.begin(), aSymbols.end(),
[](LIB_PART *lhs, LIB_PART *rhs) -> bool
{ return lhs->GetName() < rhs->GetName(); });
}
LIB_ALIAS* PART_LIB::FindAlias( const wxString& aName ) const
{
LIB_ALIAS* alias = m_plugin->LoadSymbol( fileName.GetFullPath(), aName, m_properties.get() );
// Set the library to this even though technically the legacy cache plugin owns the
// symbols. This allows the symbol library table conversion tool to determine the
// correct library where the symbol was found.
if( alias && alias->GetPart() && !alias->GetPart()->GetLib() )
alias->GetPart()->SetLib( const_cast<PART_LIB*>( this ) );
return alias;
}
LIB_ALIAS* PART_LIB::FindAlias( const LIB_ID& aLibId ) const
{
return FindAlias( aLibId.Format().wx_str() );
}
LIB_PART* PART_LIB::FindPart( const wxString& aName ) const
{
LIB_ALIAS* alias = FindAlias( aName );
LIB_PART* symbol = m_plugin->LoadSymbol( fileName.GetFullPath(), aName, m_properties.get() );
if( alias != NULL )
return alias->GetPart();
// Set the library to this even though technically the legacy cache plugin owns the
// symbols. This allows the symbol library table conversion tool to determine the
// correct library where the symbol was found.
if( symbol && !symbol->GetLib() )
symbol->SetLib( const_cast<PART_LIB*>( this ) );
return NULL;
return symbol;
}
@ -204,7 +187,8 @@ LIB_PART* PART_LIB::FindPart( const LIB_ID& aLibId ) const
void PART_LIB::AddPart( LIB_PART* aPart )
{
// add a clone, not the caller's copy, the plugin take ownership of the new symbol.
m_plugin->SaveSymbol( fileName.GetFullPath(), new LIB_PART( *aPart, this ), m_properties.get() );
m_plugin->SaveSymbol( fileName.GetFullPath(), new LIB_PART( *aPart->SharedPtr().get(), this ),
m_properties.get() );
// If we are not buffering, the library file is updated immediately when the plugin
// SaveSymbol() function is called.
@ -215,11 +199,11 @@ void PART_LIB::AddPart( LIB_PART* aPart )
}
LIB_ALIAS* PART_LIB::RemoveAlias( LIB_ALIAS* aEntry )
LIB_PART* PART_LIB::RemovePart( LIB_PART* aEntry )
{
wxCHECK_MSG( aEntry != NULL, NULL, "NULL pointer cannot be removed from library." );
m_plugin->DeleteAlias( fileName.GetFullPath(), aEntry->GetName(), m_properties.get() );
m_plugin->DeleteSymbol( fileName.GetFullPath(), aEntry->GetName(), m_properties.get() );
// If we are not buffering, the library file is updated immediately when the plugin
// SaveSymbol() function is called.
@ -256,19 +240,18 @@ PART_LIB* PART_LIB::LoadLibrary( const wxString& aFileName )
{
std::unique_ptr<PART_LIB> lib( new PART_LIB( LIBRARY_TYPE_EESCHEMA, aFileName ) );
std::vector<LIB_ALIAS*> aliases;
std::vector<LIB_PART*> parts;
// This loads the library.
lib->GetAliases( aliases );
lib->GetParts( parts );
// Now, set the LIB_PART m_library member but it will only be used
// when loading legacy libraries in the future. Once the symbols in the
// schematic have a full #LIB_ID, this will not get called.
for( size_t ii = 0; ii < aliases.size(); ii++ )
for( size_t ii = 0; ii < parts.size(); ii++ )
{
LIB_ALIAS* alias = aliases[ii];
LIB_PART* part = parts[ii];
if( alias->GetPart() )
alias->GetPart()->SetLib( lib.get() );
part->SetLib( lib.get() );
}
PART_LIB* ret = lib.release();
@ -394,26 +377,7 @@ LIB_PART* PART_LIBS::FindLibPart( const LIB_ID& aLibId, const wxString& aLibrary
}
LIB_ALIAS* PART_LIBS::FindLibraryAlias( const LIB_ID& aLibId, const wxString& aLibraryName )
{
LIB_ALIAS* entry = NULL;
for( PART_LIB& lib : *this )
{
if( !aLibraryName.IsEmpty() && lib.GetName() != aLibraryName )
continue;
entry = lib.FindAlias( aLibId.GetLibItemName().wx_str() );
if( entry )
break;
}
return entry;
}
void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates,
void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_PART*>& aCandidates,
const wxString& aEntryName,
const wxString& aLibraryName )
{
@ -422,17 +386,17 @@ void PART_LIBS::FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates,
if( !aLibraryName.IsEmpty() && lib.GetName() != aLibraryName )
continue;
wxArrayString aliasNames;
wxArrayString partNames;
lib.GetAliasNames( aliasNames );
lib.GetPartNames( partNames );
if( aliasNames.IsEmpty() )
if( partNames.IsEmpty() )
continue;
for( size_t i = 0; i < aliasNames.size(); i++ )
for( size_t i = 0; i < partNames.size(); i++ )
{
if( aliasNames[i].CmpNoCase( aEntryName ) == 0 )
aCandidates.push_back( lib.FindAlias( aliasNames[i] ) );
if( partNames[i].CmpNoCase( aEntryName ) == 0 )
aCandidates.push_back( lib.FindPart( partNames[i] ) );
}
}
}

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2017 KiCad Developers, see change_log.txt for contributors.
* Copyright (C) 2004-2019 KiCad Developers, see change_log.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -31,15 +31,16 @@
#ifndef CLASS_LIBRARY_H
#define CLASS_LIBRARY_H
#include <boost/ptr_container/ptr_vector.hpp>
#include <wx/filename.h>
#include <class_libentry.h>
#include <sch_io_mgr.h>
#include <project.h>
#include <map>
class LIB_PART;
class LIB_ID;
class LINE_READER;
class OUTPUTFORMATTER;
@ -163,9 +164,9 @@ class PART_LIB;
class wxRegEx;
/**
* LIB_ALIAS map sorting.
* LIB_PART map sorting.
*/
struct AliasMapSort
struct LibPartMapSort
{
bool operator() ( const wxString& aItem1, const wxString& aItem2 ) const
{
@ -173,11 +174,11 @@ struct AliasMapSort
}
};
/// Alias map used by part library object.
/// Part map used by part library object.
typedef std::map< wxString, LIB_ALIAS*, AliasMapSort > LIB_ALIAS_MAP;
typedef std::vector< LIB_ALIAS* > LIB_ALIASES;
typedef boost::ptr_vector< PART_LIB > PART_LIBS_BASE;
typedef std::map< wxString, LIB_PART*, LibPartMapSort > LIB_PART_MAP;
typedef std::vector< LIB_PART* > LIB_PARTS;
typedef boost::ptr_vector< PART_LIB > PART_LIBS_BASE;
/**
@ -276,21 +277,8 @@ public:
LIB_PART* FindLibPart( const LIB_ID& aLibId, const wxString& aLibraryName = wxEmptyString );
/**
* Function FindLibraryEntry
* searches all libraries in the list for an entry.
* Search all libraries in the list for a #LIB_PART using a case insensitive comparison.
*
* The object can be either a part or an alias.
*
* @param aLibId - The library indentifaction of entry to search for (case sensitive).
* @param aLibraryName - Name of the library to search.
* @return The entry object if found, otherwise NULL.
*/
LIB_ALIAS* FindLibraryAlias( const LIB_ID& aLibId,
const wxString& aLibraryName = wxEmptyString );
/**
* Function FindLibraryNearEntries
* Searches all libraries in the list for an entry, using a case insensitive comparison.
* Helper function used in dialog to find all candidates.
* During a long time, eeschema was using a case insensitive search.
* Therefore, for old schematics (<= 2013), or libs, for some components,
@ -301,7 +289,7 @@ public:
* @param aLibraryName - Name of the library to search.
* @param aCandidates - a std::vector to store candidates
*/
void FindLibraryNearEntries( std::vector<LIB_ALIAS*>& aCandidates, const wxString& aEntryName,
void FindLibraryNearEntries( std::vector<LIB_PART*>& aCandidates, const wxString& aEntryName,
const wxString& aLibraryName = wxEmptyString );
int GetLibraryCount() { return size(); }
@ -310,6 +298,9 @@ public:
/**
* Object used to load, save, search, and otherwise manipulate symbol library files.
*
* @warning This code is obsolete with the exception of the cache library. All other
* symbol library I/O is managed by the #SCH_IO_MGR object.
*/
class PART_LIB
{
@ -369,33 +360,20 @@ public:
*
* @param aNames - String array to place entry names into.
*/
void GetAliasNames( wxArrayString& aNames ) const;
void GetPartNames( wxArrayString& aNames ) const;
/**
* Load a vector with all the entries in this library.
*
* @param aAliases - vector to receive the aliases.
* @param aParts - vector to receive the aliases.
*/
void GetAliases( std::vector<LIB_ALIAS*>& aAliases ) const;
void GetParts( std::vector<LIB_PART*>& aPart) const;
/**
* Find #LIB_ALIAS by \a aName.
*
* @param aName - Name of entry, case sensitive.
* @return #LIB_ALIAS* if found. NULL if not found.
*/
LIB_ALIAS* FindAlias( const wxString& aName ) const;
LIB_ALIAS* FindAlias( const LIB_ID& aLibId ) const;
/**
* Find part by \a aName.
*
* This is a helper for FindEntry so casting a LIB_ALIAS pointer to
* a LIB_PART pointer is not required.
* Find #LIB_PART by \a aName.
*
* @param aName - Name of part, case sensitive.
* @return LIB_PART* - part if found, else NULL.
* @return LIB_PART pointer part if found, else NULL.
*/
LIB_PART* FindPart( const wxString& aName ) const;
@ -422,10 +400,11 @@ public:
* @param aEntry - Entry to remove from library.
* @return The next entry in the library or NULL if the library is empty.
*/
LIB_ALIAS* RemoveAlias( LIB_ALIAS* aEntry );
LIB_PART* RemovePart( LIB_PART* aEntry );
/**
* Replace an existing part entry in the library.
*
* Note a part can have an alias list,
* so these alias will be added in library (and previously existing alias removed)
* @param aOldPart - The part to replace.

View File

@ -41,6 +41,7 @@
#include <widgets/symbol_preview_widget.h>
#include <wx/clipbrd.h>
#include <kiface_i.h>
#include <class_libentry.h>
#define SYM_CHOOSER_HSASH wxT( "SymbolChooserHSashPosition" )
#define SYM_CHOOSER_VSASH wxT( "SymbolChooserVSashPosition" )
@ -152,7 +153,8 @@ DIALOG_CHOOSE_COMPONENT::DIALOG_CHOOSE_COMPONENT( SCH_BASE_FRAME* aParent, const
m_hsplitter->SetSashPosition( m_config->Read( SYM_CHOOSER_HSASH, HorizPixelsFromDU( 220 ) ) );
if( m_vsplitter )
m_vsplitter->SetSashPosition( m_config->Read( SYM_CHOOSER_VSASH, VertPixelsFromDU( 230 ) ) );
m_vsplitter->SetSashPosition( m_config->Read( SYM_CHOOSER_VSASH,
VertPixelsFromDU( 230 ) ) );
wxSize dlgSize( m_config->Read( SYM_CHOOSER_WIDTH_KEY, HorizPixelsFromDU( 390 ) ),
m_config->Read( SYM_CHOOSER_HEIGHT_KEY, VertPixelsFromDU( 300 ) ) );
@ -353,11 +355,11 @@ void DIALOG_CHOOSE_COMPONENT::ShowFootprintFor( LIB_ID const& aLibId )
if( !m_fp_preview || !m_fp_preview->IsInitialized() )
return;
LIB_ALIAS* alias = nullptr;
LIB_PART* symbol = nullptr;
try
{
alias = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
symbol = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
}
catch( const IO_ERROR& ioe )
{
@ -367,10 +369,10 @@ void DIALOG_CHOOSE_COMPONENT::ShowFootprintFor( LIB_ID const& aLibId )
ioe.What() ) );
}
if( !alias )
if( !symbol )
return;
LIB_FIELD* fp_field = alias->GetPart()->GetField( FOOTPRINT );
LIB_FIELD* fp_field = symbol->GetField( FOOTPRINT );
wxString fp_name = fp_field ? fp_field->GetFullText() : wxString( "" );
ShowFootprint( fp_name );
@ -411,13 +413,13 @@ void DIALOG_CHOOSE_COMPONENT::PopulateFootprintSelector( LIB_ID const& aLibId )
m_fp_sel_ctrl->ClearFilters();
LIB_ALIAS* alias = nullptr;
LIB_PART* symbol = nullptr;
if( aLibId.IsValid() )
{
try
{
alias = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
symbol = Prj().SchSymbolLibTable()->LoadSymbol( aLibId );
}
catch( const IO_ERROR& ioe )
{
@ -429,16 +431,16 @@ void DIALOG_CHOOSE_COMPONENT::PopulateFootprintSelector( LIB_ID const& aLibId )
}
}
if( alias != nullptr )
if( symbol != nullptr )
{
LIB_PINS temp_pins;
LIB_FIELD* fp_field = alias->GetPart()->GetField( FOOTPRINT );
LIB_FIELD* fp_field = symbol->GetField( FOOTPRINT );
wxString fp_name = fp_field ? fp_field->GetFullText() : wxString( "" );
alias->GetPart()->GetPins( temp_pins );
symbol->GetPins( temp_pins );
m_fp_sel_ctrl->FilterByPinCount( temp_pins.size() );
m_fp_sel_ctrl->FilterByFootprintFilters( alias->GetPart()->GetFootprints(), true );
m_fp_sel_ctrl->FilterByFootprintFilters( symbol->GetFootprints(), true );
m_fp_sel_ctrl->SetDefaultFootprint( fp_name );
m_fp_sel_ctrl->UpdateList();
m_fp_sel_ctrl->Enable();

View File

@ -33,7 +33,8 @@
#include <widgets/wx_grid.h>
#include <widgets/grid_text_button_helpers.h>
#include <lib_edit_frame.h>
#include <class_library.h>
#include <lib_manager.h>
#include <class_libentry.h>
#include <symbol_lib_table.h>
#include <sch_item.h>
#include <sch_component.h>
@ -51,6 +52,8 @@
#define LibEditFieldsShownColumnsKey wxT( "LibEditFieldsShownColumns" )
int DIALOG_EDIT_COMPONENT_IN_LIBRARY::m_lastOpenedPage = 0;
DIALOG_EDIT_COMPONENT_IN_LIBRARY::LAST_LAYOUT
DIALOG_EDIT_COMPONENT_IN_LIBRARY::m_lastLayout = DIALOG_EDIT_COMPONENT_IN_LIBRARY::NONE;
DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRAME* aParent,
@ -58,7 +61,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( aParent ),
m_Parent( aParent ),
m_libEntry( aLibEntry ),
m_currentAlias( wxNOT_FOUND ),
m_pinNameOffset( aParent, m_nameOffsetLabel, m_nameOffsetCtrl, m_nameOffsetUnits, true ),
m_delayedFocusCtrl( nullptr ),
m_delayedFocusGrid( nullptr ),
@ -71,37 +73,17 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
// Give a bit more room for combobox editors
m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + 4 );
m_aliasGrid->SetDefaultRowSize( m_aliasGrid->GetDefaultRowSize() + 4 );
// Work around a bug in wxWidgets where it fails to recalculate the grid height
// after changing the default row size
m_aliasGrid->AppendRows( 1 );
m_aliasGrid->DeleteRows( m_grid->GetNumberRows() - 1, 1 );
m_fields = new FIELDS_GRID_TABLE<LIB_FIELD>( this, aParent, m_libEntry );
m_grid->SetTable( m_fields );
m_grid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
m_aliasGrid->PushEventHandler( new FIELDS_GRID_TRICKS( m_grid, this ) );
// Show/hide columns according to the user's preference
m_config->Read( LibEditFieldsShownColumnsKey, &m_shownColumns, wxT( "0 1 2 3 4 5 6 7" ) );
m_grid->ShowHideColumns( m_shownColumns );
// Hide non-overridden rows in aliases grid
m_aliasGrid->HideRow( REFERENCE );
m_aliasGrid->HideRow( FOOTPRINT );
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetReadOnly();
m_aliasGrid->SetColAttr( FDC_NAME, attr );
m_aliasGrid->SetCellValue( VALUE, FDC_NAME, TEMPLATE_FIELDNAME::GetDefaultFieldName( VALUE ) );
m_aliasGrid->SetCellValue( DATASHEET, FDC_NAME,
TEMPLATE_FIELDNAME::GetDefaultFieldName( DATASHEET ) );
attr = new wxGridCellAttr;
attr->SetEditor( new GRID_CELL_URL_EDITOR( this ) );
m_aliasGrid->SetAttr( DATASHEET, FDC_VALUE, attr );
m_grid->SetAttr( DATASHEET, FDC_VALUE, attr );
m_SymbolNameCtrl->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE ) );
@ -110,8 +92,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
m_bpDelete->SetBitmap( KiBitmap( trash_xpm ) );
m_bpMoveUp->SetBitmap( KiBitmap( small_up_xpm ) );
m_bpMoveDown->SetBitmap( KiBitmap( small_down_xpm ) );
m_addAliasButton->SetBitmap( KiBitmap( small_plus_xpm ) );
m_deleteAliasButton->SetBitmap( KiBitmap( trash_xpm ) );
m_addFilterButton->SetBitmap( KiBitmap( small_plus_xpm ) );
m_deleteFilterButton->SetBitmap( KiBitmap( trash_xpm ) );
m_editFilterButton->SetBitmap( KiBitmap( small_edit_xpm ) );
@ -126,12 +106,21 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::DIALOG_EDIT_COMPONENT_IN_LIBRARY( LIB_EDIT_FRA
m_grid->Connect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging ),
NULL, this );
m_aliasGrid->Connect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging ),
NULL, this );
if( m_lastLayout != DIALOG_EDIT_COMPONENT_IN_LIBRARY::NONE )
{
if( ( m_lastLayout == DIALOG_EDIT_COMPONENT_IN_LIBRARY::ALIAS && aLibEntry->IsRoot() )
|| ( m_lastLayout == DIALOG_EDIT_COMPONENT_IN_LIBRARY::PARENT && aLibEntry->IsAlias() ) )
{
ResetSize();
}
}
m_lastLayout = ( aLibEntry->IsAlias() ) ? DIALOG_EDIT_COMPONENT_IN_LIBRARY::ALIAS :
DIALOG_EDIT_COMPONENT_IN_LIBRARY::PARENT;
m_grid->GetParent()->Layout();
m_aliasGrid->GetParent()->Layout();
syncControlStates( m_libEntry->IsAlias() );
Layout();
FinishDialogSettings();
@ -150,18 +139,9 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY::~DIALOG_EDIT_COMPONENT_IN_LIBRARY()
m_grid->Disconnect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnGridCellChanging ),
NULL, this );
m_aliasGrid->Disconnect( wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging ),
NULL, this );
// Delete the GRID_TRICKS.
m_grid->PopEventHandler( true );
m_aliasGrid->PopEventHandler( true );
// An OK will have transferred these and cleared the buffer, but we have to delete them
// on a Cancel.
for( LIB_ALIAS* alias : m_aliasesBuffer )
delete alias;
}
@ -170,23 +150,11 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
if( !wxDialog::TransferDataToWindow() )
return false;
LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
// Push a copy of each field into m_fields
m_libEntry->GetFields( *m_fields );
// The datasheet field is special. Grab its value from the LIB_ALIAS document file
// member except for old libraries that saved the root alias document file in the
// datasheet field in the LIB_PART object.
if( rootAlias->GetDocFileName().IsEmpty() )
{
m_fields->at( DATASHEET ).SetText( m_libEntry->GetField( DATASHEET )->GetText() );
rootAlias->SetDocFileName( m_libEntry->GetField( DATASHEET )->GetText() );
}
else
{
m_fields->at( DATASHEET ).SetText( rootAlias->GetDocFileName() );
}
// Copy the data sheet field from the old alias document file name.
m_fields->at( DATASHEET ).SetText( m_libEntry->GetDocFileName() );
// The Y axis for components in lib is from bottom to top while the screen axis is top
// to bottom: we must change the y coord sign for editing
@ -200,13 +168,12 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
// notify the grid
wxGridTableMessage msg( m_fields, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, m_fields->GetNumberRows() );
m_grid->ProcessTableMessage( msg );
adjustGridColumns( m_grid->GetRect().GetWidth());
adjustGridColumns( m_grid->GetRect().GetWidth() );
m_SymbolNameCtrl->SetValue( m_libEntry->GetName() );
m_DescCtrl->SetValue( rootAlias->GetDescription() );
m_KeywordCtrl->SetValue( rootAlias->GetKeyWords() );
m_DescCtrl->SetValue( m_libEntry->GetDescription() );
m_KeywordCtrl->SetValue( m_libEntry->GetKeyWords() );
m_SelNumberOfUnits->SetValue( m_libEntry->GetUnitCount() );
m_OptionPartsLocked->SetValue( m_libEntry->UnitsLocked() && m_libEntry->GetUnitCount() > 1 );
m_AsConvertButt->SetValue( m_libEntry->HasConversion() );
@ -217,27 +184,36 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
m_PinsNameInsideButt->SetValue( m_libEntry->GetPinNameOffset() != 0 );
m_pinNameOffset.SetValue( Mils2iu( m_libEntry->GetPinNameOffset() ) );
const LIB_ALIASES aliases = m_libEntry->GetAliases();
wxArrayString tmp = m_libEntry->GetFootprints();
m_FootprintFilterListBox->Append( tmp );
for( LIB_ALIAS* alias : aliases )
// Populate the list of root parts for inherited objects.
if( m_libEntry->IsAlias() )
{
if( alias->IsRoot() )
continue;
wxArrayString rootSymbolNames;
wxString libName = m_Parent->GetCurLib();
m_aliasesBuffer.push_back( new LIB_ALIAS( *alias, m_libEntry ) );
m_aliasListBox->Append( alias->GetName() );
// Someone forgot to set the current library in the editor frame window.
wxCHECK( !libName.empty(), false );
m_Parent->GetLibManager().GetRootSymbolNames( libName, rootSymbolNames );
m_inheritanceSelectCombo->Append( rootSymbolNames );
PART_SPTR rootPart = m_libEntry->GetParent().lock();
wxCHECK( rootPart, false );
wxString parentName = rootPart->GetName();
int selection = m_inheritanceSelectCombo->FindString( parentName );
wxCHECK( selection != wxNOT_FOUND, false );
m_inheritanceSelectCombo->SetSelection( selection );
// Copy the reference field from the root symbol to prevent validation errors.
m_fields->at( REFERENCE ).SetText( rootPart->GetReferenceField().GetText() );
m_lastOpenedPage = 0;
}
if( m_aliasListBox->GetCount() )
m_aliasListBox->SetSelection( 0 );
wxCommandEvent dummy;
OnSelectAlias( dummy );
adjustAliasGridColumns( m_aliasGrid->GetClientRect().GetWidth() - 4 );
m_FootprintFilterListBox->Append( m_libEntry->GetFootprints() );
m_NoteBook->SetSelection( (unsigned) m_lastOpenedPage );
return true;
@ -246,7 +222,7 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataToWindow()
bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::Validate()
{
if( !m_grid->CommitPendingChanges() || !m_aliasGrid->CommitPendingChanges() )
if( !m_grid->CommitPendingChanges() )
return false;
if( !SCH_COMPONENT::IsReferenceStringValid( m_fields->at( REFERENCE ).GetText() ) )
@ -310,7 +286,6 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataFromWindow()
if( !wxDialog::TransferDataFromWindow() )
return false;
LIB_ALIAS* rootAlias = m_libEntry->GetAlias( m_libEntry->GetName() );
// We need to keep the name and the value the same at the moment!
wxString newName = m_fields->at( VALUE ).GetText();
@ -329,19 +304,15 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataFromWindow()
}
// Datasheet field is special; copy it to the root alias docfilename
rootAlias->SetDocFileName( m_fields->at( DATASHEET ).GetText() );
m_libEntry->SetDocFileName( m_fields->at( DATASHEET ).GetText() );
m_libEntry->SetFields( *m_fields );
// We need to keep the name and the value the same at the moment!
m_libEntry->SetName( newName );
rootAlias->SetDescription( m_DescCtrl->GetValue() );
rootAlias->SetKeyWords( m_KeywordCtrl->GetValue() );
m_libEntry->SetDescription( m_DescCtrl->GetValue() );
m_libEntry->SetKeyWords( m_KeywordCtrl->GetValue() );
m_libEntry->SetUnitCount( m_SelNumberOfUnits->GetValue() );
m_libEntry->LockUnits( m_libEntry->GetUnitCount() > 1 && m_OptionPartsLocked->GetValue() );
m_libEntry->SetConversion( m_AsConvertButt->GetValue() );
if( m_OptionPower->GetValue() )
@ -364,16 +335,7 @@ bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::TransferDataFromWindow()
m_libEntry->SetPinNameOffset( 0 ); // pin text outside the body (name is on the pin)
}
transferAliasDataToBuffer();
m_libEntry->RemoveAllAliases();
for( LIB_ALIAS* alias : m_aliasesBuffer )
m_libEntry->AddAlias( alias ); // Transfers ownership; no need to delete
m_aliasesBuffer.clear();
m_libEntry->GetFootprints().Clear();
m_libEntry->GetFootprints() = m_FootprintFilterListBox->GetStrings();
m_libEntry->SetFootprintFilters( m_FootprintFilterListBox->GetStrings() );
return true;
}
@ -513,77 +475,6 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnMoveDown( wxCommandEvent& event )
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::updateAliasName( bool aFromGrid, const wxString& aName )
{
int idx = m_aliasListBox->GetSelection();
if( idx >= 0 )
{
m_aliasListBox->SetString( (unsigned) idx, aName );
m_aliasesBuffer[ idx ]->SetName( aName );
if( aFromGrid )
m_AliasNameCtrl->ChangeValue( aName );
else
m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, aName );
}
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasGridCellChanging( wxGridEvent& event )
{
if( event.GetRow() == VALUE )
{
int idx = m_aliasListBox->GetSelection();
wxString newName = event.GetString();
if( idx < 0 || !checkAliasName( newName ) )
{
event.Veto();
m_delayedFocusGrid = m_aliasGrid;
m_delayedFocusRow = event.GetRow();
m_delayedFocusColumn = event.GetCol();
m_delayedFocusPage = 1;
}
else
updateAliasName( true, newName );
}
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasNameText( wxCommandEvent& event )
{
updateAliasName( false, m_AliasNameCtrl->GetValue() );
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAliasNameKillFocus( wxFocusEvent& event )
{
if( !m_delayedFocusCtrl && !checkAliasName( m_AliasNameCtrl->GetValue() ) )
{
m_delayedFocusCtrl = m_AliasNameCtrl;
m_delayedFocusPage = 1;
}
event.Skip();
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::transferAliasDataToBuffer()
{
if( m_currentAlias >= 0 )
{
LIB_ALIAS* alias = m_aliasesBuffer[ m_currentAlias ];
alias->SetName( m_aliasGrid->GetCellValue( VALUE, FDC_VALUE ) );
alias->SetDocFileName( m_aliasGrid->GetCellValue( DATASHEET, FDC_VALUE ) );
alias->SetDescription( m_AliasDescCtrl->GetValue() );
alias->SetKeyWords( m_AliasKeywordsCtrl->GetValue() );
}
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnEditSpiceModel( wxCommandEvent& event )
{
#ifdef KICAD_SPICE
@ -613,153 +504,6 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnEditSpiceModel( wxCommandEvent& event )
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnSelectAlias( wxCommandEvent& event )
{
if( m_delayedFocusCtrl || !m_aliasGrid->CommitPendingChanges() )
{
m_aliasListBox->SetSelection( m_currentAlias ); // veto selection change
return;
}
// Copy any pending changes back into the buffer
transferAliasDataToBuffer();
LIB_ALIAS* alias = nullptr;
int newIdx = m_aliasListBox->GetSelection();
if( newIdx >= 0 )
{
alias = m_aliasesBuffer[ newIdx ];
m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, alias->GetName() );
m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, alias->GetDocFileName() );
m_aliasGrid->Enable( true );
// Use ChangeValue() so we don't generate events
m_AliasNameCtrl->ChangeValue( alias->GetName() );
m_AliasNameCtrl->Enable( true );
m_AliasDescCtrl->ChangeValue( alias->GetDescription() );
m_AliasDescCtrl->Enable( true );
m_AliasKeywordsCtrl->ChangeValue( alias->GetKeyWords() );
m_AliasKeywordsCtrl->Enable( true );
}
else
{
m_aliasGrid->SetCellValue( VALUE, FDC_VALUE, wxEmptyString );
m_aliasGrid->SetCellValue( DATASHEET, FDC_VALUE, wxEmptyString );
m_aliasGrid->Enable( false );
// Use ChangeValue() so we don't generate events
m_AliasNameCtrl->ChangeValue( wxEmptyString );
m_AliasNameCtrl->Enable( false );
m_AliasDescCtrl->ChangeValue( wxEmptyString );
m_AliasDescCtrl->Enable( false );
m_AliasKeywordsCtrl->ChangeValue( wxEmptyString );
m_AliasKeywordsCtrl->Enable( false );
}
m_currentAlias = newIdx;
}
bool DIALOG_EDIT_COMPONENT_IN_LIBRARY::checkAliasName( const wxString& aName )
{
if( aName.IsEmpty() )
return false;
if( m_SymbolNameCtrl->GetValue().CmpNoCase( aName ) == 0 )
{
wxString msg;
msg.Printf( _( "Alias can not have same name as symbol." ) );
DisplayInfoMessage( this, msg );
return false;
}
for( int i = 0; i < (int)m_aliasListBox->GetCount(); ++i )
{
if( i == m_aliasListBox->GetSelection() )
continue;
if( m_aliasListBox->GetString( i ).CmpNoCase( aName ) == 0 )
{
wxString msg;
msg.Printf( _( "Alias \"%s\" already exists." ), aName );
DisplayInfoMessage( this, msg );
return false;
}
}
wxString library = m_Parent->GetCurLib();
if( !library.empty() )
{
LIB_ALIAS* existing = Prj().SchSymbolLibTable()->LoadSymbol( library, aName );
if( existing && existing->GetPart()->GetName() != m_libEntry->GetName() )
{
wxString msg;
msg.Printf( _( "Symbol name \"%s\" already exists in library \"%s\"." ),
aName, library );
DisplayErrorMessage( this, msg );
return false;
}
}
return true;
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddAlias( wxCommandEvent& event )
{
if( m_delayedFocusCtrl || !m_aliasGrid->CommitPendingChanges() )
return;
wxCommandEvent dummy;
wxString aliasname = _( "untitled" );
int suffix = 1;
while( m_aliasListBox->FindString( aliasname ) != wxNOT_FOUND )
aliasname = wxString::Format( _( "untitled%i" ), suffix++ );
LIB_ALIAS* alias = new LIB_ALIAS( aliasname, m_libEntry );
// Initialize with parent's data
alias->SetDescription( m_DescCtrl->GetValue() );
alias->SetKeyWords( m_KeywordCtrl->GetValue() );
alias->SetDocFileName( m_grid->GetCellValue( DATASHEET, FDC_VALUE ) );
m_aliasesBuffer.push_back( alias ); // transfers ownership of alias to aliasesBuffer
m_aliasListBox->Append( aliasname );
m_aliasListBox->SetSelection( m_aliasListBox->GetCount() - 1 );
OnSelectAlias( dummy );
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnDeleteAlias( wxCommandEvent& event )
{
if( m_delayedFocusCtrl || !m_aliasGrid->CommitPendingChanges() )
return;
int sel = m_aliasListBox->GetSelection();
if( sel == wxNOT_FOUND )
return;
m_aliasListBox->Delete( (unsigned) sel );
m_aliasesBuffer.erase( m_aliasesBuffer.begin() + sel );
m_currentAlias = wxNOT_FOUND;
if( m_aliasListBox->GetCount() == 0 )
m_aliasListBox->SetSelection( wxNOT_FOUND );
else
m_aliasListBox->SetSelection( std::max( 0, sel - 1 ) );
wxCommandEvent dummy;
OnSelectAlias( dummy );
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnFilterDClick( wxMouseEvent& event)
{
int idx = m_FootprintFilterListBox->HitTest( event.GetPosition() );
@ -783,11 +527,6 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnCancelButtonClick( wxCommandEvent& even
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnAddFootprintFilter( wxCommandEvent& event )
{
wxString filterLine;
LIB_PART* component = m_Parent->GetCurPart();
if( component == NULL )
return;
WX_TEXT_ENTRY_DIALOG dlg( this, _( "Filter:" ), _( "Add Footprint Filter" ), filterLine );
if( dlg.ShowModal() == wxID_CANCEL || dlg.GetValue().IsEmpty() )
@ -853,13 +592,6 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::adjustGridColumns( int aWidth )
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::adjustAliasGridColumns( int aWidth )
{
m_aliasGrid->AutoSizeColumn( FDC_NAME );
m_aliasGrid->SetColSize( FDC_VALUE, aWidth - m_aliasGrid->GetColSize( FDC_NAME ) - 2 );
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
{
m_OptionPartsLocked->Enable( m_SelNumberOfUnits->GetValue() > 1 );
@ -878,13 +610,6 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnUpdateUI( wxUpdateUIEvent& event )
}
}
// Synthesize a Select event when the selection is cleared
if( m_aliasListBox->GetSelection() == wxNOT_FOUND && m_currentAlias != wxNOT_FOUND )
{
wxCommandEvent dummy;
OnSelectAlias( dummy );
}
// Handle shown columns changes
wxString shownColumns = m_grid->GetShownColumns();
@ -957,9 +682,21 @@ void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnSizeGrid( wxSizeEvent& event )
}
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::OnSizeAliasGrid( wxSizeEvent& event )
void DIALOG_EDIT_COMPONENT_IN_LIBRARY::syncControlStates( bool aIsAlias )
{
adjustAliasGridColumns( event.GetSize().GetX() );
if( aIsAlias )
m_PanelFootprintFilter->Hide();
else
m_PanelFootprintFilter->Show();
event.Skip();
bSizerLowerBasicPanel->Show( !aIsAlias );
bButtonSize->Show( !aIsAlias );
#ifdef KICAD_SPICE
m_spiceFieldsButton->Show( !aIsAlias );
#endif
m_inheritanceSelectCombo->Enable( aIsAlias );
m_inheritsStaticText->Enable( aIsAlias );
m_grid->ForceRefresh();
}

View File

@ -26,7 +26,6 @@
#define _DIALOG_EDIT_COMPONENT_IN_LIB_H_
#include <fields_grid_table.h>
#include <class_library.h>
#include <widgets/unit_binder.h>
#include <dialog_edit_component_in_lib_base.h>
@ -40,6 +39,14 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY: public DIALOG_EDIT_COMPONENT_IN_LIBRARY_
{
static int m_lastOpenedPage; // To remember the last notebook selection
enum LAST_LAYOUT {
NONE,
ALIAS,
PARENT
};
static LAST_LAYOUT m_lastLayout;
public:
wxConfigBase* m_config;
@ -48,8 +55,6 @@ public:
FIELDS_GRID_TABLE<LIB_FIELD>* m_fields;
int m_currentAlias;
LIB_ALIASES m_aliasesBuffer;
UNIT_BINDER m_pinNameOffset;
wxControl* m_delayedFocusCtrl;
@ -81,27 +86,18 @@ private:
void OnMoveDown( wxCommandEvent& event ) override;
void OnSymbolNameKillFocus( wxFocusEvent& event ) override;
void OnSymbolNameText( wxCommandEvent& event ) override;
void OnSelectAlias( wxCommandEvent& event ) override;
void OnAddAlias( wxCommandEvent& event ) override;
void OnDeleteAlias( wxCommandEvent& event ) override;
void OnAddFootprintFilter( wxCommandEvent& event ) override;
void OnDeleteFootprintFilter( wxCommandEvent& event ) override;
void OnEditFootprintFilter( wxCommandEvent& event ) override;
void OnSizeGrid( wxSizeEvent& event ) override;
void OnSizeAliasGrid( wxSizeEvent& event ) override;
void OnGridCellChanging( wxGridEvent& event );
void OnAliasGridCellChanging( wxGridEvent& event );
void OnAliasNameKillFocus( wxFocusEvent& event ) override;
void OnAliasNameText( wxCommandEvent& event ) override;
void OnEditSpiceModel( wxCommandEvent& event ) override;
void OnUpdateUI( wxUpdateUIEvent& event ) override;
void OnFilterDClick( wxMouseEvent& event ) override;
void OnCancelButtonClick( wxCommandEvent& event ) override;
void updateAliasName( bool aFromGrid, const wxString& aName );
bool checkAliasName( const wxString& aName );
void adjustGridColumns( int aWidth );
void adjustAliasGridColumns( int aWidth );
void syncControlStates( bool aIsAlias );
};
#endif // _DIALOG_EDIT_COMPONENT_IN_LIB_H_

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 1 2018)
// C++ code generated with wxFormBuilder (version Aug 15 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -9,7 +9,7 @@
#include "dialog_edit_component_in_lib_base.h"
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
@ -75,11 +75,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
// Cell Defaults
m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_grid->SetMinSize( wxSize( -1,180 ) );
m_grid->SetMinSize( wxSize( -1,160 ) );
sbSizer4->Add( m_grid, 1, wxTOP|wxBOTTOM|wxEXPAND, 5 );
sbSizer4->Add( m_grid, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bButtonSize;
bButtonSize = new wxBoxSizer( wxHORIZONTAL );
m_bpAdd = new wxBitmapButton( sbSizer4->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
@ -113,7 +112,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
sbSizer4->Add( bButtonSize, 0, wxEXPAND|wxBOTTOM, 5 );
bSizerBasicPanel->Add( sbSizer4, 1, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerBasicPanel->Add( sbSizer4, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerMidBasicPanel;
bSizerMidBasicPanel = new wxBoxSizer( wxVERTICAL );
@ -127,10 +126,10 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
wxStaticText* staticNameLabel;
staticNameLabel = new wxStaticText( m_PanelBasic, wxID_ANY, _("Symbol name:"), wxDefaultPosition, wxDefaultSize, 0 );
staticNameLabel->Wrap( -1 );
fgSizerFPID->Add( staticNameLabel, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
fgSizerFPID->Add( staticNameLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_SymbolNameCtrl = new wxTextCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID->Add( m_SymbolNameCtrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
fgSizerFPID->Add( m_SymbolNameCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
wxStaticText* staticDescriptionLabel;
staticDescriptionLabel = new wxStaticText( m_PanelBasic, wxID_ANY, _("Description:"), wxDefaultPosition, wxDefaultSize, 0 );
@ -138,22 +137,30 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
fgSizerFPID->Add( staticDescriptionLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_DescCtrl = new wxTextCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID->Add( m_DescCtrl, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
fgSizerFPID->Add( m_DescCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
staticKeywordsLabel = new wxStaticText( m_PanelBasic, wxID_ANY, _("Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
staticKeywordsLabel->Wrap( -1 );
fgSizerFPID->Add( staticKeywordsLabel, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT|wxLEFT, 5 );
m_KeywordCtrl = new wxTextCtrl( m_PanelBasic, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID->Add( m_KeywordCtrl, 0, wxRIGHT|wxLEFT|wxEXPAND, 5 );
fgSizerFPID->Add( m_KeywordCtrl, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
m_inheritsStaticText = new wxStaticText( m_PanelBasic, wxID_ANY, _("Derive from symbol:"), wxDefaultPosition, wxDefaultSize, 0 );
m_inheritsStaticText->Wrap( -1 );
fgSizerFPID->Add( m_inheritsStaticText, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_inheritanceSelectCombo = new wxComboBox( m_PanelBasic, wxID_ANY, _("<None>"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxCB_READONLY );
m_inheritanceSelectCombo->SetToolTip( _("Select symbol to derive this symbol from or select\n<None> for root symbol.\n\nDerived symbols were formerly referred to as aliases.\nThis is no longer the case and all symbols are either\nderived from another symbols or they stand alone as\nroot symbols.") );
fgSizerFPID->Add( m_inheritanceSelectCombo, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 5 );
bSizerMidBasicPanel->Add( fgSizerFPID, 1, wxEXPAND|wxTOP|wxBOTTOM, 5 );
bSizerBasicPanel->Add( bSizerMidBasicPanel, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
bSizerBasicPanel->Add( bSizerMidBasicPanel, 0, wxEXPAND, 5 );
wxBoxSizer* bSizerLowerBasicPanel;
bSizerLowerBasicPanel = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerLeftCol;
@ -261,134 +268,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_PanelBasic->Layout();
bSizerBasicPanel->Fit( m_PanelBasic );
m_NoteBook->AddPage( m_PanelBasic, _("General"), true );
m_PanelAlias = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerMainPanelAlias;
bSizerMainPanelAlias = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bLeftBoxSizerPanelAlias;
bLeftBoxSizerPanelAlias = new wxBoxSizer( wxVERTICAL );
wxStaticText* staticAliasesLabel;
staticAliasesLabel = new wxStaticText( m_PanelAlias, wxID_ANY, _("Aliases:"), wxDefaultPosition, wxDefaultSize, 0 );
staticAliasesLabel->Wrap( -1 );
bLeftBoxSizerPanelAlias->Add( staticAliasesLabel, 0, wxRIGHT|wxLEFT, 5 );
m_aliasListBox = new wxListBox( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
bLeftBoxSizerPanelAlias->Add( m_aliasListBox, 1, wxEXPAND|wxLEFT, 5 );
wxBoxSizer* bSizerButtons;
bSizerButtons = new wxBoxSizer( wxHORIZONTAL );
m_addAliasButton = new wxBitmapButton( m_PanelAlias, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_addAliasButton->SetToolTip( _("Add alias") );
m_addAliasButton->SetMinSize( wxSize( 30,29 ) );
bSizerButtons->Add( m_addAliasButton, 0, wxALL, 5 );
bSizerButtons->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 );
m_deleteAliasButton = new wxBitmapButton( m_PanelAlias, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_deleteAliasButton->SetToolTip( _("Delete alias") );
m_deleteAliasButton->SetMinSize( wxSize( 30,29 ) );
bSizerButtons->Add( m_deleteAliasButton, 0, wxALL, 5 );
bLeftBoxSizerPanelAlias->Add( bSizerButtons, 0, wxEXPAND, 5 );
bSizerMainPanelAlias->Add( bLeftBoxSizerPanelAlias, 2, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* bRightBoxSizerPanelAlias;
bRightBoxSizerPanelAlias = new wxBoxSizer( wxVERTICAL );
m_staticText12 = new wxStaticText( m_PanelAlias, wxID_ANY, _("Alias field substitutions:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText12->Wrap( -1 );
bRightBoxSizerPanelAlias->Add( m_staticText12, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_aliasGrid = new WX_GRID( m_PanelAlias, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_aliasGrid->CreateGrid( 4, 2 );
m_aliasGrid->EnableEditing( true );
m_aliasGrid->EnableGridLines( true );
m_aliasGrid->EnableDragGridSize( false );
m_aliasGrid->SetMargins( 0, 0 );
// Columns
m_aliasGrid->SetColSize( 0, 72 );
m_aliasGrid->SetColSize( 1, 420 );
m_aliasGrid->EnableDragColMove( false );
m_aliasGrid->EnableDragColSize( true );
m_aliasGrid->SetColLabelSize( 22 );
m_aliasGrid->SetColLabelValue( 0, _("Name") );
m_aliasGrid->SetColLabelValue( 1, _("Value") );
m_aliasGrid->SetColLabelValue( 2, _("Show") );
m_aliasGrid->SetColLabelValue( 3, _("H Align") );
m_aliasGrid->SetColLabelValue( 4, _("V Align") );
m_aliasGrid->SetColLabelValue( 5, _("Italic") );
m_aliasGrid->SetColLabelValue( 6, _("Bold") );
m_aliasGrid->SetColLabelValue( 7, _("Text Size") );
m_aliasGrid->SetColLabelValue( 8, _("Orientation") );
m_aliasGrid->SetColLabelValue( 9, _("X Position") );
m_aliasGrid->SetColLabelValue( 10, _("Y Position") );
m_aliasGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_aliasGrid->EnableDragRowSize( true );
m_aliasGrid->SetRowLabelSize( 0 );
m_aliasGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_aliasGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
bRightBoxSizerPanelAlias->Add( m_aliasGrid, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bRightBoxSizerPanelAlias->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 5 );
wxFlexGridSizer* fgSizerFPID1;
fgSizerFPID1 = new wxFlexGridSizer( 6, 1, 0, 0 );
fgSizerFPID1->AddGrowableCol( 0 );
fgSizerFPID1->SetFlexibleDirection( wxBOTH );
fgSizerFPID1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxStaticText* staticAliasNameLabel;
staticAliasNameLabel = new wxStaticText( m_PanelAlias, wxID_ANY, _("Alias name:"), wxDefaultPosition, wxDefaultSize, 0 );
staticAliasNameLabel->Wrap( -1 );
fgSizerFPID1->Add( staticAliasNameLabel, 0, wxLEFT|wxRIGHT, 5 );
m_AliasNameCtrl = new wxTextCtrl( m_PanelAlias, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID1->Add( m_AliasNameCtrl, 0, wxBOTTOM|wxLEFT|wxRIGHT|wxEXPAND, 5 );
wxStaticText* staticAliasDescLabel;
staticAliasDescLabel = new wxStaticText( m_PanelAlias, wxID_ANY, _("Alias description:"), wxDefaultPosition, wxDefaultSize, 0 );
staticAliasDescLabel->Wrap( -1 );
fgSizerFPID1->Add( staticAliasDescLabel, 0, wxLEFT|wxRIGHT, 5 );
m_AliasDescCtrl = new wxTextCtrl( m_PanelAlias, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID1->Add( m_AliasDescCtrl, 0, wxBOTTOM|wxEXPAND|wxLEFT|wxRIGHT, 5 );
staticAliasKeywordsLabel = new wxStaticText( m_PanelAlias, wxID_ANY, _("Alias keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
staticAliasKeywordsLabel->Wrap( -1 );
fgSizerFPID1->Add( staticAliasKeywordsLabel, 0, wxLEFT|wxRIGHT, 5 );
m_AliasKeywordsCtrl = new wxTextCtrl( m_PanelAlias, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizerFPID1->Add( m_AliasKeywordsCtrl, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bRightBoxSizerPanelAlias->Add( fgSizerFPID1, 1, wxEXPAND, 5 );
bSizerMainPanelAlias->Add( bRightBoxSizerPanelAlias, 7, wxEXPAND|wxRIGHT|wxTOP, 20 );
m_PanelAlias->SetSizer( bSizerMainPanelAlias );
m_PanelAlias->Layout();
bSizerMainPanelAlias->Fit( m_PanelAlias );
m_NoteBook->AddPage( m_PanelAlias, _("Aliases"), false );
m_PanelFootprintFilter = new wxPanel( m_NoteBook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bPanelFpFilterBoxSizer;
bPanelFpFilterBoxSizer = new wxBoxSizer( wxHORIZONTAL );
@ -470,6 +349,7 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
this->SetSizer( bMainSizer );
this->Layout();
bMainSizer->Fit( this );
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnUpdateUI ) );
@ -480,12 +360,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wx
m_bpDelete->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteField ), NULL, this );
m_SymbolNameCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameKillFocus ), NULL, this );
m_SymbolNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameText ), NULL, this );
m_aliasListBox->Connect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSelectAlias ), NULL, this );
m_addAliasButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddAlias ), NULL, this );
m_deleteAliasButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteAlias ), NULL, this );
m_aliasGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSizeAliasGrid ), NULL, this );
m_AliasNameCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAliasNameKillFocus ), NULL, this );
m_AliasNameCtrl->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAliasNameText ), NULL, this );
m_FootprintFilterListBox->Connect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnFilterDClick ), NULL, this );
m_FootprintFilterListBox->Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnEditFootprintFilter ), NULL, this );
m_addFilterButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddFootprintFilter ), NULL, this );
@ -506,12 +380,6 @@ DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE()
m_bpDelete->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteField ), NULL, this );
m_SymbolNameCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameKillFocus ), NULL, this );
m_SymbolNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSymbolNameText ), NULL, this );
m_aliasListBox->Disconnect( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSelectAlias ), NULL, this );
m_addAliasButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddAlias ), NULL, this );
m_deleteAliasButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnDeleteAlias ), NULL, this );
m_aliasGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnSizeAliasGrid ), NULL, this );
m_AliasNameCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAliasNameKillFocus ), NULL, this );
m_AliasNameCtrl->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAliasNameText ), NULL, this );
m_FootprintFilterListBox->Disconnect( wxEVT_LEFT_DCLICK, wxMouseEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnFilterDClick ), NULL, this );
m_FootprintFilterListBox->Disconnect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnEditFootprintFilter ), NULL, this );
m_addFilterButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE::OnAddFootprintFilter ), NULL, this );

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 1 2018)
// C++ code generated with wxFormBuilder (version Aug 15 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -28,6 +28,7 @@ class WX_GRID;
#include <wx/statbox.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/combobox.h>
#include <wx/checkbox.h>
#include <wx/spinctrl.h>
#include <wx/panel.h>
@ -50,6 +51,7 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
wxNotebook* m_NoteBook;
wxPanel* m_PanelBasic;
WX_GRID* m_grid;
wxBoxSizer* bButtonSize;
wxBitmapButton* m_bpAdd;
wxBitmapButton* m_bpMoveUp;
wxBitmapButton* m_bpMoveDown;
@ -58,6 +60,9 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
wxTextCtrl* m_DescCtrl;
wxStaticText* staticKeywordsLabel;
wxTextCtrl* m_KeywordCtrl;
wxStaticText* m_inheritsStaticText;
wxComboBox* m_inheritanceSelectCombo;
wxBoxSizer* bSizerLowerBasicPanel;
wxCheckBox* m_AsConvertButt;
wxCheckBox* m_OptionPower;
wxStaticText* m_staticTextNbUnits;
@ -69,16 +74,6 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
wxStaticText* m_nameOffsetLabel;
wxTextCtrl* m_nameOffsetCtrl;
wxStaticText* m_nameOffsetUnits;
wxPanel* m_PanelAlias;
wxListBox* m_aliasListBox;
wxBitmapButton* m_addAliasButton;
wxBitmapButton* m_deleteAliasButton;
wxStaticText* m_staticText12;
WX_GRID* m_aliasGrid;
wxTextCtrl* m_AliasNameCtrl;
wxTextCtrl* m_AliasDescCtrl;
wxStaticText* staticAliasKeywordsLabel;
wxTextCtrl* m_AliasKeywordsCtrl;
wxPanel* m_PanelFootprintFilter;
wxStaticText* m_staticTextFootprints;
wxListBox* m_FootprintFilterListBox;
@ -99,12 +94,6 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
virtual void OnDeleteField( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSymbolNameKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnSymbolNameText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSelectAlias( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddAlias( wxCommandEvent& event ) { event.Skip(); }
virtual void OnDeleteAlias( wxCommandEvent& event ) { event.Skip(); }
virtual void OnSizeAliasGrid( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAliasNameKillFocus( wxFocusEvent& event ) { event.Skip(); }
virtual void OnAliasNameText( wxCommandEvent& event ) { event.Skip(); }
virtual void OnFilterDClick( wxMouseEvent& event ) { event.Skip(); }
virtual void OnEditFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddFootprintFilter( wxCommandEvent& event ) { event.Skip(); }
@ -115,7 +104,7 @@ class DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE : public DIALOG_SHIM
public:
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id = ID_LIBEDIT_NOTEBOOK, const wxString& title = _("Library Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 855,579 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE( wxWindow* parent, wxWindowID id = ID_LIBEDIT_NOTEBOOK, const wxString& title = _("Library Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_EDIT_COMPONENT_IN_LIBRARY_BASE();
};

View File

@ -201,15 +201,9 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataToWindow()
int mirror = m_cmp->GetOrientation() & ( CMP_MIRROR_X | CMP_MIRROR_Y );
if( mirror == CMP_MIRROR_X )
{
m_rbMirror->SetSelection( 1 );
DBG( printf( "mirror=X,1\n" ); )
}
else if( mirror == CMP_MIRROR_Y )
{
m_rbMirror->SetSelection( 2 );
DBG( printf( "mirror=Y,2\n" ); )
}
else
m_rbMirror->SetSelection( 0 );
@ -346,7 +340,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::Validate()
}
else if( id != m_cmp->GetLibId() )
{
LIB_ALIAS* alias = nullptr;
LIB_PART* alias = nullptr;
try
{

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// C++ code generated with wxFormBuilder (version Nov 6 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -14,22 +14,22 @@
DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* mainSizer;
mainSizer = new wxBoxSizer( wxVERTICAL );
wxStaticBoxSizer* sbFields;
sbFields = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Fields") ), wxVERTICAL );
m_grid = new WX_GRID( sbFields->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_grid->CreateGrid( 4, 11 );
m_grid->EnableEditing( true );
m_grid->EnableGridLines( true );
m_grid->EnableDragGridSize( false );
m_grid->SetMargins( 0, 0 );
// Columns
m_grid->SetColSize( 0, 72 );
m_grid->SetColSize( 1, 120 );
@ -57,189 +57,189 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE
m_grid->SetColLabelValue( 9, _("X Position") );
m_grid->SetColLabelValue( 10, _("Y Position") );
m_grid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_grid->EnableDragRowSize( true );
m_grid->SetRowLabelSize( 0 );
m_grid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_grid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
m_grid->SetMinSize( wxSize( -1,180 ) );
sbFields->Add( m_grid, 1, wxEXPAND|wxBOTTOM, 5 );
sbFields->Add( m_grid, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bButtonSize;
bButtonSize = new wxBoxSizer( wxHORIZONTAL );
m_bpAdd = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_bpAdd = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bpAdd->SetToolTip( _("Add field") );
m_bpAdd->SetMinSize( wxSize( 30,30 ) );
bButtonSize->Add( m_bpAdd, 0, wxRIGHT, 5 );
m_bpMoveUp = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bButtonSize->Add( m_bpAdd, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_bpMoveUp = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bpMoveUp->SetToolTip( _("Move up") );
m_bpMoveUp->SetMinSize( wxSize( 30,30 ) );
bButtonSize->Add( m_bpMoveUp, 0, wxRIGHT, 5 );
m_bpMoveDown = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bButtonSize->Add( m_bpMoveUp, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
m_bpMoveDown = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bpMoveDown->SetToolTip( _("Move down") );
m_bpMoveDown->SetMinSize( wxSize( 30,30 ) );
bButtonSize->Add( m_bpMoveDown, 0, wxRIGHT, 5 );
bButtonSize->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
m_bpDelete = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
bButtonSize->Add( m_bpMoveDown, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
bButtonSize->Add( 0, 0, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxLEFT|wxRIGHT, 10 );
m_bpDelete = new wxBitmapButton( sbFields->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_bpDelete->SetToolTip( _("Delete field") );
m_bpDelete->SetMinSize( wxSize( 30,30 ) );
bButtonSize->Add( m_bpDelete, 0, wxRIGHT, 5 );
bButtonSize->Add( 0, 0, 1, wxEXPAND, 5 );
bButtonSize->Add( m_bpDelete, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
bButtonSize->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_updateFieldValues = new wxButton( sbFields->GetStaticBox(), wxID_ANY, _("Update Fields from Library..."), wxDefaultPosition, wxDefaultSize, 0 );
m_updateFieldValues->SetToolTip( _("Sets fields to the original library values") );
bButtonSize->Add( m_updateFieldValues, 0, wxALL|wxEXPAND, 5 );
sbFields->Add( bButtonSize, 0, wxEXPAND, 10 );
mainSizer->Add( sbFields, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
bButtonSize->Add( m_updateFieldValues, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
sbFields->Add( bButtonSize, 0, wxALL|wxEXPAND, 5 );
mainSizer->Add( sbFields, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* lowerSizer;
lowerSizer = new wxBoxSizer( wxHORIZONTAL );
wxStaticBoxSizer* sbSizerLibraryReference;
sbSizerLibraryReference = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Symbol") ), wxVERTICAL );
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 3, 2, 0, 0 );
fgSizer1->AddGrowableCol( 1 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText3 = new wxStaticText( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, _("Library Reference:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
fgSizer1->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxRIGHT, 5 );
fgSizer1->Add( m_staticText3, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxBoxSizer* bLibraryReferenceSizer;
bLibraryReferenceSizer = new wxBoxSizer( wxHORIZONTAL );
m_libraryNameTextCtrl = new wxTextCtrl( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
m_libraryNameTextCtrl->SetToolTip( _("Name of the symbol in the library to which this symbol is linked") );
bLibraryReferenceSizer->Add( m_libraryNameTextCtrl, 1, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
m_buttonBrowseLibrary = new wxBitmapButton( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, 0 );
m_buttonBrowseLibrary = new wxBitmapButton( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
m_buttonBrowseLibrary->SetToolTip( _("Browse library") );
m_buttonBrowseLibrary->SetMinSize( wxSize( 30,29 ) );
bLibraryReferenceSizer->Add( m_buttonBrowseLibrary, 0, wxALIGN_CENTER_VERTICAL, 5 );
fgSizer1->Add( bLibraryReferenceSizer, 1, wxEXPAND|wxRIGHT, 5 );
bLibraryReferenceSizer->Add( m_buttonBrowseLibrary, 0, wxALIGN_CENTER_VERTICAL|wxLEFT, 5 );
fgSizer1->Add( bLibraryReferenceSizer, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxRIGHT, 5 );
m_unitLabel = new wxStaticText( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, _("Unit:"), wxDefaultPosition, wxDefaultSize, 0 );
m_unitLabel->Wrap( -1 );
fgSizer1->Add( m_unitLabel, 0, wxRIGHT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizer1->Add( m_unitLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
wxArrayString m_unitChoiceChoices;
m_unitChoice = new wxChoice( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_unitChoiceChoices, 0 );
m_unitChoice->SetSelection( 0 );
m_unitChoice->SetMinSize( wxSize( 100,-1 ) );
fgSizer1->Add( m_unitChoice, 0, wxRIGHT|wxLEFT|wxALIGN_CENTER_VERTICAL, 5 );
fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
fgSizer1->Add( m_unitChoice, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxTOP, 5 );
fgSizer1->Add( 0, 0, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_cbAlternateSymbol = new wxCheckBox( sbSizerLibraryReference->GetStaticBox(), wxID_ANY, _("Alternate symbol (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbAlternateSymbol->SetToolTip( _("Use the alternate shape of this symbol.\nFor gates, this is the \"De Morgan\" conversion") );
fgSizer1->Add( m_cbAlternateSymbol, 0, wxALL, 5 );
fgSizer1->Add( m_cbAlternateSymbol, 0, wxRIGHT|wxTOP, 5 );
sbSizerLibraryReference->Add( fgSizer1, 0, wxEXPAND, 5 );
lowerSizer->Add( sbSizerLibraryReference, 5, wxEXPAND|wxRIGHT|wxLEFT, 10 );
lowerSizer->Add( sbSizerLibraryReference, 5, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxString m_rbOrientationChoices[] = { _("0"), _("+90"), _("+180"), _("-90") };
int m_rbOrientationNChoices = sizeof( m_rbOrientationChoices ) / sizeof( wxString );
m_rbOrientation = new wxRadioBox( this, wxID_ANY, _("Orientation"), wxDefaultPosition, wxDefaultSize, m_rbOrientationNChoices, m_rbOrientationChoices, 1, wxRA_SPECIFY_COLS );
m_rbOrientation->SetSelection( 0 );
m_rbOrientation->SetToolTip( _("Select if the symbol is to be rotated when drawn") );
lowerSizer->Add( m_rbOrientation, 2, wxEXPAND|wxRIGHT|wxLEFT, 8 );
lowerSizer->Add( m_rbOrientation, 2, wxEXPAND|wxRIGHT|wxLEFT, 5 );
wxString m_rbMirrorChoices[] = { _("Default"), _("Mirror around X axis"), _("Mirror around Y axis") };
int m_rbMirrorNChoices = sizeof( m_rbMirrorChoices ) / sizeof( wxString );
m_rbMirror = new wxRadioBox( this, wxID_ANY, _("Aspect"), wxDefaultPosition, wxDefaultSize, m_rbMirrorNChoices, m_rbMirrorChoices, 1, wxRA_SPECIFY_COLS );
m_rbMirror->SetSelection( 1 );
m_rbMirror->SetToolTip( _("Pick the graphical transformation to be used when displaying the symbol") );
lowerSizer->Add( m_rbMirror, 2, wxEXPAND|wxRIGHT|wxLEFT, 8 );
mainSizer->Add( lowerSizer, 0, wxEXPAND|wxTOP|wxRIGHT, 5 );
lowerSizer->Add( m_rbMirror, 2, wxEXPAND|wxLEFT|wxRIGHT, 5 );
mainSizer->Add( lowerSizer, 0, wxEXPAND, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
mainSizer->Add( m_staticline1, 0, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 10 );
wxBoxSizer* bSizer101;
bSizer101 = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizer11;
bSizer11 = new wxBoxSizer( wxHORIZONTAL );
wxStaticText* timeStampLabel;
timeStampLabel = new wxStaticText( this, wxID_ANY, _("Unique ID:"), wxDefaultPosition, wxDefaultSize, 0 );
timeStampLabel->Wrap( -1 );
bSizer11->Add( timeStampLabel, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
m_textCtrlTimeStamp = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY );
m_textCtrlTimeStamp->SetToolTip( _("Unique ID that identifies the symbol") );
bSizer11->Add( m_textCtrlTimeStamp, 1, wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM|wxRIGHT, 5 );
bSizer101->Add( bSizer11, 0, wxEXPAND|wxRIGHT|wxLEFT, 10 );
bSizer101->Add( 0, 0, 1, wxEXPAND, 5 );
m_spiceFieldsButton = new wxButton( this, wxID_ANY, _("Edit Spice Model..."), wxDefaultPosition, wxDefaultSize, 0 );
bSizer101->Add( m_spiceFieldsButton, 0, wxEXPAND|wxALL, 5 );
bSizer101->Add( 0, 0, 0, wxEXPAND|wxRIGHT|wxLEFT, 15 );
m_stdDialogButtonSizer = new wxStdDialogButtonSizer();
m_stdDialogButtonSizerOK = new wxButton( this, wxID_OK );
m_stdDialogButtonSizer->AddButton( m_stdDialogButtonSizerOK );
m_stdDialogButtonSizerCancel = new wxButton( this, wxID_CANCEL );
m_stdDialogButtonSizer->AddButton( m_stdDialogButtonSizerCancel );
m_stdDialogButtonSizer->Realize();
bSizer101->Add( m_stdDialogButtonSizer, 0, wxEXPAND|wxALL, 5 );
bSizer101->Add( m_stdDialogButtonSizer, 0, wxEXPAND, 5 );
mainSizer->Add( bSizer101, 0, wxEXPAND, 5 );
this->SetSizer( mainSizer );
this->Layout();
mainSizer->Fit( this );
// Connect Events
this->Connect( wxEVT_INIT_DIALOG, wxInitDialogEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::OnInitDlg ) );
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::OnUpdateUI ) );
@ -268,5 +268,5 @@ DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::~DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BAS
m_buttonBrowseLibrary->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::OnBrowseLibrary ), NULL, this );
m_spiceFieldsButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::OnEditSpiceModel ), NULL, this );
m_stdDialogButtonSizerCancel->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE::OnCancelButtonClick ), NULL, this );
}

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,11 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// C++ code generated with wxFormBuilder (version Nov 6 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE_H__
#define __DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE_H__
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
@ -20,10 +19,10 @@ class WX_GRID;
#include <wx/font.h>
#include <wx/grid.h>
#include <wx/gdicmn.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/bmpbuttn.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/statbox.h>
@ -44,7 +43,7 @@ class WX_GRID;
class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE : public DIALOG_SHIM
{
private:
protected:
WX_GRID* m_grid;
wxBitmapButton* m_bpAdd;
@ -66,7 +65,7 @@ class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE : public DIALOG_SHIM
wxStdDialogButtonSizer* m_stdDialogButtonSizer;
wxButton* m_stdDialogButtonSizerOK;
wxButton* m_stdDialogButtonSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnInitDlg( wxInitDialogEvent& event ) { event.Skip(); }
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
@ -79,13 +78,12 @@ class DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE : public DIALOG_SHIM
virtual void OnBrowseLibrary( wxCommandEvent& event ) { event.Skip(); }
virtual void OnEditSpiceModel( wxCommandEvent& event ) { event.Skip(); }
virtual void OnCancelButtonClick( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Symbol Properties"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU );
~DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE();
};
#endif //__DIALOG_EDIT_COMPONENT_IN_SCHEMATIC_BASE_H__

View File

@ -23,7 +23,8 @@
#include "dialog_lib_edit_pin_table_base.h"
#include "class_library.h"
#include <lib_item.h>
#include <class_library.h>
enum COL_ORDER
{

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2016-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -26,9 +26,13 @@
#include <sch_validators.h>
#include <template_fieldnames.h>
DIALOG_LIB_NEW_COMPONENT::DIALOG_LIB_NEW_COMPONENT( wxWindow* parent ) :
DIALOG_LIB_NEW_COMPONENT::DIALOG_LIB_NEW_COMPONENT( wxWindow* parent,
const wxArrayString* aRootSymbolNames ) :
DIALOG_LIB_NEW_COMPONENT_BASE( parent )
{
if( aRootSymbolNames && aRootSymbolNames->GetCount() )
m_comboInheritanceSelect->Append( *aRootSymbolNames );
m_textName->SetValidator( SCH_FIELD_VALIDATOR( true, VALUE ) );
m_textReference->SetValidator( SCH_FIELD_VALIDATOR( true, REFERENCE ) );
@ -41,3 +45,26 @@ DIALOG_LIB_NEW_COMPONENT::DIALOG_LIB_NEW_COMPONENT( wxWindow* parent ) :
// Now all widgets have the size fixed, call FinishDialogSettings
FinishDialogSettings();
}
void DIALOG_LIB_NEW_COMPONENT::OnParentSymbolSelect( wxCommandEvent& event )
{
syncControls( !m_comboInheritanceSelect->GetValue().IsEmpty() );
}
void DIALOG_LIB_NEW_COMPONENT::syncControls( bool aIsDerivedPart )
{
m_staticTextDes->Enable( !aIsDerivedPart );
m_textReference->Enable( !aIsDerivedPart );
m_staticTextUnits->Enable( !aIsDerivedPart );
m_spinPartCount->Enable( !aIsDerivedPart );
m_checkLockItems->Enable( !aIsDerivedPart );
m_checkHasConversion->Enable( !aIsDerivedPart );
m_checkIsPowerSymbol->Enable( !aIsDerivedPart );
m_staticText12->Enable( !aIsDerivedPart );
m_spinPinTextPosition->Enable( !aIsDerivedPart );
m_checkShowPinNumber->Enable( !aIsDerivedPart );
m_checkShowPinName->Enable( !aIsDerivedPart );
m_checkShowPinNameInside->Enable( !aIsDerivedPart );
}

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009-2105 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2015-2019 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -37,11 +37,13 @@ class DIALOG_LIB_NEW_COMPONENT : public DIALOG_LIB_NEW_COMPONENT_BASE
{
public:
/** Constructor */
DIALOG_LIB_NEW_COMPONENT( wxWindow* parent );
DIALOG_LIB_NEW_COMPONENT( wxWindow* parent, const wxArrayString* aRootSymbolNames = nullptr );
void SetName( const wxString& name ) override { m_textName->SetValue( name ); }
wxString GetName( void ) const override { return m_textName->GetValue(); }
wxString GetParentSymbolName() const { return m_comboInheritanceSelect->GetValue(); }
void SetReference( const wxString& reference )
{
m_textReference->SetValue( reference );
@ -92,6 +94,12 @@ public:
m_checkShowPinNameInside->SetValue( show );
}
bool GetPinNameInside( void ) { return m_checkShowPinNameInside->GetValue(); }
protected:
virtual void OnParentSymbolSelect( wxCommandEvent& event ) override;
private:
void syncControls( bool aIsDerivedPart );
};
#endif // __dialog_lib_new_component__

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// C++ code generated with wxFormBuilder (version Aug 15 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -7,133 +7,135 @@
#include "dialog_lib_new_component_base.h"
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE( DIALOG_LIB_NEW_COMPONENT_BASE, DIALOG_SHIM )
EVT_COMBOBOX( wxID_ANY, DIALOG_LIB_NEW_COMPONENT_BASE::_wxFB_OnParentSymbolSelect )
END_EVENT_TABLE()
DIALOG_LIB_NEW_COMPONENT_BASE::DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
{
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
wxBoxSizer* bSizerMain;
bSizerMain = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bSizerTop;
bSizerTop = new wxBoxSizer( wxVERTICAL );
wxFlexGridSizer* fgSizer31;
fgSizer31 = new wxFlexGridSizer( 0, 2, 0, 0 );
fgSizer31 = new wxFlexGridSizer( 0, 2, 6, 6 );
fgSizer31->AddGrowableCol( 1 );
fgSizer31->SetFlexibleDirection( wxBOTH );
fgSizer31->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticTextName = new wxStaticText( this, wxID_ANY, _("Symbol name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextName->Wrap( -1 );
m_staticTextName->SetToolTip( _("This is the symbol name in library,\nand also the default component value when loaded in the schematic.") );
fgSizer31->Add( m_staticTextName, 0, wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT, 5 );
m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 100,-1 ), 0 );
fgSizer31->Add( m_textName, 1, wxEXPAND|wxTOP|wxRIGHT|wxLEFT, 5 );
fgSizer31->Add( m_staticTextName, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_textName = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( -1,-1 ), 0 );
fgSizer31->Add( m_textName, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticText5 = new wxStaticText( this, wxID_ANY, _("Derive from existing symbol:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText5->Wrap( -1 );
fgSizer31->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_comboInheritanceSelect = new wxComboBox( this, wxID_ANY, _("Combo!"), wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_DROPDOWN|wxCB_READONLY );
m_comboInheritanceSelect->SetToolTip( _("Select symbol in the current library as parent symbol.\n\nThis was previously known as an alias. Do not select\nan existing symbol to create a new root symbol.") );
fgSizer31->Add( m_comboInheritanceSelect, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
m_staticTextDes = new wxStaticText( this, wxID_ANY, _("Default reference designator:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextDes->Wrap( -1 );
fgSizer31->Add( m_staticTextDes, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
fgSizer31->Add( m_staticTextDes, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_textReference = new wxTextCtrl( this, wxID_ANY, _("U"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer31->Add( m_textReference, 0, wxEXPAND|wxALL, 5 );
fgSizer31->Add( 0, 0, 1, wxEXPAND|wxTOP, 10 );
fgSizer31->Add( 0, 0, 1, wxEXPAND, 10 );
fgSizer31->Add( m_textReference, 0, wxEXPAND, 5 );
m_staticTextUnits = new wxStaticText( this, wxID_ANY, _("Number of units per package:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticTextUnits->Wrap( -1 );
fgSizer31->Add( m_staticTextUnits, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
fgSizer31->Add( m_staticTextUnits, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_spinPartCount = new wxSpinCtrl( this, wxID_ANY, wxT("1"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 64, 0 );
fgSizer31->Add( m_spinPartCount, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
bSizerTop->Add( fgSizer31, 1, wxEXPAND|wxLEFT|wxRIGHT, 5 );
fgSizer31->Add( m_spinPartCount, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
bSizerTop->Add( fgSizer31, 1, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizer17;
bSizer17 = new wxBoxSizer( wxVERTICAL );
m_checkLockItems = new wxCheckBox( this, wxID_ANY, _("Units are not interchangeable"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer17->Add( m_checkLockItems, 0, wxRIGHT|wxLEFT, 5 );
bSizer17->Add( 0, 0, 0, wxEXPAND|wxTOP|wxBOTTOM, 10 );
m_checkHasConversion = new wxCheckBox( this, wxID_ANY, _("Create symbol with alternate body style (DeMorgan)"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer17->Add( m_checkHasConversion, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_checkIsPowerSymbol = new wxCheckBox( this, wxID_ANY, _("Create symbol as power symbol"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer17->Add( m_checkIsPowerSymbol, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
bSizerTop->Add( bSizer17, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 );
bSizerTop->Add( bSizer17, 0, wxBOTTOM|wxEXPAND, 5 );
bSizerMain->Add( bSizerTop, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizerBottom;
bSizerBottom = new wxBoxSizer( wxVERTICAL );
bSizerBottom->Add( 0, 0, 1, wxEXPAND|wxTOP, 5 );
wxFlexGridSizer* fgSizer4;
fgSizer4 = new wxFlexGridSizer( 0, 2, 0, 55 );
fgSizer4 = new wxFlexGridSizer( 0, 2, 6, 6 );
fgSizer4->AddGrowableCol( 1 );
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_staticText12 = new wxStaticText( this, wxID_ANY, _("Pin text position offset:"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText12->Wrap( -1 );
fgSizer4->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
fgSizer4->Add( m_staticText12, 0, wxALIGN_CENTER_VERTICAL, 5 );
m_spinPinTextPosition = new wxSpinCtrl( this, wxID_ANY, wxT("40"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 100, 40 );
fgSizer4->Add( m_spinPinTextPosition, 0, wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND, 5 );
bSizerBottom->Add( fgSizer4, 0, wxLEFT|wxRIGHT, 5 );
fgSizer4->Add( m_spinPinTextPosition, 0, wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 );
bSizerBottom->Add( fgSizer4, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizer19;
bSizer19 = new wxBoxSizer( wxVERTICAL );
m_checkShowPinNumber = new wxCheckBox( this, wxID_ANY, _("Show pin number text"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinNumber->SetValue(true);
m_checkShowPinNumber->SetValue(true);
bSizer19->Add( m_checkShowPinNumber, 0, wxRIGHT|wxLEFT, 5 );
m_checkShowPinName = new wxCheckBox( this, wxID_ANY, _("Show pin name text"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinName->SetValue(true);
m_checkShowPinName->SetValue(true);
bSizer19->Add( m_checkShowPinName, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
m_checkShowPinNameInside = new wxCheckBox( this, wxID_ANY, _("Pin name inside"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkShowPinNameInside->SetValue(true);
m_checkShowPinNameInside->SetValue(true);
bSizer19->Add( m_checkShowPinNameInside, 0, wxTOP|wxRIGHT|wxLEFT, 5 );
bSizerBottom->Add( bSizer19, 0, wxEXPAND|wxLEFT|wxRIGHT, 5 );
bSizerBottom->Add( bSizer19, 0, wxEXPAND, 5 );
bSizerMain->Add( bSizerBottom, 1, wxALL|wxEXPAND, 5 );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
m_sdbSizer->AddButton( m_sdbSizerOK );
m_sdbSizerCancel = new wxButton( this, wxID_CANCEL );
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerMain->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="13" />
<FileVersion major="1" minor="15" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -14,6 +14,8 @@
<property name="file">dialog_lib_new_component_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">dialog_lib_new_component</property>
<property name="namespace"></property>
@ -24,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Dialog" expanded="1">
@ -52,42 +55,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnActivate"></event>
<event name="OnActivateApp"></event>
<event name="OnAuiFindManager"></event>
<event name="OnAuiPaneButton"></event>
<event name="OnAuiPaneClose"></event>
<event name="OnAuiPaneMaximize"></event>
<event name="OnAuiPaneRestore"></event>
<event name="OnAuiRender"></event>
<event name="OnChar"></event>
<event name="OnClose"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnHibernate"></event>
<event name="OnIconize"></event>
<event name="OnIdle"></event>
<event name="OnInitDialog"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerMain</property>
@ -104,23 +71,23 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">1</property>
<property name="growablerows"></property>
<property name="hgap">0</property>
<property name="hgap">6</property>
<property name="minimum_size"></property>
<property name="name">fgSizer31</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">0</property>
<property name="vgap">6</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxTOP|wxRIGHT|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -151,6 +118,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Symbol name:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -176,34 +144,11 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP|wxRIGHT|wxLEFT</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -250,7 +195,7 @@
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">100,-1</property>
<property name="size">-1,-1</property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
@ -263,38 +208,138 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Derive from existing symbol:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText5</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxComboBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="choices"></property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_comboInheritanceSelect</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="selection">-1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxCB_DROPDOWN|wxCB_READONLY</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Select symbol in the current library as parent symbol.&#x0A;&#x0A;This was previously known as an alias. Do not select&#x0A;an existing symbol to create a new root symbol.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value">Combo!</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCombobox">OnParentSymbolSelect</event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -325,6 +370,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Default reference designator:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -350,34 +396,11 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxTextCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -437,58 +460,11 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="0">
<property name="BottomDockable">1</property>
@ -519,6 +495,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Number of units per package:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -544,34 +521,11 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxSpinCtrl" expanded="0">
<property name="BottomDockable">1</property>
@ -629,39 +583,13 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnSpinCtrl"></event>
<event name="OnSpinCtrlText"></event>
<event name="OnTextEnter"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="flag">wxBOTTOM|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@ -730,40 +658,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">10</property>
<property name="flag">wxEXPAND|wxTOP|wxBOTTOM</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="0">
@ -828,30 +722,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="0">
@ -916,30 +786,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
@ -957,33 +803,23 @@
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxLEFT|wxRIGHT</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxFlexGridSizer" expanded="1">
<property name="cols">2</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols"></property>
<property name="growablecols">1</property>
<property name="growablerows"></property>
<property name="hgap">55</property>
<property name="hgap">6</property>
<property name="minimum_size"></property>
<property name="name">fgSizer4</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_SPECIFIED</property>
<property name="permission">none</property>
<property name="rows">0</property>
<property name="vgap">0</property>
<property name="vgap">6</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL</property>
<property name="flag">wxALIGN_CENTER_VERTICAL</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="1">
<property name="BottomDockable">1</property>
@ -1014,6 +850,7 @@
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Pin text position offset:</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -1039,34 +876,11 @@
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxALL|wxEXPAND</property>
<property name="flag">wxALIGN_CENTER_VERTICAL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxSpinCtrl" expanded="1">
<property name="BottomDockable">1</property>
@ -1124,39 +938,13 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnSpinCtrl"></event>
<event name="OnSpinCtrlText"></event>
<event name="OnTextEnter"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT|wxRIGHT</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
@ -1225,30 +1013,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
@ -1313,30 +1077,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
@ -1401,30 +1141,6 @@
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object>
@ -1447,14 +1163,6 @@
<property name="minimum_size"></property>
<property name="name">m_sdbSizer</property>
<property name="permission">protected</property>
<event name="OnApplyButtonClick"></event>
<event name="OnCancelButtonClick"></event>
<event name="OnContextHelpButtonClick"></event>
<event name="OnHelpButtonClick"></event>
<event name="OnNoButtonClick"></event>
<event name="OnOKButtonClick"></event>
<event name="OnSaveButtonClick"></event>
<event name="OnYesButtonClick"></event>
</object>
</object>
</object>

View File

@ -1,12 +1,11 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Dec 30 2017)
// C++ code generated with wxFormBuilder (version Aug 15 2019)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#ifndef __DIALOG_LIB_NEW_COMPONENT_BASE_H__
#define __DIALOG_LIB_NEW_COMPONENT_BASE_H__
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
@ -19,6 +18,7 @@
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/combobox.h>
#include <wx/spinctrl.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
@ -32,11 +32,18 @@
///////////////////////////////////////////////////////////////////////////////
class DIALOG_LIB_NEW_COMPONENT_BASE : public DIALOG_SHIM
{
DECLARE_EVENT_TABLE()
private:
// Private event handlers
void _wxFB_OnParentSymbolSelect( wxCommandEvent& event ){ OnParentSymbolSelect( event ); }
protected:
wxStaticText* m_staticTextName;
wxTextCtrl* m_textName;
wxStaticText* m_staticText5;
wxComboBox* m_comboInheritanceSelect;
wxStaticText* m_staticTextDes;
wxTextCtrl* m_textReference;
wxStaticText* m_staticTextUnits;
@ -52,12 +59,15 @@ class DIALOG_LIB_NEW_COMPONENT_BASE : public DIALOG_SHIM
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
// Virtual event handlers, overide them in your derived class
virtual void OnParentSymbolSelect( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("New Symbol"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_LIB_NEW_COMPONENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("New Symbol"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_LIB_NEW_COMPONENT_BASE();
};
#endif //__DIALOG_LIB_NEW_COMPONENT_BASE_H__

View File

@ -296,7 +296,7 @@ bool DIALOG_SYMBOL_REMAP::remapSymbolToLibTable( SCH_COMPONENT* aSymbol )
if( it->IsCache() )
continue;
LIB_ALIAS* alias = it->FindAlias( aSymbol->GetLibId().GetLibItemName().wx_str() );
LIB_PART* alias = it->FindPart( aSymbol->GetLibId().GetLibItemName().wx_str() );
// Found in the same library as the old look up method assuming the user didn't
// change the libraries or library ordering since the last time the schematic was

View File

@ -99,7 +99,7 @@ bool DIALOG_UPDATE_FIELDS::TransferDataToWindow()
{
for( auto component : m_components )
{
const auto part = component->GetPartRef().lock();
const std::unique_ptr< LIB_PART >& part = component->GetPartRef();
if( !part )
continue;
@ -145,12 +145,12 @@ void DIALOG_UPDATE_FIELDS::updateFields( SCH_COMPONENT* aComponent )
std::vector<SCH_FIELD*> oldFields;
SCH_FIELDS newFields;
PART_SPTR libPart = aComponent->GetPartRef().lock();
std::unique_ptr< LIB_PART >& libPart = aComponent->GetPartRef();
if( libPart == nullptr ) // the symbol is not found in lib: cannot update fields
if( !libPart ) // the symbol is not found in lib: cannot update fields
return;
LIB_ALIAS* alias = m_frame->GetLibAlias( aComponent->GetLibId() );
LIB_PART* alias = m_frame->GetLibPart( aComponent->GetLibId() );
aComponent->GetFields( oldFields, false );

View File

@ -199,13 +199,20 @@ bool FIELDS_GRID_TABLE<T>::CanSetValueAs( int aRow, int aCol, const wxString& aT
template <class T>
wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAttr::wxAttrKind )
{
wxGridCellAttr* tmp;
// Only the VALUE and DATASHEET fields can be edited for inherited symbols.
bool rowIsReadOnly = m_part && m_part->IsAlias() && ( aRow == REFERENCE || aRow == FOOTPRINT );
switch( aCol )
{
case FDC_NAME:
if( aRow < MANDATORY_FIELDS )
if( aRow < MANDATORY_FIELDS || rowIsReadOnly )
{
m_readOnlyAttr->IncRef();
return m_readOnlyAttr;
tmp = m_fieldNameAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
@ -216,17 +223,30 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
case FDC_VALUE:
if( aRow == REFERENCE )
{
m_referenceAttr->IncRef();
return m_referenceAttr;
if( rowIsReadOnly )
{
tmp = m_referenceAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_referenceAttr->IncRef();
return m_referenceAttr;
}
}
else if( aRow == VALUE )
{
// For power symbols, the value is not editable, because value and pin name must
// be the same and can be edited only in library editor.
if( m_part && m_part->IsPower() && ! m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
if( ( m_part && m_part->IsPower() && !m_frame->IsType( FRAME_SCH_LIB_EDITOR ) )
|| rowIsReadOnly )
{
m_readOnlyAttr->IncRef();
return m_readOnlyAttr;
tmp = m_readOnlyAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
@ -236,8 +256,18 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
}
else if( aRow == FOOTPRINT )
{
m_footprintAttr->IncRef();
return m_footprintAttr;
if( rowIsReadOnly )
{
tmp = m_footprintAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_footprintAttr->IncRef();
return m_footprintAttr;
}
}
else if( aRow == DATASHEET )
{
@ -251,39 +281,109 @@ wxGridCellAttr* FIELDS_GRID_TABLE<T>::GetAttr( int aRow, int aCol, wxGridCellAtt
if( templateFn && templateFn->m_URL )
{
m_urlAttr->IncRef();
return m_urlAttr;
if( rowIsReadOnly )
{
tmp = m_urlAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_urlAttr->IncRef();
return m_urlAttr;
}
}
else
{
m_nonUrlAttr->IncRef();
return m_nonUrlAttr;
if( rowIsReadOnly )
{
tmp = m_nonUrlAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_nonUrlAttr->IncRef();
return m_nonUrlAttr;
}
}
}
return nullptr;
case FDC_TEXT_SIZE:
case FDC_POSX:
case FDC_POSY:
return nullptr;
if( rowIsReadOnly )
{
tmp = m_readOnlyAttr->Clone();
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
return nullptr;
}
case FDC_H_ALIGN:
m_hAlignAttr->IncRef();
return m_hAlignAttr;
if( rowIsReadOnly )
{
tmp = m_hAlignAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_hAlignAttr->IncRef();
return m_hAlignAttr;
}
case FDC_V_ALIGN:
m_vAlignAttr->IncRef();
return m_vAlignAttr;
if( rowIsReadOnly )
{
tmp = m_vAlignAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_vAlignAttr->IncRef();
return m_vAlignAttr;
}
case FDC_ORIENTATION:
m_orientationAttr->IncRef();
return m_orientationAttr;
if( rowIsReadOnly )
{
tmp = m_orientationAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_orientationAttr->IncRef();
return m_orientationAttr;
}
case FDC_SHOWN:
case FDC_ITALIC:
case FDC_BOLD:
m_boolAttr->IncRef();
return m_boolAttr;
if( rowIsReadOnly )
{
tmp = m_boolAttr->Clone();
tmp->SetReadOnly( true );
tmp->SetTextColour( wxSystemSettings::GetColour( wxSYS_COLOUR_GRAYTEXT ) );
return tmp;
}
else
{
m_boolAttr->IncRef();
return m_boolAttr;
}
default:
wxFAIL;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -50,7 +50,7 @@ class FOOTPRINT_INFO_GENERATOR
wxString m_html;
SYMBOL_LIB_TABLE* m_sym_lib_table;
LIB_ID const m_lib_id;
LIB_ALIAS* m_module;
LIB_PART* m_symbol;
int m_unit;
public:
@ -58,7 +58,7 @@ public:
: m_html( DescriptionFormat ),
m_sym_lib_table( aSymbolLibTable ),
m_lib_id( aLibId ),
m_module( nullptr ),
m_symbol( nullptr ),
m_unit( aUnit )
{ }
@ -74,7 +74,7 @@ public:
try
{
m_module = const_cast< LIB_ALIAS* >( m_sym_lib_table->LoadSymbol( m_lib_id ) );
m_symbol = const_cast< LIB_PART* >( m_sym_lib_table->LoadSymbol( m_lib_id ) );
}
catch( const IO_ERROR& ioe )
{
@ -86,7 +86,7 @@ public:
return;
}
if( m_module )
if( m_symbol )
{
SetHtmlName();
SetHtmlAliasOf();
@ -107,13 +107,13 @@ public:
protected:
void SetHtmlName()
{
m_html.Replace( "__NAME__", EscapedHTML( m_module->GetName() ) );
m_html.Replace( "__NAME__", EscapedHTML( m_symbol->GetName() ) );
}
void SetHtmlAliasOf()
{
if( m_module->IsRoot() )
if( m_symbol->IsRoot() )
{
m_html.Replace( "__ALIASOF__", wxEmptyString );
}
@ -122,14 +122,8 @@ protected:
wxString root_name = _( "Unknown" );
wxString root_desc = "";
LIB_PART* root = m_module->GetPart();
LIB_ALIAS* root_alias = root ? root->GetAlias( 0 ) : nullptr;
if( root )
root_name = root->GetName();
if( root_alias )
root_desc = root_alias->GetDescription();
root_name = m_symbol->SharedPtr()->GetName();
root_desc = m_symbol->SharedPtr()->GetDescription();
m_html.Replace(
"__ALIASOF__", wxString::Format(
@ -140,7 +134,7 @@ protected:
void SetHtmlDesc()
{
wxString raw_desc = m_module->GetDescription();
wxString raw_desc = m_symbol->GetDescription();
m_html.Replace( "__DESC__", wxString::Format( DescFormat, EscapedHTML( raw_desc ) ) );
}
@ -148,7 +142,7 @@ protected:
void SetHtmlKeywords()
{
wxString keywords = m_module->GetKeyWords();
wxString keywords = m_symbol->GetKeyWords();
if( keywords.empty() )
m_html.Replace( "__KEY__", wxEmptyString );
@ -169,26 +163,25 @@ protected:
switch( aField.GetId() )
{
case DATASHEET:
text = m_symbol->GetDocFileName();
if( text.IsEmpty() || text == wxT( "~" ) )
{
text = m_module->GetDocFileName();
if( text.IsEmpty() || text == wxT( "~" ) )
{
fieldhtml.Replace( "__VALUE__", text );
}
else
{
wxString datasheetlink = DatasheetLinkFormat;
datasheetlink.Replace( "__HREF__", EscapedHTML( text ) );
if( text.Length() > 75 )
text = text.Left( 72 ) + wxT( "..." );
datasheetlink.Replace( "__TEXT__", EscapedHTML( text ) );
fieldhtml.Replace( "__VALUE__", datasheetlink );
}
fieldhtml.Replace( "__VALUE__", text );
}
else
{
wxString datasheetlink = DatasheetLinkFormat;
datasheetlink.Replace( "__HREF__", EscapedHTML( text ) );
if( text.Length() > 75 )
text = text.Left( 72 ) + wxT( "..." );
datasheetlink.Replace( "__TEXT__", EscapedHTML( text ) );
fieldhtml.Replace( "__VALUE__", datasheetlink );
}
break;
case VALUE:
@ -207,13 +200,34 @@ protected:
{
wxString fieldtable;
LIB_FIELDS fields;
m_module->GetPart()->GetFields( fields );
m_symbol->GetFields( fields );
for( auto const & field: fields )
{
fieldtable += GetHtmlFieldRow( field );
}
if( m_symbol->IsAlias() )
{
std::shared_ptr< LIB_PART > parent = m_symbol->GetParent().lock();
// Append all of the unique parent fields if this is an alias.
if( parent )
{
LIB_FIELDS parentFields;
parent->GetFields( parentFields );
for( auto const& parentField : parentFields )
{
if( m_symbol->FindField( parentField.GetName() ) )
continue;
fieldtable += GetHtmlFieldRow( parentField );
}
}
}
m_html.Replace( "__FIELDS__", fieldtable );
}
};

View File

@ -136,14 +136,15 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectCompFromLibTree(
for( auto const& i : aHistoryList )
{
LIB_ALIAS* alias = GetLibAlias( i.LibId );
LIB_PART* symbol = GetLibPart( i.LibId );
// This can be null, for example when a symbol has been deleted from a library
if( alias )
history_list.push_back( alias );
if( symbol )
history_list.push_back( symbol );
}
adapter->DoAddLibrary( "-- " + _( "Recently Used" ) + " --", wxEmptyString, history_list, true );
adapter->DoAddLibrary( "-- " + _( "Recently Used" ) + " --", wxEmptyString, history_list,
true );
if( !aHistoryList.empty() )
adapter->SetPreselectNode( aHistoryList[0].LibId, aHistoryList[0].Unit );

View File

@ -91,7 +91,7 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
try
{
if( archLib->FindAlias( component->GetLibId() ) )
if( archLib->FindPart( component->GetLibId() ) )
continue;
part = GetLibPart( component->GetLibId(), true );

View File

@ -105,7 +105,6 @@ LIB_EDIT_FRAME::LIB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
SetShowElectricalType( true );
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
m_my_part = nullptr;
m_treePane = nullptr;
m_libMgr = nullptr;
m_unit = 1;
@ -198,7 +197,6 @@ LIB_EDIT_FRAME::~LIB_EDIT_FRAME()
SetScreen( m_dummyScreen );
delete m_libMgr;
delete m_my_part;
}
@ -250,16 +248,14 @@ void LIB_EDIT_FRAME::RebuildSymbolUnitsList()
if( m_unitSelectBox->GetCount() != 0 )
m_unitSelectBox->Clear();
LIB_PART* part = GetCurPart();
if( !part || part->GetUnitCount() <= 1 )
if( !m_my_part || m_my_part->GetUnitCount() <= 1 )
{
m_unit = 1;
m_unitSelectBox->Append( wxEmptyString );
}
else
{
for( int i = 0; i < part->GetUnitCount(); i++ )
for( int i = 0; i < m_my_part->GetUnitCount(); i++ )
{
wxString sub = LIB_PART::SubReference( i+1, false );
wxString unit = wxString::Format( _( "Unit %s" ), GetChars( sub ) );
@ -268,7 +264,7 @@ void LIB_EDIT_FRAME::RebuildSymbolUnitsList()
}
// Ensure the selected unit is compatible with the number of units of the current part:
if( part && part->GetUnitCount() < m_unit )
if( m_my_part && m_my_part->GetUnitCount() < m_unit )
m_unit = 1;
m_unitSelectBox->SetSelection(( m_unit > 0 ) ? m_unit - 1 : 0 );
@ -312,11 +308,9 @@ void LIB_EDIT_FRAME::OnUpdatePartNumber( wxUpdateUIEvent& event )
if( !m_unitSelectBox )
return;
LIB_PART* part = GetCurPart();
// Using the typical event.Enable() call doesn't seem to work with wxGTK
// so use the pointer to alias combobox to directly enable or disable.
m_unitSelectBox->Enable( part && part->GetUnitCount() > 1 );
m_unitSelectBox->Enable( m_my_part && m_my_part->GetUnitCount() > 1 );
}
@ -371,39 +365,36 @@ wxString LIB_EDIT_FRAME::SetCurLib( const wxString& aLibNickname )
void LIB_EDIT_FRAME::SetCurPart( LIB_PART* aPart )
{
if( !aPart && !m_my_part )
return;
m_toolManager->RunAction( EE_ACTIONS::clearSelection, true );
if( m_my_part != aPart )
{
delete m_my_part;
m_my_part = aPart;
// Datasheet field is special; copy it to the root alias docfilename but watch out
// for clearing the aPart
if( m_my_part )
{
m_my_part->GetField( DATASHEET )->SetText( aPart->GetRootAlias()->GetDocFileName() );
}
}
m_my_part.reset( aPart );
// select the current component in the tree widget
if( aPart )
m_treePane->GetLibTree()->SelectLibId( aPart->GetLibId() );
if( m_my_part )
{
m_treePane->GetLibTree()->SelectLibId( m_my_part->GetLibId() );
m_my_part->GetField( DATASHEET )->SetText( aPart->GetDocFileName() );
}
wxString partName = aPart ? aPart->GetName() : wxString();
wxString partName = m_my_part ? m_my_part->GetName() : wxString();
m_libMgr->SetCurrentPart( partName );
// retain in case this wxFrame is re-opened later on the same PROJECT
Prj().SetRString( PROJECT::SCH_LIBEDIT_CUR_PART, partName );
// Ensure synchronized pin edit can be enabled only symbols with interchangeable units
m_SyncPinEdit = aPart && aPart->IsMulti() && !aPart->UnitsLocked();
m_SyncPinEdit = aPart && aPart->IsRoot() && aPart->IsMulti() && !aPart->UnitsLocked();
m_toolManager->ResetTools( TOOL_BASE::MODEL_RELOAD );
RebuildView();
SyncLibraries( false );
}
LIB_MANAGER& LIB_EDIT_FRAME::GetLibManager()
{
wxASSERT( m_libMgr );
return *m_libMgr;
}
@ -434,9 +425,7 @@ void LIB_EDIT_FRAME::OnModify()
bool LIB_EDIT_FRAME::SynchronizePins()
{
LIB_PART* part = GetCurPart();
return m_SyncPinEdit && part && part->IsMulti() && !part->UnitsLocked();
return m_SyncPinEdit && m_my_part && m_my_part->IsMulti() && !m_my_part->UnitsLocked();
}
@ -514,11 +503,11 @@ LIB_PART* LIB_EDIT_FRAME::getTargetPart() const
if( libId.IsValid() )
{
LIB_ALIAS* alias = m_libMgr->GetAlias( libId.GetLibItemName(), libId.GetLibNickname() );
return alias ? alias->GetPart() : nullptr;
LIB_PART* alias = m_libMgr->GetAlias( libId.GetLibItemName(), libId.GetLibNickname() );
return alias;
}
return GetCurPart();
return m_my_part.get();
}
@ -526,8 +515,8 @@ LIB_ID LIB_EDIT_FRAME::getTargetLibId() const
{
LIB_ID id = GetTreeLIBID();
if( id.GetLibNickname().empty() && GetCurPart() )
id = GetCurPart()->GetLibId();
if( id.GetLibNickname().empty() && m_my_part )
id = m_my_part->GetLibId();
return id;
}
@ -553,7 +542,8 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
m_libMgr->Sync( true, [&]( int progress, int max, const wxString& libName )
{
progressDlg.Update( progress, wxString::Format( _( "Loading library \"%s\"" ), libName ) );
progressDlg.Update( progress, wxString::Format( _( "Loading library \"%s\"" ),
libName ) );
} );
}
else
@ -588,9 +578,9 @@ void LIB_EDIT_FRAME::SyncLibraries( bool aShowProgress )
}
// If no selection, see if there's a current part to centre
if( !selected.IsValid() && GetCurPart() )
if( !selected.IsValid() && m_my_part )
{
LIB_ID current( GetCurLib(), GetCurPart()->GetName() );
LIB_ID current( GetCurLib(), m_my_part->GetName() );
m_treePane->GetLibTree()->CenterLibId( current );
}
}
@ -649,7 +639,7 @@ bool LIB_EDIT_FRAME::backupFile( const wxFileName& aOriginalFile, const wxString
void LIB_EDIT_FRAME::storeCurrentPart()
{
if( m_my_part && !GetCurLib().IsEmpty() && GetScreen()->IsModify() )
m_libMgr->UpdatePart( m_my_part, GetCurLib() ); // UpdatePart() makes a copy
m_libMgr->UpdatePart( m_my_part.get(), GetCurLib() ); // UpdatePart() makes a copy
}
@ -658,7 +648,7 @@ bool LIB_EDIT_FRAME::isCurrentPart( const LIB_ID& aLibId ) const
// This will return the root part of any alias
LIB_PART* part = m_libMgr->GetBufferedPart( aLibId.GetLibItemName(), aLibId.GetLibNickname() );
// Now we can compare the libId of the current part and the root part
return ( part && GetCurPart() && part->GetLibId() == GetCurPart()->GetLibId() );
return ( part && m_my_part && part->GetLibId() == m_my_part->GetLibId() );
}
@ -711,8 +701,8 @@ void LIB_EDIT_FRAME::RebuildView()
{
GetRenderSettings()->m_ShowUnit = m_unit;
GetRenderSettings()->m_ShowConvert = m_convert;
GetCanvas()->DisplayComponent( m_my_part );
GetRenderSettings()->m_ShowDisabled = m_my_part && m_my_part->IsAlias();
GetCanvas()->DisplayComponent( m_my_part.get() );
GetCanvas()->GetView()->HideWorksheet();
GetCanvas()->GetView()->ClearHiddenFlags();
@ -729,16 +719,15 @@ void LIB_EDIT_FRAME::HardRedraw()
const BOX2I LIB_EDIT_FRAME::GetDocumentExtents() const
{
LIB_PART* part = GetCurPart();
if( !part )
if( !m_my_part )
{
return BOX2I( VECTOR2I(-100, -100), VECTOR2I( 200, 200 ) );
}
else
{
EDA_RECT boundingBox = part->GetUnitBoundingBox( m_unit, m_convert );
return BOX2I( boundingBox.GetOrigin(), VECTOR2I( boundingBox.GetWidth(), boundingBox.GetHeight() ) );
EDA_RECT boundingBox = m_my_part->Flatten()->GetUnitBoundingBox( m_unit, m_convert );
return BOX2I( boundingBox.GetOrigin(), VECTOR2I( boundingBox.GetWidth(),
boundingBox.GetHeight() ) );
}
}

View File

@ -37,7 +37,6 @@
class SCH_EDIT_FRAME;
class SYMBOL_LIB_TABLE;
class LIB_PART;
class LIB_ALIAS;
class LIB_FIELD;
class DIALOG_LIB_EDIT_TEXT;
class SYMBOL_TREE_PANE;
@ -50,12 +49,12 @@ class LIB_MANAGER;
*/
class LIB_EDIT_FRAME : public SCH_BASE_FRAME
{
LIB_PART* m_my_part; // a part I own, it is not in any library, but a copy
std::unique_ptr< LIB_PART > m_my_part; // a part I own, it is not in any library, but a copy
// could be.
wxComboBox* m_unitSelectBox; // a ComboBox to select a unit to edit (if the part
// has multiple units)
SYMBOL_TREE_PANE* m_treePane; // component search tree widget
LIB_MANAGER* m_libMgr; // manager taking care of temporary modificatoins
LIB_MANAGER* m_libMgr; // manager taking care of temporary modifications
// The unit number to edit and show
int m_unit;
@ -150,13 +149,15 @@ public:
*
* This is a LIB_PART that I own, it is at best a copy of one in a library.
*/
LIB_PART* GetCurPart() const { return m_my_part; }
LIB_PART* GetCurPart() { return m_my_part.get(); }
/**
* Take ownership of aPart and notes that it is the one currently being edited.
*/
void SetCurPart( LIB_PART* aPart );
LIB_MANAGER& GetLibManager();
static int GetPinNumDefaultSize() { return m_textPinNumDefaultSize; }
static void SetPinNumDefaultSize( int aSize ) { m_textPinNumDefaultSize = aSize; }
@ -239,7 +240,7 @@ public:
void RebuildSymbolUnitsList();
void OnCloseWindow( wxCloseEvent& Event );
void OnExitKiCad( wxCommandEvent& event );
void OnExitKiCad( wxCommandEvent& event );
void ReCreateHToolbar() override;
void ReCreateVToolbar() override;
void ReCreateOptToolbar() override;
@ -331,14 +332,14 @@ private:
/**
* Create a copy of \a aLibEntry into memory.
*
* @param aLibEntry A pointer to the LIB_ALIAS object to an already loaded.
* @param aLibEntry A pointer to the LIB_PART object to an already loaded symbol.
* @param aLibrary the path to the library file that \a aLibEntry was loaded from. This is
* for error messaging purposes only.
* @param aUnit the initial unit to show.
* @param aConvert the initial DeMorgan variant to show.
* @return True if a copy of \a aLibEntry was successfully copied.
*/
bool LoadOneLibraryPartAux( LIB_ALIAS* aLibEntry, const wxString& aLibrary, int aUnit,
bool LoadOneLibraryPartAux( LIB_PART* aLibEntry, const wxString& aLibrary, int aUnit,
int aConvert );
/**
@ -446,7 +447,7 @@ private:
/**
* Displays a dialog asking the user to select a symbol library table.
* @param aOptional if set the Cancel button will be relabelled "Skip".
* @return Pointer to the selected symbol library table or nullptr if cancelled.
* @return Pointer to the selected symbol library table or nullptr if canceled.
*/
SYMBOL_LIB_TABLE* selectSymLibTable( bool aOptional = false );
@ -464,7 +465,7 @@ private:
///> or the library that is currently modified.
wxString getTargetLib() const;
/* Returns true when the operation has succeded (all requested libraries have been saved or
/* Returns true when the operation has succeeded (all requested libraries have been saved or
* none was selected and confirmed by OK).
* @param aRequireConfirmation when true, the user must be asked to confirm.
*/

View File

@ -27,6 +27,7 @@
#include <confirm.h>
#include <symbol_lib_table.h>
#include <lib_edit_frame.h>
#include <class_libentry.h>
#include <class_library.h>
#include <wildcards_and_files_ext.h>
#include <lib_manager.h>
@ -78,7 +79,7 @@ void LIB_EDIT_FRAME::ImportPart()
}
wxString symbolName = symbols[0];
LIB_ALIAS* entry = pi->LoadSymbol( fn.GetFullPath(), symbolName );
LIB_PART* entry = pi->LoadSymbol( fn.GetFullPath(), symbolName );
if( m_libMgr->PartExists( symbols[0], libName ) )
{
@ -87,7 +88,7 @@ void LIB_EDIT_FRAME::ImportPart()
return;
}
m_libMgr->UpdatePart( entry->GetPart(), libName );
m_libMgr->UpdatePart( entry, libName );
SyncLibraries( false );
LoadPart( symbolName, libName, 1 );
}
@ -126,10 +127,7 @@ void LIB_EDIT_FRAME::ExportPart()
{
try
{
LIB_ALIAS* alias = pi->LoadSymbol( fn.GetFullPath(), part->GetName() );
if( alias )
old_part = alias->GetPart();
old_part = pi->LoadSymbol( fn.GetFullPath(), part->GetName() );
}
catch( const IO_ERROR& ioe )
{

View File

@ -95,7 +95,8 @@ int LIB_MANAGER::GetLibraryHash( const wxString& aLibrary ) const
auto row = GetLibrary( aLibrary );
// return -1 if library does not exist or 0 if not modified
return row ? std::hash<std::string>{}( aLibrary.ToStdString() + row->GetFullURI( true ).ToStdString() ) : -1;
return row ? std::hash<std::string>{}( aLibrary.ToStdString() +
row->GetFullURI( true ).ToStdString() ) : -1;
}
@ -176,7 +177,34 @@ bool LIB_MANAGER::SaveLibrary( const wxString& aLibrary, const wxString& aFileNa
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
for( auto part : getOriginalParts( aLibrary ) )
pi->SaveSymbol( aLibrary, new LIB_PART( *part ), &properties );
{
LIB_PART* newSymbol;
if( part->IsAlias() )
{
std::shared_ptr< LIB_PART > oldParent = part->GetParent().lock();
wxCHECK_MSG( oldParent, false,
wxString::Format( "Derived symbol '%s' found with undefined parent.",
part->GetName() ) );
LIB_PART* libParent = pi->LoadSymbol( aLibrary, oldParent->GetName(), &properties );
if( !libParent )
{
libParent = new LIB_PART( *oldParent.get() );
pi->SaveSymbol( aLibrary, libParent, &properties );
}
newSymbol = new LIB_PART( *part );
newSymbol->SetParent( libParent );
pi->SaveSymbol( aLibrary, newSymbol, &properties );
}
else if( !pi->LoadSymbol( aLibrary, part->GetName(), &properties ) )
{
pi->SaveSymbol( aLibrary, new LIB_PART( *part ), &properties );
}
}
}
pi->SaveLibrary( aFileName );
@ -246,9 +274,9 @@ bool LIB_MANAGER::IsLibraryReadOnly( const wxString& aLibrary ) const
}
std::list<LIB_ALIAS*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
std::list<LIB_PART*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
{
std::list<LIB_ALIAS*> ret;
std::list<LIB_PART*> ret;
wxCHECK( LibraryExists( aLibrary ), ret );
auto libIt = m_libs.find( aLibrary );
@ -257,13 +285,12 @@ std::list<LIB_ALIAS*> LIB_MANAGER::GetAliases( const wxString& aLibrary ) const
{
for( auto& partBuf : libIt->second.GetBuffers() )
{
for( unsigned int i = 0; i < partBuf->GetPart()->GetAliasCount(); ++i )
ret.push_back( partBuf->GetPart()->GetAlias( i ) );
ret.push_back( partBuf->GetPart() );
}
}
else
{
std::vector<LIB_ALIAS*> aliases;
std::vector<LIB_PART*> aliases;
try
{
@ -294,12 +321,36 @@ LIB_PART* LIB_MANAGER::GetBufferedPart( const wxString& aAlias, const wxString&
// create a copy of the part
try
{
LIB_ALIAS* alias = symTable()->LoadSymbol( aLibrary, aAlias );
LIB_PART* part = symTable()->LoadSymbol( aLibrary, aAlias );
if( alias == nullptr )
if( part == nullptr )
THROW_IO_ERROR( _( "Symbol not found." ) );
bufferedPart = new LIB_PART( *alias->GetPart(), nullptr );
LIB_PART* bufferedParent = nullptr;
// Create parent symbols on demand so parent symbol can be set.
if( part->IsAlias() )
{
std::shared_ptr< LIB_PART > parent = part->GetParent().lock();
wxCHECK_MSG( parent, nullptr,
wxString::Format( "Derived symbol '%s' found with undefined parent.",
part->GetName() ) );
// Check if the parent symbol buffer has already be created.
bufferedParent = libBuf.GetPart( parent->GetName() );
if( !bufferedParent )
{
bufferedParent = new LIB_PART( *parent.get() );
libBuf.CreateBuffer( bufferedParent, new SCH_SCREEN( &m_frame.Kiway() ) );
}
}
bufferedPart = new LIB_PART( *part );
if( bufferedParent )
bufferedPart->SetParent( bufferedParent );
libBuf.CreateBuffer( bufferedPart, new SCH_SCREEN( &m_frame.Kiway() ) );
}
catch( const IO_ERROR& e )
@ -352,13 +403,13 @@ bool LIB_MANAGER::UpdatePart( LIB_PART* aPart, const wxString& aLibrary )
}
bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAlias,
bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& aOldName,
const wxString& aLibrary )
{
// This is essentially a delete/update.
LIB_BUFFER& libBuf = getLibraryBuffer( aLibrary );
auto partBuf = libBuf.GetBuffer( oldAlias );
auto partBuf = libBuf.GetBuffer( aOldName );
wxCHECK( partBuf, false );
// Save the original record so it is transferred to the new buffer
@ -367,6 +418,26 @@ bool LIB_MANAGER::UpdatePartAfterRename( LIB_PART* aPart, const wxString& oldAli
// Save the screen object, so it is transferred to the new buffer
std::unique_ptr<SCH_SCREEN> screen = partBuf->RemoveScreen();
if( partBuf->GetPart()->IsRoot() && libBuf.HasDerivedSymbols( aOldName ) )
{
// Reparent derived symbols.
for( auto entry : libBuf.GetBuffers() )
{
if( entry->GetPart()->IsRoot() )
continue;
if( entry->GetPart()->GetParent().lock() == original->SharedPtr() )
{
if( !libBuf.DeleteBuffer( entry ) )
return false;
LIB_PART* reparentedPart = new LIB_PART( *entry->GetPart() );
reparentedPart->SetParent( original.get() );
libBuf.CreateBuffer( reparentedPart, new SCH_SCREEN( &m_frame.Kiway() ) );
}
}
}
if( !libBuf.DeleteBuffer( partBuf ) )
return false;
@ -470,14 +541,16 @@ bool LIB_MANAGER::RemovePart( const wxString& aAlias, const wxString& aLibrary )
auto partBuf = libBuf.GetBuffer( aAlias );
wxCHECK( partBuf, false );
bool res = libBuf.DeleteBuffer( partBuf );
bool retv = true;
retv &= libBuf.DeleteBuffer( partBuf );
m_frame.SyncLibraries( false );
return res;
return retv;
}
LIB_ALIAS* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibrary ) const
LIB_PART* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibrary ) const
{
// Try the library buffers first
auto libIt = m_libs.find( aLibrary );
@ -487,11 +560,11 @@ LIB_ALIAS* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibra
LIB_PART* part = libIt->second.GetPart( aAlias );
if( part )
return part->GetAlias( aAlias );
return part;
}
// Get the original part
LIB_ALIAS* alias = nullptr;
LIB_PART* alias = nullptr;
try
{
@ -510,7 +583,7 @@ LIB_ALIAS* LIB_MANAGER::GetAlias( const wxString& aAlias, const wxString& aLibra
bool LIB_MANAGER::PartExists( const wxString& aAlias, const wxString& aLibrary ) const
{
auto libBufIt = m_libs.find( aLibrary );
LIB_ALIAS* alias = nullptr;
LIB_PART* alias = nullptr;
if( libBufIt != m_libs.end() )
return !!libBufIt->second.GetBuffer( aAlias );
@ -560,6 +633,15 @@ wxString LIB_MANAGER::GetUniqueLibraryName() const
}
void LIB_MANAGER::GetRootSymbolNames( const wxString& aLibraryName,
wxArrayString& aRootSymbolNames )
{
LIB_BUFFER& libBuf = getLibraryBuffer( aLibraryName );
libBuf.GetRootSymbolNames( aRootSymbolNames );
}
wxString LIB_MANAGER::getLibraryName( const wxString& aFilePath )
{
wxFileName fn( aFilePath );
@ -620,8 +702,8 @@ std::set<LIB_PART*> LIB_MANAGER::getOriginalParts( const wxString& aLibrary )
for( const auto& aliasName : aliases )
{
LIB_ALIAS* alias = symTable()->LoadSymbol( aLibrary, aliasName );
parts.insert( alias->GetPart() );
LIB_PART* alias = symTable()->LoadSymbol( aLibrary, aliasName );
parts.insert( alias );
}
}
catch( const IO_ERROR& e )
@ -645,7 +727,34 @@ LIB_MANAGER::LIB_BUFFER& LIB_MANAGER::getLibraryBuffer( const wxString& aLibrary
LIB_BUFFER& buf = ret.first->second;
for( auto part : getOriginalParts( aLibrary ) )
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
{
LIB_PART* newSymbol;
if( part->IsAlias() )
{
std::shared_ptr< LIB_PART > oldParent = part->GetParent().lock();
wxCHECK_MSG( oldParent, buf,
wxString::Format( "Derived symbol '%s' found with undefined parent.",
part->GetName() ) );
LIB_PART* libParent = buf.GetPart( oldParent->GetName() );
if( !libParent )
{
libParent = new LIB_PART( *oldParent.get() );
buf.CreateBuffer( libParent, new SCH_SCREEN( &m_frame.Kiway() ) );
}
newSymbol = new LIB_PART( *part );
newSymbol->SetParent( libParent );
buf.CreateBuffer( newSymbol, new SCH_SCREEN( &m_frame.Kiway() ) );
}
else if( !buf.GetPart( part->GetName() ) )
{
buf.CreateBuffer( new LIB_PART( *part, nullptr ), new SCH_SCREEN( &m_frame.Kiway() ) );
}
}
return buf;
}
@ -704,19 +813,34 @@ bool LIB_MANAGER::PART_BUFFER::IsModified() const
}
LIB_PART* LIB_MANAGER::LIB_BUFFER::GetPart( const wxString& aAlias ) const
{
auto buf = GetBuffer( aAlias );
if( !buf )
return nullptr;
LIB_PART* part = buf->GetPart();
wxCHECK( part, nullptr );
return part;
}
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 );
wxASSERT( aCopy->GetLib() == nullptr );
std::unique_ptr<SCH_SCREEN> screen( aScreen );
auto partBuf = std::make_shared<PART_BUFFER>( aCopy, std::move( screen ) );
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 = (LIB_ID&) aCopy->GetLibId();
LIB_ID libId = aCopy->GetLibId();
libId.SetLibNickname( m_libName );
aCopy->SetLibId( libId );
++m_hash;
return true;
@ -728,9 +852,7 @@ bool LIB_MANAGER::LIB_BUFFER::UpdateBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartB
{
bool ret = true;
ret &= removeAliases( aPartBuf );
aPartBuf->SetPart( aCopy );
ret &= addAliases( aPartBuf );
++m_hash;
return ret;
@ -741,11 +863,18 @@ bool LIB_MANAGER::LIB_BUFFER::DeleteBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartB
{
auto partBufIt = std::find( m_parts.begin(), m_parts.end(), aPartBuf );
wxCHECK( partBufIt != m_parts.end(), false );
bool retv = true;
// Remove all derived symbols to prevent broken inheritance.
if( aPartBuf->GetPart()->IsRoot() )
retv &= removeChildSymbols( aPartBuf );
m_deleted.emplace_back( *partBufIt );
m_parts.erase( partBufIt );
++m_hash;
return removeAliases( aPartBuf );
return retv;
}
@ -755,10 +884,55 @@ bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf
wxCHECK( aPartBuf, false );
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
SYMBOL_LIB_TABLE::SAVE_T result = aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) );
wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
SYMBOL_LIB_TABLE::SAVE_T result;
if( part->IsAlias() )
{
LIB_PART* originalPart;
LIB_PART* newCachedPart = new LIB_PART( *part );
std::shared_ptr< LIB_PART > bufferedParent = part->GetParent().lock();
wxCHECK( bufferedParent, false );
LIB_PART* cachedParent = aLibTable->LoadSymbol( m_libName, bufferedParent->GetName() );
if( !cachedParent )
{
cachedParent = new LIB_PART( *bufferedParent.get() );
newCachedPart->SetParent( cachedParent );
result = aLibTable->SaveSymbol( m_libName, cachedParent );
wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
result = aLibTable->SaveSymbol( m_libName, newCachedPart );
wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
LIB_PART* originalParent = new LIB_PART( *bufferedParent.get() );
aPartBuf->SetOriginal( originalParent );
originalPart = new LIB_PART( *part );
originalPart->SetParent( originalParent );
aPartBuf->SetOriginal( originalPart );
}
else
{
newCachedPart->SetParent( cachedParent );
result = aLibTable->SaveSymbol( m_libName, newCachedPart );
wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
LIB_MANAGER::PART_BUFFER::PTR originalBufferedParent =
GetBuffer( bufferedParent->GetName() );
wxCHECK( originalBufferedParent, false );
originalPart = new LIB_PART( *part );
originalPart->SetParent( originalBufferedParent->GetPart() );
aPartBuf->SetOriginal( originalPart );
}
}
else if( !aLibTable->LoadSymbol( m_libName, part->GetName() ) )
{
// TODO there is no way to check if symbol has been successfully saved
result = aLibTable->SaveSymbol( m_libName, new LIB_PART( *part ) );
wxCHECK( result == SYMBOL_LIB_TABLE::SAVE_OK, false );
aPartBuf->SetOriginal( new LIB_PART( *part ) );
}
aPartBuf->SetOriginal( new LIB_PART( *part ) );
++m_hash;
return true;
}
@ -775,59 +949,132 @@ bool LIB_MANAGER::LIB_BUFFER::SaveBuffer( LIB_MANAGER::PART_BUFFER::PTR aPartBuf
PROPERTIES properties;
properties.emplace( SCH_LEGACY_PLUGIN::PropBuffering, "" );
// TODO there is no way to check if symbol has been successfully saved
aPlugin->SaveSymbol( m_libName, new LIB_PART( *part ), aBuffer ? &properties : nullptr );
aPartBuf->SetOriginal( new LIB_PART( *part ) );
if( part->IsAlias() )
{
LIB_PART* originalPart;
LIB_PART* newCachedPart = new LIB_PART( *part );
std::shared_ptr< LIB_PART > bufferedParent = part->GetParent().lock();
wxCHECK( bufferedParent, false );
LIB_PART* cachedParent = aPlugin->LoadSymbol( m_libName, bufferedParent->GetName() );
if( !cachedParent )
{
cachedParent = new LIB_PART( *bufferedParent.get() );
newCachedPart->SetParent( cachedParent );
aPlugin->SaveSymbol( m_libName, cachedParent, aBuffer ? &properties : nullptr );
aPlugin->SaveSymbol( m_libName, newCachedPart, aBuffer ? &properties : nullptr );
LIB_PART* originalParent = new LIB_PART( *bufferedParent.get() );
aPartBuf->SetOriginal( originalParent );
originalPart = new LIB_PART( *part );
originalPart->SetParent( originalParent );
aPartBuf->SetOriginal( originalPart );
}
else
{
newCachedPart->SetParent( cachedParent );
aPlugin->SaveSymbol( m_libName, newCachedPart, aBuffer ? &properties : nullptr );
LIB_MANAGER::PART_BUFFER::PTR originalBufferedParent =
GetBuffer( bufferedParent->GetName() );
wxCHECK( originalBufferedParent, false );
originalPart = new LIB_PART( *part );
originalPart->SetParent( originalBufferedParent->GetPart() );
aPartBuf->SetOriginal( originalPart );
}
}
else if( !aPlugin->LoadSymbol( m_libName, part->GetName(), aBuffer ? &properties : nullptr ) )
{
// TODO there is no way to check if symbol has been successfully saved
aPlugin->SaveSymbol( m_libName, new LIB_PART( *part ), aBuffer ? &properties : nullptr );
aPartBuf->SetOriginal( new LIB_PART( *part ) );
}
++m_hash;
return true;
}
bool LIB_MANAGER::LIB_BUFFER::addAliases( PART_BUFFER::PTR aPartBuf )
LIB_MANAGER::PART_BUFFER::PTR LIB_MANAGER::LIB_BUFFER::GetBuffer( const wxString& aAlias ) const
{
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
bool ret = true; // Assume everything is ok
for( unsigned int i = 0; i < part->GetAliasCount(); ++i )
for( auto entry : m_parts )
{
bool newAlias;
std::tie( std::ignore, newAlias ) = m_aliases.emplace( part->GetAlias( i )->GetName(),
aPartBuf );
if( !newAlias ) // Overwrite check
{
wxFAIL;
ret = false;
}
if( entry->GetPart()->GetName() == aAlias )
return entry;
}
return ret;
return PART_BUFFER::PTR( nullptr );
}
bool LIB_MANAGER::LIB_BUFFER::removeAliases( PART_BUFFER::PTR aPartBuf )
bool LIB_MANAGER::LIB_BUFFER::HasDerivedSymbols( const wxString& aParentName ) const
{
LIB_PART* part = aPartBuf->GetPart();
wxCHECK( part, false );
bool ret = true; // Assume everything is ok
for( unsigned int i = 0; i < part->GetAliasCount(); ++i )
for( auto entry : m_parts )
{
auto aliasIt = m_aliases.find( part->GetAlias( i )->GetName() );
if( aliasIt == m_aliases.end() )
if( entry->GetPart()->IsAlias() )
{
wxFAIL;
ret = false;
PART_SPTR parent = entry->GetPart()->GetParent().lock();
// Check for inherited part without a valid parent.
wxCHECK( parent, false );
if( parent->GetName() == aParentName )
return true;
}
}
return false;
}
void LIB_MANAGER::LIB_BUFFER::GetRootSymbolNames( wxArrayString& aRootSymbolNames )
{
for( auto entry : m_parts )
{
if( entry->GetPart()->IsAlias() )
continue;
aRootSymbolNames.Add( entry->GetPart()->GetName() );
}
}
int LIB_MANAGER::LIB_BUFFER::removeChildSymbols( LIB_MANAGER::PART_BUFFER::PTR aPartBuf )
{
wxCHECK( aPartBuf && aPartBuf->GetPart()->IsRoot(), 0 );
int cnt = 0;
std::deque< LIB_MANAGER::PART_BUFFER::PTR >::iterator it = m_parts.begin();
while( it != m_parts.end() )
{
if( (*it)->GetPart()->IsRoot() )
{
++it;
}
else
{
PART_SPTR parent = (*it)->GetPart()->GetParent().lock();
// Be sure the alias belongs to the assigned owner
wxASSERT( aliasIt->second.lock() == aPartBuf );
wxCHECK2( parent, ++it; continue );
m_aliases.erase( aliasIt );
if( parent->GetName() == aPartBuf->GetPart()->GetName() )
{
wxCHECK2( parent == aPartBuf->GetPart()->SharedPtr(), ++it; continue );
m_deleted.emplace_back( *it );
it = m_parts.erase( it );
cnt++;
}
else
{
++it;
}
}
}
return ret;
return cnt;
}

View File

@ -35,7 +35,6 @@
#include <symbol_tree_synchronizing_adapter.h>
#include <sch_screen.h>
class LIB_ALIAS;
class LIB_PART;
class PART_LIB;
class SCH_PLUGIN;
@ -81,8 +80,8 @@ public:
{
if( m_bHasMessages )
{
wxLogMessage( _( "Not all libraries could be loaded. Use the Manage Symbol Libraries dialog \n"
"to adjust paths and add or remove libraries." ) );
wxLogMessage( _( "Not all symbol libraries could be loaded. Use the Manage Symbol\n"
"Libraries dialog to adjust paths and add or remove libraries." ) );
wxLogGui::Flush();
}
}
@ -130,7 +129,7 @@ public:
*/
SYMBOL_LIB_TABLE_ROW* GetLibrary( const wxString& aLibrary ) const;
std::list<LIB_ALIAS*> GetAliases( const wxString& aLibrary ) const;
std::list<LIB_PART*> GetAliases( const wxString& aLibrary ) const;
/**
* Creates an empty library and adds it to the library table. The library file is created.
@ -172,7 +171,7 @@ public:
* 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;
LIB_PART* 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.
@ -186,7 +185,8 @@ public:
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).
* 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;
@ -288,6 +288,8 @@ public:
return LIB_ID( m_currentLib, m_currentPart );
}
void GetRootSymbolNames( const wxString& aLibName, wxArrayString& aRootSymbolNames );
private:
///> Extracts library name basing on the file name
static wxString getLibraryName( const wxString& aFilePath );
@ -363,12 +365,8 @@ private:
int GetHash() const { return m_hash; }
///> 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;
}
///> Returns the working copy of a LIB_PART root object with specified alias.
LIB_PART* GetPart( const wxString& aAlias ) const;
///> Creates a new buffer to store a part. LIB_BUFFER takes ownership of aCopy.
bool CreateBuffer( LIB_PART* aCopy, SCH_SCREEN* aScreen );
@ -392,23 +390,38 @@ private:
bool SaveBuffer( PART_BUFFER::PTR aPartBuf, SCH_PLUGIN* aPlugin, bool aBuffer );
///> 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 );
}
PART_BUFFER::PTR GetBuffer( const wxString& aAlias ) const;
///> Returns all buffered parts
const std::deque<PART_BUFFER::PTR>& GetBuffers() const { return m_parts; }
/**
* Checks to see any parts in the buffer are derived from a parent named \a aParentName.
*
* @param aParentName is the name of the parent to test.
*
* @return true if any symbols are found derived from a symbol named \a aParent, otherwise
* false.
*/
bool HasDerivedSymbols( const wxString& aParentName ) const;
/**
* Fetchs a list of root symbols names from the library buffer.
*
* @param aRootSymbolNames is a reference to a list to populate with root symbol names.
*/
void GetRootSymbolNames( wxArrayString& aRootSymbolNames );
private:
///> Creates alias entries for a particular part buffer
bool addAliases( PART_BUFFER::PTR aPartBuf );
/**
* Remove all symbols derived from \a aParent from the library buffer.
*
* @param aParent is the #PART_BUFFER to check against.
*
* @return the count of #PART_BUFFER objects removed from the library.
*/
int removeChildSymbols( 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;
std::deque<PART_BUFFER::PTR> m_deleted; // Buffer for deleted parts until library is saved
const wxString m_libName; // Buffered library name

View File

@ -29,6 +29,7 @@
#include <gestfich.h>
#include <tools/ee_actions.h>
#include <lib_edit_frame.h>
#include <class_libentry.h>
#include <class_library.h>
#include <template_fieldnames.h>
#include <wildcards_and_files_ext.h>
@ -163,7 +164,7 @@ bool LIB_EDIT_FRAME::LoadComponentAndSelectLib( const LIB_ID& aLibId, int aUnit,
bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, int aUnit,
int aConvert )
{
LIB_ALIAS* alias = nullptr;
LIB_PART* alias = nullptr;
try
{
@ -187,7 +188,7 @@ bool LIB_EDIT_FRAME::LoadComponentFromCurrentLib( const wxString& aAliasName, in
GetScreen()->ClearUndoRedoList();
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
SetShowDeMorgan( GetCurPart()->HasConversion() );
SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );
if( aUnit > 0 )
RebuildSymbolUnitsList();
@ -212,7 +213,7 @@ static void synchronizeLibEditScreenSettings( const SCH_SCREEN& aCurrentScreen,
}
bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& aLibrary,
bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_PART* aEntry, const wxString& aLibrary,
int aUnit, int aConvert )
{
wxString msg, rootName;
@ -227,7 +228,7 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
}
LIB_PART* lib_part = m_libMgr->GetBufferedPart( aEntry->GetName(), aLibrary );
wxASSERT( lib_part );
wxCHECK( lib_part, false );
m_unit = aUnit > 0 ? aUnit : 1;
m_convert = aConvert > 0 ? aConvert : 1;
@ -250,7 +251,7 @@ bool LIB_EDIT_FRAME::LoadOneLibraryPartAux( LIB_ALIAS* aEntry, const wxString& a
m_toolManager->RunAction( ACTIONS::zoomFitScreen, true );
updateTitle();
RebuildSymbolUnitsList();
SetShowDeMorgan( GetCurPart()->HasConversion() );
SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );
SyncToolbars();
// Display the document information based on the entry selected just in
@ -273,6 +274,8 @@ void LIB_EDIT_FRAME::SaveAll()
void LIB_EDIT_FRAME::CreateNewPart()
{
m_toolManager->RunAction( ACTIONS::cancelInteractive, true );
wxArrayString rootSymbols;
wxString lib = getTargetLib();
if( !m_libMgr->LibraryExists( lib ) )
@ -283,7 +286,9 @@ void LIB_EDIT_FRAME::CreateNewPart()
return;
}
DIALOG_LIB_NEW_COMPONENT dlg( this );
m_libMgr->GetRootSymbolNames( lib, rootSymbols );
DIALOG_LIB_NEW_COMPONENT dlg( this, &rootSymbols );
dlg.SetMinSize( dlg.GetSize() );
if( dlg.ShowModal() == wxID_CANCEL )
@ -309,41 +314,53 @@ void LIB_EDIT_FRAME::CreateNewPart()
}
LIB_PART new_part( name ); // do not create part on the heap, it will be buffered soon
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
wxString parentSymbolName = dlg.GetParentSymbolName();
if( dlg.GetPinNameInside() )
if( parentSymbolName.IsEmpty() )
{
new_part.SetPinNameOffset( dlg.GetPinTextPosition() );
new_part.GetReferenceField().SetText( dlg.GetReference() );
new_part.SetUnitCount( dlg.GetUnitCount() );
if( new_part.GetPinNameOffset() == 0 )
new_part.SetPinNameOffset( 1 );
// 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
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 );
new_part.SetConversion( dlg.GetAlternateBodyStyle() );
// must be called after loadPart, that calls SetShowDeMorgan, but
// because the symbol is empty,it looks like it has no alternate body
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
}
else
{
new_part.SetPinNameOffset( 0 );
LIB_PART* parent = m_libMgr->GetAlias( parentSymbolName, lib );
wxCHECK( parent, /* void */ );
new_part.SetParent( parent );
}
( 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 );
SyncLibraries( false );
LoadPart( name, lib, 1 );
new_part.SetConversion( dlg.GetAlternateBodyStyle() );
// must be called after loadPart, that calls SetShowDeMorgan, but
// because the symbol is empty,it looks like it has no alternate body
SetShowDeMorgan( dlg.GetAlternateBodyStyle() );
}
@ -483,46 +500,32 @@ void LIB_EDIT_FRAME::savePartAs()
void LIB_EDIT_FRAME::UpdateAfterSymbolProperties( wxString* aOldName, wxArrayString* aOldAliases )
{
wxCHECK( m_my_part, /* void */ );
wxString msg;
wxString lib = GetCurLib();
LIB_PART* part = GetCurPart();
if( aOldName && *aOldName != part->GetName() )
if( aOldName && *aOldName != m_my_part->GetName() )
{
// Test the current library for name conflicts
if( !lib.empty() && m_libMgr->PartExists( part->GetName(), lib ) )
if( !lib.empty() && m_libMgr->PartExists( m_my_part->GetName(), lib ) )
{
msg.Printf( _( "The name '%s' conflicts with an existing entry in the library '%s'." ),
part->GetName(),
m_my_part->GetName(),
lib );
DisplayErrorMessage( this, msg );
part->SetName( *aOldName );
m_my_part->SetName( *aOldName );
}
else
m_libMgr->UpdatePartAfterRename( part, *aOldName, lib );
}
if( aOldAliases && *aOldAliases != part->GetAliasNames( false ) )
{
// If the number of aliases (or their names) have changed, do a full re-sync
SyncLibraries( false );
}
else
{
// Otherwise just update each alias
for( LIB_ALIAS* alias : part->GetAliases() )
{
wxDataViewItem item = m_libMgr->GetAdapter()->FindItem( alias->GetLibId() );
static_cast<LIB_TREE_NODE_LIB_ID*>( item.GetID() )->Update( alias );
}
m_libMgr->UpdatePartAfterRename( m_my_part.get(), *aOldName, lib );
}
// Reselect the renamed part
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, part->GetName() ) );
m_treePane->GetLibTree()->SelectLibId( LIB_ID( lib, m_my_part->GetName() ) );
RebuildSymbolUnitsList();
SetShowDeMorgan( part->HasConversion() );
SetShowDeMorgan( GetCurPart()->Flatten()->HasConversion() );
updateTitle();
DisplayCmpDoc();
@ -618,7 +621,20 @@ void LIB_EDIT_FRAME::DuplicatePart( bool aFromClipboard )
else
{
srcPart = m_libMgr->GetBufferedPart( libId.GetLibItemName(), lib );
wxCHECK( srcPart, /* void */ );
newPart = new LIB_PART( *srcPart );
// Derive from same parent.
if( srcPart->IsAlias() )
{
std::shared_ptr< LIB_PART > srcParent = srcPart->GetParent().lock();
wxCHECK( srcParent, /* void */ );
newPart->SetParent( srcParent.get() );
}
}
if( !newPart )
@ -635,28 +651,13 @@ void LIB_EDIT_FRAME::DuplicatePart( bool aFromClipboard )
void LIB_EDIT_FRAME::fixDuplicateAliases( LIB_PART* aPart, const wxString& aLibrary )
{
wxCHECK( aPart, /* void */ );
wxString newName;
for( unsigned int i = 0; i < aPart->GetAliasCount(); ++i )
{
LIB_ALIAS* alias = aPart->GetAlias( i );
int sfx = 0;
newName = alias->GetName();
newName.Printf( "%s_copy", aPart->GetName() );
while( m_libMgr->PartExists( newName, aLibrary ) )
{
if( sfx == 0 )
newName = wxString::Format( "%s_copy", alias->GetName() );
else
newName = wxString::Format( "%s_copy%d", alias->GetName(), sfx );
++sfx;
}
if( i == 0 )
aPart->SetName( newName );
else
alias->SetName( newName );
}
aPart->SetName( newName );
}
@ -664,7 +665,9 @@ void LIB_EDIT_FRAME::Revert( bool aConfirm )
{
LIB_ID libId = getTargetLibId();
const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName(); // Empty if this is the library itself that is selected
// Empty if this is the library itself that is selected.
const wxString& partName = libId.GetLibItemName();
wxString msg = wxString::Format( _( "Revert \"%s\" to last version saved?" ),
partName.IsEmpty() ? libName : partName );
@ -688,7 +691,9 @@ void LIB_EDIT_FRAME::Revert( bool aConfirm )
curr_partName = curr_libId.GetLibItemName();
}
else
{
reload_currentPart = isCurrentPart( libId );
}
}
int unit = m_unit;
@ -727,15 +732,13 @@ void LIB_EDIT_FRAME::RevertAll()
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 )
if( !part )
{
wxString msg = wxString::Format( _( "Symbol name \"%s\" not found in library \"%s\"" ),
GetChars( aAlias ),
GetChars( aLibrary ) );
wxString msg;
msg.Printf( _( "Symbol name \"%s\" not found in library \"%s\"" ), aAlias, aLibrary );
DisplayError( this, msg );
return;
}
@ -745,7 +748,7 @@ void LIB_EDIT_FRAME::LoadPart( const wxString& aAlias, const wxString& aLibrary,
// and if units are interchangeable, graphic items are common to units
m_DrawSpecificUnit = part->UnitsLocked();
LoadOneLibraryPartAux( alias, aLibrary, aUnit, 0 );
LoadOneLibraryPartAux( part, aLibrary, aUnit, 0 );
}
@ -823,6 +826,7 @@ bool LIB_EDIT_FRAME::saveLibrary( const wxString& aLibrary, bool aNewFile )
if( !aNewFile )
m_libMgr->ClearLibraryModified( aLibrary );
ClearMsgPanel();
msg.Printf( _( "Symbol library file \"%s\" saved" ), fn.GetFullPath() );
wxString msg1;
msg1.Printf( _( "Symbol library documentation file \"%s\" saved" ), docFileName.GetFullPath() );

View File

@ -28,6 +28,7 @@
#include <sch_screen.h>
#include <general.h>
#include <lib_edit_frame.h>
#include <class_libentry.h>
#include <class_library.h>
#include <plotter.h>
@ -60,9 +61,7 @@ void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName )
plotter->StartPlot();
LIB_PART* part = GetCurPart();
if( part )
if( m_my_part )
{
TRANSFORM temp; // Uses default transform
wxPoint plotPos;
@ -70,10 +69,10 @@ void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName )
plotPos.x = pageInfo.GetWidthIU() /2;
plotPos.y = pageInfo.GetHeightIU()/2;
part->Plot( plotter, GetUnit(), GetConvert(), plotPos, temp );
m_my_part->Plot( plotter, GetUnit(), GetConvert(), plotPos, temp );
// Plot lib fields, not plotted by m_component->Plot():
part->PlotLibFields( plotter, GetUnit(), GetConvert(), plotPos, temp );
m_my_part->PlotLibFields( plotter, GetUnit(), GetConvert(), plotPos, temp );
}
plotter->EndPlot();
@ -83,9 +82,7 @@ void LIB_EDIT_FRAME::SVG_PlotComponent( const wxString& aFullFileName )
void LIB_EDIT_FRAME::PrintPage( wxDC* aDC )
{
LIB_PART* part = GetCurPart();
if( !part )
if( !m_my_part )
return;
wxSize pagesize = GetScreen()->GetPageSettings().GetSizeIU();
@ -98,5 +95,5 @@ void LIB_EDIT_FRAME::PrintPage( wxDC* aDC )
plot_offset.x = pagesize.x / 2;
plot_offset.y = pagesize.y / 2;
part->Print( aDC, plot_offset, m_unit, m_convert, PART_DRAW_OPTIONS::Default() );
m_my_part->Print( aDC, plot_offset, m_unit, m_convert, PART_DRAW_OPTIONS::Default() );
}

View File

@ -75,7 +75,7 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList()
// Store the current part in the undo buffer
PICKED_ITEMS_LIST* undoCommand = new PICKED_ITEMS_LIST();
LIB_PART* oldPart = GetCurPart();
LIB_PART* oldPart = m_my_part.get();
oldPart->SetFlags( UR_TRANSIENT );
ITEM_PICKER undoWrapper( oldPart, undoRedoType );
undoCommand->PushItem( undoWrapper );
@ -85,7 +85,7 @@ void LIB_EDIT_FRAME::GetComponentFromRedoList()
// which calls delete <previous part>.
// <previous part> is now put in undo list and is owned by this list
// Just set the current part to the part which come from the redo list
m_my_part = part;
m_my_part.reset( part );
if( undoRedoType == UR_LIB_RENAME )
{
@ -123,7 +123,7 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList()
// Store the current part in the redo buffer
PICKED_ITEMS_LIST* redoCommand = new PICKED_ITEMS_LIST();
LIB_PART* oldPart = GetCurPart();
LIB_PART* oldPart = m_my_part.get();
oldPart->SetFlags( UR_TRANSIENT );
ITEM_PICKER redoWrapper( oldPart, undoRedoType );
redoCommand->PushItem( redoWrapper );
@ -133,7 +133,7 @@ void LIB_EDIT_FRAME::GetComponentFromUndoList()
// which calls delete <previous part>.
// <previous part> is now put in redo list and is owned by this list.
// Just set the current part to the part which come from the undo list
m_my_part = part;
m_my_part.reset( part );
if( undoRedoType == UR_LIB_RENAME )
{
@ -172,4 +172,4 @@ void LIB_EDIT_FRAME::RollbackPartFromUndo()
SetShowDeMorgan( part->HasConversion() );
RebuildView();
}
}

View File

@ -91,13 +91,13 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
CONDITIONAL_MENU* editMenu = new CONDITIONAL_MENU( false, selTool );
auto enableUndoCondition = [ this ] ( const SELECTION& sel ) {
return GetCurPart() && GetScreen() && GetScreen()->GetUndoCommandCount() != 0;
return m_my_part && GetScreen() && GetScreen()->GetUndoCommandCount() != 0;
};
auto enableRedoCondition = [ this ] ( const SELECTION& sel ) {
return GetCurPart() && GetScreen() && GetScreen()->GetRedoCommandCount() != 0;
return m_my_part && GetScreen() && GetScreen()->GetRedoCommandCount() != 0;
};
auto havePartCondition = [ this ] ( const SELECTION& sel ) {
return GetCurPart();
return m_my_part != nullptr;
};
editMenu->AddItem( ACTIONS::undo, enableUndoCondition );
@ -166,14 +166,18 @@ void LIB_EDIT_FRAME::ReCreateMenuBar()
//-- Place menu -----------------------------------------------
//
auto enableIsEditableCondition = [ this ] ( const SELECTION& aSel ) {
return m_my_part && m_my_part->IsRoot();
};
CONDITIONAL_MENU* placeMenu = new CONDITIONAL_MENU( false, selTool );
placeMenu->AddItem( EE_ACTIONS::placeSymbolPin, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::placeSymbolText, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::drawSymbolRectangle, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::drawSymbolCircle, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::drawSymbolArc, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::drawSymbolLines, EE_CONDITIONS::ShowAlways );
placeMenu->AddItem( EE_ACTIONS::placeSymbolPin, enableIsEditableCondition );
placeMenu->AddItem( EE_ACTIONS::placeSymbolText, enableIsEditableCondition );
placeMenu->AddItem( EE_ACTIONS::drawSymbolRectangle, enableIsEditableCondition );
placeMenu->AddItem( EE_ACTIONS::drawSymbolCircle, enableIsEditableCondition );
placeMenu->AddItem( EE_ACTIONS::drawSymbolArc, enableIsEditableCondition );
placeMenu->AddItem( EE_ACTIONS::drawSymbolLines, enableIsEditableCondition );
placeMenu->Resolve();

View File

@ -43,10 +43,9 @@
void LIB_EDIT_FRAME::LoadOneSymbol()
{
EE_SELECTION_TOOL* selTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
LIB_PART* part = GetCurPart();
// Exit if no library entry is selected or a command is in progress.
if( !part || !EE_CONDITIONS::Idle( selTool->GetSelection() ) )
if( !m_my_part || !EE_CONDITIONS::Idle( selTool->GetSelection() ) )
return;
PROJECT& prj = Prj();
@ -97,7 +96,7 @@ void LIB_EDIT_FRAME::LoadOneSymbol()
wxMessageBox( msg, _( "Warning" ), wxOK | wxICON_EXCLAMATION, this );
}
LIB_ALIAS* alias = nullptr;
LIB_PART* alias = nullptr;
try
{
@ -108,11 +107,11 @@ void LIB_EDIT_FRAME::LoadOneSymbol()
return;
}
wxCHECK_RET( alias && alias->GetPart(), "Invalid symbol." );
wxCHECK_RET( alias, "Invalid symbol." );
SaveCopyInUndoList( part );
SaveCopyInUndoList( m_my_part.get() );
LIB_PART* first = alias->GetPart();
LIB_PART* first = alias;
LIB_ITEMS_CONTAINER& drawList = first->GetDrawItems();
for( LIB_ITEM& item : drawList )
@ -130,12 +129,12 @@ void LIB_EDIT_FRAME::LoadOneSymbol()
LIB_ITEM* newItem = (LIB_ITEM*) item.Clone();
newItem->SetParent( part );
part->AddDrawItem( newItem );
newItem->SetParent( m_my_part.get() );
m_my_part->AddDrawItem( newItem );
item.ClearSelected();
}
part->RemoveDuplicateDrawItems();
m_my_part->RemoveDuplicateDrawItems();
OnModify();
}
@ -143,12 +142,12 @@ void LIB_EDIT_FRAME::LoadOneSymbol()
void LIB_EDIT_FRAME::SaveOneSymbol()
{
wxCHECK( m_my_part, /* void */ );
// Export the current part as a symbol (.sym file)
// this is the current part without its aliases and doc file
// because a .sym file is used to import graphics in a part being edited
LIB_PART* part = GetCurPart();
if( !part || part->GetDrawItems().empty() )
if( m_my_part->GetDrawItems().empty() )
return;
PROJECT& prj = Prj();
@ -160,7 +159,7 @@ void LIB_EDIT_FRAME::SaveOneSymbol()
default_path = search->LastVisitedPath();
wxFileDialog dlg( this, _( "Export Symbol" ), default_path,
part->GetName() + "." + SchematicSymbolFileExtension,
m_my_part->GetName() + "." + SchematicSymbolFileExtension,
SchematicSymbolFileWildcard(),
wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
@ -189,8 +188,8 @@ void LIB_EDIT_FRAME::SaveOneSymbol()
nodoc_props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
plugin->CreateSymbolLib( fn.GetFullPath(), &nodoc_props );
LIB_PART* saved_part = new LIB_PART( *part );
saved_part->RemoveAllAliases(); // useless in a .sym file
// The part gets flattened by the LIB_PART copy constructor.
LIB_PART* saved_part = new LIB_PART( *m_my_part.get() );
plugin->SaveSymbol( fn.GetFullPath(), saved_part, &nodoc_props );
}
catch( const IO_ERROR& ioe )
@ -204,18 +203,23 @@ void LIB_EDIT_FRAME::SaveOneSymbol()
void LIB_EDIT_FRAME::DisplayCmpDoc()
{
LIB_PART* part = GetCurPart();
EDA_DRAW_FRAME::ClearMsgPanel();
if( !part )
if( !m_my_part )
return;
LIB_ALIAS* alias = part->GetAlias( part->GetName() );
wxString msg = part->GetName();
wxString msg = m_my_part->GetName();
AppendMsgPanel( _( "Name" ), msg, BLUE, 8 );
if( m_my_part->IsAlias() )
{
PART_SPTR parent = m_my_part->GetParent().lock();
msg = parent ? parent->GetName() : _( "Undefined!" );
AppendMsgPanel( _( "Parent" ), msg, BROWN, 8 );
}
static wxChar UnitLetter[] = wxT( "?ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
msg = UnitLetter[m_unit];
@ -228,13 +232,13 @@ void LIB_EDIT_FRAME::DisplayCmpDoc()
AppendMsgPanel( _( "Body" ), msg, GREEN, 8 );
if( part->IsPower() )
if( m_my_part->IsPower() )
msg = _( "Power Symbol" );
else
msg = _( "Symbol" );
AppendMsgPanel( _( "Type" ), msg, MAGENTA, 8 );
AppendMsgPanel( _( "Description" ), alias->GetDescription(), CYAN, 8 );
AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
AppendMsgPanel( _( "Datasheet" ), alias->GetDocFileName(), DARKDARKGRAY );
AppendMsgPanel( _( "Description" ), m_my_part->GetDescription(), CYAN, 8 );
AppendMsgPanel( _( "Key words" ), m_my_part->GetKeyWords(), DARKDARKGRAY );
AppendMsgPanel( _( "Datasheet" ), m_my_part->GetDocFileName(), DARKDARKGRAY );
}

View File

@ -30,7 +30,7 @@
#include <dialog_helpers.h>
#include <bitmaps.h>
#include <lib_manager.h>
#include <class_library.h>
#include <class_libentry.h>
#include <tool/action_toolbar.h>
#include <tools/ee_actions.h>
@ -156,7 +156,7 @@ void LIB_EDIT_FRAME::SyncToolbars()
LIB_ID libId = getTargetLibId();
const wxString& libName = libId.GetLibNickname();
const wxString& partName = libId.GetLibItemName();
bool isEditable = m_my_part && m_my_part->IsRoot();
bool modified = m_libMgr->HasModifications();
if( !modified && !partName.IsEmpty() && m_libMgr->IsPartModified( partName, libName ) )
@ -166,15 +166,16 @@ void LIB_EDIT_FRAME::SyncToolbars()
m_mainToolBar->Toggle( ACTIONS::undo, GetScreen() && GetScreen()->GetUndoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::redo, GetScreen() && GetScreen()->GetRedoCommandCount() > 0 );
m_mainToolBar->Toggle( ACTIONS::zoomTool, IsCurrentTool( ACTIONS::zoomTool ) );
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, GetCurPart() != nullptr );
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, (bool) m_my_part );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganStandard,
GetShowDeMorgan(),
m_convert == LIB_ITEM::LIB_CONVERT::BASE );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganAlternate,
GetShowDeMorgan(),
m_convert == LIB_ITEM::LIB_CONVERT::DEMORGAN );
m_mainToolBar->Toggle( EE_ACTIONS::pinTable, isEditable );
m_mainToolBar->Toggle( EE_ACTIONS::toggleSyncedPinsMode,
GetCurPart() && GetCurPart()->IsMulti() && !GetCurPart()->UnitsLocked(),
m_my_part && m_my_part->IsMulti() && !m_my_part->UnitsLocked(),
m_SyncPinEdit );
m_mainToolBar->Refresh();
@ -186,36 +187,19 @@ void LIB_EDIT_FRAME::SyncToolbars()
m_optionsToolBar->Toggle( EE_ACTIONS::showComponentTree, IsSearchTreeShown() );
m_optionsToolBar->Refresh();
#define TOGGLE_TOOL( toolbar, tool ) toolbar->Toggle( tool, true, IsCurrentTool( tool ) )
#define TOGGLE_TOOL( toolbar, enable, tool ) toolbar->Toggle( tool, enable, IsCurrentTool( tool ) )
if( !GetCurPart() )
{
// If no part is loaded for editing, disable the editing tools
m_drawToolBar->Toggle( EE_ACTIONS::placeSymbolPin, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::placeSymbolText, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::drawSymbolRectangle, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::drawSymbolCircle, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::drawSymbolArc, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::drawSymbolLines, false, false );
m_drawToolBar->Toggle( EE_ACTIONS::placeSymbolAnchor, false, false );
m_drawToolBar->EnableTool( ID_LIBEDIT_IMPORT_BODY_BUTT, false );
m_drawToolBar->EnableTool( ID_LIBEDIT_EXPORT_BODY_BUTT, false );
m_drawToolBar->Toggle( ACTIONS::deleteTool, false, false );
}
else
{
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::placeSymbolPin );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::placeSymbolText );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::drawSymbolRectangle );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::drawSymbolCircle );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::drawSymbolArc );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::drawSymbolLines );
TOGGLE_TOOL( m_drawToolBar, EE_ACTIONS::placeSymbolAnchor );
m_drawToolBar->EnableTool( ID_LIBEDIT_IMPORT_BODY_BUTT, true );
m_drawToolBar->EnableTool( ID_LIBEDIT_EXPORT_BODY_BUTT, true );
TOGGLE_TOOL( m_drawToolBar, ACTIONS::deleteTool );
}
TOGGLE_TOOL( m_drawToolBar, isEditable, ACTIONS::selectionTool );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::placeSymbolPin );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::placeSymbolText );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::drawSymbolRectangle );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::drawSymbolCircle );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::drawSymbolArc );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::drawSymbolLines );
TOGGLE_TOOL( m_drawToolBar, isEditable, EE_ACTIONS::placeSymbolAnchor );
TOGGLE_TOOL( m_drawToolBar, isEditable, ACTIONS::deleteTool );
m_drawToolBar->EnableTool( ID_LIBEDIT_IMPORT_BODY_BUTT, isEditable );
m_drawToolBar->EnableTool( ID_LIBEDIT_EXPORT_BODY_BUTT, isEditable );
TOGGLE_TOOL( m_drawToolBar, ACTIONS::selectionTool );
m_drawToolBar->Refresh();
}

View File

@ -124,13 +124,11 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_P
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
LIB_PART* part = comp->GetPartRef().lock().get();
if( !part )
if( !comp->GetPartRef() )
continue;
// If component is a "multi parts per package" type
if( part->GetUnitCount() > 1 )
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
@ -138,7 +136,7 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_P
}
// record the usage of this library component entry.
m_LibParts.insert( part ); // rejects non-unique pointers
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
return comp;
}
@ -184,13 +182,11 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList(
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
LIB_PART* part = comp->GetPartRef().lock().get();
if( !part )
if( !comp->GetPartRef() )
continue;
// If component is a "multi parts per package" type
if( part->GetUnitCount() > 1 )
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
@ -199,14 +195,15 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList(
// Collect all pins for this reference designator by searching
// the entire design for other parts with the same reference designator.
// This is only done once, it would be too expensive otherwise.
findAllUnitsOfComponent( comp, part, aSheetPath );
findAllUnitsOfComponent( comp, comp->GetPartRef().get(), aSheetPath );
}
else // entry->GetUnitCount() <= 1 means one part per package
{
LIB_PINS pins; // constructed once here
part->GetPins( pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() );
comp->GetPartRef()->GetPins( pins, comp->GetUnitSelection( aSheetPath ),
comp->GetConvert() );
for( size_t i = 0; i < pins.size(); i++ )
{
@ -226,7 +223,7 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList(
eraseDuplicatePins();
// record the usage of this library component entry.
m_LibParts.insert( part ); // rejects non-unique pointers
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
return comp;
}

View File

@ -242,10 +242,8 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
// "logical" library name, which is in anticipation of a better search
// algorithm for parts based on "logical_lib.part" and where logical_lib
// is merely the library name minus path and extension.
PART_SPTR part = comp->GetPartRef().lock();
if( part )
xlibsource->AddAttribute( "lib", part->GetLibId().GetLibNickname() );
if( comp->GetPartRef() )
xlibsource->AddAttribute( "lib", comp->GetPartRef()->GetLibId().GetLibNickname() );
// We only want the symbol name, not the full LIB_ID.
xlibsource->AddAttribute( "part", comp->GetLibId().GetLibItemName() );
@ -404,26 +402,12 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeLibParts()
xlibpart->AddAttribute( "lib", libNickname );
xlibpart->AddAttribute( "part", lcomp->GetName() );
if( lcomp->GetAliasCount() )
{
wxArrayString aliases = lcomp->GetAliasNames( false );
if( aliases.GetCount() )
{
XNODE* xaliases = node( "aliases" );
xlibpart->AddChild( xaliases );
for( unsigned i=0; i<aliases.GetCount(); ++i )
{
xaliases->AddChild( node( "alias", aliases[i] ) );
}
}
}
//----- show the important properties -------------------------
if( !lcomp->GetAlias( 0 )->GetDescription().IsEmpty() )
xlibpart->AddChild( node( "description", lcomp->GetAlias( 0 )->GetDescription() ) );
if( !lcomp->GetDescription().IsEmpty() )
xlibpart->AddChild( node( "description", lcomp->GetDescription() ) );
if( !lcomp->GetAlias( 0 )->GetDocFileName().IsEmpty() )
xlibpart->AddChild( node( "docs", lcomp->GetAlias( 0 )->GetDocFileName() ) );
if( !lcomp->GetDocFileName().IsEmpty() )
xlibpart->AddChild( node( "docs", lcomp->GetDocFileName() ) );
// Write the footprint list
if( lcomp->GetFootprints().GetCount() )

View File

@ -81,13 +81,12 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
item = comp;
PART_SPTR part = comp->GetPartRef().lock();
if( part )
if( comp->GetPartRef() )
{
if( part->GetFootprints().GetCount() != 0 ) // Put in list
if( comp->GetPartRef()->GetFootprints().GetCount() != 0 ) // Put in list
{
cmpList.emplace_back( comp, part.get(), sheetList[i] );
cmpList.push_back( SCH_REFERENCE( comp, comp->GetPartRef().get(),
sheetList[i] ) );
}
}

View File

@ -237,9 +237,8 @@ wxString NETLIST_EXPORTER_PSPICE::GetSpiceFieldDefVal( SPICE_FIELD aField,
wxString nodeSeq;
std::vector<LIB_PIN*> pins;
auto part = aComponent->GetPartRef().lock();
wxCHECK( part, wxString() );
part->GetPins( pins );
wxCHECK( aComponent->GetPartRef(), wxString() );
aComponent->GetPartRef()->GetPins( pins );
for( auto pin : pins )
nodeSeq += pin->GetNumber() + " ";

View File

@ -139,8 +139,8 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
candidate_map_t candidate_map;
// Remember the list of components is sorted by part name.
// So a search in libraries is made only once by group
LIB_ALIAS* case_sensitive_match = nullptr;
std::vector<LIB_ALIAS*> case_insensitive_matches;
LIB_PART* case_sensitive_match = nullptr;
std::vector<LIB_PART*> case_insensitive_matches;
wxString last_part_name;
@ -157,7 +157,7 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
LIB_ID id( wxEmptyString, part_name );
case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibraryAlias( id );
case_sensitive_match = aRescuer.GetPrj()->SchLibs()->FindLibPart( id );
if( !case_sensitive_match )
// the case sensitive match failed. Try a case insensitive match
@ -169,7 +169,7 @@ void RESCUE_CASE_CANDIDATE::FindRescues( RESCUER& aRescuer,
continue;
RESCUE_CASE_CANDIDATE candidate( part_name, case_insensitive_matches[0]->GetName(),
case_insensitive_matches[0]->GetPart() );
case_insensitive_matches[0] );
candidate_map[part_name] = candidate;
}
@ -310,7 +310,6 @@ bool RESCUE_CACHE_CANDIDATE::PerformAction( RESCUER* aRescuer )
LIB_PART new_part( *tmp );
new_part.SetName( m_new_name );
new_part.RemoveAllAliases();
aRescuer->AddPart( &new_part );
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
@ -446,7 +445,6 @@ bool RESCUE_SYMBOL_LIB_TABLE_CANDIDATE::PerformAction( RESCUER* aRescuer )
LIB_PART new_part( *tmp );
new_part.SetLibId( m_new_id );
new_part.SetName( m_new_id.GetLibItemName() );
new_part.RemoveAllAliases();
aRescuer->AddPart( &new_part );
for( SCH_COMPONENT* each_component : *aRescuer->GetComponents() )
@ -654,17 +652,14 @@ void LEGACY_RESCUER::OpenRescueLibrary()
if( rescueLib )
{
// For items in the rescue library, aliases are the root symbol.
std::vector< LIB_ALIAS* > aliases;
std::vector< LIB_PART* > symbols;
rescueLib->GetAliases( aliases );
rescueLib->GetParts( symbols );
for( auto alias : aliases )
for( auto symbol : symbols )
{
LIB_PART* part = alias->GetPart();
wxCHECK2( part, continue );
m_rescue_lib->AddPart( new LIB_PART( *part, m_rescue_lib.get() ) );
// The LIB_PART copy constructor flattens derived symbols (formerly known as aliases).
m_rescue_lib->AddPart( new LIB_PART( *symbol, m_rescue_lib.get() ) );
}
}
}

View File

@ -42,20 +42,21 @@
#include <tools/ee_actions.h>
#include <tools/ee_selection_tool.h>
LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
wxWindow* aParent, bool aShowErrorMsg )
LIB_PART* SchGetLibPart( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
wxWindow* aParent, bool aShowErrorMsg )
{
// wxCHECK_MSG( aLibId.IsValid(), NULL, "LIB_ID is not valid." );
wxCHECK_MSG( aLibTable, NULL, "Invalid symbol library table." );
LIB_ALIAS* alias = NULL;
LIB_PART* symbol = NULL;
try
{
alias = aLibTable->LoadSymbol( aLibId );
symbol = aLibTable->LoadSymbol( aLibId );
if( !alias && aCacheLib )
alias = aCacheLib->FindAlias( aLibId );
if( !symbol && aCacheLib )
symbol = aCacheLib->FindPart( aLibId );
}
catch( const IO_ERROR& ioe )
{
@ -68,16 +69,7 @@ LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PA
}
}
return alias;
}
LIB_PART* SchGetLibPart( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable, PART_LIB* aCacheLib,
wxWindow* aParent, bool aShowErrorMsg )
{
LIB_ALIAS* alias = SchGetLibAlias( aLibId, aLibTable, aCacheLib, aParent, aShowErrorMsg );
return ( alias ) ? alias->GetPart() : NULL;
return symbol;
}
@ -252,14 +244,6 @@ void SCH_BASE_FRAME::UpdateStatusBar()
}
LIB_ALIAS* SCH_BASE_FRAME::GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowError )
{
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;
return SchGetLibAlias( aLibId, Prj().SchSymbolLibTable(), cache, this, aShowError );
}
LIB_PART* SCH_BASE_FRAME::GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib, bool aShowErrorMsg )
{
PART_LIB* cache = ( aUseCacheLib ) ? Prj().SchLibs()->GetCacheLibrary() : NULL;

View File

@ -42,7 +42,6 @@ class PAGE_INFO;
class TITLE_BLOCK;
class LIB_VIEW_FRAME;
class LIB_EDIT_FRAME;
class LIB_ALIAS;
class LIB_PART;
class PART_LIB;
class SCHLIB_FILTER;
@ -64,15 +63,10 @@ class SCH_DRAW_PANEL;
*
* @return The symbol found in the library or NULL if the symbol was not found.
*/
LIB_ALIAS* SchGetLibAlias( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
PART_LIB* aCacheLib = NULL, wxWindow* aParent = NULL,
bool aShowErrorMsg = false );
LIB_PART* SchGetLibPart( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aLibTable,
PART_LIB* aCacheLib = NULL, wxWindow* aParent = NULL,
bool aShowErrorMsg = false );
/**
* A shim class between EDA_DRAW_FRAME and several derived classes:
* LIB_EDIT_FRAME, LIB_VIEW_FRAME, and SCH_EDIT_FRAME, and it brings in a
@ -284,12 +278,11 @@ public:
* @param aShowErrorMessage set to true to show any error messages.
* @return The symbol found in the library or NULL if the symbol was not found.
*/
LIB_ALIAS* GetLibAlias( const LIB_ID& aLibId, bool aUseCacheLib = false,
bool aShowError = false );
LIB_PART* GetLibPart( const LIB_ID& aLibId, bool aUseCacheLib = false,
bool aShowErrorMsg = false );
LIB_PART* GetFlattenedLibPart( const LIB_ID& aLibId, bool aShowErrorMsg = false );
/**
* Function SelectComponentFromLibBrowser
* Calls the library viewer to select component to import into schematic.

View File

@ -41,6 +41,7 @@
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_legacy_plugin.h>
#include <netlist_object.h>
#include <lib_item.h>
#include <symbol_lib_table.h>
@ -57,8 +58,7 @@
/**
* Function toUTFTildaText
* convert a wxString to UTF8 and replace any control characters with a ~,
* Convert a wxString to UTF8 and replace any control characters with a ~,
* where a control character is one of the first ASCII values up to ' ' 32d.
*/
std::string toUTFTildaText( const wxString& txt )
@ -130,7 +130,7 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
m_unit = unit;
m_convert = convert;
m_lib_id = aLibId;
m_part = aPart.SharedPtr();
m_part.reset( new LIB_PART( aPart ) );
m_fieldsAutoplaced = AUTOPLACED_NO;
SetTimeStamp( GetNewTimeStamp() );
@ -171,7 +171,9 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
m_unit = aComponent.m_unit;
m_convert = aComponent.m_convert;
m_lib_id = aComponent.m_lib_id;
m_part = aComponent.m_part;
if( aComponent.m_part )
m_part.reset( new LIB_PART( *aComponent.m_part.get() ) );
SetTimeStamp( aComponent.m_TimeStamp );
@ -267,31 +269,33 @@ void SCH_COMPONENT::SetLibId( const LIB_ID& aLibId, SYMBOL_LIB_TABLE* aSymLibTab
m_lib_id = aLibId;
SetModified();
LIB_ALIAS* alias = nullptr;
std::unique_ptr< LIB_PART > symbol;
if( aSymLibTable && aSymLibTable->HasLibrary( m_lib_id.GetLibNickname() ) )
alias = aSymLibTable->LoadSymbol( m_lib_id.GetLibNickname(), m_lib_id.GetLibItemName() );
{
LIB_PART* tmp = aSymLibTable->LoadSymbol( m_lib_id );
if( !alias && aCacheLib )
alias = aCacheLib->FindAlias( m_lib_id.Format().wx_str() );
if( tmp )
symbol = tmp->Flatten();
}
if( alias && alias->GetPart() )
m_part = alias->GetPart()->SharedPtr();
else
m_part.reset();
if( !symbol && aCacheLib )
{
LIB_PART* tmp = aCacheLib->FindPart( m_lib_id.Format().wx_str() );
if( tmp )
symbol.reset( new LIB_PART( *tmp ) );
}
m_part.reset( symbol.release() );
}
wxString SCH_COMPONENT::GetDescription() const
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
LIB_ALIAS* alias = part->GetAlias( GetLibId().GetLibItemName() );
if( !alias )
return wxEmptyString;
return alias->GetDescription();
return m_part->GetDescription();
}
return wxEmptyString;
@ -300,14 +304,9 @@ wxString SCH_COMPONENT::GetDescription() const
wxString SCH_COMPONENT::GetDatasheet() const
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
LIB_ALIAS* alias = part->GetAlias( GetLibId().GetLibItemName() );
if( !alias )
return wxEmptyString;
return alias->GetDocFileName();
return m_part->GetDocFileName();
}
return wxEmptyString;
@ -320,7 +319,7 @@ bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs )
// flimsy search path ordering. None-the-less find a part based on that design:
if( LIB_PART* part = aLibs->FindLibPart( m_lib_id ) )
{
m_part = part->SharedPtr();
m_part.reset( part );
return true;
}
@ -330,31 +329,44 @@ bool SCH_COMPONENT::Resolve( PART_LIBS* aLibs )
bool SCH_COMPONENT::Resolve( SYMBOL_LIB_TABLE& aLibTable, PART_LIB* aCacheLib )
{
LIB_ALIAS* alias = nullptr;
std::unique_ptr< LIB_PART > part;
try
{
// We want a full symbol not just the top level child symbol.
PROPERTIES props;
props[ SCH_LEGACY_PLUGIN::PropNoDocFile ] = "";
// LIB_TABLE_BASE::LoadSymbol() throws an IO_ERROR if the the library nickname
// is not found in the table so check if the library still exists in the table
// before attempting to load the symbol.
if( m_lib_id.IsValid() && aLibTable.HasLibrary( m_lib_id.GetLibNickname() ) )
alias = aLibTable.LoadSymbol( m_lib_id );
{
LIB_PART* tmp = aLibTable.LoadSymbol( m_lib_id );
if( tmp )
part = tmp->Flatten();
}
// Fall back to cache library. This is temporary until the new schematic file
// format is implemented.
if( !alias && aCacheLib )
if( !part && aCacheLib )
{
wxString libId = m_lib_id.Format().wx_str();
libId.Replace( ":", "_" );
alias = aCacheLib->FindAlias( libId );
wxLogTrace( traceSymbolResolver,
"Library symbol %s not found falling back to cache library.",
m_lib_id.Format().wx_str() );
LIB_PART* tmp = aCacheLib->FindPart( libId );
if( tmp )
part.reset( new LIB_PART( *tmp ) );
}
if( alias && alias->GetPart() )
if( part )
{
m_part = alias->GetPart()->SharedPtr();
m_part.reset( part.release() );
return true;
}
}
@ -422,7 +434,8 @@ void SCH_COMPONENT::ResolveAll( const EE_COLLECTOR& aComponents, SYMBOL_LIB_TABL
if( curr_libid != next_cmp->m_lib_id )
break;
next_cmp->m_part = cmp->m_part;
if( cmp->m_part )
next_cmp->m_part.reset( new LIB_PART( *cmp->m_part.get() ) );
next_cmp->UpdatePins();
@ -446,12 +459,12 @@ void SCH_COMPONENT::UpdatePins( const EE_COLLECTOR& aComponents )
void SCH_COMPONENT::UpdatePins( SCH_SHEET_PATH* aSheet )
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
m_pinMap.clear();
unsigned i = 0;
for( LIB_PIN* libPin = part->GetNextPin(); libPin; libPin = part->GetNextPin( libPin ) )
for( LIB_PIN* libPin = m_part->GetNextPin(); libPin; libPin = m_part->GetNextPin( libPin ) )
{
wxASSERT( libPin->Type() == LIB_PIN_T );
@ -532,10 +545,8 @@ void SCH_COMPONENT::SetTransform( const TRANSFORM& aTransform )
int SCH_COMPONENT::GetUnitCount() const
{
if( PART_SPTR part = m_part.lock() )
{
return part->GetUnitCount();
}
if( m_part )
return m_part->GetUnitCount();
return 0;
}
@ -548,9 +559,9 @@ void SCH_COMPONENT::Print( wxDC* aDC, const wxPoint& aOffset )
opts.draw_visible_fields = false;
opts.draw_hidden_fields = false;
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
part->Print( aDC, m_Pos + aOffset, m_unit, m_convert, opts );
m_part->Print( aDC, m_Pos + aOffset, m_unit, m_convert, opts );
}
else // Use dummy() part if the actual cannot be found.
{
@ -893,11 +904,11 @@ SCH_FIELD* SCH_COMPONENT::FindField( const wxString& aFieldName, bool aIncludeDe
void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
wxString symbolName;
LIB_FIELDS fields;
part->GetFields( fields );
m_part->GetFields( fields );
for( const LIB_FIELD& field : fields )
{
@ -946,8 +957,8 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
// Some older libraries may be broken and the alias datasheet information
// in the document file for the root part may have been dropped. This only
// happens for the root part.
if( schField->GetText().IsEmpty() && symbolName == part->GetName() )
schField->SetText( part->GetField( DATASHEET )->GetText() );
if( schField->GetText().IsEmpty() && symbolName == m_part->GetName() )
schField->SetText( m_part->GetField( DATASHEET )->GetText() );
}
else
{
@ -960,26 +971,19 @@ void SCH_COMPONENT::UpdateFields( bool aResetStyle, bool aResetRef )
LIB_PIN* SCH_COMPONENT::GetPin( const wxString& number )
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
return part->GetPin( number, m_unit, m_convert );
return m_part->GetPin( number, m_unit, m_convert );
}
return NULL;
}
void SCH_COMPONENT::GetPins( std::vector<LIB_PIN*>& aPinsList )
{
if( m_part.expired() )
{
// no pins; nothing to get
}
else if( PART_SPTR part = m_part.lock() )
{
part->GetPins( aPinsList, m_unit, m_convert );
}
else
wxFAIL_MSG( "Could not obtain PART_SPTR lock" );
if( m_part )
m_part->GetPins( aPinsList, m_unit, m_convert );
}
@ -991,7 +995,11 @@ void SCH_COMPONENT::SwapData( SCH_ITEM* aItem )
SCH_COMPONENT* component = (SCH_COMPONENT*) aItem;
std::swap( m_lib_id, component->m_lib_id );
std::swap( m_part, component->m_part );
LIB_PART* part = component->m_part.release();
component->m_part.reset( m_part.release() );
m_part.reset( part );
std::swap( m_Pos, component->m_Pos );
std::swap( m_unit, component->m_unit );
std::swap( m_convert, component->m_convert );
@ -1035,7 +1043,6 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
{
wxArrayString reference_fields;
static const wxChar separators[] = wxT( " " );
PART_SPTR part = m_part.lock();
// Build a reference with no annotation,
// i.e. a reference ended by only one '?'
@ -1309,9 +1316,9 @@ EDA_RECT SCH_COMPONENT::GetBodyBoundingBox() const
{
EDA_RECT bBox;
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
bBox = part->GetBodyBoundingBox( m_unit, m_convert );
bBox = m_part->GetBodyBoundingBox( m_unit, m_convert );
}
else
{
@ -1366,43 +1373,36 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
wxString msg;
// part and alias can differ if alias is not the root
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
if( part.get() != dummy() )
if( m_part.get() != dummy() )
{
LIB_ALIAS* alias = nullptr;
if( part->GetLib() && part->GetLib()->IsCache() )
{
wxString libId = GetLibId().Format();
libId.Replace( ":", "_" );
alias = part->GetAlias( libId );
}
else
{
alias = part->GetAlias( GetLibId().GetLibItemName() );
}
if( !alias )
return;
if( g_CurrentSheet )
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ),
DARKCYAN ) );
msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
msg = m_part->IsPower() ? _( "Power symbol" ) : _( "Value" );
aList.push_back( MSG_PANEL_ITEM( msg, GetField( VALUE )->GetShownText(), DARKCYAN ) );
// Display component reference in library and library
aList.push_back( MSG_PANEL_ITEM( _( "Name" ), GetLibId().GetLibItemName(), BROWN ) );
if( alias->GetName() != part->GetName() )
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), part->GetName(), BROWN ) );
if( !m_part->IsRoot() )
{
msg = _( "Missing parent" );
if( part->GetLib() && part->GetLib()->IsCache() )
std::shared_ptr< LIB_PART > parent = m_part->GetParent().lock();
if( parent )
msg = parent->GetName();
aList.push_back( MSG_PANEL_ITEM( _( "Alias of" ), msg, BROWN ) );
}
if( m_part->GetLib() && m_part->GetLib()->IsCache() )
aList.push_back( MSG_PANEL_ITEM( _( "Library" ),
part->GetLib()->GetLogicalName(), RED ) );
m_part->GetLib()->GetLogicalName(), RED ) );
else if( !m_lib_id.GetLibNickname().empty() )
aList.push_back( MSG_PANEL_ITEM( _( "Library" ), m_lib_id.GetLibNickname(),
BROWN ) );
@ -1418,9 +1418,9 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
aList.push_back( MSG_PANEL_ITEM( _( "Footprint" ), msg, DARKRED ) );
// Display description of the component, and keywords found in lib
aList.push_back( MSG_PANEL_ITEM( _( "Description" ), alias->GetDescription(),
aList.push_back( MSG_PANEL_ITEM( _( "Description" ), m_part->GetDescription(),
DARKCYAN ) );
aList.push_back( MSG_PANEL_ITEM( _( "Key words" ), alias->GetKeyWords(), DARKCYAN ) );
aList.push_back( MSG_PANEL_ITEM( _( "Key words" ), m_part->GetKeyWords(), DARKCYAN ) );
}
}
else
@ -1520,9 +1520,9 @@ bool SCH_COMPONENT::Matches( wxFindReplaceData& aSearchData, void* aAuxData )
void SCH_COMPONENT::GetEndPoints( std::vector <DANGLING_END_ITEM>& aItemList )
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
for( LIB_PIN* pin = m_part->GetNextPin(); pin; pin = m_part->GetNextPin( pin ) )
{
wxASSERT( pin->Type() == LIB_PIN_T );
@ -1609,12 +1609,12 @@ LIB_ITEM* SCH_COMPONENT::GetDrawItem( const wxPoint& aPosition, KICAD_T aType )
{
UpdatePins();
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
// Calculate the position relative to the component.
wxPoint libPosition = aPosition - m_Pos;
return part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
return m_part->LocateDrawItem( m_unit, m_convert, aType, libPosition, m_transform );
}
return NULL;
@ -1694,9 +1694,9 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR aInspector, void* aTestData,
void SCH_COMPONENT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
for( LIB_PIN* pin = m_part->GetNextPin(); pin; pin = m_part->GetNextPin( pin ) )
{
wxASSERT( pin->Type() == LIB_PIN_T );
@ -1796,7 +1796,10 @@ SCH_COMPONENT& SCH_COMPONENT::operator=( const SCH_ITEM& aItem )
SCH_COMPONENT* c = (SCH_COMPONENT*) &aItem;
m_lib_id = c->m_lib_id;
m_part = c->m_part;
LIB_PART* libSymbol = c->m_part ? new LIB_PART( *c->m_part.get() ) : nullptr;
m_part.reset( libSymbol );
m_Pos = c->m_Pos;
m_unit = c->m_unit;
m_convert = c->m_convert;
@ -1877,12 +1880,12 @@ void SCH_COMPONENT::Plot( PLOTTER* aPlotter )
{
TRANSFORM temp;
if( PART_SPTR part = m_part.lock() )
if( m_part )
{
temp = GetTransform();
aPlotter->StartBlock( nullptr );
part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp );
m_part->Plot( aPlotter, GetUnit(), GetConvert(), m_Pos, temp );
for( SCH_FIELD field : m_Fields )
field.Plot( aPlotter );

View File

@ -93,7 +93,8 @@ private:
TRANSFORM m_transform; ///< The rotation/mirror transformation matrix.
SCH_FIELDS m_Fields; ///< Variable length list of fields.
PART_REF m_part; ///< points into the PROJECT's libraries to the LIB_PART for this component
///< A flattened copy of a LIB_PART found in the PROJECT's libraries to for this component.
std::unique_ptr< LIB_PART > m_part;
SCH_PINS m_pins; ///< the component's pins
SCH_PIN_MAP m_pinMap; ///< the component's pins mapped by LIB_PIN*.
@ -182,7 +183,7 @@ public:
const LIB_ID& GetLibId() const { return m_lib_id; }
PART_REF& GetPartRef() { return m_part; }
std::unique_ptr< LIB_PART >& GetPartRef() { return m_part; }
/**
* Return information about the aliased parts

View File

@ -1097,16 +1097,16 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
package = p->second;
}
LIB_ALIAS* alias = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
m_properties.get() );
LIB_PART* part = m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname,
m_properties.get() );
if( !alias || !alias->GetPart() )
if( !part )
{
wxLogMessage( wxString::Format( _( "Could not find %s in the imported library" ), kisymbolname ) );
wxLogMessage( wxString::Format( _( "Could not find %s in the imported library" ),
kisymbolname ) );
return;
}
LIB_PART* part = alias->GetPart();
LIB_ID libId( getLibName(), kisymbolname );
std::unique_ptr<SCH_COMPONENT> component( new SCH_COMPONENT() );
component->SetLibId( libId );
@ -1126,7 +1126,6 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
}
}
LIB_FIELDS partFields;
part->GetFields( partFields );
@ -1186,7 +1185,6 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
bool valueAttributeFound = false;
bool nameAttributeFound = false;
wxXmlNode* attributeNode = aInstanceNode->GetChildren();
// Parse attributes for the instance
@ -2582,18 +2580,17 @@ bool SCH_EAGLE_PLUGIN::checkConnections( const SCH_COMPONENT* aComponent, const
void SCH_EAGLE_PLUGIN::addImplicitConnections( SCH_COMPONENT* aComponent,
SCH_SCREEN* aScreen, bool aUpdateSet )
{
auto partRef = aComponent->GetPartRef().lock();
wxCHECK( partRef, /*void*/ );
wxCHECK( aComponent->GetPartRef(), /*void*/ );
// Normally power parts also have power input pins,
// but they already force net names on the attached wires
if( partRef->IsPower() )
if( aComponent->GetPartRef()->IsPower() )
return;
int unit = aComponent->GetUnit();
const wxString reference = aComponent->GetField( REFERENCE )->GetText();
std::vector<LIB_PIN*> pins;
partRef->GetPins( pins );
aComponent->GetPartRef()->GetPins( pins );
std::set<int> missingUnits;
// Search all units for pins creating implicit connections

View File

@ -52,7 +52,6 @@ class PROPERTIES;
class SCH_EAGLE_PLUGIN_CACHE;
class LIB_PART;
class PART_LIB;
class LIB_ALIAS;
class LIB_CIRCLE;
class LIB_FIELD;
class LIB_RECTANGLE;
@ -106,8 +105,8 @@ public:
//void EnumerateSymbolLib( wxArrayString& aAliasNameList, const wxString& aLibraryPath,
// const PROPERTIES* aProperties = NULL ) override;
//LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
// const PROPERTIES* aProperties = NULL ) override;
//LIB_PART* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
// const PROPERTIES* aProperties = NULL ) override;
//void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
// const PROPERTIES* aProperties = NULL ) override;

View File

@ -310,7 +310,7 @@ bool SCH_FIELD::IsReplaceable() const
return true;
SCH_COMPONENT* component = dynamic_cast<SCH_COMPONENT*>( GetParent() );
LIB_PART* part = component ? component->GetPartRef().lock().get() : nullptr;
LIB_PART* part = component ? component->GetPartRef().get() : nullptr;
bool isPower = part ? part->IsPower() : false;
return !isPower;

View File

@ -34,7 +34,6 @@ class SCH_SCREEN;
class SCH_PLUGIN;
class KIWAY;
class LIB_PART;
class LIB_ALIAS;
class PART_LIB;
class PROPERTIES;
@ -274,8 +273,8 @@ public:
/**
* Populate a list of #LIB_PART alias names contained within the library \a aLibraryPath.
*
* @param aAliasNameList is an array to populate with the #LIB_ALIAS names associated with
* the library.
* @param aSymbolNameList is an array to populate with the #LIB_PART names associated with
* the library.
*
* @param aLibraryPath is a locator for the "library", usually a directory, file,
* or URL containing one or more #LIB_PART objects.
@ -287,15 +286,18 @@ public:
*
* @throw IO_ERROR if the library cannot be found, the part library cannot be loaded.
*/
virtual void EnumerateSymbolLib( wxArrayString& aAliasNameList,
virtual void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL );
/**
* Populate a list of #LIB_PART aliases contained within the library \a aLibraryPath.
*
* @param aAliasList is an array to populate with the #LIB_ALIAS pointers associated with
* the library.
* @note It is the reponsibility of the caller to delete the returned object from the heap.
* Failure to do this will result in memory leaks.
*
* @param aSymbolList is an array to populate with the #LIB_PART pointers associated with
* the library.
*
* @param aLibraryPath is a locator for the "library", usually a directory, file,
* or URL containing one or more #LIB_PART objects.
@ -307,19 +309,18 @@ public:
*
* @throw IO_ERROR if the library cannot be found, the part library cannot be loaded.
*/
virtual void EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
virtual void EnumerateSymbolLib( std::vector<LIB_PART*>& aSymbolList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = NULL );
/**
* Load a #LIB_ALIAS object having \a aAliasName from the \a aLibraryPath containing
* a library format that this #SCH_PLUGIN knows about. The #LIB_PART should be accessed
* indirectly using the #LIB_ALIAS it is associated with.
* Load a #LIB_PART object having \a aPartName from the \a aLibraryPath containing
* a library format that this #SCH_PLUGIN knows about.
*
* @param aLibraryPath is a locator for the "library", usually a directory, file,
* or URL containing several symbols.
*
* @param aAliasName is the alias name of the #LIB_PART to load.
* @param aPartName is the name of the #LIB_PART to load.
*
* @param aProperties is an associative array that can be used to tell the loader
* implementation to do something special, because it can take
@ -328,13 +329,13 @@ public:
* (plugin may not delete it), and plugins should expect it to be
* optionally NULL.
*
* @return the alias if found caller shares it or NULL if not found.
* @return the part created on the heap if found caller shares it or NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where aAliasName cannot be found.
*/
virtual LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL );
virtual LIB_PART* LoadSymbol( const wxString& aLibraryPath, const wxString& aPartName,
const PROPERTIES* aProperties = NULL );
/**
* Write \a aSymbol to an existing library located at \a aLibraryPath. If a #LIB_PART
@ -360,30 +361,6 @@ public:
virtual void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
const PROPERTIES* aProperties = NULL );
/**
* Delete \a aAliasName from the library at \a aLibraryPath.
*
* If \a aAliasName refers the the root #LIB_PART object, the part is renamed to
* the next or previous #LIB_ALIAS in the #LIB_PART if one exists. If the #LIB_ALIAS
* is the last alias referring to the root #LIB_PART, the #LIB_PART is also removed
* from the library.
*
* @param aLibraryPath is a locator for the "library", usually a directory, file,
* or URL containing several symbols.
*
* @param aAliasName is the name of a #LIB_ALIAS to delete from the specified library.
*
* @param aProperties is an associative array that can be used to tell the library
* delete function anything special, because it can take any number
* of additional named tuning arguments that the plugin is known to
* support. The caller continues to own this object (plugin may not
* delete it), and plugins should expect it to be optionally NULL.
*
* @throw IO_ERROR if there is a problem finding the alias or the library or deleting it.
*/
virtual void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = NULL );
/**
* Delete the entire #LIB_PART associated with \a aAliasName from the library
* \a aLibraryPath.
@ -391,8 +368,8 @@ public:
* @param aLibraryPath is a locator for the "library", usually a directory, file,
* or URL containing several symbols.
*
* @param aAliasName is the name of a #LIB_ALIAS associated with it's root #LIB_PART
* object to delete from the specified library.
* @param aSymbolName is the name of a #LIB_PART associated with it's root #LIB_PART
* object to delete from the specified library.
*
* @param aProperties is an associative array that can be used to tell the library
* delete function anything special, because it can take any number
@ -402,7 +379,7 @@ public:
*
* @throw IO_ERROR if there is a problem finding the alias or the library or deleting it.
*/
virtual void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
virtual void DeleteSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties = NULL );
/**

View File

@ -473,7 +473,7 @@ class SCH_LEGACY_PLUGIN_CACHE
wxString m_fileName; // Absolute path and file name.
wxFileName m_libFileName; // Absolute path and file name is required here.
wxDateTime m_fileModTime;
LIB_ALIAS_MAP m_aliases; // Map of names of LIB_ALIAS pointers.
LIB_PART_MAP m_symbols; // Map of names of #LIB_PART pointers.
bool m_isWritable;
bool m_isModified;
int m_versionMajor;
@ -481,7 +481,8 @@ class SCH_LEGACY_PLUGIN_CACHE
int m_libType; // Is this cache a component or symbol library.
void loadHeader( FILE_LINE_READER& aReader );
static void loadAliases( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static void loadAliases( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader,
LIB_PART_MAP* aMap = nullptr );
static void loadField( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static void loadDrawEntries( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader,
int aMajorVersion, int aMinorVersion );
@ -499,8 +500,8 @@ class SCH_LEGACY_PLUGIN_CACHE
static LIB_BEZIER* loadBezier( std::unique_ptr<LIB_PART>& aPart, LINE_READER& aReader );
static FILL_T parseFillMode( LINE_READER& aReader, const char* aLine,
const char** aOutput );
LIB_ALIAS* removeAlias( LIB_ALIAS* aAlias );
const char** aOutput );
LIB_PART* removeSymbol( LIB_PART* aAlias );
void saveDocFile();
static void saveArc( LIB_ARC* aArc, OUTPUTFORMATTER& aFormatter );
@ -531,9 +532,7 @@ public:
void AddSymbol( const LIB_PART* aPart );
void DeleteAlias( const wxString& aAliasName );
void DeleteSymbol( const wxString& aAliasName );
void DeleteSymbol( const wxString& aName );
// If m_libFileName is a symlink follow it to the real source file
wxFileName GetRealFile() const;
@ -552,8 +551,10 @@ public:
wxString GetFileName() const { return m_libFileName.GetFullPath(); }
static LIB_PART* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion );
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter );
static LIB_PART* LoadPart( LINE_READER& aReader, int aMajorVersion, int aMinorVersion,
LIB_PART_MAP* aMap = nullptr );
static void SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
LIB_PART_MAP* aMap = nullptr );
};
@ -2328,22 +2329,13 @@ SCH_LEGACY_PLUGIN_CACHE::SCH_LEGACY_PLUGIN_CACHE( const wxString& aFullPathAndFi
SCH_LEGACY_PLUGIN_CACHE::~SCH_LEGACY_PLUGIN_CACHE()
{
std::vector< LIB_PART* > rootParts;
// When the cache is destroyed, all of the alias objects on the heap should be deleted.
for( LIB_ALIAS_MAP::iterator it = m_aliases.begin(); it != m_aliases.end(); ++it )
{
wxLogTrace( traceSchLegacyPlugin, wxT( "Removing alias %s from library %s." ),
GetChars( it->second->GetName() ), GetChars( GetLogicalName() ) );
LIB_PART* part = it->second->GetPart();
LIB_ALIAS* alias = it->second;
delete alias;
for( LIB_PART_MAP::iterator it = m_symbols.begin(); it != m_symbols.end(); ++it )
delete it->second;
// When the last alias of a part is destroyed, the part is no longer required and it
// too is destroyed.
if( part && part->GetAliasCount() == 0 )
delete part;
}
m_aliases.clear();
m_symbols.clear();
}
@ -2400,69 +2392,83 @@ bool SCH_LEGACY_PLUGIN_CACHE::IsFileChanged() const
}
LIB_ALIAS* SCH_LEGACY_PLUGIN_CACHE::removeAlias( LIB_ALIAS* aAlias )
LIB_PART* SCH_LEGACY_PLUGIN_CACHE::removeSymbol( LIB_PART* aPart )
{
wxCHECK_MSG( aAlias != NULL, NULL, "NULL pointer cannot be removed from library." );
wxCHECK_MSG( aPart != NULL, NULL, "NULL pointer cannot be removed from library." );
LIB_ALIAS_MAP::iterator it = m_aliases.find( aAlias->GetName() );
LIB_PART* firstChild = NULL;
LIB_PART_MAP::iterator it = m_symbols.find( aPart->GetName() );
if( it == m_aliases.end() )
if( it == m_symbols.end() )
return NULL;
// If the entry pointer doesn't match the name it is mapped to in the library, we
// have done something terribly wrong.
wxCHECK_MSG( *it->second == aAlias, NULL,
"Pointer mismatch while attempting to remove alias entry <" + aAlias->GetName() +
wxCHECK_MSG( *it->second == aPart, NULL,
"Pointer mismatch while attempting to remove alias entry <" + aPart->GetName() +
"> from library cache <" + m_libFileName.GetName() + ">." );
LIB_ALIAS* alias = aAlias;
LIB_PART* part = alias->GetPart();
alias = part->RemoveAlias( alias );
if( !alias )
// If the symbol is a root symbol used by other symbols find the first alias that uses
// the root part and make it the new root.
if( aPart->IsRoot() )
{
delete part;
if( m_aliases.size() > 1 )
for( auto entry : m_symbols )
{
LIB_ALIAS_MAP::iterator next = it;
next++;
if( entry.second->IsAlias()
&& entry.second->GetParent().lock() == aPart->SharedPtr() )
{
firstChild = entry.second;
break;
}
}
if( next == m_aliases.end() )
next = m_aliases.begin();
if( firstChild )
{
for( LIB_ITEM& drawItem : aPart->GetDrawItems() )
{
if( drawItem.Type() == LIB_FIELD_T )
{
LIB_FIELD& field = static_cast<LIB_FIELD&>( drawItem );
alias = next->second;
if( firstChild->FindField( field.GetName() ) )
continue;
}
LIB_ITEM* newItem = (LIB_ITEM*) drawItem.Clone();
drawItem.SetParent( firstChild );
firstChild->AddDrawItem( newItem );
}
// Reparent the remaining aliases.
for( auto entry : m_symbols )
{
if( entry.second->IsAlias()
&& entry.second->GetParent().lock() == aPart->SharedPtr() )
entry.second->SetParent( firstChild );
}
}
}
m_aliases.erase( it );
m_symbols.erase( it );
delete aPart;
m_isModified = true;
++m_modHash;
return alias;
return firstChild;
}
void SCH_LEGACY_PLUGIN_CACHE::AddSymbol( const LIB_PART* aPart )
{
// aPart is cloned in PART_LIB::AddPart(). The cache takes ownership of aPart.
wxArrayString aliasNames = aPart->GetAliasNames();
wxString name = aPart->GetName();
LIB_PART_MAP::iterator it = m_symbols.find( name );
for( size_t i = 0; i < aliasNames.size(); i++ )
if( it != m_symbols.end() )
{
LIB_ALIAS_MAP::iterator it = m_aliases.find( aliasNames[i] );
if( it != m_aliases.end() )
removeAlias( it->second );
LIB_ALIAS* alias = const_cast< LIB_PART* >( aPart )->GetAlias( aliasNames[i] );
wxASSERT_MSG( alias != NULL, "No alias <" + aliasNames[i] + "> found in symbol <" +
aPart->GetName() +">." );
m_aliases[ aliasNames[i] ] = alias;
removeSymbol( it->second );
}
m_symbols[ name ] = const_cast< LIB_PART* >( aPart );
m_isModified = true;
++m_modHash;
}
@ -2538,49 +2544,9 @@ void SCH_LEGACY_PLUGIN_CACHE::Load()
if( strCompare( "DEF", line ) )
{
// Read one DEF/ENDDEF part entry from library:
LIB_PART * part = LoadPart( reader, m_versionMajor, m_versionMinor );
LIB_PART* part = LoadPart( reader, m_versionMajor, m_versionMinor, &m_symbols );
// Add aliases to cache
for( size_t ii = 0; ii < part->GetAliasCount(); ++ii )
{
LIB_ALIAS* alias = part->GetAlias( ii );
const wxString& aliasName = alias->GetName();
// This section seems to do a similar job as checkForDuplicates, so
// I'm not sure checkForDuplicates needs to be preserved.
auto it = m_aliases.find( aliasName );
if( it != m_aliases.end() )
{
// Find a new name for the alias
wxString newName;
int idx = 0;
LIB_ALIAS_MAP::const_iterator jt;
do
{
newName = wxString::Format( "%s_%d", aliasName, idx );
jt = m_aliases.find( newName );
++idx;
}
while( jt != m_aliases.end() );
wxLogWarning( "Symbol name conflict in library:\n%s\n"
"'%s' has been renamed to '%s'",
m_fileName, aliasName, newName );
if( alias->IsRoot() )
part->SetName( newName );
else
alias->SetName( newName );
m_aliases[newName] = alias;
}
else
{
m_aliases[aliasName] = alias;
}
}
m_symbols[ part->GetName() ] = part;
}
}
@ -2602,7 +2568,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDocs()
wxString text;
wxString aliasName;
wxFileName fn = m_libFileName;
LIB_ALIAS* alias = NULL;;
LIB_PART* symbol = NULL;;
fn.SetExt( DOC_EXT );
@ -2639,14 +2605,14 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDocs()
aliasName.Trim();
aliasName = LIB_ID::FixIllegalChars( aliasName, LIB_ID::ID_SCH );
LIB_ALIAS_MAP::iterator it = m_aliases.find( aliasName );
LIB_PART_MAP::iterator it = m_symbols.find( aliasName );
if( it == m_aliases.end() )
wxLogWarning( "Alias '%s' not found in library:\n\n"
if( it == m_symbols.end() )
wxLogWarning( "Symbol '%s' not found in library:\n\n"
"'%s'\n\nat line %d offset %d", aliasName, fn.GetFullPath(),
reader.LineNumber(), (int) (line - reader.Line() ) );
else
alias = it->second;
symbol = it->second;
// Read the curent alias associated doc.
// if the alias does not exist, just skip the description
@ -2668,18 +2634,21 @@ void SCH_LEGACY_PLUGIN_CACHE::loadDocs()
switch( line[0] )
{
case 'D':
if( alias )
alias->SetDescription( text );
if( symbol )
symbol->SetDescription( text );
break;
case 'K':
if( alias )
alias->SetKeyWords( text );
if( symbol )
symbol->SetKeyWords( text );
break;
case 'F':
if( alias )
alias->SetDocFileName( text );
if( symbol )
{
symbol->SetDocFileName( text );
symbol->GetField( DATASHEET )->SetText( text );
}
break;
case 0:
@ -2720,7 +2689,7 @@ void SCH_LEGACY_PLUGIN_CACHE::loadHeader( FILE_LINE_READER& aReader )
LIB_PART* SCH_LEGACY_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorVersion,
int aMinorVersion )
int aMinorVersion, LIB_PART_MAP* aMap )
{
const char* line = aReader.Line();
@ -2812,11 +2781,6 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorVer
// Don't set the library alias, this is determined by the symbol library table.
part->SetLibId( LIB_ID( wxEmptyString, part->GetName() ) );
// There are some code paths in SetText() that do not set the root alias to the
// alias list so add it here if it didn't get added by SetText().
if( !part->HasAlias( part->GetName() ) )
part->AddAlias( part->GetName() );
LIB_FIELD& reference = part->GetReferenceField();
if( prefix == "~" )
@ -2873,19 +2837,19 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorVer
// Read lines until "ENDDEF" is found.
while( line )
{
if( *line == '#' ) // Comment
if( *line == '#' ) // Comment
;
else if( strCompare( "Ti", line, &line ) ) // Modification date is ignored.
else if( strCompare( "Ti", line, &line ) ) // Modification date is ignored.
continue;
else if( strCompare( "ALIAS", line, &line ) ) // Aliases
loadAliases( part, aReader );
else if( *line == 'F' ) // Fields
else if( strCompare( "ALIAS", line, &line ) ) // Aliases
loadAliases( part, aReader, aMap );
else if( *line == 'F' ) // Fields
loadField( part, aReader );
else if( strCompare( "DRAW", line, &line ) ) // Drawing objects.
else if( strCompare( "DRAW", line, &line ) ) // Drawing objects.
loadDrawEntries( part, aReader, aMajorVersion, aMinorVersion );
else if( strCompare( "$FPLIST", line, &line ) ) // Footprint filter list
else if( strCompare( "$FPLIST", line, &line ) ) // Footprint filter list
loadFootprintFilters( part, aReader );
else if( strCompare( "ENDDEF", line, &line ) ) // End of part description
else if( strCompare( "ENDDEF", line, &line ) ) // End of part description
{
return part.release();
}
@ -2897,38 +2861,11 @@ LIB_PART* SCH_LEGACY_PLUGIN_CACHE::LoadPart( LINE_READER& aReader, int aMajorVer
}
#if 0
bool SCH_LEGACY_PLUGIN_CACHE::checkForDuplicates( wxString& aAliasName )
{
wxCHECK_MSG( !aAliasName.IsEmpty(), false, "alias name cannot be empty" );
// The alias name is not a duplicate so don't change it.
if( m_aliases.find( aAliasName ) == m_aliases.end() )
return false;
int dupCounter = 1;
wxString newAlias = aAliasName;
// If the alias is already loaded, the library is broken. It may have been possible in
// the past that this could happen so we assign a new alias name to prevent any conflicts
// rather than throw an exception.
while( m_aliases.find( newAlias ) != m_aliases.end() )
{
newAlias = aAliasName << dupCounter;
dupCounter++;
}
aAliasName = newAlias;
return true;
}
#endif
void SCH_LEGACY_PLUGIN_CACHE::loadAliases( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader,
LIB_PART_MAP* aMap )
{
wxString newAlias;
wxString newAliasName;
const char* line = aReader.Line();
wxCHECK_RET( strCompare( "ALIAS", line, &line ), "Invalid ALIAS section" );
@ -2939,14 +2876,42 @@ void SCH_LEGACY_PLUGIN_CACHE::loadAliases( std::unique_ptr<LIB_PART>& aPart,
// Parse the ALIAS list.
while( tokens.HasMoreTokens() )
{
newAlias = tokens.GetNextToken();
aPart->AddAlias( newAlias );
newAliasName = tokens.GetNextToken();
if( aMap )
{
LIB_PART* newPart = new LIB_PART( newAliasName );
newPart->SetParent( aPart.get() );
// Inherit the mandatory field positions and the reference and footprint field
// values from the parent symbol.
for( LIB_ITEM& item : aPart->GetDrawItems() )
{
if( item.Type() != LIB_FIELD_T )
continue;
LIB_FIELD* field = (LIB_FIELD*) &item;
wxString tmp = field->GetText();
if( field->GetId() < MANDATORY_FIELDS )
{
*newPart->GetField( field->GetId() ) = *field;
if( field->GetId() == REFERENCE || field->GetId() == FOOTPRINT )
newPart->GetField( field->GetId() )->SetText( tmp );
}
}
// This will prevent duplicate aliases.
(*aMap)[ newPart->GetName() ] = newPart;
}
}
}
void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3094,9 +3059,9 @@ void SCH_LEGACY_PLUGIN_CACHE::loadField( std::unique_ptr<LIB_PART>& aPart,
void SCH_LEGACY_PLUGIN_CACHE::loadDrawEntries( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
{
const char* line = aReader.Line();
@ -3170,7 +3135,7 @@ FILL_T SCH_LEGACY_PLUGIN_CACHE::parseFillMode( LINE_READER& aReader, const char*
LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3236,7 +3201,7 @@ LIB_ARC* SCH_LEGACY_PLUGIN_CACHE::loadArc( std::unique_ptr<LIB_PART>& aPart,
LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3263,9 +3228,9 @@ LIB_CIRCLE* SCH_LEGACY_PLUGIN_CACHE::loadCircle( std::unique_ptr<LIB_PART>& aPar
LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
LINE_READER& aReader,
int aMajorVersion,
int aMinorVersion )
{
const char* line = aReader.Line();
@ -3356,7 +3321,7 @@ LIB_TEXT* SCH_LEGACY_PLUGIN_CACHE::loadText( std::unique_ptr<LIB_PART>& aPart,
LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3388,7 +3353,7 @@ LIB_RECTANGLE* SCH_LEGACY_PLUGIN_CACHE::loadRectangle( std::unique_ptr<LIB_PART>
LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3570,7 +3535,7 @@ LIB_PIN* SCH_LEGACY_PLUGIN_CACHE::loadPin( std::unique_ptr<LIB_PART>& aPart,
LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3601,7 +3566,7 @@ LIB_POLYLINE* SCH_LEGACY_PLUGIN_CACHE::loadPolyLine( std::unique_ptr<LIB_PART>&
LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3632,7 +3597,7 @@ LIB_BEZIER* SCH_LEGACY_PLUGIN_CACHE::loadBezier( std::unique_ptr<LIB_PART>& aPar
void SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters( std::unique_ptr<LIB_PART>& aPart,
LINE_READER& aReader )
LINE_READER& aReader )
{
const char* line = aReader.Line();
@ -3640,15 +3605,20 @@ void SCH_LEGACY_PLUGIN_CACHE::loadFootprintFilters( std::unique_ptr<LIB_PART>& a
line = aReader.ReadLine();
wxArrayString footprintFilters;
while( line )
{
if( strCompare( "$ENDFPLIST", line, &line ) )
{
aPart->SetFootprintFilters( footprintFilters );
return;
}
wxString footprint;
parseUnquotedString( footprint, aReader, line, &line );
aPart->GetFootprints().Add( footprint );
footprintFilters.Add( footprint );
line = aReader.ReadLine();
}
@ -3668,12 +3638,12 @@ void SCH_LEGACY_PLUGIN_CACHE::Save( bool aSaveDocFile )
formatter->Print( 0, "%s %d.%d\n", LIBFILE_IDENT, LIB_VERSION_MAJOR, LIB_VERSION_MINOR );
formatter->Print( 0, "#encoding utf-8\n");
for( LIB_ALIAS_MAP::iterator it = m_aliases.begin(); it != m_aliases.end(); it++ )
for( LIB_PART_MAP::iterator it = m_symbols.begin(); it != m_symbols.end(); it++ )
{
if( !it->second->IsRoot() )
continue;
SaveSymbol( it->second->GetPart(), *formatter.get() );
SaveSymbol( it->second, *formatter.get(), &m_symbols );
}
formatter->Print( 0, "#\n#End Library\n" );
@ -3687,10 +3657,25 @@ void SCH_LEGACY_PLUGIN_CACHE::Save( bool aSaveDocFile )
}
void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol,
OUTPUTFORMATTER& aFormatter )
void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol, OUTPUTFORMATTER& aFormatter,
LIB_PART_MAP* aMap )
{
wxCHECK_RET( aSymbol, "Invalid LIB_PART pointer." );
wxCHECK_RET( aSymbol && aSymbol->IsRoot(), "Invalid LIB_PART pointer." );
// LIB_ALIAS objects are deprecated but we still need to gather up the derived symbols
// and save their names for the old file format.
wxArrayString aliasNames;
if( aMap )
{
for( auto entry : *aMap )
{
LIB_PART* part = entry.second;
if( part->IsAlias() && part->GetParent().lock() == aSymbol->SharedPtr() )
aliasNames.Add( part->GetName() );
}
}
LIB_FIELD& value = aSymbol->GetValueField();
@ -3762,18 +3747,14 @@ void SCH_LEGACY_PLUGIN_CACHE::SaveSymbol( LIB_PART* aSymbol,
}
}
// Save the alias list: a line starting by "ALIAS". The first alias is the root
// and has the same name as the component. In the old library file format this
// alias does not get added to the alias list.
if( aSymbol->GetAliasCount() > 1 )
// Save the alias list: a line starting by "ALIAS".
if( !aliasNames.IsEmpty() )
{
wxArrayString aliases = aSymbol->GetAliasNames();
aFormatter.Print( 0, "ALIAS" );
for( unsigned i = 1; i < aliases.size(); i++ )
for( unsigned i = 0; i < aliasNames.GetCount(); i++ )
{
aFormatter.Print( 0, " %s", TO_UTF8( aliases[i] ) );
aFormatter.Print( 0, " %s", TO_UTF8( aliasNames[i] ) );
}
aFormatter.Print( 0, "\n" );
@ -4148,7 +4129,7 @@ void SCH_LEGACY_PLUGIN_CACHE::saveDocFile()
formatter.Print( 0, "%s\n", DOCFILE_IDENT );
for( LIB_ALIAS_MAP::iterator it = m_aliases.begin(); it != m_aliases.end(); it++ )
for( LIB_PART_MAP::iterator it = m_symbols.begin(); it != m_symbols.end(); ++it )
{
wxString description = it->second->GetDescription();
wxString keyWords = it->second->GetKeyWords();
@ -4175,60 +4156,52 @@ void SCH_LEGACY_PLUGIN_CACHE::saveDocFile()
}
void SCH_LEGACY_PLUGIN_CACHE::DeleteAlias( const wxString& aAliasName )
void SCH_LEGACY_PLUGIN_CACHE::DeleteSymbol( const wxString& aSymbolName )
{
LIB_ALIAS_MAP::iterator it = m_aliases.find( aAliasName );
LIB_PART_MAP::iterator it = m_symbols.find( aSymbolName );
if( it == m_aliases.end() )
THROW_IO_ERROR( wxString::Format( _( "library %s does not contain an alias %s" ),
m_libFileName.GetFullName(), aAliasName ) );
if( it == m_symbols.end() )
THROW_IO_ERROR( wxString::Format( _( "library %s does not contain a symbol named %s" ),
m_libFileName.GetFullName(), aSymbolName ) );
LIB_ALIAS* alias = it->second;
LIB_PART* part = alias->GetPart();
LIB_PART* part = it->second;
alias = part->RemoveAlias( alias );
if( !alias )
if( part->IsRoot() )
{
delete part;
LIB_PART* rootPart = part;
if( m_aliases.size() > 1 )
// Remove the root symbol and all it's children.
m_symbols.erase( it );
LIB_PART_MAP::iterator it1 = m_symbols.begin();
while( it1 != m_symbols.end() )
{
LIB_ALIAS_MAP::iterator next = it;
next++;
if( next == m_aliases.end() )
next = m_aliases.begin();
alias = next->second;
if( it1->second->IsAlias() && it1->second->GetParent().lock() == rootPart->SharedPtr() )
{
delete it->second;
it = m_symbols.erase( it );
}
else
{
it++;
}
}
delete rootPart;
}
else
{
// Just remove the alias.
m_symbols.erase( it );
delete part;
}
m_aliases.erase( it );
++m_modHash;
m_isModified = true;
}
void SCH_LEGACY_PLUGIN_CACHE::DeleteSymbol( const wxString& aAliasName )
{
LIB_ALIAS_MAP::iterator it = m_aliases.find( aAliasName );
if( it == m_aliases.end() )
THROW_IO_ERROR( wxString::Format( _( "library %s does not contain an alias %s" ),
m_libFileName.GetFullName(), aAliasName ) );
LIB_ALIAS* alias = it->second;
LIB_PART* part = alias->GetPart();
wxArrayString aliasNames = part->GetAliasNames();
// Deleting all of the aliases deletes the symbol from the library.
for( size_t i = 0; i < aliasNames.Count(); i++ )
DeleteAlias( aliasNames[i] );
}
void SCH_LEGACY_PLUGIN::cacheLib( const wxString& aLibraryFileName )
{
if( !m_cache || !m_cache->IsFile( aLibraryFileName ) || m_cache->IsFileChanged() )
@ -4275,7 +4248,7 @@ int SCH_LEGACY_PLUGIN::GetModifyHash() const
}
void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( wxArrayString& aAliasNameList,
void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties )
{
@ -4287,17 +4260,17 @@ void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( wxArrayString& aAliasNameList,
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
cacheLib( aLibraryPath );
const LIB_ALIAS_MAP& aliases = m_cache->m_aliases;
const LIB_PART_MAP& symbols = m_cache->m_symbols;
for( LIB_ALIAS_MAP::const_iterator it = aliases.begin(); it != aliases.end(); ++it )
for( LIB_PART_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
{
if( !powerSymbolsOnly || it->second->GetPart()->IsPower() )
aAliasNameList.Add( it->first );
if( !powerSymbolsOnly || it->second->IsPower() )
aSymbolNameList.Add( it->first );
}
}
void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( std::vector<LIB_PART*>& aSymbolList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties )
{
@ -4309,18 +4282,18 @@ void SCH_LEGACY_PLUGIN::EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
aProperties->find( SYMBOL_LIB_TABLE::PropPowerSymsOnly ) != aProperties->end() );
cacheLib( aLibraryPath );
const LIB_ALIAS_MAP& aliases = m_cache->m_aliases;
const LIB_PART_MAP& symbols = m_cache->m_symbols;
for( LIB_ALIAS_MAP::const_iterator it = aliases.begin(); it != aliases.end(); ++it )
for( LIB_PART_MAP::const_iterator it = symbols.begin(); it != symbols.end(); ++it )
{
if( !powerSymbolsOnly || it->second->GetPart()->IsPower() )
aAliasList.push_back( it->second );
if( !powerSymbolsOnly || it->second->IsPower() )
aSymbolList.push_back( it->second );
}
}
LIB_ALIAS* SCH_LEGACY_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties )
LIB_PART* SCH_LEGACY_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties )
{
LOCALE_IO toggle; // toggles on, then off, the C locale.
@ -4328,10 +4301,10 @@ LIB_ALIAS* SCH_LEGACY_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wx
cacheLib( aLibraryPath );
LIB_ALIAS_MAP::const_iterator it = m_cache->m_aliases.find( aAliasName );
LIB_PART_MAP::const_iterator it = m_cache->m_symbols.find( aSymbolName );
if( it == m_cache->m_aliases.end() )
return NULL;
if( it == m_cache->m_symbols.end() )
return nullptr;
return it->second;
}
@ -4351,28 +4324,14 @@ void SCH_LEGACY_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART
}
void SCH_LEGACY_PLUGIN::DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties )
{
m_props = aProperties;
cacheLib( aLibraryPath );
m_cache->DeleteAlias( aAliasName );
if( !isBuffering( aProperties ) )
m_cache->Save( writeDocFile( aProperties ) );
}
void SCH_LEGACY_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
void SCH_LEGACY_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties )
{
m_props = aProperties;
cacheLib( aLibraryPath );
m_cache->DeleteSymbol( aAliasName );
m_cache->DeleteSymbol( aSymbolName );
if( !isBuffering( aProperties ) )
m_cache->Save( writeDocFile( aProperties ) );

View File

@ -46,7 +46,6 @@ class SELECTION;
class SCH_LEGACY_PLUGIN_CACHE;
class LIB_PART;
class PART_LIB;
class LIB_ALIAS;
class BUS_ALIAS;
@ -79,18 +78,14 @@ public:
}
/**
* const char* PropBuffering
*
* is a property used internally by the plugin to enable cache buffering which prevents
* The property used internally by the plugin to enable cache buffering which prevents
* the library file from being written every time the cache is changed. This is useful
* when writing the schematic cache library file or saving a library to a new file name.
*/
static const char* PropBuffering;
/**
* const char* PropBuffering
*
* is a property used internally by the plugin to disable writing the library
* The property used internally by the plugin to disable writing the library
* documentation (.dcm) file when saving the library cache.
*/
static const char* PropNoDocFile;
@ -98,7 +93,7 @@ public:
int GetModifyHash() const override;
SCH_SHEET* Load( const wxString& aFileName, KIWAY* aKiway,
SCH_SHEET* aAppendToMe = nullptr,
SCH_SHEET* aAppendToMe = nullptr,
const PROPERTIES* aProperties = nullptr ) override;
void LoadContent( LINE_READER& aReader, SCH_SCREEN* aScreen,
@ -111,19 +106,17 @@ public:
void Format( SELECTION* aSelection, OUTPUTFORMATTER* aFormatter );
void EnumerateSymbolLib( wxArrayString& aAliasNameList,
void EnumerateSymbolLib( wxArrayString& aSymbolNameList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = nullptr ) override;
void EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
void EnumerateSymbolLib( std::vector<LIB_PART*>& aSymbolList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties = nullptr ) override;
LIB_ALIAS* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
LIB_PART* LoadSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = nullptr ) override;
void SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymbol,
const PROPERTIES* aProperties = nullptr ) override;
void DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties = nullptr ) override;
void DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
void DeleteSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties = nullptr ) override;
void CreateSymbolLib( const wxString& aLibraryPath,
const PROPERTIES* aProperties = nullptr ) override;

View File

@ -2,9 +2,10 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@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 2
@ -65,7 +66,8 @@ namespace KIGFX
{
SCH_RENDER_SETTINGS::SCH_RENDER_SETTINGS() :
m_ShowUnit( 0 ), m_ShowConvert( 0 )
m_ShowUnit( 0 ),
m_ShowConvert( 0 )
{
ImportLegacyColors( nullptr );
@ -73,6 +75,7 @@ SCH_RENDER_SETTINGS::SCH_RENDER_SETTINGS() :
m_ShowHiddenPins = true;
m_ShowPinsElectricalType = true;
m_ShowUmbilicals = true;
m_ShowDisabled = false;
}
@ -117,7 +120,7 @@ static LIB_PART* dummy()
LIB_RECTANGLE* square = new LIB_RECTANGLE( part );
square->MoveTo( wxPoint( -200, 200 ));
square->MoveTo( wxPoint( -200, 200 ) );
square->SetEndPosition( wxPoint( 200, -200 ) );
LIB_TEXT* text = new LIB_TEXT( part );
@ -134,7 +137,7 @@ static LIB_PART* dummy()
SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
KIGFX::PAINTER (aGal)
KIGFX::PAINTER( aGal )
{ }
@ -144,7 +147,7 @@ SCH_PAINTER::SCH_PAINTER( GAL* aGal ) :
bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
{
auto item2 = static_cast<const EDA_ITEM*>( aItem );
auto item2 = static_cast<const EDA_ITEM*>( aItem );
auto item = const_cast<EDA_ITEM*>( item2 );
m_schSettings.ImportLegacyColors( nullptr );
@ -169,38 +172,37 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
#endif
switch( item->Type() )
{
HANDLE_ITEM(LIB_ALIAS_T, LIB_ALIAS);
HANDLE_ITEM(LIB_PART_T, LIB_PART);
HANDLE_ITEM(LIB_RECTANGLE_T, LIB_RECTANGLE);
HANDLE_ITEM(LIB_POLYLINE_T, LIB_POLYLINE);
HANDLE_ITEM(LIB_CIRCLE_T, LIB_CIRCLE);
HANDLE_ITEM(LIB_PIN_T, LIB_PIN);
HANDLE_ITEM(LIB_ARC_T, LIB_ARC);
HANDLE_ITEM(LIB_FIELD_T, LIB_FIELD);
HANDLE_ITEM(LIB_TEXT_T, LIB_TEXT);
HANDLE_ITEM(LIB_BEZIER_T, LIB_BEZIER);
HANDLE_ITEM(SCH_COMPONENT_T, SCH_COMPONENT);
HANDLE_ITEM(SCH_JUNCTION_T, SCH_JUNCTION);
HANDLE_ITEM(SCH_LINE_T, SCH_LINE);
HANDLE_ITEM(SCH_TEXT_T, SCH_TEXT);
HANDLE_ITEM(SCH_LABEL_T, SCH_TEXT);
HANDLE_ITEM(SCH_FIELD_T, SCH_FIELD);
HANDLE_ITEM(SCH_HIER_LABEL_T, SCH_HIERLABEL);
HANDLE_ITEM(SCH_GLOBAL_LABEL_T, SCH_GLOBALLABEL);
HANDLE_ITEM(SCH_SHEET_T, SCH_SHEET);
HANDLE_ITEM(SCH_SHEET_PIN_T, SCH_HIERLABEL);
HANDLE_ITEM(SCH_NO_CONNECT_T, SCH_NO_CONNECT);
HANDLE_ITEM(SCH_BUS_WIRE_ENTRY_T, SCH_BUS_ENTRY_BASE);
HANDLE_ITEM(SCH_BUS_BUS_ENTRY_T, SCH_BUS_ENTRY_BASE);
HANDLE_ITEM(SCH_BITMAP_T, SCH_BITMAP);
HANDLE_ITEM(SCH_MARKER_T, SCH_MARKER);
switch( item->Type() )
{
HANDLE_ITEM( LIB_PART_T, LIB_PART );
HANDLE_ITEM( LIB_RECTANGLE_T, LIB_RECTANGLE );
HANDLE_ITEM( LIB_POLYLINE_T, LIB_POLYLINE );
HANDLE_ITEM( LIB_CIRCLE_T, LIB_CIRCLE );
HANDLE_ITEM( LIB_PIN_T, LIB_PIN );
HANDLE_ITEM( LIB_ARC_T, LIB_ARC );
HANDLE_ITEM( LIB_FIELD_T, LIB_FIELD );
HANDLE_ITEM( LIB_TEXT_T, LIB_TEXT );
HANDLE_ITEM( LIB_BEZIER_T, LIB_BEZIER );
HANDLE_ITEM( SCH_COMPONENT_T, SCH_COMPONENT );
HANDLE_ITEM( SCH_JUNCTION_T, SCH_JUNCTION );
HANDLE_ITEM( SCH_LINE_T, SCH_LINE );
HANDLE_ITEM( SCH_TEXT_T, SCH_TEXT );
HANDLE_ITEM( SCH_LABEL_T, SCH_TEXT );
HANDLE_ITEM( SCH_FIELD_T, SCH_FIELD );
HANDLE_ITEM( SCH_HIER_LABEL_T, SCH_HIERLABEL );
HANDLE_ITEM( SCH_GLOBAL_LABEL_T, SCH_GLOBALLABEL );
HANDLE_ITEM( SCH_SHEET_T, SCH_SHEET );
HANDLE_ITEM( SCH_SHEET_PIN_T, SCH_HIERLABEL );
HANDLE_ITEM( SCH_NO_CONNECT_T, SCH_NO_CONNECT );
HANDLE_ITEM( SCH_BUS_WIRE_ENTRY_T, SCH_BUS_ENTRY_BASE );
HANDLE_ITEM( SCH_BUS_BUS_ENTRY_T, SCH_BUS_ENTRY_BASE );
HANDLE_ITEM( SCH_BITMAP_T, SCH_BITMAP );
HANDLE_ITEM( SCH_MARKER_T, SCH_MARKER );
default: return false;
}
}
return false;
return false;
}
@ -260,6 +262,9 @@ COLOR4D SCH_PAINTER::getRenderColor( const EDA_ITEM* aItem, int aLayer, bool aDr
color = highlightColor;
}
if( m_schSettings.m_ShowDisabled )
color = color.Darken( 0.5f );
return color;
}
@ -314,7 +319,16 @@ void SCH_PAINTER::draw( LIB_PART *aPart, int aLayer, bool aDrawFields, int aUnit
if( !aConvert )
aConvert = m_schSettings.m_ShowConvert;
for( auto& item : aPart->GetDrawItems() )
std::unique_ptr< LIB_PART > tmpPart;
LIB_PART* drawnPart = aPart;
if( aPart->IsAlias() )
{
tmpPart = aPart->Flatten();
drawnPart = tmpPart.get();
}
for( auto& item : drawnPart->GetDrawItems() )
{
if( !aDrawFields && item.Type() == LIB_FIELD_T )
continue;
@ -330,26 +344,6 @@ void SCH_PAINTER::draw( LIB_PART *aPart, int aLayer, bool aDrawFields, int aUnit
}
void SCH_PAINTER::draw( LIB_ALIAS *aAlias, int aLayer )
{
LIB_PART* comp = aAlias->GetPart();
draw( comp, aLayer, false );
LIB_FIELDS fields;
comp->GetFields( fields );
if( !aAlias->IsRoot() )
{
fields[ VALUE ].SetText( aAlias->GetName() );
fields[ DATASHEET ].SetText( aAlias->GetDocFileName() );
}
for( LIB_FIELD& field : fields )
draw( &field, aLayer );
}
static VECTOR2D mapCoords( const wxPoint& aCoord )
{
return VECTOR2D( aCoord.x, -aCoord.y );
@ -678,11 +672,11 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
VECTOR2I p0;
VECTOR2I dir;
int len = aPin->GetLength();
int len = aPin->GetLength();
int orient = aPin->GetOrientation();
switch( orient )
{
{
case PIN_UP:
p0 = VECTOR2I( pos.x, pos.y - len );
dir = VECTOR2I(0, 1);
@ -698,12 +692,12 @@ void SCH_PAINTER::draw( LIB_PIN *aPin, int aLayer )
dir = VECTOR2I(1, 0);
break;
default:
default:
case PIN_RIGHT:
p0 = VECTOR2I( pos.x + len, pos.y );
dir = VECTOR2I(-1, 0);
break;
}
}
VECTOR2D pc;
@ -1319,10 +1313,8 @@ static void orientPart( LIB_PART* part, int orientation )
void SCH_PAINTER::draw( SCH_COMPONENT *aComp, int aLayer )
{
PART_SPTR originalPartSptr = aComp->GetPartRef().lock();
// Use dummy part if the actual couldn't be found (or couldn't be locked).
LIB_PART* originalPart = originalPartSptr ? originalPartSptr.get() : dummy();
LIB_PART* originalPart = aComp->GetPartRef() ? aComp->GetPartRef().get() : dummy();
// Copy the source so we can re-orient and translate it.
LIB_PART tempPart( *originalPart );

View File

@ -35,7 +35,6 @@ class LIB_PIN;
class LIB_CIRCLE;
class LIB_ITEM;
class LIB_PART;
class LIB_ALIAS;
class LIB_POLYLINE;
class LIB_ARC;
class LIB_FIELD;
@ -87,7 +86,10 @@ public:
return luma < 0.5;
}
const COLOR4D& GetBackgroundColor() override { return m_layerColors[ LAYER_SCHEMATIC_BACKGROUND ]; }
const COLOR4D& GetBackgroundColor() override
{
return m_layerColors[ LAYER_SCHEMATIC_BACKGROUND ];
}
void SetBackgroundColor( const COLOR4D& aColor ) override
{
@ -104,7 +106,7 @@ public:
bool m_ShowHiddenText;
bool m_ShowHiddenPins;
bool m_ShowPinsElectricalType;
bool m_ShowDisabled;
bool m_ShowUmbilicals;
};
@ -138,7 +140,6 @@ private:
void draw( LIB_PIN* aPin, int aLayer );
void draw( LIB_CIRCLE* aCircle, int aLayer );
void draw( LIB_PART* aPart, int, bool aDrawFields = true, int aUnit = 0, int aConvert = 0 );
void draw( LIB_ALIAS* aAlias, int aLayer );
void draw( LIB_ARC* aArc, int aLayer );
void draw( LIB_POLYLINE* aLine, int aLayer );
void draw( LIB_FIELD* aField, int aLayer );

View File

@ -72,7 +72,7 @@ void SCH_PLUGIN::EnumerateSymbolLib( wxArrayString& aAliasNameList,
}
void SCH_PLUGIN::EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
void SCH_PLUGIN::EnumerateSymbolLib( std::vector<LIB_PART*>& aSymbolList,
const wxString& aLibraryPath,
const PROPERTIES* aProperties )
{
@ -81,8 +81,8 @@ void SCH_PLUGIN::EnumerateSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
}
LIB_ALIAS* SCH_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties )
LIB_PART* SCH_PLUGIN::LoadSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
not_implemented( this, __FUNCTION__ );
@ -98,15 +98,7 @@ void SCH_PLUGIN::SaveSymbol( const wxString& aLibraryPath, const LIB_PART* aSymb
}
void SCH_PLUGIN::DeleteAlias( const wxString& aLibraryPath, const wxString& aAliasName,
const PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.
not_implemented( this, __FUNCTION__ );
}
void SCH_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aAliasName,
void SCH_PLUGIN::DeleteSymbol( const wxString& aLibraryPath, const wxString& aSymbolName,
const PROPERTIES* aProperties )
{
// not pure virtual so that plugins only have to implement subset of the SCH_PLUGIN interface.

View File

@ -633,12 +633,11 @@ LIB_PIN* SCH_SCREEN::GetPin( const wxPoint& aPosition, SCH_COMPONENT** aComponen
{
pin = NULL;
auto part = component->GetPartRef().lock();
if( !part )
if( !component->GetPartRef() )
continue;
for( pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
for( pin = component->GetPartRef()->GetNextPin(); pin;
pin = component->GetPartRef()->GetNextPin( pin ) )
{
// Skip items not used for this part.
if( component->GetUnit() && pin->GetUnit() &&

View File

@ -226,7 +226,7 @@ void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aInclu
if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) )
continue;
LIB_PART* part = component->GetPartRef().lock().get();
LIB_PART* part = component->GetPartRef().get();
if( part || aForceIncludeOrphanComponents )
{
@ -256,7 +256,7 @@ void SCH_SHEET_PATH::GetMultiUnitComponents( SCH_MULTI_UNIT_REFERENCE_MAP& aRefL
if( !aIncludePowerSymbols && component->GetRef( this )[0] == wxT( '#' ) )
continue;
LIB_PART* part = component->GetPartRef().lock().get();
LIB_PART* part = component->GetPartRef().get();
if( part && part->GetUnitCount() > 1 )
{
@ -551,7 +551,7 @@ void SCH_SHEET_LIST::AnnotatePowerSymbols()
continue;
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
LIB_PART* part = component->GetPartRef().lock().get();
LIB_PART* part = component->GetPartRef().get();
if( !part || !part->IsPower() )
continue;

View File

@ -2,6 +2,8 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2013-2018 CERN
* Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -72,7 +74,7 @@ void SCH_VIEW::SetScale( double aScale, VECTOR2D aAnchor )
{
VIEW::SetScale( aScale, aAnchor );
//Redraw selection halos since their width is dependant on zoom
//Redraw selection halos since their width is dependent on zoom
if( m_frame )
m_frame->RefreshSelection();
}
@ -130,8 +132,43 @@ void SCH_VIEW::DisplayComponent( LIB_PART* aPart )
if( !aPart )
return;
for( auto& item : aPart->GetDrawItems() )
std::shared_ptr< LIB_PART > parent;
LIB_PART* drawnPart = aPart;
if( aPart->IsAlias() )
{
// Draw the alias mandatory fields.
for( auto& item : aPart->GetDrawItems() )
{
if( item.Type() != LIB_FIELD_T )
continue;
LIB_FIELD* field = (LIB_FIELD*) &item;
if( field->GetId() < MANDATORY_FIELDS )
Add( &item );
}
parent = aPart->GetParent().lock();
wxCHECK( parent, /* void */ );
drawnPart = parent.get();
}
for( auto& item : drawnPart->GetDrawItems() )
{
// Do not overwrite the alias mandatory fields with the parent mandatory fields.
if( item.Type() == LIB_FIELD_T )
{
LIB_FIELD* field = (LIB_FIELD*) &item;
if( aPart->IsAlias() && field->GetId() < MANDATORY_FIELDS )
continue;
}
Add( &item );
}
m_selectionArea.reset( new KIGFX::PREVIEW::SELECTION_AREA() );
m_preview.reset( new KIGFX::VIEW_GROUP() );
@ -223,4 +260,3 @@ void SCH_VIEW::HighlightItem( EDA_ITEM *aItem, LIB_PIN* aPin )
}
}; // namespace KIGFX

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2018-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License

View File

@ -286,9 +286,10 @@ SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname )
if( !row )
{
wxString msg = wxString::Format(
_( "sym-lib-table files contain no library with nickname \"%s\"" ),
GetChars( aNickname ) );
wxString msg;
msg.Printf( _( "sym-lib-table files contain no library with nickname \"%s\"" ),
aNickname );
THROW_IO_ERROR( msg );
}
@ -303,7 +304,7 @@ SYMBOL_LIB_TABLE_ROW* SYMBOL_LIB_TABLE::FindRow( const wxString& aNickname )
}
void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_PART*>& aSymbolList,
const wxString& aNickname, bool aPowerSymbolsOnly )
{
SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
@ -314,7 +315,7 @@ void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
if( aPowerSymbolsOnly )
row->SetOptions( row->GetOptions() + " " + PropPowerSymsOnly );
row->plugin->EnumerateSymbolLib( aAliasList, row->GetFullURI( true ), row->GetProperties() );
row->plugin->EnumerateSymbolLib( aSymbolList, row->GetFullURI( true ), row->GetProperties() );
if( aPowerSymbolsOnly )
row->SetOptions( options );
@ -323,39 +324,40 @@ void SYMBOL_LIB_TABLE::LoadSymbolLib( std::vector<LIB_ALIAS*>& aAliasList,
// Therefore footprints cannot know their own library nickname when residing in
// a symbol library.
// Only at this API layer can we tell the symbol about its actual library nickname.
for( LIB_ALIAS* alias : aAliasList )
for( LIB_PART* part : aSymbolList )
{
// remove "const"-ness, I really do want to set nickname without
// having to copy the LIB_ID and its two strings, twice each.
LIB_ID& id = (LIB_ID&) alias->GetPart()->GetLibId();
LIB_ID id = part->GetLibId();
id.SetLibNickname( row->GetNickName() );
part->SetLibId( id );
}
}
LIB_ALIAS* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxString& aAliasName )
LIB_PART* SYMBOL_LIB_TABLE::LoadSymbol( const wxString& aNickname, const wxString& aSymbolName )
{
const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
wxCHECK( row && row->plugin, nullptr );
LIB_ALIAS* ret = row->plugin->LoadSymbol( row->GetFullURI( true ), aAliasName,
LIB_PART* part = row->plugin->LoadSymbol( row->GetFullURI( true ), aSymbolName,
row->GetProperties() );
if( part == nullptr )
return part;
// The library cannot know its own name, because it might have been renamed or moved.
// Therefore footprints cannot know their own library nickname when residing in
// a symbol library.
// Only at this API layer can we tell the symbol about its actual library nickname.
if( ret )
if( part )
{
// remove "const"-ness, I really do want to set nickname without
// having to copy the LIB_ID and its two strings, twice each.
LIB_ID& id = (LIB_ID&) ret->GetPart()->GetLibId();
LIB_ID id = part->GetLibId();
id.SetLibNickname( row->GetNickName() );
part->SetLibId( id );
}
return ret;
return part;
}
@ -372,9 +374,9 @@ SYMBOL_LIB_TABLE::SAVE_T SYMBOL_LIB_TABLE::SaveSymbol( const wxString& aNickname
wxString name = aSymbol->GetLibId().GetLibItemName();
std::unique_ptr< LIB_ALIAS > symbol( row->plugin->LoadSymbol( row->GetFullURI( true ),
name,
row->GetProperties() ) );
std::unique_ptr< LIB_PART > symbol( row->plugin->LoadSymbol( row->GetFullURI( true ),
name,
row->GetProperties() ) );
if( symbol.get() )
return SAVE_SKIPPED;
@ -395,15 +397,6 @@ void SYMBOL_LIB_TABLE::DeleteSymbol( const wxString& aNickname, const wxString&
}
void SYMBOL_LIB_TABLE::DeleteAlias( const wxString& aNickname, const wxString& aAliasName )
{
const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
wxCHECK( row && row->plugin, /* void */ );
return row->plugin->DeleteAlias( row->GetFullURI( true ), aAliasName,
row->GetProperties() );
}
bool SYMBOL_LIB_TABLE::IsSymbolLibWritable( const wxString& aNickname )
{
const SYMBOL_LIB_TABLE_ROW* row = FindRow( aNickname );
@ -428,7 +421,7 @@ void SYMBOL_LIB_TABLE::CreateSymbolLib( const wxString& aNickname )
}
LIB_ALIAS* SYMBOL_LIB_TABLE::LoadSymbolWithOptionalNickname( const LIB_ID& aLibId )
LIB_PART* SYMBOL_LIB_TABLE::LoadSymbolWithOptionalNickname( const LIB_ID& aLibId )
{
wxString nickname = aLibId.GetLibNickname();
wxString name = aLibId.GetLibItemName();
@ -448,13 +441,13 @@ LIB_ALIAS* SYMBOL_LIB_TABLE::LoadSymbolWithOptionalNickname( const LIB_ID& aLibI
{
// FootprintLoad() returns NULL on not found, does not throw exception
// unless there's an IO_ERROR.
LIB_ALIAS* ret = LoadSymbol( nicks[i], name );
LIB_PART* ret = LoadSymbol( nicks[i], name );
if( ret )
return ret;
}
return NULL;
return nullptr;
}
}

View File

@ -28,8 +28,9 @@
#include <lib_table_base.h>
#include <sch_io_mgr.h>
#include <lib_id.h>
#include <class_libentry.h>
class LIB_PART;
//class LIB_PART;
class SYMBOL_LIB_TABLE_GRID;
class DIALOG_SYMBOL_LIB_TABLE;
@ -157,25 +158,24 @@ public:
void EnumerateSymbolLib( const wxString& aNickname, wxArrayString& aAliasNames,
bool aPowerSymbolsOnly = false );
void LoadSymbolLib( std::vector<LIB_ALIAS*>& aAliasList, const wxString& aNickname,
void LoadSymbolLib( std::vector<LIB_PART*>& aAliasList, const wxString& aNickname,
bool aPowerSymbolsOnly = false );
/**
* Load a #LIB_ALIAS having @a aAliasName from the library given by @a aNickname.
*
* The actual symbol can be retreaved from the LIB_ALIAS::GetPart() method.
* Load a #LIB_PART having @a aName from the library given by @a aNickname.
*
* @param aNickname is a locator for the "library", it is a "name" in #LIB_TABLE_ROW
* @param aAliasName is the name of the #LIB_ALIAS to load.
* @param aName is the name of the #LIB_PART to load.
* @param aFlatten set to true to flatten derived parts.
*
* @return the symbol alias if found or NULL if not found.
*
* @throw IO_ERROR if the library cannot be found or read. No exception
* is thrown in the case where aAliasName cannot be found.
* is thrown in the case where \a aNickname cannot be found.
*/
LIB_ALIAS* LoadSymbol( const wxString& aNickname, const wxString& aAliasName );
LIB_PART* LoadSymbol( const wxString& aNickname, const wxString& aName );
LIB_ALIAS* LoadSymbol( const LIB_ID& aLibId )
LIB_PART* LoadSymbol( const LIB_ID& aLibId )
{
return LoadSymbol( aLibId.GetLibNickname(), aLibId.GetLibItemName() );
}
@ -221,22 +221,6 @@ public:
*/
void DeleteSymbol( const wxString& aNickname, const wxString& aSymbolName );
/**
* Delete @a aAliasName from the library at @a aLibraryPath.
*
* If @a aAliasName refers the the root #LIB_PART object, the part is renamed to
* the next or previous #LIB_ALIAS in the #LIB_PART if one exists. If the #LIB_ALIAS
* is the last alias referring to the root #LIB_PART, the #LIB_PART is also removed
* from the library.
*
* @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW
*
* @param aAliasName is the name of a #LIB_ALIAS to delete from the specified library.
*
* @throw IO_ERROR if there is a problem finding the alias or the library or deleting it.
*/
void DeleteAlias( const wxString& aNickname, const wxString& aAliasName );
/**
* Return true if the library given by @a aNickname is writable.
*
@ -266,7 +250,7 @@ public:
* is thrown in the case where aId cannot be found.
* @throw PARSE_ERROR if @a aId is not parsed OK.
*/
LIB_ALIAS* LoadSymbolWithOptionalNickname( const LIB_ID& aId );
LIB_PART* LoadSymbolWithOptionalNickname( const LIB_ID& aId );
/**
* Load the global symbol library table into \a aTable.

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Chris Pavlina <pavlina.chris@gmail.com>
* Copyright (C) 2014 Henner Zeller <h.zeller@acm.org>
* Copyright (C) 2014-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@ -89,12 +89,12 @@ void SYMBOL_TREE_MODEL_ADAPTER::AddLibraries( const std::vector<wxString>& aNick
void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
{
bool onlyPowerSymbols = ( GetFilter() == CMP_FILTER_POWER );
std::vector<LIB_ALIAS*> alias_list;
std::vector<LIB_PART*> symbols;
std::vector<LIB_TREE_ITEM*> comp_list;
try
{
m_libs->LoadSymbolLib( alias_list, aLibNickname, onlyPowerSymbols );
m_libs->LoadSymbolLib( symbols, aLibNickname, onlyPowerSymbols );
}
catch( const IO_ERROR& ioe )
{
@ -104,9 +104,9 @@ void SYMBOL_TREE_MODEL_ADAPTER::AddLibrary( wxString const& aLibNickname )
return;
}
if( alias_list.size() > 0 )
if( symbols.size() > 0 )
{
comp_list.assign( alias_list.begin(), alias_list.end() );
comp_list.assign( symbols.begin(), symbols.end() );
DoAddLibrary( aLibNickname, m_libs->GetDescription( aLibNickname ), comp_list, false );
}
}

View File

@ -153,13 +153,13 @@ void SYMBOL_TREE_SYNCHRONIZING_ADAPTER::updateLibrary( LIB_TREE_NODE_LIB& aLibNo
else if( hashIt->second != m_libMgr->GetLibraryHash( aLibNode.Name ) )
{
// update an existing library
std::list<LIB_ALIAS*> aliases = m_libMgr->GetAliases( aLibNode.Name );
std::list<LIB_PART*> aliases = m_libMgr->GetAliases( aLibNode.Name );
// remove the common part from the aliases list
for( auto nodeIt = aLibNode.Children.begin(); nodeIt != aLibNode.Children.end(); /**/ )
{
auto aliasIt = std::find_if( aliases.begin(), aliases.end(),
[&] ( const LIB_ALIAS* a ) {
[&] ( const LIB_PART* a ) {
return a->GetName() == (*nodeIt)->Name;
} );

View File

@ -146,10 +146,10 @@ void LIB_VIEW_FRAME::ReCreateMenuBar()
void LIB_VIEW_FRAME::SyncToolbars()
{
LIB_PART* symbol = GetSelectedSymbol();
LIB_ALIAS* alias = GetSelectedAlias();
std::unique_ptr< LIB_PART > symbol( GetSelectedSymbol() );
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet, alias && !alias->GetDocFileName().IsEmpty() );
m_mainToolBar->Toggle( EE_ACTIONS::showDatasheet,
symbol && !symbol->GetDocFileName().IsEmpty() );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganStandard, symbol && symbol->HasConversion(),
m_convert == LIB_FIELD::LIB_CONVERT::BASE );
m_mainToolBar->Toggle( EE_ACTIONS::showDeMorganAlternate, symbol && symbol->HasConversion(),

View File

@ -248,29 +248,12 @@ int EE_INSPECTION_TOOL::ShowDatasheet( const TOOL_EVENT& aEvent )
if( !part )
return 0;
if( part->GetAliasCount() > 1 )
{
ACTION_MENU popup( true );
wxString msg;
int id = 0;
for( LIB_ALIAS* alias : part->GetAliases() )
{
msg.Printf( wxT( "%s (%s)" ), alias->GetName(), alias->GetDocFileName() );
popup.Append( id++, msg );
}
m_frame->PopupMenu( &popup );
if( popup.GetSelected() >= 0 )
datasheet = part->GetAlias( (unsigned) popup.GetSelected() )->GetDocFileName();
}
else
datasheet = part->GetAlias( 0 )->GetDocFileName();
datasheet = part->GetDocFileName();
}
else if( m_frame->IsType( FRAME_SCH_VIEWER ) || m_frame->IsType( FRAME_SCH_VIEWER_MODAL ) )
{
LIB_ALIAS* entry = static_cast<LIB_VIEW_FRAME*>( m_frame )->GetSelectedAlias();
std::unique_ptr< LIB_PART > entry =
static_cast<LIB_VIEW_FRAME*>( m_frame )->GetSelectedSymbol();
if( !entry )
return 0;

View File

@ -74,8 +74,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleSymbol = [] (const SELECTION& aSel )
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return !partRef || !partRef->IsPower();
return !comp->GetPartRef() || !comp->GetPartRef()->IsPower();
}
}
@ -91,8 +90,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleDeMorganSymbol = [] ( const SELECTION&
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return partRef && partRef->HasConversion();
return comp->GetPartRef() && comp->GetPartRef()->HasConversion();
}
}
@ -108,8 +106,7 @@ SELECTION_CONDITION EE_CONDITIONS::SingleMultiUnitSymbol = [] ( const SELECTION&
if( comp )
{
auto partRef = comp->GetPartRef().lock();
return partRef && partRef->GetUnitCount() >= 2;
return comp->GetPartRef() && comp->GetPartRef()->GetUnitCount() >= 2;
}
}

View File

@ -373,8 +373,8 @@ int LIB_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
}
else
{
part = viewFrame->GetSelectedSymbol();
libId = viewFrame->GetSelectedAlias()->GetLibId();
part = viewFrame->GetSelectedSymbol().get();
libId = part->GetLibId();
unit = viewFrame->GetUnit();
convert = viewFrame->GetConvert();
}

View File

@ -206,7 +206,6 @@ int LIB_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
static KICAD_T nonFields[] =
{
LIB_PART_T,
LIB_ALIAS_T,
LIB_ARC_T,
LIB_CIRCLE_T,
LIB_TEXT_T,
@ -521,7 +520,6 @@ void LIB_EDIT_TOOL::editSymbolProperties()
LIB_PART* part = m_frame->GetCurPart();
bool partLocked = part->UnitsLocked();
wxString oldName = part->GetName();
wxArrayString oldAliases = part->GetAliasNames( false );
m_toolMgr->RunAction( ACTIONS::cancelInteractive, true );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
@ -535,6 +533,8 @@ void LIB_EDIT_TOOL::editSymbolProperties()
if( dlg.ShowQuasiModal() != wxID_OK )
return;
m_frame->OnModify();
// if m_UnitSelectionLocked has changed, set some edit options or defaults
// to the best value
if( partLocked != part->UnitsLocked() )
@ -546,8 +546,6 @@ void LIB_EDIT_TOOL::editSymbolProperties()
// and if units are interchangeable, graphic items are common to units
m_frame->m_DrawSpecificUnit = part->UnitsLocked();
}
m_frame->UpdateAfterSymbolProperties( &oldName, &oldAliases );
}

View File

@ -88,16 +88,15 @@ private:
}
int unit = component->GetUnit();
auto partRef = component->GetPartRef().lock();
if( !partRef || partRef->GetUnitCount() < 2 )
if( !component->GetPartRef() || component->GetPartRef()->GetUnitCount() < 2 )
{
Append( ID_POPUP_SCH_UNFOLD_BUS, _( "symbol is not multi-unit" ), wxEmptyString );
Enable( ID_POPUP_SCH_UNFOLD_BUS, false );
return;
}
for( int ii = 0; ii < partRef->GetUnitCount(); ii++ )
for( int ii = 0; ii < component->GetPartRef()->GetUnitCount(); ii++ )
{
wxString num_unit;
num_unit.Printf( _( "Unit %s" ), LIB_PART::SubReference( ii + 1, false ) );

View File

@ -207,7 +207,7 @@ LIB_VIEW_FRAME::LIB_VIEW_FRAME( KIWAY* aKiway, wxWindow* aParent, FRAME_T aFrame
LIB_VIEW_FRAME::~LIB_VIEW_FRAME()
{
if( m_previewItem )
GetCanvas()->GetView()->Remove( m_previewItem );
GetCanvas()->GetView()->Remove( m_previewItem.get() );
}
@ -248,24 +248,17 @@ void LIB_VIEW_FRAME::SetUnitAndConvert( int aUnit, int aConvert )
}
LIB_ALIAS* LIB_VIEW_FRAME::GetSelectedAlias() const
std::unique_ptr< LIB_PART > LIB_VIEW_FRAME::GetSelectedSymbol() const
{
LIB_ALIAS* alias = NULL;
std::unique_ptr< LIB_PART > symbol;
if( !m_libraryName.IsEmpty() && !m_entryName.IsEmpty() )
alias = Prj().SchSymbolLibTable()->LoadSymbol( m_libraryName, m_entryName );
{
LIB_PART* tmp = Prj().SchSymbolLibTable()->LoadSymbol( m_libraryName, m_entryName );
return alias;
}
LIB_PART* LIB_VIEW_FRAME::GetSelectedSymbol() const
{
LIB_PART* symbol = NULL;
LIB_ALIAS* alias = GetSelectedAlias();
if( alias )
symbol = alias->GetPart();
if( tmp )
symbol = tmp->Flatten();
}
return symbol;
}
@ -273,28 +266,35 @@ LIB_PART* LIB_VIEW_FRAME::GetSelectedSymbol() const
void LIB_VIEW_FRAME::updatePreviewSymbol()
{
LIB_ALIAS* alias = GetSelectedAlias();
std::unique_ptr< LIB_PART > symbol = GetSelectedSymbol();
KIGFX::SCH_VIEW* view = GetCanvas()->GetView();
if( m_previewItem )
{
view->Remove( m_previewItem );
view->Remove( m_previewItem.get() );
m_previewItem = nullptr;
}
ClearMsgPanel();
if( alias )
if( symbol )
{
GetRenderSettings()->m_ShowUnit = m_unit;
GetRenderSettings()->m_ShowConvert = m_convert;
view->Add( alias );
m_previewItem = alias;
m_previewItem.reset( symbol.release() );
view->Add( m_previewItem.get() );
AppendMsgPanel( _( "Name" ), alias->GetName(), BLUE, 6 );
AppendMsgPanel( _( "Description" ), alias->GetDescription(), CYAN, 6 );
AppendMsgPanel( _( "Key words" ), alias->GetKeyWords(), DARKDARKGRAY );
wxString parentName = _( "<none>" );
std::shared_ptr< LIB_PART > parent = m_previewItem->GetParent().lock();
if( parent )
parentName = parent->GetName();
AppendMsgPanel( _( "Name" ), m_previewItem->GetName(), BLUE, 6 );
AppendMsgPanel( _( "Parent" ), parentName, RED, 6 );
AppendMsgPanel( _( "Description" ), m_previewItem->GetDescription(), CYAN, 6 );
AppendMsgPanel( _( "Key words" ), m_previewItem->GetKeyWords(), DARKDARKGRAY );
}
GetCanvas()->ForceRefresh();
@ -370,7 +370,7 @@ void LIB_VIEW_FRAME::OnSize( wxSizeEvent& SizeEv )
void LIB_VIEW_FRAME::onUpdateUnitChoice( wxUpdateUIEvent& aEvent )
{
LIB_PART* part = GetSelectedSymbol();
std::unique_ptr< LIB_PART > part = GetSelectedSymbol();
int unit_count = 1;
@ -701,8 +701,7 @@ void LIB_VIEW_FRAME::SetFilter( const SCHLIB_FILTER* aFilter )
const BOX2I LIB_VIEW_FRAME::GetDocumentExtents() const
{
LIB_ALIAS* alias = GetSelectedAlias();
LIB_PART* part = alias ? alias->GetPart() : nullptr;
std::unique_ptr< LIB_PART > part = GetSelectedSymbol();
if( !part )
{

View File

@ -32,7 +32,6 @@
class wxListBox;
class SCHLIB_FILTER;
class LIB_ALIAS;
class LIB_PART;
class SYMBOL_LIB_TABLE_ROW;
@ -138,8 +137,7 @@ public:
int GetUnit() const { return m_unit; }
int GetConvert() const { return m_convert; }
LIB_PART* GetSelectedSymbol() const;
LIB_ALIAS* GetSelectedAlias() const;
std::unique_ptr< LIB_PART > GetSelectedSymbol() const;
const BOX2I GetDocumentExtents() const override;
@ -192,7 +190,7 @@ private:
*/
bool m_selection_changed;
LIB_ALIAS* m_previewItem;
std::unique_ptr< LIB_PART > m_previewItem;
DECLARE_EVENT_TABLE()
};

View File

@ -32,6 +32,7 @@
#include <viewlib_frame.h>
#include <eeschema_id.h>
#include <class_libentry.h>
#include <class_library.h>
#include <dialog_helpers.h>
#include <dialog_choose_component.h>
@ -54,7 +55,7 @@ void LIB_VIEW_FRAME::OnSelectSymbol( wxCommandEvent& aEvent )
const auto libNicknames = libs->GetLogicalLibs();
adapter->AddLibraries( libNicknames, this );
LIB_ALIAS *current = GetSelectedAlias();
std::unique_ptr< LIB_PART > current( GetSelectedSymbol() );
LIB_ID id;
int unit = 0;

View File

@ -145,11 +145,14 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
{
KIGFX::VIEW* view = m_preview->GetView();
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
LIB_ALIAS* alias = nullptr;
std::unique_ptr< LIB_PART > symbol;
try
{
alias = m_kiway.Prj().SchSymbolLibTable()->LoadSymbol( aSymbolID );
LIB_PART* tmp = m_kiway.Prj().SchSymbolLibTable()->LoadSymbol( aSymbolID );
if( tmp )
symbol = tmp->Flatten();
}
catch( const IO_ERROR& ioe )
{
@ -166,25 +169,25 @@ void SYMBOL_PREVIEW_WIDGET::DisplaySymbol( const LIB_ID& aSymbolID, int aUnit )
m_previewItem = nullptr;
}
if( alias )
if( symbol )
{
LIB_PART* part = alias->GetPart();
// This will flatten derived parts so that the correct final symbol can be shown.
m_previewItem = symbol.release();
// If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
// draw all of them.)
if( part->IsMulti() && aUnit == 0 )
if( m_previewItem->IsMulti() && aUnit == 0 )
aUnit = 1;
settings->m_ShowUnit = aUnit;
// For symbols having a De Morgan body style, use the first style
settings->m_ShowConvert = part->HasConversion() ? 1 : 0;
settings->m_ShowConvert = m_previewItem->HasConversion() ? 1 : 0;
m_previewItem = new LIB_ALIAS( *alias, part );
view->Add( m_previewItem );
// Get the symbole size, in internal units
m_itemBBox = part->GetUnitBoundingBox( aUnit, 0 );
m_itemBBox = m_previewItem->GetUnitBoundingBox( aUnit, 0 );
if( !m_preview->IsShown() )
{
@ -214,15 +217,16 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
if( aPart )
{
m_previewItem = new LIB_PART( *aPart );
// If unit isn't specified for a multi-unit part, pick the first. (Otherwise we'll
// draw all of them.)
if( aPart->IsMulti() && aUnit == 0 )
if( m_previewItem->IsMulti() && aUnit == 0 )
aUnit = 1;
// For symbols having a De Morgan body style, use the first style
auto settings = static_cast<KIGFX::SCH_RENDER_SETTINGS*>( view->GetPainter()->GetSettings() );
settings->m_ShowConvert = aPart->HasConversion() ? 1 : 0;
m_previewItem = new LIB_PART( *aPart );
settings->m_ShowConvert = m_previewItem->HasConversion() ? 1 : 0;
view->Add( m_previewItem );
// Get the symbole size, in internal units
@ -233,7 +237,6 @@ void SYMBOL_PREVIEW_WIDGET::DisplayPart( LIB_PART* aPart, int aUnit )
}
m_preview->ForceRefresh();
m_preview->Show();
m_statusSizer->ShowItems( false );
}

View File

@ -26,9 +26,7 @@
#include <class_draw_panel_gal.h>
class EDA_ITEM;
class LIB_ID;
class LIB_ALIAS;
class LIB_PART;
class wxStaticText;
class wxSizer;
@ -75,9 +73,10 @@ private:
wxStaticText* m_status;
wxSizer* m_statusSizer;
/** a local copy of the LIB_ALIAS or the LIB_PART to display on the canvas
/**
* A local copy of the #LIB_PART to display on the canvas.
*/
EDA_ITEM* m_previewItem;
LIB_PART* m_previewItem;
/// The bounding box of the current item
BOX2I m_itemBBox;

View File

@ -72,28 +72,25 @@ class WX_EVENT_LOOP;
/**
* Class DIALOG_SHIM
* may sit in the inheritance tree between wxDialog and any class written by
* wxFormBuilder. To put it there, use wxFormBuilder tool and set:
* Dialog helper object to sit in the inheritance tree between wxDialog and any class written
* by wxFormBuilder.
*
* To put it there, use wxFormBuilder tool and set:
* <br> subclass name = DIALOG_SHIM
* <br> subclass header = dialog_shim.h
* <br>
* in the dialog window's properties.
**/
*/
class DIALOG_SHIM : public wxDialog, public KIWAY_HOLDER
{
/**
* Function OnCloseWindow
*
* properly handles the wxCloseEvent when in the quasimodal mode when not calling
* Properly handle the wxCloseEvent when in the quasimodal mode when not calling
* EndQuasiModal which is possible with any dialog derived from #DIALOG_SHIM.
*/
void OnCloseWindow( wxCloseEvent& aEvent );
/**
* Function OnCloseWindow
*
* properly handles the default button events when in the quasimodal mode when not
* Properly handle the default button events when in the quasimodal mode when not
* calling EndQuasiModal which is possible with any dialog derived from #DIALOG_SHIM.
*/
void OnButton( wxCommandEvent& aEvent );
@ -136,12 +133,14 @@ public:
static bool IsCtrl( int aChar, const wxKeyEvent& e )
{
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && !e.ShiftDown() && !e.MetaDown();
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() &&
!e.ShiftDown() && !e.MetaDown();
}
static bool IsShiftCtrl( int aChar, const wxKeyEvent& e )
{
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() && e.ShiftDown() && !e.MetaDown();
return e.GetKeyCode() == aChar && e.ControlDown() && !e.AltDown() &&
e.ShiftDown() && !e.MetaDown();
}
protected:
@ -182,6 +181,15 @@ protected:
*/
int VertPixelsFromDU( int y );
/**
* Clear the existing dialog size and position.
*
* This will cause the dialog size to be clear so the next time the dialog is shown
* the sizers will layout the dialog accordingly. This useful when there are dialog
* windows that size changes due to layout dependency hidden controls.
*/
void ResetSize();
EDA_UNITS_T m_units; // userUnits for display and parsing
std::string m_hash_key; // alternate for class_map when classname re-used

View File

@ -81,7 +81,7 @@ public:
return m_nickname;
}
const wxString& GetName() const override
const wxString GetName() const override
{
return m_fpname;
}
@ -91,13 +91,13 @@ public:
return LIB_ID( m_nickname, m_fpname );
}
const wxString& GetDescription() override
const wxString GetDescription() override
{
ensure_loaded();
return m_doc;
}
const wxString& GetKeywords()
const wxString GetKeywords()
{
ensure_loaded();
return m_keywords;

View File

@ -41,10 +41,10 @@ class APIEXPORT LIB_TREE_ITEM
public:
virtual LIB_ID GetLibId() const = 0;
virtual const wxString& GetName() const = 0;
virtual const wxString GetName() const = 0;
virtual wxString GetLibNickname() const = 0;
virtual const wxString& GetDescription() = 0;
virtual const wxString GetDescription() = 0;
virtual wxString GetSearchText() { return wxEmptyString; }
@ -56,7 +56,7 @@ public:
/**
* For items with units, return the number of units.
*/
virtual int GetUnitCount() { return 0; }
virtual int GetUnitCount() const { return 0; }
/**
* For items with units, return an identifier for unit x.

View File

@ -204,7 +204,7 @@ public:
return CONST_ITERATOR( this, operator[]( bucket ).end(), bucket, aType );
}
size_t size( int aType = UNDEFINED_TYPE )
size_t size( int aType = UNDEFINED_TYPE ) const
{
if( aType != UNDEFINED_TYPE )
{

View File

@ -30,6 +30,9 @@
// Code under test
#include <class_libentry.h>
#include <lib_rectangle.h>
#include <lib_arc.h>
#include <lib_pin.h>
#include "lib_field_test_utils.h"
@ -63,7 +66,9 @@ BOOST_AUTO_TEST_CASE( DefaultProperties )
BOOST_CHECK_EQUAL( m_part_no_data.GetLib(), nullptr );
// only get the root
BOOST_CHECK_EQUAL( m_part_no_data.GetAliasCount(), 1 );
BOOST_CHECK_EQUAL( m_part_no_data.IsRoot(), true );
BOOST_CHECK_EQUAL( m_part_no_data.IsAlias(), false );
BOOST_CHECK_EQUAL( m_part_no_data.SharedPtr().use_count(), 2 );
// no sub units
BOOST_CHECK_EQUAL( m_part_no_data.GetUnitCount(), 1 );
@ -81,6 +86,7 @@ BOOST_AUTO_TEST_CASE( DefaultDrawings )
{
// default drawings exist
BOOST_CHECK_EQUAL( m_part_no_data.GetDrawItems().size(), 4 );
BOOST_CHECK_EQUAL( m_part_no_data.GetNextDrawItem( NULL, LIB_PIN_T ), (LIB_ITEM*)NULL );
}
@ -150,6 +156,14 @@ BOOST_AUTO_TEST_CASE( AddedFields )
}
/**
* Test adding draw items to a LIB_PART
*/
BOOST_AUTO_TEST_CASE( AddedDrawItems )
{
}
struct TEST_LIB_PART_SUBREF_CASE
{
int m_index;
@ -203,4 +217,188 @@ BOOST_AUTO_TEST_CASE( SubReference )
}
BOOST_AUTO_TEST_SUITE_END()
/**
* Check the compare method.
*/
BOOST_AUTO_TEST_CASE( Compare )
{
// Identical root part to m_part_no_data sans time stamp.
LIB_PART testPart( "part_name" );
// Self comparison test.
BOOST_CHECK_EQUAL( m_part_no_data.Compare( m_part_no_data ), 0 );
// Test for identical LIB_PART.
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
// Test name.
testPart.SetName( "tart_name" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.SetName( "cart_name" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
testPart.SetName( "part_name" );
// LIB_ID comparison tests.
LIB_ID id = testPart.GetLibId();
id.SetLibItemName( "tart_name" );
testPart.SetLibId( id );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
id.SetLibItemName( "cart_name" );
testPart.SetLibId( id );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
id.SetLibItemName( "part_name" );
testPart.SetLibId( id );
// Unit count comparison tests.
testPart.SetUnitCount( 2 );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.SetUnitCount( 1 );
m_part_no_data.SetUnitCount( 2 );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetUnitCount( 1 );
// Options flag comparison tests.
testPart.SetPower();
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.SetNormal();
m_part_no_data.SetPower();
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetNormal();
// Draw item list size comparison tests.
testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) );
m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) );
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
// Draw item list contents comparison tests.
testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) );
m_part_no_data.AddDrawItem( new LIB_ARC( &m_part_no_data ) );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_ARC_T ) );
m_part_no_data.AddDrawItem( new LIB_PIN( &m_part_no_data ) );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_PIN_T ) );
testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
// Footprint filter array comparison tests.
wxArrayString footPrintFilters;
BOOST_CHECK( m_part_no_data.GetFootprints() == footPrintFilters );
footPrintFilters.Add( "b" );
testPart.SetFootprintFilters( footPrintFilters );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetFootprintFilters( footPrintFilters );
footPrintFilters.Clear();
testPart.SetFootprintFilters( footPrintFilters );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
footPrintFilters.Clear();
m_part_no_data.SetFootprintFilters( footPrintFilters );
testPart.SetFootprintFilters( footPrintFilters );
// Description string tests.
m_part_no_data.SetDescription( "b" );
testPart.SetDescription( "b" );
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
m_part_no_data.SetDescription( "a" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetDescription( "c" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetDescription( wxEmptyString );
testPart.SetDescription( wxEmptyString );
// Key word string tests.
m_part_no_data.SetKeyWords( "b" );
testPart.SetKeyWords( "b" );
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
m_part_no_data.SetKeyWords( "a" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetKeyWords( "c" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetKeyWords( wxEmptyString );
testPart.SetKeyWords( wxEmptyString );
// Documentation file string tests.
m_part_no_data.SetDocFileName( "b" );
testPart.SetDocFileName( "b" );
BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
m_part_no_data.SetDocFileName( "a" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetDocFileName( "c" );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.SetDocFileName( wxEmptyString );
testPart.SetDocFileName( wxEmptyString );
// Pin name offset comparison tests.
testPart.SetPinNameOffset( testPart.GetPinNameOffset() + 1 );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.SetPinNameOffset( testPart.GetPinNameOffset() - 2 );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
testPart.SetPinNameOffset( testPart.GetPinNameOffset() + 1 );
// Units locked flag comparision tests.
testPart.LockUnits( true );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
testPart.LockUnits( false );
m_part_no_data.LockUnits( true );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
m_part_no_data.LockUnits( false );
// Show pin names flag comparison tests.
m_part_no_data.SetShowPinNames( false );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetShowPinNames( true );
testPart.SetShowPinNames( false );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
testPart.SetShowPinNames( true );
// Show pin numbers flag comparison tests.
m_part_no_data.SetShowPinNumbers( false );
BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
m_part_no_data.SetShowPinNumbers( true );
testPart.SetShowPinNumbers( false );
BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
testPart.SetShowPinNumbers( true );
// Time stamp comparison tests.
}
/**
* Check inheritance support.
*/
BOOST_AUTO_TEST_CASE( Inheritance )
{
std::unique_ptr< LIB_PART > parent( new LIB_PART( "parent" ) );
BOOST_CHECK( parent->IsRoot() );
std::unique_ptr< LIB_PART > child1( new LIB_PART( "child1", parent.get() ) );
BOOST_CHECK( child1->IsAlias() );
PART_SPTR parentRef = child1->GetParent().lock();
BOOST_CHECK( parentRef );
BOOST_CHECK( parentRef == parent->SharedPtr() );
BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 3 );
BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
parent->SetUnitCount( 4 );
BOOST_CHECK_EQUAL( child1->GetUnitCount(), 4 );
child1->SetParent();
BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
parentRef.reset();
BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 2 );
}
/**
* Check the copy constructor.
*/
BOOST_AUTO_TEST_CASE( CopyConstructor )
{
std::shared_ptr< LIB_PART > copy( new LIB_PART( m_part_no_data ) );
BOOST_CHECK( m_part_no_data == *copy.get() );
}
BOOST_AUTO_TEST_SUITE_END()