Improve repeat-last-item to handle unfold-from-bus.
Fixes https://gitlab.com/kicad/code/kicad/issues/12018
This commit is contained in:
parent
4973816f90
commit
b2a29e08a4
|
@ -112,8 +112,7 @@ END_EVENT_TABLE()
|
|||
SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
|
||||
SCH_BASE_FRAME( aKiway, aParent, FRAME_SCH, wxT( "Eeschema" ), wxDefaultPosition,
|
||||
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
|
||||
m_highlightedConn( nullptr ),
|
||||
m_item_to_repeat( nullptr )
|
||||
m_highlightedConn( nullptr )
|
||||
{
|
||||
m_maximizeByDefault = true;
|
||||
m_schematic = new SCHEMATIC( nullptr );
|
||||
|
@ -298,8 +297,6 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
|
|||
m_toolManager = nullptr;
|
||||
}
|
||||
|
||||
delete m_item_to_repeat; // we own the cloned object, see this->SaveCopyForRepeatItem()
|
||||
|
||||
SetScreen( nullptr );
|
||||
|
||||
delete m_schematic;
|
||||
|
@ -590,12 +587,27 @@ void SCH_EDIT_FRAME::SaveCopyForRepeatItem( const SCH_ITEM* aItem )
|
|||
|
||||
if( aItem )
|
||||
{
|
||||
delete m_item_to_repeat;
|
||||
m_items_to_repeat.clear();
|
||||
|
||||
m_item_to_repeat = (SCH_ITEM*) aItem->Clone();
|
||||
AddCopyForRepeatItem( aItem );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_EDIT_FRAME::AddCopyForRepeatItem( const SCH_ITEM* aItem )
|
||||
{
|
||||
// we cannot store a pointer to an item in the display list here since
|
||||
// that item may be deleted, such as part of a line concatenation or other.
|
||||
// So simply always keep a copy of the object which is to be repeated.
|
||||
|
||||
if( aItem )
|
||||
{
|
||||
std::unique_ptr<SCH_ITEM> repeatItem( static_cast<SCH_ITEM*>( aItem->Clone() ) );
|
||||
|
||||
// Clone() preserves the flags, we want 'em cleared.
|
||||
m_item_to_repeat->ClearFlags();
|
||||
repeatItem->ClearFlags();
|
||||
|
||||
m_items_to_repeat.emplace_back( std::move( repeatItem ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -682,13 +682,16 @@ public:
|
|||
* Clone \a aItem and owns that clone in this container.
|
||||
*/
|
||||
void SaveCopyForRepeatItem( const SCH_ITEM* aItem );
|
||||
void AddCopyForRepeatItem( const SCH_ITEM* aItem );
|
||||
|
||||
/**
|
||||
* Return the item which is to be repeated with the insert key.
|
||||
*
|
||||
* Such object is owned by this container, and must be cloned.
|
||||
* Return the items which are to be repeated with the insert key. Such objects are owned by
|
||||
* this container, and must be cloned.
|
||||
*/
|
||||
SCH_ITEM* GetRepeatItem() const { return m_item_to_repeat; }
|
||||
const std::vector<std::unique_ptr<SCH_ITEM>>& GetRepeatItems() const
|
||||
{
|
||||
return m_items_to_repeat;
|
||||
}
|
||||
|
||||
EDA_ITEM* GetItem( const KIID& aId ) const override;
|
||||
|
||||
|
@ -914,7 +917,8 @@ private:
|
|||
const SCH_CONNECTION* m_highlightedConn; ///< The highlighted net or bus, or nullptr
|
||||
|
||||
wxPageSetupDialogData m_pageSetupData;
|
||||
SCH_ITEM* m_item_to_repeat; ///< Last item to insert by the repeat command.
|
||||
std::vector<std::unique_ptr<SCH_ITEM>> m_items_to_repeat; ///< For the repeat-last-item cmd
|
||||
|
||||
wxString m_netListerCommand; ///< Command line to call a custom net list
|
||||
///< generator.
|
||||
int m_exec_flags; ///< Flags of the wxExecute() function
|
||||
|
|
|
@ -979,25 +979,19 @@ int SCH_EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
|
||||
int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
SCH_ITEM* sourceItem = m_frame->GetRepeatItem();
|
||||
const std::vector<std::unique_ptr<SCH_ITEM>>& sourceItems = m_frame->GetRepeatItems();
|
||||
|
||||
if( !sourceItem )
|
||||
if( sourceItems.empty() )
|
||||
return 0;
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
|
||||
|
||||
SCH_ITEM* newItem = sourceItem->Duplicate();
|
||||
bool performDrag = false;
|
||||
bool appendUndo = false;
|
||||
EE_SELECTION newItems;
|
||||
|
||||
// If cloning a symbol then put into 'move' mode.
|
||||
if( newItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
|
||||
newItem->Move( cursorPos - newItem->GetPosition() );
|
||||
performDrag = true;
|
||||
}
|
||||
else
|
||||
for( const std::unique_ptr<SCH_ITEM>& item : sourceItems )
|
||||
{
|
||||
SCH_ITEM* newItem = item->Duplicate();
|
||||
EESCHEMA_SETTINGS* cfg = Pgm().GetSettingsManager().GetAppSettings<EESCHEMA_SETTINGS>();
|
||||
|
||||
if( SCH_LABEL_BASE* label = dynamic_cast<SCH_LABEL_BASE*>( newItem ) )
|
||||
|
@ -1008,45 +1002,51 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
|||
m_frame->ShowInfoBarWarning( _( "Label value cannot go below zero" ), true );
|
||||
}
|
||||
|
||||
newItem->Move( VECTOR2I( Mils2iu( cfg->m_Drawing.default_repeat_offset_x ),
|
||||
Mils2iu( cfg->m_Drawing.default_repeat_offset_y ) ) );
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem );
|
||||
newItem->SetFlags( IS_NEW );
|
||||
m_frame->AddToScreen( newItem, m_frame->GetScreen() );
|
||||
m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, false );
|
||||
|
||||
if( newItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
EESCHEMA_SETTINGS::PANEL_ANNOTATE& annotate = m_frame->eeconfig()->m_AnnotatePanel;
|
||||
SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
|
||||
int annotateStartNum = projSettings.m_AnnotateStartNum;
|
||||
|
||||
if( annotate.automatic )
|
||||
// If cloning a symbol then put into 'move' mode.
|
||||
if( newItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
|
||||
NULL_REPORTER reporter;
|
||||
m_frame->AnnotateSymbols( ANNOTATE_SELECTION, (ANNOTATE_ORDER_T) annotate.sort_order,
|
||||
(ANNOTATE_ALGO_T) annotate.method, annotate.recursive,
|
||||
annotateStartNum, false, false, reporter, true );
|
||||
VECTOR2I cursorPos = getViewControls()->GetCursorPosition( true );
|
||||
newItem->Move( cursorPos - newItem->GetPosition() );
|
||||
}
|
||||
else
|
||||
{
|
||||
newItem->Move( VECTOR2I( Mils2iu( cfg->m_Drawing.default_repeat_offset_x ),
|
||||
Mils2iu( cfg->m_Drawing.default_repeat_offset_y ) ) );
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addItemToSel, true, newItem );
|
||||
newItem->SetFlags( IS_NEW );
|
||||
m_frame->AddToScreen( newItem, m_frame->GetScreen() );
|
||||
m_frame->SaveCopyInUndoList( m_frame->GetScreen(), newItem, UNDO_REDO::NEWITEM, appendUndo );
|
||||
appendUndo = true;
|
||||
|
||||
if( newItem->Type() == SCH_SYMBOL_T )
|
||||
{
|
||||
EESCHEMA_SETTINGS::PANEL_ANNOTATE& annotate = m_frame->eeconfig()->m_AnnotatePanel;
|
||||
SCHEMATIC_SETTINGS& projSettings = m_frame->Schematic().Settings();
|
||||
int annotateStartNum = projSettings.m_AnnotateStartNum;
|
||||
|
||||
if( annotate.automatic )
|
||||
{
|
||||
static_cast<SCH_SYMBOL*>( newItem )->ClearAnnotation( nullptr, false );
|
||||
NULL_REPORTER reporter;
|
||||
m_frame->AnnotateSymbols( ANNOTATE_SELECTION, (ANNOTATE_ORDER_T) annotate.sort_order,
|
||||
(ANNOTATE_ALGO_T) annotate.method, annotate.recursive,
|
||||
annotateStartNum, false, false, reporter, appendUndo );
|
||||
}
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::move, true );
|
||||
}
|
||||
|
||||
newItems.Add( newItem );
|
||||
|
||||
newItem->ClearFlags();
|
||||
}
|
||||
|
||||
// Symbols need to be handled by the move tool. The move tool will handle schematic
|
||||
// cleanup routines
|
||||
if( performDrag )
|
||||
m_toolMgr->RunAction( EE_ACTIONS::move, true );
|
||||
|
||||
newItem->ClearFlags();
|
||||
|
||||
if( !performDrag && newItem->IsConnectable() )
|
||||
if( !newItems.Empty() )
|
||||
{
|
||||
EE_SELECTION new_sel;
|
||||
new_sel.Add( newItem );
|
||||
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &new_sel );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &new_sel );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::trimOverlappingWires, true, &newItems );
|
||||
m_toolMgr->RunAction( EE_ACTIONS::addNeededJunctions, true, &newItems );
|
||||
|
||||
m_frame->RecalculateConnections( LOCAL_CLEANUP );
|
||||
m_frame->TestDanglingEnds();
|
||||
|
@ -1055,8 +1055,11 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
|
|||
m_frame->GetCanvas()->Refresh();
|
||||
m_frame->OnModify();
|
||||
|
||||
// Save newItem at the new position.
|
||||
m_frame->SaveCopyForRepeatItem( newItem );
|
||||
if( !newItems.Empty() )
|
||||
m_frame->SaveCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[0] ) );
|
||||
|
||||
for( size_t ii = 1; ii < newItems.GetSize(); ++ii )
|
||||
m_frame->AddCopyForRepeatItem( static_cast<SCH_ITEM*>( newItems[ii] ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -376,7 +376,9 @@ int SCH_LINE_WIRE_BUS_TOOL::UnfoldBus( const TOOL_EVENT& aEvent )
|
|||
|
||||
// If we have an unfolded wire to draw, then draw it
|
||||
if( segment )
|
||||
{
|
||||
return doDrawSegments( tool, LAYER_WIRE, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame->PopTool( tool );
|
||||
|
@ -1151,6 +1153,7 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
|
|||
if( IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), pt ) )
|
||||
new_ends.push_back( pt );
|
||||
}
|
||||
|
||||
itemList.PushItem( ITEM_PICKER( screen, wire, UNDO_REDO::NEWITEM ) );
|
||||
}
|
||||
|
||||
|
@ -1159,13 +1162,23 @@ void SCH_LINE_WIRE_BUS_TOOL::finishSegments()
|
|||
wxASSERT( m_busUnfold.entry && m_busUnfold.label );
|
||||
|
||||
itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.entry, UNDO_REDO::NEWITEM ) );
|
||||
m_frame->SaveCopyForRepeatItem( m_busUnfold.entry );
|
||||
|
||||
itemList.PushItem( ITEM_PICKER( screen, m_busUnfold.label, UNDO_REDO::NEWITEM ) );
|
||||
m_frame->AddCopyForRepeatItem( m_busUnfold.label );
|
||||
m_busUnfold.label->ClearEditFlags();
|
||||
}
|
||||
else if( !m_wires.empty() )
|
||||
{
|
||||
m_frame->SaveCopyForRepeatItem( m_wires[0] );
|
||||
}
|
||||
|
||||
for( size_t ii = 1; ii < m_wires.size(); ++ii )
|
||||
m_frame->AddCopyForRepeatItem( m_wires[ii] );
|
||||
|
||||
// Get the last non-null wire (this is the last created segment).
|
||||
if( !m_wires.empty() )
|
||||
m_frame->SaveCopyForRepeatItem( m_wires.back() );
|
||||
m_frame->AddCopyForRepeatItem( m_wires.back() );
|
||||
|
||||
// Add the new wires
|
||||
for( SCH_LINE* wire : m_wires )
|
||||
|
|
Loading…
Reference in New Issue