Eeschema: add 'place next unit' action

This makes a new symbol with the lowest unplaced
unit number and enters the PlaceSymbol action
(but only places that one unit)

Fixes: https://gitlab.com/kicad/code/kicad/-/issues/18882
This commit is contained in:
John Beard 2024-10-26 20:43:28 +08:00
parent f3e099a5ca
commit 1a2c84eb76
8 changed files with 153 additions and 7 deletions

View File

@ -423,6 +423,15 @@ TOOL_ACTION EE_ACTIONS::placeSymbol( TOOL_ACTION_ARGS()
.FriendlyName( _( "Place Symbols" ) )
.Icon( BITMAPS::add_component )
.Flags( AF_ACTIVATE )
.Parameter<EE_ACTIONS::PLACE_SYMBOL_PARAMS>( {} ) );
TOOL_ACTION EE_ACTIONS::placeNextSymbolUnit( TOOL_ACTION_ARGS()
.Name( "eeschema.InteractiveDrawing.placeNextSymbolUnit" )
.Scope( AS_GLOBAL )
.FriendlyName( _( "Place Next Symbol Unit" ) )
.Tooltip( _( "Place the next unit of the current symbol that is missing from the schematic" ) )
.Flags( AF_ACTIVATE )
// The symbol to use as a reference for the next unit
.Parameter<SCH_SYMBOL*>( nullptr ) );
TOOL_ACTION EE_ACTIONS::placePower( TOOL_ACTION_ARGS()

View File

@ -27,6 +27,7 @@
#include <tool/tool_action.h>
#include <tool/actions.h>
class SCH_SYMBOL;
class TOOL_EVENT;
class TOOL_MANAGER;
@ -76,6 +77,7 @@ public:
// Schematic Tools
static TOOL_ACTION pickerTool;
static TOOL_ACTION placeSymbol;
static TOOL_ACTION placeNextSymbolUnit;
static TOOL_ACTION placePower;
static TOOL_ACTION placeDesignBlock;
static TOOL_ACTION drawWire;
@ -311,4 +313,12 @@ public:
// Drag and drop
static TOOL_ACTION ddAppendFile;
struct PLACE_SYMBOL_PARAMS
{
///< Provide a symbol to place
SCH_SYMBOL* m_Symbol = nullptr;
///< If a symbol is provide, reannotate it?
bool m_Reannotate = true;
};
};

View File

@ -26,6 +26,8 @@
#include <sch_text.h>
#include <sch_field.h>
#include <sch_pin.h>
#include <sch_reference_list.h>
#include <sch_symbol.h>
#include <sch_table.h>
#include <sch_tablecell.h>
#include <sch_textbox.h>
@ -123,4 +125,36 @@ wxString GetSelectedItemsAsText( const SELECTION& aSel )
}
return wxJoin( itemTexts, '\n', '\0' );
}
std::set<int> GetUnplacedUnitsForSymbol( const SCH_SYMBOL& aSym )
{
SCHEMATIC const* schematic = aSym.Schematic();
const wxString symRefDes = aSym.GetRef( &schematic->CurrentSheet(), false );
if( !schematic )
return {};
SCH_SHEET_LIST hierarchy = schematic->Hierarchy();
// Get a list of all references in the schematic
SCH_REFERENCE_LIST existingRefs;
hierarchy.GetSymbols( existingRefs );
std::set<int> missingUnits;
for( int unit = 1; unit <= aSym.GetUnitCount(); ++unit )
{
missingUnits.insert( unit );
}
for( const SCH_REFERENCE& ref : existingRefs )
{
if( symRefDes == ref.GetRef() )
{
missingUnits.erase( ref.GetUnit() );
}
}
return missingUnits;
}

View File

@ -23,9 +23,16 @@
#pragma once
#include <set>
#include <sch_item.h>
#include <tool/selection.h>
wxString GetSchItemAsText( const SCH_ITEM& aItem );
wxString GetSelectedItemsAsText( const SELECTION& aSel );
wxString GetSelectedItemsAsText( const SELECTION& aSel );
/**
* Get a list of unplaced (i.e. not in schamtic) unit numbers for a symbol.
*/
std::set<int> GetUnplacedUnitsForSymbol( const SCH_SYMBOL& aSym );

View File

