Improve EE_COLLECTOR to not miss children of sheets or symbols.

Also implements pin highlighting and special cases for power symbols.

Fixes https://gitlab.com/kicad/code/kicad/issues/4180
This commit is contained in:
Jeff Young 2020-04-10 14:08:14 +01:00
parent 4bfd5f8197
commit 962aa73e12
4 changed files with 64 additions and 34 deletions

View File

@ -95,7 +95,7 @@ SEARCH_RESULT EE_COLLECTOR::Inspect( EDA_ITEM* aItem, void* aTestData )
void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], const wxPoint& aPos, void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], const wxPoint& aPos,
int aUnit, int aConvert ) int aUnit, int aConvert )
{ {
Empty(); // empty the collection just in case Empty(); // empty the collection just in case
@ -108,9 +108,33 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co
if( aScreen ) if( aScreen )
{ {
// Components and sheets own their own children so have to be visited even if
// they're not in the filter list
bool componentsVisited = false;
bool sheetsVisited = false;
for( const KICAD_T* filter = aFilterList; *filter != EOT; ++filter ) for( const KICAD_T* filter = aFilterList; *filter != EOT; ++filter )
{ {
for( auto item : aScreen->Items().OfType( *filter ) ) for( SCH_ITEM* item : aScreen->Items().OfType( *filter ) )
{
if( *filter == SCH_COMPONENT_T )
componentsVisited = true;
else if( *filter == SCH_SHEET_T )
sheetsVisited = true;
item->Visit( m_inspector, nullptr, m_ScanTypes );
}
}
if( !componentsVisited )
{
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_COMPONENT_T ) )
item->Visit( m_inspector, nullptr, m_ScanTypes );
}
if( !sheetsVisited )
{
for( SCH_ITEM* item : aScreen->Items().OfType( SCH_SHEET_T ) )
item->Visit( m_inspector, nullptr, m_ScanTypes ); item->Visit( m_inspector, nullptr, m_ScanTypes );
} }
} }
@ -118,7 +142,7 @@ void EE_COLLECTOR::Collect( SCH_SCREEN* aScreen, const KICAD_T aFilterList[], co
void EE_COLLECTOR::Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterList[], void EE_COLLECTOR::Collect( LIB_ITEMS_CONTAINER& aItems, const KICAD_T aFilterList[],
const wxPoint& aPos, int aUnit, int aConvert ) const wxPoint& aPos, int aUnit, int aConvert )
{ {
Empty(); // empty the collection just in case Empty(); // empty the collection just in case
@ -158,16 +182,6 @@ bool EE_COLLECTOR::IsCorner() const
} }
bool EE_COLLECTOR::IsDraggableJunction() const
{
for( size_t i = 0; i < m_List.size(); i++ )
if( ( (SCH_ITEM*) m_List[ i ] )->Type() == SCH_JUNCTION_T )
return true;
return false;
}
void CollectOtherUnits( SCH_SHEET_PATH& aSheet, SCH_COMPONENT* aUnit, void CollectOtherUnits( SCH_SHEET_PATH& aSheet, SCH_COMPONENT* aUnit,
std::vector<SCH_COMPONENT*>* otherUnits ) std::vector<SCH_COMPONENT*>* otherUnits )
{ {

View File

@ -105,21 +105,6 @@ public:
*/ */
bool IsCorner() const; bool IsCorner() const;
/**
* Function IsDraggableJunction
* tests to see if the collected items form a draggable junction.
* <p>
* Daggable junctions are defined as:
* <ul>
* <li> The intersection of three or more wire end points. </li>
* <li> The intersection of one or more wire end point and one wire mid point. </li>
* <li> The crossing of two or more wire mid points and a junction. </li>
* </ul>
* </p>
* @return True if the collection is a draggable junction.
*/
bool IsDraggableJunction() const;
public: public:
int m_Unit; // Fixed symbol unit filter (for symbol editor) int m_Unit; // Fixed symbol unit filter (for symbol editor)
int m_Convert; // Fixed DeMorgan filter (for symbol editor) int m_Convert; // Fixed DeMorgan filter (for symbol editor)

View File

@ -788,6 +788,7 @@ bool EE_SELECTION_TOOL::selectMultiple()
static KICAD_T nodeTypes[] = static KICAD_T nodeTypes[] =
{ {
SCH_PIN_T,
SCH_LINE_LOCATE_WIRE_T, SCH_LINE_LOCATE_WIRE_T,
SCH_LINE_LOCATE_BUS_T, SCH_LINE_LOCATE_BUS_T,
SCH_BUS_WIRE_ENTRY_T, SCH_BUS_WIRE_ENTRY_T,

View File

@ -711,9 +711,12 @@ static bool highlightNet( TOOL_MANAGER* aToolMgr, const VECTOR2D& aPosition )
} }
else else
{ {
SCH_ITEM* item = (SCH_ITEM*) selTool->GetNode( aPosition ); SCH_ITEM* item = static_cast<SCH_ITEM*>( selTool->GetNode( aPosition ) );
SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( item );
if( item && item->Connection( *g_CurrentSheet ) ) if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
netName = comp->GetPartRef()->GetName();
else if( item && item->Connection( *g_CurrentSheet ) )
netName = item->Connection( *g_CurrentSheet )->Name(); netName = item->Connection( *g_CurrentSheet )->Name();
} }
} }
@ -768,10 +771,26 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
for( SCH_ITEM* item : screen->Items() ) for( SCH_ITEM* item : screen->Items() )
{ {
SCH_CONNECTION* conn = item->Connection( *g_CurrentSheet ); wxString itemConnectionName;
SCH_COMPONENT* comp = nullptr;
bool redraw = item->IsBrightened(); bool redraw = item->IsBrightened();
if( conn && conn->Name() == selectedNetName ) if( item->Type() == SCH_COMPONENT_T )
comp = static_cast<SCH_COMPONENT*>( item );
if( comp && comp->GetPartRef() && comp->GetPartRef()->IsPower() )
{
itemConnectionName = comp->GetPartRef()->GetName();
}
else
{
SCH_CONNECTION* connection = item->Connection( *g_CurrentSheet );
if( connection )
itemConnectionName = connection->Name();
}
if( itemConnectionName == selectedNetName )
item->SetBrightened(); item->SetBrightened();
else else
item->ClearBrightened(); item->ClearBrightened();
@ -780,8 +799,6 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
if( item->Type() == SCH_COMPONENT_T ) if( item->Type() == SCH_COMPONENT_T )
{ {
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( item );
redraw |= comp->HasBrightenedPins(); redraw |= comp->HasBrightenedPins();
comp->ClearBrightenedPins(); comp->ClearBrightenedPins();
@ -798,6 +815,19 @@ int SCH_EDITOR_CONTROL::UpdateNetHighlighting( const TOOL_EVENT& aEvent )
redraw = true; redraw = true;
} }
} }
if( comp->GetPartRef() && comp->GetPartRef()->IsPower() )
{
std::vector<SCH_FIELD>& fields = comp->GetFields();
for( int id : { REFERENCE, VALUE } )
{
if( item->IsBrightened() && fields[id].IsVisible() )
fields[id].SetBrightened();
else
fields[id].ClearBrightened();
}
}
} }
else if( item->Type() == SCH_SHEET_T ) else if( item->Type() == SCH_SHEET_T )
{ {