7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-07 18:25:31 +00:00

Eeschema: Import and auto place all sheet pins

https://gitlab.com/kicad/code/kicad/-/issues/6736
This commit is contained in:
Dhineshkumar S 2025-02-26 21:24:02 +00:00 committed by Seth Hillbrand
parent 797de67c6c
commit 20c72504c3
5 changed files with 137 additions and 0 deletions

View File

@ -546,6 +546,12 @@ TOOL_ACTION EE_ACTIONS::placeSheetPin( TOOL_ACTION_ARGS()
.Icon( BITMAPS::add_hierar_pin )
.Flags( AF_ACTIVATE ) );
TOOL_ACTION EE_ACTIONS::autoplaceAllSheetPins( TOOL_ACTION_ARGS()
.Name( "eeschema.InteractiveDrawing.autoplaceAllSheetPins" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Autoplace All Sheet Pins" ) )
.Tooltip( _( "Imports and auto places all sheet pins" ) ) );
TOOL_ACTION EE_ACTIONS::syncSheetPins( TOOL_ACTION_ARGS()
.Name( "eeschema.InteractiveDrawing.syncSheetPins" )
.Scope( AS_GLOBAL )

View File

@ -94,6 +94,7 @@ public:
static TOOL_ACTION drawSheetFromFile;
static TOOL_ACTION drawSheetFromDesignBlock;
static TOOL_ACTION placeSheetPin;
static TOOL_ACTION autoplaceAllSheetPins;
static TOOL_ACTION importSheet;
// Sync sheet pins for selected sheet symbol
static TOOL_ACTION syncSheetPins;

View File

@ -325,6 +325,7 @@ bool EE_SELECTION_TOOL::Init()
menu.AddItem( EE_ACTIONS::breakWire, linesSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::slice, linesSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::placeSheetPin, sheetSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::autoplaceAllSheetPins, sheetSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::syncSheetPins, sheetSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::assignNetclass, connectedSelection && EE_CONDITIONS::Idle, 250 );
menu.AddItem( EE_ACTIONS::editPageNumber, schEditSheetPageNumberCondition, 250 );

View File

@ -3296,6 +3296,110 @@ int SCH_DRAWING_TOOLS::SyncSheetsPins( const TOOL_EVENT& aEvent )
}
int SCH_DRAWING_TOOLS::AutoPlaceAllSheetPins( const TOOL_EVENT& aEvent )
{
if( m_inDrawingTool )
return 0;
REENTRANCY_GUARD guard( &m_inDrawingTool );
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( m_selectionTool->GetSelection().Front() );
std::vector<SCH_HIERLABEL*> labels = importHierLabels( sheet );
if( labels.empty() )
{
m_frame->PushTool( aEvent );
m_statusPopup = std::make_unique<STATUS_TEXT_POPUP>( m_frame );
m_statusPopup->SetText( _( "No new hierarchical labels found." ) );
m_statusPopup->Move( KIPLATFORM::UI::GetMousePosition() + wxPoint( 20, 20 ) );
m_statusPopup->PopupFor( 2000 );
m_frame->PopTool( aEvent );
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
m_view->ClearPreview();
return 0;
}
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
SCH_COMMIT commit( m_toolMgr );
BOX2I boundingBox = sheet->GetBoundingBox();
VECTOR2I cursorPos = boundingBox.GetPosition();
SCH_ITEM* lastPlacedLabel = nullptr;
auto calculatePositionForLabel = [&]( const SCH_ITEM* lastLabel,
const SCH_HIERLABEL* currentLabel ) -> VECTOR2I
{
if( !lastLabel )
return cursorPos;
int lastX = lastLabel->GetPosition().x;
int lastY = lastLabel->GetPosition().y;
int lastWidth = lastLabel->GetBoundingBox().GetWidth();
int lastHeight = lastLabel->GetBoundingBox().GetHeight();
int currentWidth = currentLabel->GetBoundingBox().GetWidth();
int currentHeight = currentLabel->GetBoundingBox().GetHeight();
// If there is enough space, place the label to the right of the last placed label
if( ( lastX + lastWidth + currentWidth )
<= ( boundingBox.GetPosition().x + boundingBox.GetSize().x ) )
return { lastX + lastWidth, lastY };
// If not enough space to the right, move to the next row if vertical space allows
if( ( lastY + lastHeight + currentHeight )
<= ( boundingBox.GetPosition().y + boundingBox.GetSize().y ) )
return { boundingBox.GetPosition().x, lastY + lastHeight };
return cursorPos;
};
for( SCH_HIERLABEL* label : labels )
{
if( !lastPlacedLabel )
{
std::vector<SCH_SHEET_PIN*> existingPins = sheet->GetPins();
if( !existingPins.empty() )
{
std::sort( existingPins.begin(), existingPins.end(),
[]( const SCH_ITEM* a, const SCH_ITEM* b )
{
return ( a->GetPosition().x < b->GetPosition().x )
|| ( a->GetPosition().x == b->GetPosition().x
&& a->GetPosition().y < b->GetPosition().y );
} );
lastPlacedLabel = existingPins.back();
}
}
cursorPos = calculatePositionForLabel( lastPlacedLabel, label );
SCH_ITEM* item = createNewSheetPinFromLabel( sheet, cursorPos, label );
if( item )
{
item->SetFlags( IS_NEW | IS_MOVING );
item->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
item->ClearFlags( IS_MOVING );
if( item->IsConnectable() )
m_frame->AutoRotateItem( m_frame->GetScreen(), item );
commit.Modify( sheet, m_frame->GetScreen() );
sheet->AddPin( static_cast<SCH_SHEET_PIN*>( item ) );
item->AutoplaceFields( m_frame->GetScreen(), AUTOPLACE_AUTO );
commit.Push( _( "Add Sheet Pin" ) );
lastPlacedLabel = item;
}
}
return 0;
}
int SCH_DRAWING_TOOLS::SyncAllSheetsPins( const TOOL_EVENT& aEvent )
{
static const std::function<void( std::list<SCH_SHEET_PATH>&, SCH_SCREEN*,
@ -3364,6 +3468,27 @@ SCH_HIERLABEL* SCH_DRAWING_TOOLS::importHierLabel( SCH_SHEET* aSheet )
}
std::vector<SCH_HIERLABEL*> SCH_DRAWING_TOOLS::importHierLabels( SCH_SHEET* aSheet )
{
if( !aSheet->GetScreen() )
return {};
std::vector<SCH_HIERLABEL*> labels;
for( EDA_ITEM* item : aSheet->GetScreen()->Items().OfType( SCH_HIER_LABEL_T ) )
{
SCH_HIERLABEL* label = static_cast<SCH_HIERLABEL*>( item );
if( !aSheet->HasPin( label->GetText() ) )
{
labels.push_back( label );
}
}
return labels;
}
void SCH_DRAWING_TOOLS::setTransitions()
{
// clang-format off
@ -3395,5 +3520,6 @@ void SCH_DRAWING_TOOLS::setTransitions()
Go( &SCH_DRAWING_TOOLS::ImportGraphics, EE_ACTIONS::importGraphics.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SyncSheetsPins, EE_ACTIONS::syncSheetPins.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SyncAllSheetsPins, EE_ACTIONS::syncAllSheetsPins.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::AutoPlaceAllSheetPins, EE_ACTIONS::autoplaceAllSheetPins.MakeEvent() );
// clang-format on
}

View File

@ -65,6 +65,7 @@ public:
int ImportGraphics( const TOOL_EVENT& aEvent );
int SyncSheetsPins( const TOOL_EVENT& aEvent );
int SyncAllSheetsPins( const TOOL_EVENT& aEvent );
int AutoPlaceAllSheetPins( const TOOL_EVENT& aEvent );
private:
SCH_LINE* findWire( const VECTOR2I& aPosition );
@ -89,6 +90,8 @@ private:
///< Try finding any hierlabel that does not have a sheet pin associated with it
SCH_HIERLABEL* importHierLabel( SCH_SHEET* aSheet );
std::vector<SCH_HIERLABEL*> importHierLabels( SCH_SHEET* aSheet );
std::vector<PICKED_SYMBOL> m_symbolHistoryList;
std::vector<PICKED_SYMBOL> m_powerHistoryList;
std::vector<LIB_ID> m_designBlockHistoryList;