7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-19 21:41:40 +00:00

Replace EESchema DLIST

This moves EESchema DLIST structures to rtree.  These changes are more
fundamental than the pcbnew changes from 9163ac543 888c01d11 d1877d7c1
and 961b22d60 as eeschema operations were more dependent on passing
drawing list references around with SCH_ITEM* objects.
This commit is contained in:
Seth Hillbrand 2019-06-25 16:39:58 -07:00
parent a8d9fcb4e0
commit 6e5e453d0d
70 changed files with 2347 additions and 2216 deletions

View File

@ -127,7 +127,7 @@ EDA_ITEM* EDA_ITEM::Clone() const
// see base_struct.h
// many classes inherit this method, be careful:
//TODO(snh): Fix this to use std::set instead of C-style vector
//TODO (snh): Fix this to use std::set instead of C-style vector
SEARCH_RESULT EDA_ITEM::Visit( INSPECTOR inspector, void* testData, const KICAD_T scanTypes[] )
{
#if 0 && defined(DEBUG)

View File

@ -25,6 +25,7 @@
#include <kiway.h>
#include <kiway_holder.h>
#include <project.h>
#if defined(DEBUG)
#include <typeinfo>

View File

@ -266,18 +266,21 @@ protected:
*/
void get_possible_colliders( std::vector<SCH_ITEM*>& aItems )
{
wxASSERT_MSG( m_screen, "get_possible_colliders() with null m_screen" );
for( SCH_ITEM* item = m_screen->GetDrawItems(); item; item = item->Next() )
wxCHECK_RET( m_screen, "get_possible_colliders() with null m_screen" );
for( auto item : m_screen->Items().Overlapping( m_component->GetBoundingBox() ) )
{
if( SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( item ) )
{
if( comp == m_component ) continue;
if( comp == m_component )
continue;
std::vector<SCH_FIELD*> fields;
comp->GetFields( fields, /* aVisibleOnly */ true );
for( SCH_FIELD* field : fields )
aItems.push_back( field );
}
aItems.push_back( item );
}
}

View File

@ -23,23 +23,28 @@
*/
#include <fctsys.h>
#include <sch_edit_frame.h>
#include <lib_item.h>
#include <core/kicad_algo.h>
#include <eeschema_id.h>
#include <general.h>
#include <lib_item.h>
#include <sch_bus_entry.h>
#include <sch_component.h>
#include <sch_edit_frame.h>
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_no_connect.h>
#include <sch_component.h>
#include <sch_screen.h>
#include <sch_sheet.h>
#include <sch_view.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
#include <tools/ee_selection_tool.h>
#include <tool/tool_manager.h>
void SCH_EDIT_FRAME::GetSchematicConnections( std::vector< wxPoint >& aConnections )
{
for( SCH_ITEM* item = GetScreen()->GetDrawItems(); item; item = item->Next() )
for( auto item : GetScreen()->Items() )
{
// Avoid items that are changing
if( !( item->GetEditFlags() & ( IS_DRAGGED | IS_MOVED | IS_DELETED ) ) )
@ -50,7 +55,8 @@ void SCH_EDIT_FRAME::GetSchematicConnections( std::vector< wxPoint >& aConnectio
std::sort( aConnections.begin(), aConnections.end(),
[]( const wxPoint& a, const wxPoint& b ) -> bool
{ return a.x < b.x || (a.x == b.x && a.y < b.y); } );
aConnections.erase( unique( aConnections.begin(), aConnections.end() ), aConnections.end() );
aConnections.erase(
std::unique( aConnections.begin(), aConnections.end() ), aConnections.end() );
}
@ -59,16 +65,17 @@ bool SCH_EDIT_FRAME::TestDanglingEnds()
std::vector<DANGLING_END_ITEM> endPoints;
bool hasStateChanged = false;
for( SCH_ITEM* item = GetScreen()->GetDrawList().begin(); item; item = item->Next() )
for( auto item : GetScreen()->Items() )
item->GetEndPoints( endPoints );
for( SCH_ITEM* item = GetScreen()->GetDrawList().begin(); item; item = item->Next() )
for( auto item : GetScreen()->Items() )
{
if( item->UpdateDanglingState( endPoints ) )
{
GetCanvas()->GetView()->Update( item, KIGFX::REPAINT );
hasStateChanged = true;
}
item->GetEndPoints( endPoints );
}
return hasStateChanged;
@ -77,25 +84,22 @@ bool SCH_EDIT_FRAME::TestDanglingEnds()
bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd )
{
SCH_LINE* line;
SCH_ITEM* next_item = NULL;
bool retval = false;
if( aStart == aEnd )
return retval;
for( SCH_ITEM* item = GetScreen()->GetDrawItems(); item; item = next_item )
for( auto item : GetScreen()->Items().OfType( SCH_LINE_T ) )
{
next_item = item->Next();
SCH_LINE* line = static_cast<SCH_LINE*>( item );
if( line->GetLayer() != LAYER_WIRE )
continue;
// Don't remove wires that are already deleted or are currently being dragged
if( item->GetEditFlags() & ( STRUCT_DELETED | IS_DRAGGED | IS_MOVED | SKIP_STRUCT ) )
if( line->GetEditFlags() & ( STRUCT_DELETED | IS_DRAGGED | IS_MOVED | SKIP_STRUCT ) )
continue;
if( item->Type() != SCH_LINE_T || item->GetLayer() != LAYER_WIRE )
continue;
line = (SCH_LINE*) item;
if( !IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), aStart ) ||
!IsPointOnSegment( line->GetStartPoint(), line->GetEndPoint(), aEnd ) )
{
@ -134,113 +138,131 @@ bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd )
bool SCH_EDIT_FRAME::SchematicCleanUp( SCH_SCREEN* aScreen )
{
SCH_ITEM* item = NULL;
SCH_ITEM* secondItem = NULL;
PICKED_ITEMS_LIST itemList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
PICKED_ITEMS_LIST itemList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
std::vector<SCH_ITEM*> deletedItems;
std::vector<SCH_LINE*> lines;
std::vector<SCH_JUNCTION*> junctions;
std::vector<SCH_NO_CONNECT*> ncs;
if( aScreen == nullptr )
aScreen = GetScreen();
auto remove_item = [ &itemList ]( SCH_ITEM* aItem ) -> void
{
auto remove_item = [&itemList, &deletedItems]( SCH_ITEM* aItem ) -> void {
aItem->SetFlags( STRUCT_DELETED );
itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) );
deletedItems.push_back( aItem );
};
BreakSegmentsOnJunctions( aScreen );
for( item = aScreen->GetDrawItems(); item; item = item->Next() )
for( auto item : aScreen->Items().OfType( SCH_LINE_T ) )
{
if( ( item->Type() != SCH_LINE_T )
&& ( item->Type() != SCH_JUNCTION_T )
&& ( item->Type() != SCH_NO_CONNECT_T ) )
continue;
if( item->GetLayer() == LAYER_WIRE )
lines.push_back( static_cast<SCH_LINE*>( item ) );
}
if( item->GetEditFlags() & STRUCT_DELETED )
continue;
// Remove unneeded junctions
if( ( item->Type() == SCH_JUNCTION_T )
&& ( !aScreen->IsJunctionNeeded( item->GetPosition() ) ) )
{
for( auto item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
{
if( !aScreen->IsJunctionNeeded( item->GetPosition() ) )
remove_item( item );
else
junctions.push_back( static_cast<SCH_JUNCTION*>( item ) );
}
for( auto item : aScreen->Items().OfType( SCH_NO_CONNECT_T ) )
{
ncs.push_back( static_cast<SCH_NO_CONNECT*>( item ) );
}
alg::for_all_pairs(
junctions.begin(), junctions.end(), [&]( SCH_JUNCTION* aFirst, SCH_JUNCTION* aSecond ) {
if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
|| ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
return;
if( aFirst->GetPosition() == aSecond->GetPosition() )
remove_item( aSecond );
} );
alg::for_all_pairs(
ncs.begin(), ncs.end(), [&]( SCH_NO_CONNECT* aFirst, SCH_NO_CONNECT* aSecond ) {
if( ( aFirst->GetEditFlags() & STRUCT_DELETED )
|| ( aSecond->GetEditFlags() & STRUCT_DELETED ) )
return;
if( aFirst->GetPosition() == aSecond->GetPosition() )
remove_item( aSecond );
} );
for( auto it1 = lines.begin(); it1 != lines.end(); ++it1 )
{
SCH_LINE* firstLine = *it1;
if( firstLine->GetEditFlags() & STRUCT_DELETED )
continue;
if( firstLine->IsNull() )
{
remove_item( firstLine );
continue;
}
// Remove zero-length lines
if( item->Type() == SCH_LINE_T
&& ( (SCH_LINE*) item )->IsNull() )
{
remove_item( item );
continue;
}
auto it2 = it1;
for( secondItem = item->Next(); secondItem; secondItem = secondItem->Next() )
for( ++it2; it2 != lines.end(); ++it2 )
{
if( item->Type() != secondItem->Type()
|| ( secondItem->GetEditFlags() & STRUCT_DELETED ) )
SCH_LINE* secondLine = *it2;
bool needed = false;
if( secondLine->GetFlags() & STRUCT_DELETED )
continue;
// Merge overlapping lines
if( item->Type() == SCH_LINE_T )
{
SCH_LINE* firstLine = (SCH_LINE*) item;
SCH_LINE* secondLine = (SCH_LINE*) secondItem;
SCH_LINE* line = NULL;
bool needed = false;
if( !secondLine->IsParallel( firstLine )
|| secondLine->GetLineStyle() != firstLine->GetLineStyle()
|| secondLine->GetLineColor() != firstLine->GetLineColor()
|| secondLine->GetLineSize() != firstLine->GetLineSize() )
continue;
if( !secondLine->IsParallel( firstLine )
|| secondLine->GetLineStyle() != firstLine->GetLineStyle()
|| secondLine->GetLineColor() != firstLine->GetLineColor()
|| secondLine->GetLineSize() != firstLine->GetLineSize() )
continue;
// Remove identical lines
if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
// Remove identical lines
if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
&& firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
{
remove_item( secondItem );
continue;
}
// If the end points overlap, check if we still need the junction
if( secondLine->IsEndPoint( firstLine->GetStartPoint() ) )
needed = aScreen->IsJunctionNeeded( firstLine->GetStartPoint() );
else if( secondLine->IsEndPoint( firstLine->GetEndPoint() ) )
needed = aScreen->IsJunctionNeeded( firstLine->GetEndPoint() );
if( !needed && ( line = secondLine->MergeOverlap( firstLine ) ) )
{
remove_item( item );
remove_item( secondItem );
itemList.PushItem( ITEM_PICKER( line, UR_NEW ) );
AddToScreen( line, aScreen );
if( line->IsSelected() )
selectionTool->AddItemToSel( line, true /*quiet mode*/ );
break;
}
{
remove_item( secondLine );
continue;
}
// If the end points overlap, check if we still need the junction
if( secondLine->IsEndPoint( firstLine->GetStartPoint() ) )
needed = aScreen->IsJunctionNeeded( firstLine->GetStartPoint() );
else if( secondLine->IsEndPoint( firstLine->GetEndPoint() ) )
needed = aScreen->IsJunctionNeeded( firstLine->GetEndPoint() );
SCH_LINE* mergedLine = nullptr;
if( !needed && ( mergedLine = secondLine->MergeOverlap( firstLine ) ) )
{
remove_item( firstLine );
remove_item( secondLine );
itemList.PushItem( ITEM_PICKER( mergedLine, UR_NEW ) );
AddToScreen( mergedLine, aScreen );
if( firstLine->IsSelected() )
selectionTool->AddItemToSel( mergedLine, true /*quiet mode*/ );
break;
}
// Remove duplicate junctions and no-connects
else if( secondItem->GetPosition() == item->GetPosition() )
remove_item( secondItem );
}
}
for( item = aScreen->GetDrawItems(); item; item = secondItem )
for( auto item : deletedItems )
{
secondItem = item->Next();
if( item->IsSelected() )
selectionTool->RemoveItemFromSel( item, true /*quiet mode*/ );
if( item->GetEditFlags() & STRUCT_DELETED )
{
if( item->IsSelected() )
selectionTool->RemoveItemFromSel( item, true /*quiet mode*/ );
RemoveFromScreen( item, aScreen );
}
RemoveFromScreen( item, aScreen );
}
if( itemList.GetCount() )
@ -280,19 +302,24 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, SCH_SCREEN* aScreen )
{
static KICAD_T wiresAndBusses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
static const KICAD_T wiresAndBusses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
if( aScreen == nullptr )
aScreen = GetScreen();
bool brokenSegments = false;
bool brokenSegments = false;
std::vector<SCH_LINE*> wires;
EDA_RECT bbox( aPoint, wxSize( 2, 2 ) );
for( SCH_ITEM* segment = aScreen->GetDrawItems(); segment; segment = segment->Next() )
for( auto item : aScreen->Items().Overlapping( SCH_LINE_T, aPoint ) )
{
if( segment->IsType( wiresAndBusses ) )
brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint, NULL, aScreen );
if( item->IsType( wiresAndBusses ) )
wires.push_back( static_cast<SCH_LINE*>( item ) );
}
for( auto wire : wires )
brokenSegments |= BreakSegment( wire, aPoint, NULL, aScreen );
return brokenSegments;
}
@ -304,23 +331,21 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( SCH_SCREEN* aScreen )
bool brokenSegments = false;
for( SCH_ITEM* item = aScreen->GetDrawItems(); item; item = item->Next() )
std::set<wxPoint> point_set;
for( auto item : aScreen->Items().OfType( SCH_JUNCTION_T ) )
point_set.insert( item->GetPosition() );
for( auto item : aScreen->Items().OfType( SCH_BUS_WIRE_ENTRY_T ) )
{
if( item->Type() == SCH_JUNCTION_T )
{
SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
brokenSegments |= BreakSegments( junction->GetPosition(), aScreen );
}
else if( item->Type() == SCH_BUS_BUS_ENTRY_T || item->Type() == SCH_BUS_WIRE_ENTRY_T )
{
SCH_BUS_ENTRY_BASE* busEntry = (SCH_BUS_ENTRY_BASE*) item;
brokenSegments |= BreakSegments( busEntry->GetPosition(), aScreen );
brokenSegments |= BreakSegments( busEntry->m_End(), aScreen );
}
auto entry = static_cast<SCH_BUS_WIRE_ENTRY*>( item );
point_set.insert( entry->GetPosition() );
point_set.insert( entry->m_End() );
}
for( auto pt : point_set )
brokenSegments |= BreakSegments( pt, aScreen );
return brokenSegments;
}
@ -330,6 +355,7 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
SCH_SCREEN* screen = GetScreen();
PICKED_ITEMS_LIST undoList;
EE_SELECTION_TOOL* selectionTool = m_toolManager->GetTool<EE_SELECTION_TOOL>();
KICAD_T wiresAndBusses[] = { SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_BUS_T, EOT };
auto remove_item = [ & ]( SCH_ITEM* aItem ) -> void
{
@ -338,62 +364,62 @@ void SCH_EDIT_FRAME::DeleteJunction( SCH_ITEM* aJunction, bool aAppend )
};
remove_item( aJunction );
RemoveFromScreen( aJunction );
for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
/// Note that std::list or similar is required here as we may insert values in the
/// loop below. This will invalidate iterators in a std::vector or std::deque
std::list<SCH_LINE*> lines;
for( auto item : screen->Items().Overlapping( SCH_LINE_T, aJunction->GetPosition() ) )
{
SCH_LINE* firstLine = dynamic_cast<SCH_LINE*>( item );
auto line = static_cast<SCH_LINE*>( item );
if( !firstLine || !firstLine->IsEndPoint( aJunction->GetPosition() )
|| ( firstLine->GetEditFlags() & STRUCT_DELETED ) )
continue;
for( SCH_ITEM* secondItem = item->Next(); secondItem; secondItem = secondItem->Next() )
{
SCH_LINE* secondLine = dynamic_cast<SCH_LINE*>( secondItem );
if( !secondLine || !secondLine->IsEndPoint( aJunction->GetPosition() )
|| ( secondItem->GetEditFlags() & STRUCT_DELETED )
|| !secondLine->IsParallel( firstLine ) )
continue;
// Remove identical lines
if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
&& firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
{
remove_item( secondItem );
continue;
}
// Try to merge the remaining lines
if( SCH_LINE* line = secondLine->MergeOverlap( firstLine ) )
{
remove_item( item );
remove_item( secondItem );
undoList.PushItem( ITEM_PICKER( line, UR_NEW ) );
AddToScreen( line );
if( line->IsSelected() )
selectionTool->AddItemToSel( line, true /*quiet mode*/ );
break;
}
}
if( line->IsType( wiresAndBusses ) && line->IsEndPoint( aJunction->GetPosition() )
&& !( line->GetEditFlags() & STRUCT_DELETED ) )
lines.push_back( line );
}
alg::for_all_pairs(
lines.begin(), lines.end(), [&]( SCH_LINE* firstLine, SCH_LINE* secondLine ) {
if( ( firstLine->GetEditFlags() & STRUCT_DELETED )
|| ( secondLine->GetEditFlags() & STRUCT_DELETED )
|| !secondLine->IsParallel( firstLine ) )
return;
// Remove identical lines
if( firstLine->IsEndPoint( secondLine->GetStartPoint() )
&& firstLine->IsEndPoint( secondLine->GetEndPoint() ) )
{
remove_item( firstLine );
return;
}
// Try to merge the remaining lines
if( SCH_LINE* line = secondLine->MergeOverlap( firstLine ) )
{
remove_item( firstLine );
remove_item( secondLine );
undoList.PushItem( ITEM_PICKER( line, UR_NEW ) );
AddToScreen( line );
if( line->IsSelected() )
selectionTool->AddItemToSel( line, true /*quiet mode*/ );
lines.push_back( line );
}
} );
SaveCopyInUndoList( undoList, UR_DELETED, aAppend );
for( unsigned ii = 0; ii < undoList.GetCount(); ii++ )
for( auto line : lines )
{
EDA_ITEM* item = undoList.GetPickedItem( ii );
if( item->GetEditFlags() & STRUCT_DELETED )
if( line->GetEditFlags() & STRUCT_DELETED )
{
if( item->IsSelected() )
selectionTool->RemoveItemFromSel( item, true /*quiet mode*/ );
if( line->IsSelected() )
selectionTool->RemoveItemFromSel( line, true /*quiet mode*/ );
RemoveFromScreen( item );
RemoveFromScreen( line );
}
}
}

View File

@ -29,10 +29,11 @@
#include <advanced_config.h>
#include <common.h>
#include <erc.h>
#include <sch_edit_frame.h>
#include <sch_bus_entry.h>
#include <sch_component.h>
#include <sch_edit_frame.h>
#include <sch_line.h>
#include <sch_marker.h>
#include <sch_pin.h>
#include <sch_screen.h>
#include <sch_sheet.h>
@ -388,14 +389,10 @@ void CONNECTION_GRAPH::Recalculate( SCH_SHEET_LIST aSheetList, bool aUncondition
{
std::vector<SCH_ITEM*> items;
for( auto item = sheet.LastScreen()->GetDrawItems();
item; item = item->Next() )
for( auto item : sheet.LastScreen()->Items() )
{
if( item->IsConnectable() &&
( aUnconditional || item->IsConnectivityDirty() ) )
{
if( item->IsConnectable() && ( aUnconditional || item->IsConnectivityDirty() ) )
items.push_back( item );
}
}
updateItemConnectivity( sheet, items );

View File

@ -48,13 +48,11 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
const wxString& aSearchText )
{
SCH_SHEET_PATH* sheetWithComponentFound = NULL;
SCH_ITEM* item = NULL;
SCH_COMPONENT* Component = NULL;
wxPoint pos;
bool notFound = true;
LIB_PIN* pin = nullptr;
SCH_SHEET_LIST sheetList( g_RootSheet );
EDA_ITEM* foundItem = nullptr;
SCH_ITEM* foundItem = nullptr;
if( !aSearchHierarchy )
sheetList.push_back( *g_CurrentSheet );
@ -63,12 +61,11 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
for( SCH_SHEET_PATH& sheet : sheetList)
{
for( item = sheet.LastDrawList(); item && notFound; item = item->Next() )
{
if( item->Type() != SCH_COMPONENT_T )
continue;
SCH_SCREEN* screen = sheet.LastScreen();
SCH_COMPONENT* pSch = (SCH_COMPONENT*) item;
for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
{
SCH_COMPONENT* pSch = static_cast<SCH_COMPONENT*>( item );
if( aReference.CmpNoCase( pSch->GetRef( &sheet ) ) == 0 )
{
@ -82,21 +79,21 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
if( pin )
{
notFound = false;
pos += pin->GetPosition();
foundItem = Component;
break;
}
}
else
{
notFound = false;
pos = pSch->GetPosition();
foundItem = Component;
break;
}
}
}
if( notFound == false )
if( foundItem )
break;
}
@ -129,7 +126,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
if( Component )
{
if( !notFound )
if( foundItem )
msg.Printf( _( "%s %s found" ), aReference, msg_item );
else
msg.Printf( _( "%s found but %s not found" ), aReference, msg_item );
@ -152,7 +149,7 @@ SCH_ITEM* SCH_EDITOR_CONTROL::FindComponentAndItem( const wxString& aReference,
m_frame->GetCanvas()->Refresh();
return item;
return foundItem;
}

View File

@ -417,27 +417,6 @@ void DIALOG_EDIT_COMPONENTS_LIBID::initDlg()
m_isModified = false;
// Build the component list:
#if 0
// This option build a component list that works fine to edit LIB_ID fields, but does not display
// all components in a complex hierarchy.
// the list is shorter, but can be look like there are missing components in list
SCH_SCREENS screens;
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
{
for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
{
if( item->Type() == SCH_COMPONENT_T )
{
CMP_CANDIDATE candidate( static_cast< SCH_COMPONENT* >( item ) );
candidate.m_Screen = screen;
candidate.m_Reference = candidate.m_Component->GetField( REFERENCE )->GetFullyQualifiedText();
m_components.push_back( candidate );
}
}
}
#else
// This option build the full component list
// In complex hierarchies, the same component is in fact duplicated, but
// it is listed with different references (one by sheet instance)
@ -460,7 +439,6 @@ void DIALOG_EDIT_COMPONENTS_LIBID::initDlg()
candidate.m_IsOrphan = ( unitcount == 0 );
m_components.push_back( candidate );
}
#endif
if( m_components.size() == 0 )
return;
@ -734,7 +712,7 @@ bool DIALOG_EDIT_COMPONENTS_LIBID::setLibIdByBrowser( int aRow )
if( !current.IsEmpty() )
aPreselectedLibid.Parse( current, LIB_ID::ID_SCH, true );
SCH_BASE_FRAME::COMPONENT_SELECTION sel =
COMPONENT_SELECTION sel =
m_parent->SelectComponentFromLibBrowser( this, NULL, aPreselectedLibid, 0, 0 );
#endif

View File

@ -195,12 +195,13 @@ bool DIALOG_LABEL_EDITOR::TransferDataToWindow()
SCH_SCREENS allScreens;
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
if( item->Type() == m_CurrentText->Type() )
{
auto textItem = static_cast<SCH_TEXT*>( item );
existingLabels.insert( UnescapeString( textItem->GetText() ) );
}
{
for( auto item : screen->Items().OfType( m_CurrentText->Type() ) )
{
auto textItem = static_cast<const SCH_TEXT*>( item );
existingLabels.insert( UnescapeString( textItem->GetText() ) );
}
}
wxArrayString existingLabelArray;

View File

@ -256,13 +256,11 @@ void DIALOG_ERC::OnLeftClickMarkersList( wxHtmlLinkEvent& event )
SCH_SHEET_LIST sheetList( g_RootSheet );
bool found = false;
for( i = 0; i < sheetList.size(); i++ )
for( i = 0; i < sheetList.size(); i++ )
{
SCH_ITEM* item = (SCH_ITEM*) sheetList[i].LastDrawList();
for( ; item; item = item->Next() )
for( auto aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
if( item == marker )
if( static_cast<const SCH_MARKER*>( aItem ) == marker )
{
found = true;
break;
@ -440,19 +438,12 @@ void DIALOG_ERC::DisplayERC_MarkersList()
for( unsigned i = 0; i < sheetList.size(); i++ )
{
SCH_ITEM* item = sheetList[i].LastDrawList();
for( ; item != NULL; item = item->Next() )
for( auto aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
if( item->Type() != SCH_MARKER_T )
continue;
SCH_MARKER* marker = static_cast<SCH_MARKER*>( aItem );
SCH_MARKER* marker = (SCH_MARKER*) item;
if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
continue;
m_MarkersList->AppendToList( marker );
if( marker->GetMarkerType() == MARKER_BASE::MARKER_ERC )
m_MarkersList->AppendToList( marker );
}
}
@ -623,11 +614,8 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
// Display new markers from the current screen:
KIGFX::VIEW* view = m_parent->GetCanvas()->GetView();
for( auto item = m_parent->GetScreen()->GetDrawItems(); item; item = item->Next() )
{
if( item->Type() == SCH_MARKER_T )
view->Add( item );
}
for( auto item : m_parent->GetScreen()->Items().OfType( SCH_MARKER_T ) )
view->Add( item );
m_parent->GetCanvas()->Refresh();

View File

@ -346,7 +346,7 @@ bool DIALOG_GLOBAL_EDIT_TEXT_AND_GRAPHICS::TransferDataFromWindow()
if( screen )
{
for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
for( auto item : screen->Items() )
visitItem( sheetPath, item );
}
}

View File

@ -34,6 +34,7 @@
#include <wx/wupdlock.h>
#include <cctype>
#include <cstring>
// Helper function to shorten conditions
static bool empty( const wxTextCtrl* aCtrl )

View File

@ -243,32 +243,25 @@ void DIALOG_SYMBOL_REMAP::remapSymbolsToLibTable( REPORTER& aReporter )
wxString msg;
SCH_SCREENS schematic;
SCH_COMPONENT* symbol;
SCH_ITEM* item;
SCH_ITEM* nextItem;
SCH_SCREEN* screen;
for( screen = schematic.GetFirst(); screen; screen = schematic.GetNext() )
{
for( item = screen->GetDrawItems(); item; item = nextItem )
for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
{
nextItem = item->Next();
if( item->Type() != SCH_COMPONENT_T )
continue;
symbol = dynamic_cast< SCH_COMPONENT* >( item );
symbol = dynamic_cast<SCH_COMPONENT*>( item );
if( !remapSymbolToLibTable( symbol ) )
{
msg.Printf( _( "No symbol \"%s\" found in symbol library table." ),
symbol->GetLibId().GetLibItemName().wx_str() );
symbol->GetLibId().GetLibItemName().wx_str() );
aReporter.Report( msg, REPORTER::RPT_WARNING );
}
else
{
msg.Printf( _( "Symbol \"%s\" mapped to symbol library \"%s\"." ),
symbol->GetLibId().GetLibItemName().wx_str(),
symbol->GetLibId().GetLibNickname().wx_str() );
symbol->GetLibId().GetLibItemName().wx_str(),
symbol->GetLibId().GetLibNickname().wx_str() );
aReporter.Report( msg, REPORTER::RPT_ACTION );
screen->SetModify();
}

View File

@ -26,12 +26,13 @@
#include <macros.h>
#include <trace_helpers.h>
#include <sch_sheet_path.h>
#include <transform.h>
#include <ee_collectors.h>
#include <lib_item.h>
#include <sch_bus_entry.h>
#include <sch_component.h>
#include <sch_line.h>
#include <sch_bus_entry.h>
#include <sch_sheet_path.h>
#include <transform.h>
const KICAD_T EE_COLLECTOR::AllItems[] = {
@ -93,8 +94,31 @@ SEARCH_RESULT EE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
}
void EE_COLLECTOR::Collect( EDA_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit, int aConvert )
void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit, int aConvert )
{
Empty(); // empty the collection just in case
SetScanTypes( aFilterList );
m_Unit = aUnit;
m_Convert = aConvert;
// remember where the snapshot was taken from and pass refPos to the Inspect() function.
SetRefPos( aPos );
if( aScreen )
{
for( const KICAD_T* filter = aFilterList; *filter != EOT; ++filter )
{
for( auto item : aScreen->Items().OfType( *filter ) )
item->Visit( m_inspector, nullptr, m_ScanTypes );
}
}
}
void EE_COLLECTOR::Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterList[],
const wxPoint& aPos, int aUnit, int aConvert )
{
Empty(); // empty the collection just in case
@ -105,11 +129,11 @@ void EE_COLLECTOR::Collect( EDA_ITEM* aItem, const KICAD_T aFilterList[], const
// remember where the snapshot was taken from and pass refPos to the Inspect() function.
SetRefPos( aPos );
// aItem can be null for empty schematics
if( aItem && aItem->Type() == LIB_PART_T )
static_cast<LIB_PART*>( aItem )->Visit( m_inspector, nullptr, m_ScanTypes );
else
EDA_ITEM::IterateForward( aItem, m_inspector, nullptr, m_ScanTypes );
for( auto& item : aItems )
{
if( item.Visit( m_inspector, nullptr, m_ScanTypes ) == SEARCH_RESULT::QUIT )
break;
}
}
@ -142,23 +166,3 @@ bool EE_COLLECTOR::IsDraggableJunction() const
return false;
}
SEARCH_RESULT EE_TYPE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* testData )
{
// The Vist() function only visits the testItem if its type was in the
// the scanList, so therefore we can collect anything given to us here.
Append( aItem );
return SEARCH_RESULT::CONTINUE;
}
void EE_TYPE_COLLECTOR::Collect( EDA_ITEM* aItem, const KICAD_T aFilterList[] )
{
Empty(); // empty the collection
SetScanTypes( aFilterList );
EDA_ITEM::IterateForward( aItem, m_inspector, NULL, m_ScanTypes );
}

View File

@ -26,11 +26,11 @@
#ifndef EE_COLLECTORS_H
#define EE_COLLECTORS_H
#include <class_libentry.h>
#include <collector.h>
#include <dialogs/dialog_schematic_find.h>
#include <sch_item.h>
#include <sch_sheet_path.h>
#include <dialogs/dialog_schematic_find.h>
/**
@ -70,7 +70,7 @@ public:
/**
* Function Collect
* scans a EDA_ITEM using this class's Inspector method, which does the collection.
* @param aItem A EDA_ITEM to scan.
* @param aScreen The eeschema screen to use for scanning
* @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
* what is to be collected and the priority order of the resulting
* collection.
@ -78,8 +78,22 @@ public:
* @param aUnit A symbol unit filter (for symbol editor)
* @param aConvert A DeMorgan filter (for symbol editor)
*/
void Collect( EDA_ITEM* aItem, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit = 0, int aConvert = 0 );
void Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit = 0, int aConvert = 0 );
/**
* Function Collect
* scans a EDA_ITEM using this class's Inspector method, which does the collection.
* @param aItems The LIB_PART multivector holding the part components
* @param aFilterList A list of #KICAD_T types with a terminating #EOT, that determines
* what is to be collected and the priority order of the resulting
* collection.
* @param aPos A wxPoint to use in hit-testing.
* @param aUnit A symbol unit filter (for symbol editor)
* @param aConvert A DeMorgan filter (for symbol editor)
*/
void Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit = 0, int aConvert = 0 );
/**
* Function IsCorner
@ -109,35 +123,4 @@ public:
};
/**
* Class EE_TYPE_COLLECTOR
* merely gathers up all SCH_ITEMs of a given set of KICAD_T type(s). It does
* no hit-testing.
*
* @see class COLLECTOR
*/
class EE_TYPE_COLLECTOR : public EE_COLLECTOR
{
public:
/**
* Function Inspect
* is the examining function within the INSPECTOR which is passed to the Iterate function.
*
* @param testItem An EDA_ITEM to examine.
* @param testData is not used in this class.
* @return SEARCH_RESULT - SEARCH_QUIT if the Iterator is to stop the scan,
* else SCAN_CONTINUE;
*/
SEARCH_RESULT Inspect( EDA_ITEM* testItem, void* testData ) override;
/**
* Function Collect
* scans a DLIST using this class's Inspector method, which does the collection.
* @param aItem The head of a DLIST to scan.
* @param aScanList The KICAD_Ts to gather up.
*/
void Collect( EDA_ITEM* aItem, const KICAD_T aScanList[] );
};
#endif // EE_COLLECTORS_H