@ -36,6 +36,7 @@
#include <gal/graphics_abstraction_layer.h>
#include <design_block_lib_table.h>
#include <ee_actions.h>
#include <ee_tool_utils.h>
#include <sch_edit_frame.h>
#include <pgm_base.h>
#include <design_block.h>
@ -130,7 +131,15 @@ bool SCH_DRAWING_TOOLS::Init()
int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
{
SCH_SYMBOL* symbol = aEvent.Parameter<SCH_SYMBOL*>();
const EE_ACTIONS::PLACE_SYMBOL_PARAMS& toolParams =
aEvent.Parameter<EE_ACTIONS::PLACE_SYMBOL_PARAMS>();
SCH_SYMBOL* symbol = toolParams.m_Symbol;
// If we get an parameterised symbol, we probably just want to place
// that and get out of the placmeent tool, rather than popping the
// chooser afterwards
bool placeOneOnly = symbol != nullptr;
SYMBOL_LIBRARY_FILTER filter;
std::vector<PICKED_SYMBOL>* historyList = nullptr;
bool ignorePrimePosition = false;
@ -253,7 +262,10 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
if( symbol )
{
addSymbol( symbol );
annotate();
if( toolParams.m_Reannotate )
annotate();
getViewControls()->WarpMouseCursor( getViewControls()->GetMousePosition( false ) );
}
else if( aEvent.HasPosition() )
@ -415,6 +427,12 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
commit.Push( _( "Place Symbol" ) );
if( placeOneOnly )
{
m_frame->PopTool( aEvent );
break;
}
SCH_SYMBOL* nextSymbol = nullptr;
if( m_frame->eeconfig()->m_SymChooserPanel.place_all_units
@ -538,6 +556,59 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
}
int SCH_DRAWING_TOOLS::PlaceNextSymbolUnit( const TOOL_EVENT& aEvent )
{
SCH_SYMBOL* symbol = aEvent.Parameter<SCH_SYMBOL*>();
// TODO: get from selection
if( !symbol )
{
static const std::vector<KICAD_T> symbolTypes = { SCH_SYMBOL_T };
EE_SELECTION& selection = m_selectionTool->RequestSelection( symbolTypes );
if( selection.Size() != 1 )
{
m_frame->ShowInfoBarMsg( _( "Select a single symbol to place the next unit." ) );
return 0;
}
wxCHECK( selection.Front()->Type() == SCH_SYMBOL_T, 0 );
symbol = static_cast<SCH_SYMBOL*>( selection.Front() );
}
if( !symbol )
return 0;
if( !symbol->IsMulti() )
{
m_frame->ShowInfoBarMsg( _( "This symbol has only one unit." ) );
return 0;
}
const std::set<int> missingUnits = GetUnplacedUnitsForSymbol( *symbol );
if( missingUnits.empty() )
{
m_frame->ShowInfoBarMsg( _( "All units of this symbol are already placed." ) );
return 0;
}
// Find the lowest unit number that is missing
const int nextMissing = *std::min_element( missingUnits.begin(), missingUnits.end() );
std::unique_ptr<SCH_SYMBOL> newSymbol = std::make_unique<SCH_SYMBOL>( *symbol );
const SCH_SHEET_PATH& sheetPath = m_frame->GetCurrentSheet();
newSymbol->SetUnitProp( nextMissing );
newSymbol->SetRefProp( symbol->GetRef( &sheetPath, false ) );
// Post the new symbol - don't reannotate it - we set the reference ourselves
m_toolMgr->PostAction( EE_ACTIONS::placeSymbol,
EE_ACTIONS::PLACE_SYMBOL_PARAMS{ newSymbol.release(), false } );
return 0;
}
int SCH_DRAWING_TOOLS::ImportSheet( const TOOL_EVENT& aEvent )
{
bool placingDesignBlock = aEvent.IsAction( &EE_ACTIONS::placeDesignBlock );
@ -3197,6 +3268,7 @@ void SCH_DRAWING_TOOLS::setTransitions()
// clang-format off
Go( &SCH_DRAWING_TOOLS::PlaceSymbol, EE_ACTIONS::placeSymbol.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::PlaceSymbol, EE_ACTIONS::placePower.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::PlaceNextSymbolUnit, EE_ACTIONS::placeNextSymbolUnit.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SingleClickPlace, EE_ACTIONS::placeNoConnect.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SingleClickPlace, EE_ACTIONS::placeJunction.MakeEvent() );
Go( &SCH_DRAWING_TOOLS::SingleClickPlace, EE_ACTIONS::placeBusWireEntry.MakeEvent() );

View File

@ -53,6 +53,7 @@ public:
bool Init() override;
int PlaceSymbol( const TOOL_EVENT& aEvent );
int PlaceNextSymbolUnit( const TOOL_EVENT& aEvent );
int SingleClickPlace( const TOOL_EVENT& aEvent );
int TwoClickPlace( const TOOL_EVENT& aEvent );
int ImportSheet( const TOOL_EVENT& aEvent );

View File

@ -29,8 +29,9 @@
#include <tools/sch_line_wire_bus_tool.h>
#include <tools/sch_move_tool.h>
#include <tools/sch_drawing_tools.h>
#include <ee_actions.h>
#include <confirm.h>
#include <ee_actions.h>
#include <ee_tool_utils.h>
#include <increment.h>
#include <string_utils.h>
#include <sch_bitmap.h>
@ -65,6 +66,7 @@
#include <wx/textdlg.h>
#include <project/net_settings.h>
class SYMBOL_UNIT_MENU : public ACTION_MENU
{
public:
@ -92,9 +94,10 @@ private:
wxCHECK( symbol, /* void */ );
int unit = symbol->GetUnit();
const int unit = symbol->GetUnit();
const int nUnits = symbol->GetLibSymbolRef()->GetUnitCount();
for( int ii = 0; ii < symbol->GetLibSymbolRef()->GetUnitCount(); ii++ )
for( int ii = 0; ii < nUnits; ii++ )
{
wxString unit_text;
@ -114,6 +117,15 @@ private:
if( ii >= ( ID_POPUP_SCH_SELECT_UNIT_END - ID_POPUP_SCH_SELECT_UNIT1) )
break; // We have used all IDs for these submenus
}
const std::set<int> missingUnits = GetUnplacedUnitsForSymbol( *symbol );
{
AppendSeparator();
wxMenuItem* item = Add( EE_ACTIONS::placeNextSymbolUnit );
item->Enable( missingUnits.size() );
}
}
};

View File

@ -779,7 +779,8 @@ int SYMBOL_EDITOR_CONTROL::AddSymbolToSchematic( const TOOL_EVENT& aEvent )
symbol->AutoplaceFields( /* aScreen */ nullptr, /* aManual */ false );
schframe->Raise();
schframe->GetToolManager()->PostAction( EE_ACTIONS::placeSymbol, symbol );
schframe->GetToolManager()->PostAction( EE_ACTIONS::placeSymbol,
EE_ACTIONS::PLACE_SYMBOL_PARAMS{ symbol, true } );
}
return 0;