Support synchronous move in symbol editor.
Also removes duplicate-during-move. It's not really compatibile with a passed-in SCH_COMMIT, and it was never clear it was worth the code. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14274
This commit is contained in:
parent
632e94ef81
commit
4cbf512461
|
@ -407,6 +407,7 @@ void SCH_COMMIT::revertLibEdit()
|
||||||
// Symbol editor just saves copies of the whole symbol, so grab the first and discard the rest
|
// Symbol editor just saves copies of the whole symbol, so grab the first and discard the rest
|
||||||
SYMBOL_EDIT_FRAME* frame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_toolMgr->GetToolHolder() );
|
SYMBOL_EDIT_FRAME* frame = dynamic_cast<SYMBOL_EDIT_FRAME*>( m_toolMgr->GetToolHolder() );
|
||||||
LIB_SYMBOL* copy = dynamic_cast<LIB_SYMBOL*>( m_changes.front().m_copy );
|
LIB_SYMBOL* copy = dynamic_cast<LIB_SYMBOL*>( m_changes.front().m_copy );
|
||||||
|
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
|
||||||
|
|
||||||
if( frame && copy )
|
if( frame && copy )
|
||||||
{
|
{
|
||||||
|
@ -417,6 +418,9 @@ void SCH_COMMIT::revertLibEdit()
|
||||||
for( size_t ii = 1; ii < m_changes.size(); ++ii )
|
for( size_t ii = 1; ii < m_changes.size(); ++ii )
|
||||||
delete m_changes[ii].m_copy;
|
delete m_changes[ii].m_copy;
|
||||||
|
|
||||||
|
if( selTool )
|
||||||
|
selTool->RebuildSelection();
|
||||||
|
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -471,7 +471,6 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
||||||
}
|
}
|
||||||
|
|
||||||
bool restore_state = false;
|
bool restore_state = false;
|
||||||
bool chain_commands = false;
|
|
||||||
TOOL_EVENT copy = aEvent;
|
TOOL_EVENT copy = aEvent;
|
||||||
TOOL_EVENT* evt = ©
|
TOOL_EVENT* evt = ©
|
||||||
VECTOR2I prevPos;
|
VECTOR2I prevPos;
|
||||||
|
@ -842,19 +841,7 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::duplicate ) )
|
else if( evt->IsAction( &ACTIONS::duplicate ) )
|
||||||
{
|
{
|
||||||
if( selection.Front()->IsNew() )
|
|
||||||
{
|
|
||||||
// This doesn't really make sense; we'll just end up dragging a stack of
|
|
||||||
// objects so we ignore the duplicate and just carry on.
|
|
||||||
wxBell();
|
wxBell();
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move original back and exit. The duplicate will run in its own loop.
|
|
||||||
restore_state = true;
|
|
||||||
unselect = false;
|
|
||||||
chain_commands = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &EE_ACTIONS::rotateCW ) )
|
else if( evt->IsAction( &EE_ACTIONS::rotateCW ) )
|
||||||
{
|
{
|
||||||
|
@ -939,9 +926,7 @@ bool SCH_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aComm
|
||||||
controls->ShowCursor( false );
|
controls->ShowCursor( false );
|
||||||
controls->SetAutoPan( false );
|
controls->SetAutoPan( false );
|
||||||
|
|
||||||
if( !chain_commands )
|
|
||||||
m_moveOffset = { 0, 0 };
|
m_moveOffset = { 0, 0 };
|
||||||
|
|
||||||
m_anchorPos.reset();
|
m_anchorPos.reset();
|
||||||
|
|
||||||
if( restore_state )
|
if( restore_state )
|
||||||
|
|
|
@ -103,7 +103,6 @@ private:
|
||||||
///< Lines changed by drag algorithm that weren't selected
|
///< Lines changed by drag algorithm that weren't selected
|
||||||
std::unordered_set<SCH_LINE*> m_changedDragLines;
|
std::unordered_set<SCH_LINE*> m_changedDragLines;
|
||||||
|
|
||||||
///< Used for chaining commands
|
|
||||||
VECTOR2I m_moveOffset;
|
VECTOR2I m_moveOffset;
|
||||||
|
|
||||||
///< Last cursor position (needed for getModificationPoint() to avoid changes
|
///< Last cursor position (needed for getModificationPoint() to avoid changes
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
* Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -34,8 +34,7 @@
|
||||||
|
|
||||||
SYMBOL_EDITOR_MOVE_TOOL::SYMBOL_EDITOR_MOVE_TOOL() :
|
SYMBOL_EDITOR_MOVE_TOOL::SYMBOL_EDITOR_MOVE_TOOL() :
|
||||||
EE_TOOL_BASE( "eeschema.SymbolMoveTool" ),
|
EE_TOOL_BASE( "eeschema.SymbolMoveTool" ),
|
||||||
m_moveInProgress( false ),
|
m_moveInProgress( false )
|
||||||
m_moveOffset( 0, 0 )
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,21 +80,39 @@ void SYMBOL_EDITOR_MOVE_TOOL::Reset( RESET_REASON aReason )
|
||||||
EE_TOOL_BASE::Reset( aReason );
|
EE_TOOL_BASE::Reset( aReason );
|
||||||
|
|
||||||
if( aReason == MODEL_RELOAD )
|
if( aReason == MODEL_RELOAD )
|
||||||
{
|
|
||||||
m_moveInProgress = false;
|
m_moveInProgress = false;
|
||||||
m_moveOffset = { 0, 0 };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
if( SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() ) )
|
||||||
SCH_COMMIT localCommit( m_toolMgr );
|
{
|
||||||
SCH_COMMIT* commit = dynamic_cast<SCH_COMMIT*>( aEvent.Commit() );
|
wxCHECK( aEvent.SynchronousState(), 0 );
|
||||||
|
aEvent.SynchronousState()->store( STS_RUNNING );
|
||||||
|
|
||||||
if( !commit )
|
if( doMoveSelection( aEvent, commit ) )
|
||||||
commit = &localCommit;
|
aEvent.SynchronousState()->store( STS_FINISHED );
|
||||||
|
else
|
||||||
|
aEvent.SynchronousState()->store( STS_CANCELLED );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCH_COMMIT localCommit( m_toolMgr );
|
||||||
|
|
||||||
|
if( doMoveSelection( aEvent, &localCommit ) )
|
||||||
|
localCommit.Push( _( "Move" ) );
|
||||||
|
else
|
||||||
|
localCommit.Revert();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SYMBOL_EDITOR_MOVE_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aCommit )
|
||||||
|
{
|
||||||
|
KIGFX::VIEW_CONTROLS* controls = getViewControls();
|
||||||
|
|
||||||
m_anchorPos = { 0, 0 };
|
m_anchorPos = { 0, 0 };
|
||||||
|
|
||||||
|
@ -107,13 +124,13 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
bool unselect = selection.IsHover();
|
bool unselect = selection.IsHover();
|
||||||
|
|
||||||
if( !m_frame->IsSymbolEditable() || selection.Empty() )
|
if( !m_frame->IsSymbolEditable() || selection.Empty() )
|
||||||
return 0;
|
return false;
|
||||||
|
|
||||||
if( m_moveInProgress )
|
if( m_moveInProgress )
|
||||||
{
|
{
|
||||||
// The tool hotkey is interpreted as a click when already moving
|
// The tool hotkey is interpreted as a click when already moving
|
||||||
m_toolMgr->RunAction( ACTIONS::cursorClick );
|
m_toolMgr->RunAction( ACTIONS::cursorClick );
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame->PushTool( aEvent );
|
m_frame->PushTool( aEvent );
|
||||||
|
@ -124,13 +141,13 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
controls->SetAutoPan( true );
|
controls->SetAutoPan( true );
|
||||||
|
|
||||||
bool restore_state = false;
|
bool restore_state = false;
|
||||||
bool chain_commands = false;
|
|
||||||
TOOL_EVENT copy = aEvent;
|
TOOL_EVENT copy = aEvent;
|
||||||
TOOL_EVENT* evt = ©
|
TOOL_EVENT* evt = ©
|
||||||
VECTOR2I prevPos;
|
VECTOR2I prevPos;
|
||||||
|
VECTOR2I moveOffset;
|
||||||
|
|
||||||
if( !selection.Front()->IsNew() )
|
if( !selection.Front()->IsNew() )
|
||||||
commit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen() );
|
aCommit->Modify( m_frame->GetCurSymbol(), m_frame->GetScreen() );
|
||||||
|
|
||||||
m_cursor = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
|
m_cursor = controls->GetCursorPosition( !aEvent.DisableGridSnapping() );
|
||||||
|
|
||||||
|
@ -195,7 +212,7 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
// Apply any initial offset in case we're coming from a previous command.
|
// Apply any initial offset in case we're coming from a previous command.
|
||||||
//
|
//
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
moveItem( item, m_moveOffset );
|
moveItem( item, moveOffset );
|
||||||
|
|
||||||
// Set up the starting position and move/drag offset
|
// Set up the starting position and move/drag offset
|
||||||
//
|
//
|
||||||
|
@ -243,7 +260,7 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
VECTOR2I delta( m_cursor - prevPos );
|
VECTOR2I delta( m_cursor - prevPos );
|
||||||
m_anchorPos = m_cursor;
|
m_anchorPos = m_cursor;
|
||||||
|
|
||||||
m_moveOffset += delta;
|
moveOffset += delta;
|
||||||
prevPos = m_cursor;
|
prevPos = m_cursor;
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
|
@ -275,32 +292,14 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
unselect = true;
|
unselect = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( evt->Category() == TC_COMMAND )
|
else if( evt->IsAction( &ACTIONS::doDelete ) )
|
||||||
{
|
|
||||||
if( evt->IsAction( &ACTIONS::doDelete ) )
|
|
||||||
{
|
{
|
||||||
// Exit on a remove operation; there is no further processing for removed items.
|
// Exit on a remove operation; there is no further processing for removed items.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::duplicate ) )
|
else if( evt->IsAction( &ACTIONS::duplicate ) )
|
||||||
{
|
{
|
||||||
if( selection.Front()->IsNew() )
|
wxBell();
|
||||||
{
|
|
||||||
// This doesn't really make sense; we'll just end up dragging a stack of
|
|
||||||
// objects so Duplicate() is going to ignore this and we'll just carry on.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move original back and exit. The duplicate will run in its own loop.
|
|
||||||
restore_state = true;
|
|
||||||
unselect = false;
|
|
||||||
chain_commands = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
evt->SetPassEvent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Handle context menu
|
// Handle context menu
|
||||||
|
@ -350,39 +349,22 @@ int SYMBOL_EDITOR_MOVE_TOOL::Main( const TOOL_EVENT& aEvent )
|
||||||
controls->ShowCursor( false );
|
controls->ShowCursor( false );
|
||||||
controls->SetAutoPan( false );
|
controls->SetAutoPan( false );
|
||||||
|
|
||||||
if( !chain_commands )
|
|
||||||
m_moveOffset = { 0, 0 };
|
|
||||||
|
|
||||||
m_anchorPos = { 0, 0 };
|
m_anchorPos = { 0, 0 };
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
item->ClearEditFlags();
|
item->ClearEditFlags();
|
||||||
|
|
||||||
if( restore_state )
|
|
||||||
{
|
|
||||||
commit->Revert();
|
|
||||||
|
|
||||||
if( unselect )
|
if( unselect )
|
||||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
|
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
|
||||||
else
|
|
||||||
m_toolMgr->ProcessEvent( EVENTS::SelectedEvent );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if( unselect )
|
|
||||||
m_toolMgr->RunAction( EE_ACTIONS::clearSelection );
|
|
||||||
|
|
||||||
if( !localCommit.Empty() )
|
|
||||||
localCommit.Push( _( "Move" ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_moveInProgress = false;
|
m_moveInProgress = false;
|
||||||
m_frame->PopTool( aEvent );
|
m_frame->PopTool( aEvent );
|
||||||
return 0;
|
|
||||||
|
return !restore_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SYMBOL_EDITOR_MOVE_TOOL::moveItem( EDA_ITEM* aItem, VECTOR2I aDelta )
|
void SYMBOL_EDITOR_MOVE_TOOL::moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta )
|
||||||
{
|
{
|
||||||
static_cast<LIB_ITEM*>( aItem )->Offset( mapCoords( aDelta ) );
|
static_cast<LIB_ITEM*>( aItem )->Offset( mapCoords( aDelta ) );
|
||||||
aItem->SetFlags( IS_MOVING );
|
aItem->SetFlags( IS_MOVING );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2019 CERN
|
* Copyright (C) 2019 CERN
|
||||||
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
* Copyright (C) 2019-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
|
@ -50,17 +50,16 @@ public:
|
||||||
int Main( const TOOL_EVENT& aEvent );
|
int Main( const TOOL_EVENT& aEvent );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void moveItem( EDA_ITEM* aItem, VECTOR2I aDelta );
|
bool doMoveSelection( const TOOL_EVENT& aEvent, SCH_COMMIT* aCommit );
|
||||||
|
|
||||||
|
void moveItem( EDA_ITEM* aItem, const VECTOR2I& aDelta );
|
||||||
|
|
||||||
///< Set up handlers for various events.
|
///< Set up handlers for various events.
|
||||||
void setTransitions() override;
|
void setTransitions() override;
|
||||||
|
|
||||||
///< Flag determining if anything is being dragged right now
|
private:
|
||||||
bool m_moveInProgress;
|
bool m_moveInProgress;
|
||||||
|
|
||||||
///< Used for chaining commands
|
|
||||||
VECTOR2I m_moveOffset;
|
|
||||||
|
|
||||||
///< Last cursor position (needed for getModificationPoint() to avoid changes
|
///< Last cursor position (needed for getModificationPoint() to avoid changes
|
||||||
///< of edit reference point).
|
///< of edit reference point).
|
||||||
VECTOR2I m_cursor;
|
VECTOR2I m_cursor;
|
||||||
|
|
Loading…
Reference in New Issue