View File

@ -174,23 +174,23 @@ static int MinimalReq[PINTYPE_COUNT][PINTYPE_COUNT] =
int TestDuplicateSheetNames( bool aCreateMarker )
{
SCH_SCREEN* screen;
SCH_ITEM* item;
SCH_ITEM* test_item;
int err_count = 0;
SCH_SCREENS screenList; // Created the list of screen
for( screen = screenList.GetFirst(); screen != NULL; screen = screenList.GetNext() )
{
for( item = screen->GetDrawItems(); item != NULL; item = item->Next() )
{
// search for a sheet;
if( item->Type() != SCH_SHEET_T )
continue;
std::vector<SCH_SHEET*> list;
for( test_item = item->Next(); test_item != NULL; test_item = test_item->Next() )
for( auto item : screen->Items().OfType( SCH_SHEET_T ) )
list.push_back( static_cast<SCH_SHEET*>( item ) );
for( size_t i = 0; i < list.size(); i++ )
{
auto item = list[i];
for( size_t j = i + 1; j < list.size(); j++ )
{
if( test_item->Type() != SCH_SHEET_T )
continue;
auto test_item = list[j];
// We have found a second sheet: compare names
// we are using case insensitive comparison to avoid mistakes between
@ -584,12 +584,9 @@ bool WriteDiagnosticERC( EDA_UNITS aUnits, const wxString& aFullFileName )
msg << wxString::Format( _( "\n***** Sheet %s\n" ),
GetChars( sheetList[i].PathHumanReadable() ) );
for( SCH_ITEM* item = sheetList[i].LastDrawList(); item != NULL; item = item->Next() )
for( auto aItem : sheetList[i].LastScreen()->Items().OfType( SCH_MARKER_T ) )
{
if( item->Type() != SCH_MARKER_T )
continue;
SCH_MARKER* marker = (SCH_MARKER*) item;
auto marker = static_cast<const SCH_MARKER*>( aItem );
if( marker->GetMarkerType() != MARKER_BASE::MARKER_ERC )
continue;

View File

@ -649,18 +649,14 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
GetScreen()->m_Initialized = true;
EE_TYPE_COLLECTOR components;
SCH_SCREENS allScreens;
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
{
components.Collect( screen->GetDrawItems(), EE_COLLECTOR::ComponentsOnly );
for( int cmpIdx = 0; cmpIdx < components.GetCount(); ++cmpIdx )
for( auto item : screen->Items().OfType( SCH_COMPONENT_T ) )
{
std::vector<wxPoint> pts;
SCH_COMPONENT* cmp = static_cast<SCH_COMPONENT*>( components[cmpIdx] );
SCH_COMPONENT* cmp = static_cast<SCH_COMPONENT*>( item );
// Update footprint LIB_ID to point to the imported Eagle library
auto fpField = cmp->GetField( FOOTPRINT );

View File

@ -24,30 +24,31 @@
*/
#include <algorithm>
#include <fctsys.h>
#include <pgm_base.h>
#include <kiway.h>
#include <gr_basic.h>
#include <sch_draw_panel.h>
#include <confirm.h>
#include <sch_edit_frame.h>
#include <msgpanel.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
#include <general.h>
#include <class_library.h>
#include <sch_component.h>
#include <confirm.h>
#include <eeschema_id.h>
#include <fctsys.h>
#include <general.h>
#include <gr_basic.h>
#include <kiway.h>
#include <lib_edit_frame.h>
#include <lib_view_frame.h>
#include <msgpanel.h>
#include <pgm_base.h>
#include <project.h>
#include <sch_component.h>
#include <sch_draw_panel.h>
#include <sch_edit_frame.h>
#include <symbol_lib_table.h>
#include <tool/tool_manager.h>
#include <tools/ee_actions.h>
#include <dialog_choose_component.h>
#include <symbol_tree_model_adapter.h>
SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowser(
wxTopLevelWindow* aParent, const SCHLIB_FILTER* aFilter, const LIB_ID& aPreselectedLibId,
int aUnit, int aConvert )
COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowser( wxTopLevelWindow* aParent,
const SCHLIB_FILTER* aFilter, const LIB_ID& aPreselectedLibId, int aUnit, int aConvert )
{
// Close any open non-modal Lib browser, and open a new one, in "modal" mode:
LIB_VIEW_FRAME* viewlibFrame = (LIB_VIEW_FRAME*) Kiway().Player( FRAME_SCH_VIEWER, false );
@ -90,15 +91,9 @@ SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectComponentFromLibBrowse
}
SCH_BASE_FRAME::COMPONENT_SELECTION SCH_BASE_FRAME::SelectCompFromLibTree(
const SCHLIB_FILTER* aFilter,
std::vector<COMPONENT_SELECTION>& aHistoryList,
bool aUseLibBrowser,
int aUnit,
int aConvert,
bool aShowFootprints,
const LIB_ID* aHighlight,
bool aAllowFields )
COMPONENT_SELECTION SCH_BASE_FRAME::SelectCompFromLibTree( const SCHLIB_FILTER* aFilter,
std::vector<COMPONENT_SELECTION>& aHistoryList, bool aUseLibBrowser, int aUnit,
int aConvert, bool aShowFootprints, const LIB_ID* aHighlight, bool aAllowFields )
{
std::unique_lock<std::mutex> dialogLock( DIALOG_CHOOSE_COMPONENT::g_Mutex, std::defer_lock );
wxString dialogTitle;

View File

@ -158,31 +158,26 @@ void HIERARCHY_NAVIG_DLG::buildHierarchyTree( SCH_SHEET_PATH* aList, wxTreeItemI
{
wxCHECK_RET( m_nbsheets < NB_MAX_SHEET, "Maximum number of sheets exceeded." );
SCH_ITEM* schitem = aList->LastDrawList();
while( schitem && m_nbsheets < NB_MAX_SHEET )
for( auto aItem : aList->LastScreen()->Items().OfType( SCH_SHEET_T ) )
{
if( schitem->Type() == SCH_SHEET_T )
SCH_SHEET* sheet = static_cast<SCH_SHEET*>( aItem );
m_nbsheets++;
wxTreeItemId menu;
menu = m_Tree->AppendItem( *aPreviousmenu, sheet->GetName(), 0, 1 );
aList->push_back( sheet );
m_Tree->SetItemData( menu, new TreeItemData( *aList ) );
if( *aList == m_currSheet )
{
SCH_SHEET* sheet = (SCH_SHEET*) schitem;
m_nbsheets++;
wxTreeItemId menu;
menu = m_Tree->AppendItem( *aPreviousmenu, sheet->GetName(), 0, 1 );
aList->push_back( sheet );
m_Tree->SetItemData( menu, new TreeItemData( *aList ) );
if( *aList == m_currSheet )
{
m_Tree->EnsureVisible( menu );
m_Tree->SelectItem( menu );
}
buildHierarchyTree( aList, &menu );
aList->pop_back();
m_Tree->EnsureVisible( menu );
m_Tree->SelectItem( menu );
}
schitem = schitem->Next();
buildHierarchyTree( aList, &menu );
aList->pop_back();
if( m_nbsheets >= NB_MAX_SHEET )
break;
}
}

View File

@ -81,13 +81,11 @@ bool SCH_EDIT_FRAME::CreateArchiveLibrary( const wxString& aFileName )
*/
for( SCH_SCREEN* screen = screens.GetFirst(); screen; screen = screens.GetNext() )
{
for( SCH_ITEM* item = screen->GetDrawItems(); item; item = item->Next() )
{
if( item->Type() != SCH_COMPONENT_T )
continue;
for( auto aItem : screen->Items().OfType( SCH_COMPONENT_T ) )
{
LIB_PART* part = nullptr;
SCH_COMPONENT* component = (SCH_COMPONENT*) item;
auto component = static_cast<SCH_COMPONENT*>( aItem );
try
{

View File

@ -102,46 +102,40 @@ SCH_COMPONENT* NETLIST_EXPORTER::findNextComponent( EDA_ITEM* aItem, SCH_SHEET_P
{
wxString ref;
// continue searching from the middle of a linked list (the draw list)
for( ; aItem; aItem = aItem->Next() )
if( aItem->Type() != SCH_COMPONENT_T )
return nullptr;
// found next component
SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
// Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components)
ref = comp->GetRef( aSheetPath );
if( ref[0] == wxChar( '#' ) )
return nullptr;
// if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
if( !comp->GetPartRef() )
return nullptr;
// If component is a "multi parts per package" type
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
if( aItem->Type() != SCH_COMPONENT_T )
continue;
// found next component
SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
// Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components)
ref = comp->GetRef( aSheetPath );
if( ref[0] == wxChar( '#' ) )
continue;
// if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
if( !comp->GetPartRef() )
continue;
// If component is a "multi parts per package" type
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
continue;
}
// record the usage of this library component entry.
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
return comp;
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
return nullptr;
}
return NULL;
// record the usage of this library component entry.
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
return comp;
}
@ -153,82 +147,65 @@ static bool sortPinsByNum( NETLIST_OBJECT* aPin1, NETLIST_OBJECT* aPin2 )
}
SCH_COMPONENT* NETLIST_EXPORTER::findNextComponentAndCreatePinList(
EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath )
void NETLIST_EXPORTER::CreatePinList( SCH_COMPONENT* comp, SCH_SHEET_PATH* aSheetPath )
{
wxString ref;
wxString ref( comp->GetRef( aSheetPath ) );
// Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components)
if( ref[0] == wxChar( '#' ) )
return;
// if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
if( !comp->GetPartRef() )
return;
m_SortedComponentPinList.clear();
// continue searching from the middle of a linked list (the draw list)
for( ; aItem; aItem = aItem->Next() )
// If component is a "multi parts per package" type
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
if( aItem->Type() != SCH_COMPONENT_T )
continue;
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
return;
// found next component
SCH_COMPONENT* comp = (SCH_COMPONENT*) aItem;
// Power symbols and other components which have the reference starting
// with "#" are not included in netlist (pseudo or virtual components)
ref = comp->GetRef( aSheetPath );
if( ref[0] == wxChar( '#' ) )
continue;
// if( Component->m_FlagControlMulti == 1 )
// continue; /* yes */
// removed because with multiple instances of one schematic
// (several sheets pointing to 1 screen), this will be erroneously be
// toggled.
if( !comp->GetPartRef() )
continue;
// If component is a "multi parts per package" type
if( comp->GetPartRef()->GetUnitCount() > 1 )
{
// test if this reference has already been processed, and if so skip
if( m_ReferencesAlreadyFound.Lookup( ref ) )
continue;
// 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, comp->GetPartRef().get(), aSheetPath );
}
else // entry->GetUnitCount() <= 1 means one part per package
{
LIB_PINS pins; // constructed once here
comp->GetPartRef()->GetPins( pins, comp->GetUnitSelection( aSheetPath ),
comp->GetConvert() );
for( size_t i = 0; i < pins.size(); i++ )
{
LIB_PIN* pin = pins[i];
wxASSERT( pin->Type() == LIB_PIN_T );
addPinToComponentPinList( comp, aSheetPath, pin );
}
}
// Sort pins in m_SortedComponentPinList by pin number
sort( m_SortedComponentPinList.begin(),
m_SortedComponentPinList.end(), sortPinsByNum );
// Remove duplicate Pins in m_SortedComponentPinList
eraseDuplicatePins();
// record the usage of this library component entry.
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
return comp;
// 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, comp->GetPartRef().get(), aSheetPath );
}
return NULL;
else // entry->GetUnitCount() <= 1 means one part per package
{
LIB_PINS pins; // constructed once here
comp->GetPartRef()->GetPins(
pins, comp->GetUnitSelection( aSheetPath ), comp->GetConvert() );
for( size_t i = 0; i < pins.size(); i++ )
{
LIB_PIN* pin = pins[i];
wxASSERT( pin->Type() == LIB_PIN_T );
addPinToComponentPinList( comp, aSheetPath, pin );
}
}
// Sort pins in m_SortedComponentPinList by pin number
sort( m_SortedComponentPinList.begin(), m_SortedComponentPinList.end(), sortPinsByNum );
// Remove duplicate Pins in m_SortedComponentPinList
eraseDuplicatePins();
// record the usage of this library component entry.
m_LibParts.insert( comp->GetPartRef().get() ); // rejects non-unique pointers
}
@ -329,12 +306,9 @@ void NETLIST_EXPORTER::findAllUnitsOfComponent( SCH_COMPONENT* aComponent,
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
if( item->Type() != SCH_COMPONENT_T )
continue;
SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
SCH_COMPONENT* comp2 = static_cast<SCH_COMPONENT*>( item );
ref2 = comp2->GetRef( &sheetList[i] );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2013 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2018 KiCad Developers
* Copyright (C) 1992-2019 KiCad Developers
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -92,6 +92,7 @@ protected:
/// Used to temporarily store and filter the list of pins of a schematic component
/// when generating schematic component data in netlist (comp section). No ownership
/// of members.
/// TODO(snh): Descope this object
NETLIST_OBJECTS m_SortedComponentPinList;
/// Used for "multi parts per package" components,
@ -123,7 +124,7 @@ protected:
* the component is the next actual component after aItem
* (power symbols and virtual components that have their reference starting by '#'are skipped).
*/
SCH_COMPONENT* findNextComponentAndCreatePinList( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );
void CreatePinList( SCH_COMPONENT* aItem, SCH_SHEET_PATH* aSheetPath );
SCH_COMPONENT* findNextComponent( EDA_ITEM* aItem, SCH_SHEET_PATH* aSheetPath );

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2018 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 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
@ -53,7 +53,6 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
wxString StartCmpDesc = StartLine + wxT( "ADD_COM" );
wxString msg;
wxString footprint;
EDA_ITEM* DrawList;
SCH_COMPONENT* component;
wxString title = wxT( "Eeschema " ) + GetBuildVersion();
@ -74,13 +73,16 @@ bool NETLIST_EXPORTER_CADSTAR::WriteNetlist( const wxString& aOutFileName, unsig
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( DrawList = sheetList[i].LastDrawList(); DrawList != NULL; DrawList = DrawList->Next() )
std::vector<SCH_COMPONENT*> cmps;
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
DrawList = component = findNextComponentAndCreatePinList( DrawList, &sheetList[i] );
component = findNextComponent( item, &sheetList[i] );
if( component == NULL )
break;
if( !component )
continue;
CreatePinList( component, &sheetList[i] );
if( !component->GetField( FOOTPRINT )->IsVoid() )
footprint = component->GetField( FOOTPRINT )->GetText();

View File

@ -111,11 +111,8 @@ void NETLIST_EXPORTER_GENERIC::addComponentFields( XNODE* xcomp, SCH_COMPONENT*
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
if( item->Type() != SCH_COMPONENT_T )
continue;
SCH_COMPONENT* comp2 = (SCH_COMPONENT*) item;
wxString ref2 = comp2->GetRef( &sheetList[i] );
@ -215,14 +212,12 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* schItem = sheetList[i].LastDrawList(); schItem; schItem = schItem->Next() )
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
SCH_COMPONENT* comp = findNextComponent( schItem, &sheetList[i] );
SCH_COMPONENT* comp = findNextComponent( item, &sheetList[i] );
if( !comp )
break; // No component left
schItem = comp;
continue;
XNODE* xcomp; // current component being constructed

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 1992-2018 jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-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
@ -72,14 +72,15 @@ bool NETLIST_EXPORTER_ORCADPCB2::WriteNetlist( const wxString& aOutFileName,
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
// Process component attributes
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, &sheetList[i] );
SCH_COMPONENT* comp = findNextComponent( item, &sheetList[i] );
if( !comp )
break;
continue;
item = comp;
CreatePinList( comp, &sheetList[i] );
if( comp->GetPartRef() )
{

View File

@ -287,31 +287,30 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl )
for( unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ )
{
// Process component attributes to find Spice directives
for( EDA_ITEM* item = sheetList[sheet_idx].LastDrawList(); item; item = item->Next() )
for( auto item : sheetList[sheet_idx].LastScreen()->Items().OfType( SCH_COMPONENT_T ) )
{
SCH_COMPONENT* comp = findNextComponentAndCreatePinList( item, &sheetList[sheet_idx] );
SCH_COMPONENT* comp = findNextComponent( item, &sheetList[sheet_idx] );
if( !comp )
break;
item = comp;
continue;
CreatePinList( comp, &sheetList[sheet_idx] );
SPICE_ITEM spiceItem;
spiceItem.m_parent = comp;
// Obtain Spice fields
SCH_FIELD* fieldLibFile = comp->FindField( GetSpiceFieldName( SF_LIB_FILE ) );
SCH_FIELD* fieldSeq = comp->FindField( GetSpiceFieldName( SF_NODE_SEQUENCE ) );
SCH_FIELD* fieldSeq = comp->FindField( GetSpiceFieldName( SF_NODE_SEQUENCE ) );
spiceItem.m_primitive = GetSpiceField( SF_PRIMITIVE, comp, aCtl )[0];
spiceItem.m_model = GetSpiceField( SF_MODEL, comp, aCtl );
spiceItem.m_refName = comp->GetRef( &sheetList[sheet_idx] );
spiceItem.m_model = GetSpiceField( SF_MODEL, comp, aCtl );
spiceItem.m_refName = comp->GetRef( &sheetList[sheet_idx] );
// Duplicate references will result in simulation errors
if( refNames.count( spiceItem.m_refName ) )
{
DisplayError( NULL, wxT( "There are duplicate components. "
"You need to annotate schematics first." ) );
"You need to annotate schematics first." ) );
return false;
}
@ -357,8 +356,8 @@ bool NETLIST_EXPORTER_PSPICE::ProcessNetlist( unsigned aCtl )
while( tkz.HasMoreTokens() )
{
wxString pinIndex = tkz.GetNextToken();
int seq;
wxString pinIndex = tkz.GetNextToken();
int seq;
// Find PinName In Standard List assign Standard List Index to Name:
seq = pinNames.Index( pinIndex );
@ -388,11 +387,8 @@ void NETLIST_EXPORTER_PSPICE::UpdateDirectives( unsigned aCtl )
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
for( auto item : sheetList[i].LastScreen()->Items().OfType( SCH_TEXT_T ) )
{
if( item->Type() != SCH_TEXT_T )
continue;
wxString text = static_cast<SCH_TEXT*>( item )->GetText();
if( text.IsEmpty() )

Some files were not shown because too many files have changed in this diff Show More