mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 02:03:12 +02:00
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:
parent
f3e099a5ca
commit
1a2c84eb76
@ -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()
|
||||
|
@ -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;
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
@ -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 );
|
||||
|
@ -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() );
|
||||
|
@ -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 );
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user