Implement undo/redo for footprint children.
Our special-cases to handle the fact that we didn't do this had far outgrown the code necessary to actually handle it.
This commit is contained in:
parent
3233bbe0ba
commit
1218f61d0a
|
@ -254,7 +254,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
|||
bool isSyntheticClick = symbol && evt->IsActivate() && evt->HasPosition()
|
||||
&& evt->Matches( aEvent );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( symbol && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
m_frame->GetInfoBar()->Dismiss();
|
||||
|
||||
|
@ -451,7 +451,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
cleanup();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( symbol && evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
bool isSyntheticClick = image && evt->IsActivate() && evt->HasPosition()
|
||||
&& evt->Matches( aEvent );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
m_frame->GetInfoBar()->Dismiss();
|
||||
|
||||
|
@ -689,7 +689,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
cleanup();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( image && evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -806,7 +806,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
|
|||
cursorPos = grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr );
|
||||
controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
m_frame->PopTool( aEvent );
|
||||
break;
|
||||
|
@ -934,10 +934,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
|
|||
evt->SetPassEvent();
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
|
@ -1551,7 +1547,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
|||
bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
|
||||
&& evt->Matches( aEvent );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( item && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( item )
|
||||
{
|
||||
|
@ -1700,7 +1696,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( item && evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -1771,7 +1767,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
|||
bool isSyntheticClick = sheet && evt->IsActivate() && evt->HasPosition()
|
||||
&& evt->Matches( aEvent );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( sheet && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
m_frame->GetInfoBar()->Dismiss();
|
||||
|
||||
|
@ -1897,7 +1893,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( sheet && evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
#include <undo_redo_container.h>
|
||||
#include <kiid.h>
|
||||
|
||||
class EDA_ITEM;
|
||||
class BASE_SCREEN;
|
||||
|
@ -43,9 +44,7 @@ enum CHANGE_TYPE {
|
|||
CHT_MODIFY = 4,
|
||||
CHT_TYPE = CHT_ADD | CHT_REMOVE | CHT_MODIFY,
|
||||
|
||||
///< Flag to indicate the change is already applied,
|
||||
///< just notify observers (not compatible with CHT_MODIFY)
|
||||
CHT_DONE = 8,
|
||||
CHT_DONE = 8, ///< Flag to indicate the change is already applied
|
||||
CHT_FLAGS = CHT_DONE
|
||||
};
|
||||
|
||||
|
@ -151,9 +150,10 @@ public:
|
|||
protected:
|
||||
struct COMMIT_LINE
|
||||
{
|
||||
EDA_ITEM* m_item; ///< Main item that is added/deleted/modified
|
||||
EDA_ITEM* m_copy; ///< Optional copy of the item
|
||||
CHANGE_TYPE m_type; ///< Modification type
|
||||
EDA_ITEM* m_item; ///< Main item that is added/deleted/modified
|
||||
EDA_ITEM* m_copy; ///< Optional copy of the item
|
||||
CHANGE_TYPE m_type; ///< Modification type
|
||||
KIID m_parent = NilUuid(); ///< Parent item (primarily for undo of deleted items)
|
||||
BASE_SCREEN* m_screen;
|
||||
};
|
||||
|
||||
|
|
|
@ -44,30 +44,20 @@ using namespace std::placeholders;
|
|||
|
||||
BOARD_COMMIT::BOARD_COMMIT( TOOL_BASE* aTool ) :
|
||||
m_toolMgr( aTool->GetManager() ),
|
||||
m_isFootprintEditor( false ),
|
||||
m_isBoardEditor( false )
|
||||
{
|
||||
if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
|
||||
{
|
||||
m_isFootprintEditor = pcb_tool->IsFootprintEditor();
|
||||
m_isBoardEditor = pcb_tool->IsBoardEditor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame ) :
|
||||
m_toolMgr( aFrame->GetToolManager() ),
|
||||
m_isFootprintEditor( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) ),
|
||||
m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOARD_COMMIT::~BOARD_COMMIT()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BOARD* BOARD_COMMIT::GetBoard() const
|
||||
{
|
||||
return static_cast<BOARD*>( m_toolMgr->GetModel() );
|
||||
|
@ -78,68 +68,15 @@ COMMIT& BOARD_COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType, BASE_SCRE
|
|||
{
|
||||
wxCHECK( aItem, *this );
|
||||
|
||||
aItem->ClearFlags( IS_MODIFIED_CHILD );
|
||||
|
||||
// If aItem belongs a footprint, the full footprint will be saved because undo/redo does
|
||||
// not handle "sub items" modifications. This has implications for some udpate mechanisms,
|
||||
// such as auto-zone-refill and teardrop regeneration, so we need to store a bit more
|
||||
// information.
|
||||
if( aChangeType == CHT_MODIFY )
|
||||
if( aChangeType == CHT_MODIFY && aItem->Type() == PCB_GROUP_T )
|
||||
{
|
||||
if( aItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( aItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
child->SetFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
|
||||
return COMMIT::Stage( aItem, aChangeType );
|
||||
}
|
||||
else if( aItem->GetParent() && aItem->GetParent()->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
FOOTPRINT* parentFootprint = static_cast<FOOTPRINT*>( aItem->GetParent() );
|
||||
bool parentFootprintStaged = alg::contains( m_changedItems, parentFootprint );
|
||||
|
||||
if( !parentFootprintStaged )
|
||||
{
|
||||
parentFootprint->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
child->ClearFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
}
|
||||
|
||||
if( aItem->Type() == PCB_GROUP_T )
|
||||
{
|
||||
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
child->SetFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
}
|
||||
else
|
||||
{
|
||||
aItem->SetFlags( IS_MODIFIED_CHILD );
|
||||
}
|
||||
|
||||
if( !parentFootprintStaged )
|
||||
return COMMIT::Stage( parentFootprint, aChangeType );
|
||||
|
||||
return *this;
|
||||
}
|
||||
else if( aItem->Type() == PCB_GROUP_T )
|
||||
{
|
||||
// Many operations on group (move, rotate, etc.) are applied directly to their
|
||||
// children, so it's the children that must be staged.
|
||||
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
COMMIT::Stage( child, aChangeType );
|
||||
} );
|
||||
|
||||
return COMMIT::Stage( aItem, aChangeType );
|
||||
}
|
||||
// Many operations on group (move, rotate, etc.) are applied directly to their
|
||||
// children, so it's the children that must be staged.
|
||||
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
COMMIT::Stage( child, aChangeType );
|
||||
} );
|
||||
}
|
||||
|
||||
return COMMIT::Stage( aItem, aChangeType );
|
||||
|
@ -169,24 +106,12 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType )
|
|||
if( item->Type() == PCB_ZONE_T )
|
||||
zoneFillerTool->DirtyZone( static_cast<ZONE*>( item ) );
|
||||
|
||||
if( item->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( item )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
if( aChangeType != CHT_MODIFY || ( child->GetFlags() & IS_MODIFIED_CHILD ) )
|
||||
dirtyIntersectingZones( child, aChangeType );
|
||||
|
||||
child->ClearFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
}
|
||||
else if( item->Type() == PCB_GROUP_T )
|
||||
if( item->Type() == PCB_GROUP_T )
|
||||
{
|
||||
static_cast<PCB_GROUP*>( item )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* child )
|
||||
{
|
||||
dirtyIntersectingZones( child, aChangeType );
|
||||
child->ClearFlags( IS_MODIFIED_CHILD );
|
||||
} );
|
||||
}
|
||||
else
|
||||
|
@ -214,8 +139,6 @@ void BOARD_COMMIT::dirtyIntersectingZones( BOARD_ITEM* item, int aChangeType )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
item->ClearFlags( IS_MODIFIED_CHILD );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -229,7 +152,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
|
||||
// Notification info
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
std::set<EDA_ITEM*> savedModules;
|
||||
bool itemsDeselected = false;
|
||||
bool selectedModified = false;
|
||||
|
||||
|
@ -246,10 +168,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
|
||||
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
|
||||
|
||||
// Note:
|
||||
// frame == nullptr happens in QA tests
|
||||
// in this case m_isBoardEditor and m_isFootprintEditor are set to false
|
||||
// But we also test frame == nullptr mainly to make Coverity happy
|
||||
// Note: frame == nullptr happens in QA tests
|
||||
|
||||
std::vector<BOARD_ITEM*> bulkAddedItems;
|
||||
std::vector<BOARD_ITEM*> bulkRemovedItems;
|
||||
|
@ -272,41 +191,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( ent.m_item );
|
||||
|
||||
wxASSERT( ent.m_item );
|
||||
|
||||
// Module items need to be saved in the undo buffer before modification
|
||||
if( m_isFootprintEditor )
|
||||
{
|
||||
// Be sure that we are storing a footprint
|
||||
if( ent.m_item->Type() != PCB_FOOTPRINT_T )
|
||||
{
|
||||
ent.m_item = ent.m_item->GetParent();
|
||||
wxASSERT( ent.m_item );
|
||||
}
|
||||
|
||||
// We have not saved the footprint yet, so let's create an entry
|
||||
if( savedModules.count( ent.m_item ) == 0 )
|
||||
{
|
||||
if( !ent.m_copy )
|
||||
{
|
||||
wxASSERT( changeType != CHT_MODIFY ); // too late to make a copy..
|
||||
ent.m_copy = makeImage( ent.m_item );
|
||||
}
|
||||
|
||||
wxASSERT( ent.m_item->Type() == PCB_FOOTPRINT_T );
|
||||
wxASSERT( ent.m_copy->Type() == PCB_FOOTPRINT_T );
|
||||
|
||||
if( !( aCommitFlags & SKIP_UNDO ) && frame )
|
||||
{
|
||||
ITEM_PICKER itemWrapper( nullptr, ent.m_item, UNDO_REDO::CHANGED );
|
||||
itemWrapper.SetLink( ent.m_copy );
|
||||
undoList.PushItem( itemWrapper );
|
||||
frame->SaveCopyInUndoList( undoList, UNDO_REDO::CHANGED );
|
||||
}
|
||||
|
||||
savedModules.insert( ent.m_item );
|
||||
}
|
||||
}
|
||||
|
||||
wxCHECK2( boardItem, continue );
|
||||
|
||||
if( m_isBoardEditor )
|
||||
|
@ -354,43 +238,25 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
if( boardItem->IsSelected() )
|
||||
selectedModified = true;
|
||||
|
||||
// If we're the footprint editor, the boardItem will always be the containing footprint
|
||||
if( m_isFootprintEditor && boardItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( boardItem )->RunOnChildren(
|
||||
[&selectedModified]( BOARD_ITEM* aItem )
|
||||
{
|
||||
if( aItem->HasFlag( IS_MODIFIED_CHILD ) )
|
||||
selectedModified = true;
|
||||
} );
|
||||
}
|
||||
|
||||
switch( changeType )
|
||||
{
|
||||
case CHT_ADD:
|
||||
{
|
||||
if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
|
||||
&& PCB_GROUP::IsGroupableType( boardItem->Type() ) )
|
||||
{
|
||||
selTool->GetEnteredGroup()->AddItem( boardItem );
|
||||
}
|
||||
|
||||
if( m_isFootprintEditor )
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
|
||||
|
||||
if( !( changeFlags & CHT_DONE ) )
|
||||
{
|
||||
// footprints inside footprints are not supported yet
|
||||
wxASSERT( boardItem->Type() != PCB_FOOTPRINT_T );
|
||||
|
||||
boardItem->SetParent( board->Footprints().front() );
|
||||
|
||||
if( !( changeFlags & CHT_DONE ) )
|
||||
board->Footprints().front()->Add( boardItem );
|
||||
}
|
||||
else if( !boardItem->GetParentFootprint() )
|
||||
{
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::NEWITEM ) );
|
||||
|
||||
if( !( changeFlags & CHT_DONE ) )
|
||||
if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
|
||||
{
|
||||
parentFP->Add( boardItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
|
||||
bulkAddedItems.push_back( boardItem );
|
||||
|
@ -404,14 +270,13 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
view->Add( boardItem );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CHT_REMOVE:
|
||||
{
|
||||
FOOTPRINT* parentFP = boardItem->GetParentFootprint();
|
||||
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
|
||||
|
||||
if( !m_isFootprintEditor && !( aCommitFlags & SKIP_UNDO ) )
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
|
||||
|
||||
if( boardItem->IsSelected() )
|
||||
|
@ -425,6 +290,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
|
||||
parentGroup->RemoveItem( boardItem );
|
||||
|
||||
if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
|
||||
ent.m_parent = parentFP->m_Uuid;
|
||||
|
||||
if( autofillZones )
|
||||
dirtyIntersectingZones( boardItem, changeType );
|
||||
|
||||
|
@ -447,6 +315,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
case PCB_TARGET_T: // a target (graphic item)
|
||||
case PCB_MARKER_T: // a marker used to show something
|
||||
case PCB_ZONE_T:
|
||||
case PCB_FOOTPRINT_T:
|
||||
if( view )
|
||||
view->Remove( boardItem );
|
||||
|
||||
|
@ -465,27 +334,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
|
||||
break;
|
||||
|
||||
case PCB_FOOTPRINT_T:
|
||||
{
|
||||
// No support for nested footprints (yet)
|
||||
wxASSERT( !m_isFootprintEditor );
|
||||
|
||||
FOOTPRINT* footprint = static_cast<FOOTPRINT*>( boardItem );
|
||||
|
||||
if( view )
|
||||
view->Remove( footprint );
|
||||
|
||||
footprint->ClearFlags();
|
||||
|
||||
if( !( changeFlags & CHT_DONE ) )
|
||||
{
|
||||
board->Remove( footprint, REMOVE_MODE::BULK ); // handles connectivity
|
||||
bulkRemovedItems.push_back( footprint );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PCB_GROUP_T:
|
||||
if( view )
|
||||
view->Remove( boardItem );
|
||||
|
@ -523,7 +371,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
{
|
||||
BOARD_ITEM* boardItemCopy = dynamic_cast<BOARD_ITEM*>( ent.m_copy );
|
||||
|
||||
if( !m_isFootprintEditor && !( aCommitFlags & SKIP_UNDO ) )
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
{
|
||||
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
|
||||
wxASSERT( boardItemCopy );
|
||||
|
@ -539,26 +387,15 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
connectivity->Update( boardItem );
|
||||
}
|
||||
|
||||
if( autofillZones )
|
||||
if( m_isBoardEditor && autofillZones )
|
||||
{
|
||||
dirtyIntersectingZones( boardItemCopy, changeType ); // before
|
||||
dirtyIntersectingZones( boardItem, changeType ); // after
|
||||
}
|
||||
|
||||
if( view )
|
||||
{
|
||||
view->Update( boardItem );
|
||||
|
||||
if( m_isFootprintEditor )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( boardItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* aChild )
|
||||
{
|
||||
view->Update( aChild );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
itemsChanged.push_back( boardItem );
|
||||
|
||||
// if no undo entry is needed, the copy would create a memory leak
|
||||
|
@ -574,15 +411,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
}
|
||||
|
||||
boardItem->ClearEditFlags();
|
||||
|
||||
if( m_isFootprintEditor && boardItem->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
static_cast<FOOTPRINT*>( boardItem )->RunOnChildren(
|
||||
[&]( BOARD_ITEM* aChild )
|
||||
{
|
||||
aChild->ClearEditFlags();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
if( bulkAddedItems.size() > 0 )
|
||||
|
@ -658,12 +486,15 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
|||
}
|
||||
}
|
||||
|
||||
if( m_isBoardEditor && !( aCommitFlags & SKIP_UNDO ) && frame )
|
||||
if( frame )
|
||||
{
|
||||
if( aCommitFlags & APPEND_UNDO )
|
||||
frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||
else
|
||||
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||
{
|
||||
if( aCommitFlags & APPEND_UNDO )
|
||||
frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||
else
|
||||
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||
}
|
||||
}
|
||||
|
||||
m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
|
||||
|
@ -742,8 +573,17 @@ void BOARD_COMMIT::Revert()
|
|||
|
||||
view->Remove( boardItem );
|
||||
connectivity->Remove( boardItem );
|
||||
board->Remove( boardItem, REMOVE_MODE::BULK );
|
||||
bulkRemovedItems.push_back( boardItem );
|
||||
|
||||
if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
|
||||
{
|
||||
parentFP->Remove( boardItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
board->Remove( boardItem, REMOVE_MODE::BULK );
|
||||
bulkRemovedItems.push_back( boardItem );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CHT_REMOVE:
|
||||
|
@ -752,8 +592,17 @@ void BOARD_COMMIT::Revert()
|
|||
|
||||
view->Add( boardItem );
|
||||
connectivity->Add( boardItem );
|
||||
board->Add( boardItem, ADD_MODE::INSERT );
|
||||
bulkAddedItems.push_back( boardItem );
|
||||
|
||||
if( FOOTPRINT* parentFP = dynamic_cast<FOOTPRINT*>( board->GetItem( ent.m_parent ) ) )
|
||||
{
|
||||
parentFP->Add( boardItem, ADD_MODE::INSERT );
|
||||
}
|
||||
else
|
||||
{
|
||||
board->Add( boardItem, ADD_MODE::INSERT );
|
||||
bulkAddedItems.push_back( boardItem );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case CHT_MODIFY:
|
||||
|
@ -801,7 +650,7 @@ void BOARD_COMMIT::Revert()
|
|||
if( itemsChanged.size() > 0 )
|
||||
board->OnItemsChanged( itemsChanged );
|
||||
|
||||
if ( !m_isFootprintEditor )
|
||||
if( m_isBoardEditor )
|
||||
{
|
||||
connectivity->RecalculateRatsnest();
|
||||
board->UpdateRatsnestExclusions();
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
BOARD_COMMIT( EDA_DRAW_FRAME* aFrame );
|
||||
BOARD_COMMIT( TOOL_BASE *aTool );
|
||||
|
||||
virtual ~BOARD_COMMIT();
|
||||
virtual ~BOARD_COMMIT() {}
|
||||
|
||||
BOARD* GetBoard() const;
|
||||
|
||||
|
@ -74,7 +74,6 @@ private:
|
|||
|
||||
private:
|
||||
TOOL_MANAGER* m_toolMgr;
|
||||
bool m_isFootprintEditor;
|
||||
bool m_isBoardEditor;
|
||||
};
|
||||
|
||||
|
|
|
@ -1046,7 +1046,7 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
|||
if( reselect && fp )
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, fp );
|
||||
|
||||
if( evt->IsCancelInteractive() )
|
||||
if( evt->IsCancelInteractive() || ( fp && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( fp )
|
||||
{
|
||||
|
@ -1156,7 +1156,8 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
|||
// Calling 'Properties' action clears the selection, so we need to restore it
|
||||
reselect = true;
|
||||
}
|
||||
else if( fp && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
else if( fp && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -1227,7 +1228,6 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
|
|||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
||||
|
||||
wxCHECK2( board_item, continue );
|
||||
|
||||
commit.Modify( board_item );
|
||||
|
@ -1369,7 +1369,7 @@ int BOARD_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
if( mergeZones( m_frame, commit, toMerge, merged ) )
|
||||
{
|
||||
commit.Push( wxT( "Merge zones" ) );
|
||||
commit.Push( wxT( "Merge Zones" ) );
|
||||
|
||||
for( EDA_ITEM* item : merged )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, item );
|
||||
|
@ -1425,7 +1425,7 @@ int BOARD_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
|
|||
newZone->Move( VECTOR2I( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
|
||||
|
||||
commit.Add( newZone.release() );
|
||||
commit.Push( _( "Duplicate zone" ) );
|
||||
commit.Push( _( "Duplicate Zone" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1434,7 +1434,6 @@ int BOARD_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
|
|||
int BOARD_EDITOR_CONTROL::CrossProbeToSch( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
doCrossProbePcbToSch( aEvent, false );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1442,7 +1441,6 @@ int BOARD_EDITOR_CONTROL::CrossProbeToSch( const TOOL_EVENT& aEvent )
|
|||
int BOARD_EDITOR_CONTROL::ExplicitCrossProbeToSch( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
doCrossProbePcbToSch( aEvent, true );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1618,20 +1616,17 @@ void BOARD_EDITOR_CONTROL::setTransitions()
|
|||
|
||||
Go( &BOARD_EDITOR_CONTROL::BoardSetup, PCB_ACTIONS::boardSetup.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ImportNetlist, PCB_ACTIONS::importNetlist.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ImportSpecctraSession,
|
||||
PCB_ACTIONS::importSpecctraSession.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ImportSpecctraSession, PCB_ACTIONS::importSpecctraSession.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ExportSpecctraDSN, PCB_ACTIONS::exportSpecctraDSN.MakeEvent() );
|
||||
|
||||
if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame &&
|
||||
m_frame->GetExportNetlistAction() )
|
||||
Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
|
||||
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateDrillFiles,
|
||||
PCB_ACTIONS::generateDrillFiles.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateDrillFiles, PCB_ACTIONS::generateDrillFiles.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateGerbers.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GeneratePosFile, PCB_ACTIONS::generatePosFile.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles,
|
||||
PCB_ACTIONS::generateReportFile.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateReportFile.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateD356File.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateBOM.MakeEvent() );
|
||||
|
||||
|
@ -1666,10 +1661,8 @@ void BOARD_EDITOR_CONTROL::setTransitions()
|
|||
|
||||
Go( &BOARD_EDITOR_CONTROL::AssignNetclass, PCB_ACTIONS::assignNetClass.MakeEvent() );
|
||||
|
||||
Go( &BOARD_EDITOR_CONTROL::UpdatePCBFromSchematic,
|
||||
ACTIONS::updatePcbFromSchematic.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB,
|
||||
ACTIONS::updateSchematicFromPcb.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::UpdatePCBFromSchematic, ACTIONS::updatePcbFromSchematic.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB, ACTIONS::updateSchematicFromPcb.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ShowEeschema, PCB_ACTIONS::showEeschema.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ToggleLayersManager, PCB_ACTIONS::showLayersManager.MakeEvent() );
|
||||
Go( &BOARD_EDITOR_CONTROL::ToggleProperties, ACTIONS::showProperties.MakeEvent() );
|
||||
|
|
|
@ -475,9 +475,19 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
if( aEvent.IsAction( &PCB_ACTIONS::convertToPoly ) )
|
||||
commit.Push( _( "Convert shapes to polygon" ) );
|
||||
{
|
||||
if( m_userSettings.m_DeleteOriginals )
|
||||
commit.Push( _( "Convert to Polygon" ) );
|
||||
else
|
||||
commit.Push( _( "Create Polygon" ) );
|
||||
}
|
||||
else
|
||||
commit.Push( _( "Convert shapes to zone" ) );
|
||||
{
|
||||
if( m_userSettings.m_DeleteOriginals )
|
||||
commit.Push( _( "Convert to Zone" ) );
|
||||
else
|
||||
commit.Push( _( "Create Zone" ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1018,7 +1028,7 @@ int CONVERT_TOOL::CreateLines( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
commit.Push( _( "Convert polygons to lines" ) );
|
||||
commit.Push( _( "Create Lines" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1105,7 +1115,7 @@ int CONVERT_TOOL::SegmentToArc( const TOOL_EVENT& aEvent )
|
|||
commit.Add( arc );
|
||||
}
|
||||
|
||||
commit.Push( _( "Create arc from line segment" ) );
|
||||
commit.Push( _( "Create Arc" ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -344,7 +344,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
|||
if( line )
|
||||
{
|
||||
commit.Add( line );
|
||||
commit.Push( _( "Draw a line segment" ) );
|
||||
commit.Push( _( "Draw Line" ) );
|
||||
startingPoint = VECTOR2D( line->GetEnd() );
|
||||
committedLines.push( line );
|
||||
}
|
||||
|
@ -408,7 +408,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
rect->NormalizeRect();
|
||||
commit.Add( rect );
|
||||
commit.Push( isTextBox ? _( "Draw a text box" ) : _( "Draw a rectangle" ) );
|
||||
commit.Push( isTextBox ? _( "Draw Text Box" ) : _( "Draw Rectangle" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, rect );
|
||||
}
|
||||
|
@ -456,7 +456,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
|||
if( circle )
|
||||
{
|
||||
commit.Add( circle );
|
||||
commit.Push( _( "Draw a circle" ) );
|
||||
commit.Push( _( "Draw Circle" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, circle );
|
||||
}
|
||||
|
@ -503,7 +503,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
|||
if( arc )
|
||||
{
|
||||
commit.Add( arc );
|
||||
commit.Push( _( "Draw an arc" ) );
|
||||
commit.Push( _( "Draw Arc" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, arc );
|
||||
}
|
||||
|
@ -601,7 +601,7 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( image )
|
||||
{
|
||||
|
@ -703,7 +703,7 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
else
|
||||
{
|
||||
commit.Add( image );
|
||||
commit.Push( _( "Place an image" ) );
|
||||
commit.Push( _( "Place Image" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, image );
|
||||
|
||||
|
@ -727,7 +727,8 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_menu.ShowContextMenu( selectionTool->GetSelection() );
|
||||
}
|
||||
else if( image && ( evt->IsAction( &ACTIONS::refreshPreview ) || evt->IsMotion() ) )
|
||||
else if( image && ( evt->IsAction( &ACTIONS::refreshPreview )
|
||||
|| evt->IsMotion() ) )
|
||||
{
|
||||
image->SetPosition( cursorPos );
|
||||
m_view->ClearPreview();
|
||||
|
@ -738,11 +739,8 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
cleanup();
|
||||
}
|
||||
else if( image && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( image && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -837,7 +835,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( text && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( text )
|
||||
{
|
||||
|
@ -891,15 +889,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||
textAttrs.m_Valign = GR_TEXT_V_ALIGN_BOTTOM;
|
||||
|
||||
// Init the new item attributes
|
||||
if( m_isFootprintEditor )
|
||||
{
|
||||
text = new PCB_TEXT( static_cast<FOOTPRINT*>( m_frame->GetModel() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
text = new PCB_TEXT( m_frame->GetModel() );
|
||||
}
|
||||
|
||||
text->SetLayer( layer );
|
||||
text->SetAttributes( textAttrs );
|
||||
|
@ -948,7 +941,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||
|
||||
commit.Add( text );
|
||||
commit.Push( _( "Place a text" ) );
|
||||
commit.Push( _( "Place Text" ) );
|
||||
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, text );
|
||||
|
||||
|
@ -977,32 +970,23 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
|||
m_controls->CaptureCursor( text != nullptr );
|
||||
m_controls->SetAutoPan( text != nullptr );
|
||||
}
|
||||
else if( text && ( evt->IsMotion() || evt->IsAction( &PCB_ACTIONS::refreshPreview ) ) )
|
||||
else if( text && ( evt->IsMotion()
|
||||
|| evt->IsAction( &PCB_ACTIONS::refreshPreview ) ) )
|
||||
{
|
||||
text->SetPosition( cursorPos );
|
||||
selection().SetReferencePoint( cursorPos );
|
||||
m_view->Update( &selection() );
|
||||
}
|
||||
else if( text && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
else if( text && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||
else if( text && evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||
{
|
||||
if( text )
|
||||
{
|
||||
frame()->OnEditItemRequest( text );
|
||||
m_view->Update( &selection() );
|
||||
frame()->SetMsgPanel( text );
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
frame()->OnEditItemRequest( text );
|
||||
m_view->Update( &selection() );
|
||||
frame()->SetMsgPanel( text );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1124,7 +1108,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( dimension && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
m_controls->SetAutoPan( false );
|
||||
|
||||
|
@ -1283,7 +1267,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
preview.Remove( dimension );
|
||||
|
||||
commit.Add( dimension );
|
||||
commit.Push( _( "Draw a dimension" ) );
|
||||
commit.Push( _( "Draw Dimension" ) );
|
||||
|
||||
// Run the edit immediately to set the leader text
|
||||
if( t == PCB_DIM_LEADER_T )
|
||||
|
@ -1443,11 +1427,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
|||
wxBell();
|
||||
}
|
||||
}
|
||||
else if( dimension && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( dimension && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -1525,7 +1506,6 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
|||
for( std::unique_ptr<EDA_ITEM>& ptr : list )
|
||||
{
|
||||
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( ptr.get() );
|
||||
|
||||
wxCHECK2( item, continue );
|
||||
|
||||
newItems.push_back( item );
|
||||
|
@ -1545,7 +1525,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : newItems )
|
||||
commit.Add( item );
|
||||
|
||||
commit.Push( _( "Place a DXF_SVG drawing" ) );
|
||||
commit.Push( _( "Import Graphic" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1632,7 +1612,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
|||
for( BOARD_ITEM* item : newItems )
|
||||
commit.Add( item );
|
||||
|
||||
commit.Push( _( "Place a DXF_SVG drawing" ) );
|
||||
commit.Push( _( "Import Graphic" ) );
|
||||
break; // This is a one-shot command, not a tool
|
||||
}
|
||||
else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
|
@ -1713,7 +1693,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
|||
VECTOR2I moveVector = footprint->GetPosition() - cursorPos;
|
||||
footprint->MoveAnchorPosition( moveVector );
|
||||
|
||||
commit.Push( _( "Move the footprint reference anchor" ) );
|
||||
commit.Push( _( "Move Footprint Anchor" ) );
|
||||
|
||||
// Usually, we do not need to change twice the anchor position,
|
||||
// so deselect the active tool
|
||||
|
@ -1807,12 +1787,12 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
}
|
||||
|
||||
// geometric construction manager
|
||||
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointManager;
|
||||
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointMgr;
|
||||
|
||||
// drawing assistant overlay
|
||||
// TODO: workaround because EDA_SHAPE_TYPE_T is not visible from commons.
|
||||
KIGFX::PREVIEW::GEOM_SHAPE geomShape( static_cast<KIGFX::PREVIEW::GEOM_SHAPE>( shape ) );
|
||||
KIGFX::PREVIEW::TWO_POINT_ASSISTANT twoPointAsst( twoPointManager, pcbIUScale, userUnits, geomShape );
|
||||
KIGFX::PREVIEW::TWO_POINT_ASSISTANT twoPointAsst( twoPointMgr, pcbIUScale, userUnits, geomShape );
|
||||
|
||||
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||
PCB_SELECTION preview;
|
||||
|
@ -1976,8 +1956,8 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
|
||||
grid.SetSkipPoint( cursorPos );
|
||||
|
||||
twoPointManager.SetOrigin( cursorPos );
|
||||
twoPointManager.SetEnd( cursorPos );
|
||||
twoPointMgr.SetOrigin( cursorPos );
|
||||
twoPointMgr.SetEnd( cursorPos );
|
||||
|
||||
if( !isLocalOriginSet )
|
||||
m_frame->GetScreen()->m_LocalOrigin = cursorPos;
|
||||
|
@ -1993,35 +1973,28 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
||||
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||
|
||||
started = true;
|
||||
}
|
||||
else if( shape == SHAPE_T::CIRCLE )
|
||||
{
|
||||
// No clever logic if drawing a circle
|
||||
preview.Clear();
|
||||
twoPointManager.Reset();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
PCB_SHAPE* snapItem = dynamic_cast<PCB_SHAPE*>( grid.GetSnapped() );
|
||||
|
||||
if( twoPointManager.GetOrigin() == twoPointManager.GetEnd()
|
||||
|| ( evt->IsDblClick( BUT_LEFT ) && shape == SHAPE_T::SEGMENT )
|
||||
|| snapItem )
|
||||
// User has clicked twice in the same spot
|
||||
// or clicked on the end of an existing segment (closing a path)
|
||||
if( shape == SHAPE_T::SEGMENT && ( twoPointMgr.GetOrigin() == twoPointMgr.GetEnd()
|
||||
|| evt->IsDblClick( BUT_LEFT )
|
||||
|| snapItem ) )
|
||||
{
|
||||
// User has clicked twice in the same spot
|
||||
// or clicked on the end of an existing segment (closing a path)
|
||||
BOARD_COMMIT commit( m_frame );
|
||||
|
||||
// If the user clicks on an existing snap point from a drawsegment
|
||||
// we finish the segment as they are likely closing a path
|
||||
if( snapItem && ( shape == SHAPE_T::RECT || graphic->GetLength() > 0.0 ) )
|
||||
if( snapItem && graphic->GetLength() > 0.0 )
|
||||
{
|
||||
commit.Add( graphic );
|
||||
commit.Push( _( "Draw a line segment" ) );
|
||||
commit.Push( _( "Draw Line" ) );
|
||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, graphic );
|
||||
}
|
||||
else
|
||||
|
@ -2033,59 +2006,53 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
}
|
||||
|
||||
preview.Clear();
|
||||
twoPointManager.Reset();
|
||||
twoPointMgr.Reset();
|
||||
break;
|
||||
}
|
||||
|
||||
twoPointManager.SetEnd( GetClampedCoords( cursorPos ) );
|
||||
twoPointMgr.SetEnd( GetClampedCoords( cursorPos ) );
|
||||
}
|
||||
else if( evt->IsMotion() )
|
||||
{
|
||||
VECTOR2I clampedCursorPos = cursorPos;
|
||||
|
||||
if( shape == SHAPE_T::CIRCLE || shape == SHAPE_T::ARC )
|
||||
{
|
||||
clampedCursorPos = getClampedRadiusEnd( twoPointManager.GetOrigin(), cursorPos );
|
||||
}
|
||||
clampedCursorPos = getClampedRadiusEnd( twoPointMgr.GetOrigin(), cursorPos );
|
||||
else
|
||||
{
|
||||
clampedCursorPos = getClampedDifferenceEnd( twoPointManager.GetOrigin(),
|
||||
cursorPos );
|
||||
}
|
||||
clampedCursorPos = getClampedDifferenceEnd( twoPointMgr.GetOrigin(), cursorPos );
|
||||
|
||||
// 45 degree lines
|
||||
if( started && Is45Limited() )
|
||||
{
|
||||
const VECTOR2I lineVector( clampedCursorPos
|
||||
- VECTOR2I( twoPointManager.GetOrigin() ) );
|
||||
const VECTOR2I lineVector( clampedCursorPos - VECTOR2I( twoPointMgr.GetOrigin() ) );
|
||||
|
||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||
VECTOR2I newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECT ) );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
||||
twoPointManager.SetEnd( twoPointManager.GetOrigin() + newEnd );
|
||||
twoPointManager.SetAngleSnap( true );
|
||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointMgr.GetEnd() ) );
|
||||
twoPointMgr.SetEnd( twoPointMgr.GetOrigin() + newEnd );
|
||||
twoPointMgr.SetAngleSnap( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
twoPointManager.SetEnd( clampedCursorPos );
|
||||
twoPointManager.SetAngleSnap( false );
|
||||
twoPointMgr.SetEnd( clampedCursorPos );
|
||||
twoPointMgr.SetAngleSnap( false );
|
||||
}
|
||||
|
||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
||||
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::undo )
|
||||
|| evt->IsAction( &PCB_ACTIONS::doDelete )
|
||||
|| evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
|
||||
else if( started && ( evt->IsAction( &ACTIONS::undo )
|
||||
|| evt->IsAction( &PCB_ACTIONS::doDelete )
|
||||
|| evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) ) )
|
||||
{
|
||||
if( graphic && !aCommittedGraphics->empty() )
|
||||
if( aCommittedGraphics && !aCommittedGraphics->empty() )
|
||||
{
|
||||
twoPointManager.SetOrigin( aCommittedGraphics->top()->GetStart() );
|
||||
twoPointManager.SetEnd( aCommittedGraphics->top()->GetEnd() );
|
||||
twoPointMgr.SetOrigin( aCommittedGraphics->top()->GetStart() );
|
||||
twoPointMgr.SetEnd( aCommittedGraphics->top()->GetEnd() );
|
||||
aCommittedGraphics->pop();
|
||||
|
||||
getViewControls()->WarpMouseCursor( twoPointManager.GetEnd(), true );
|
||||
getViewControls()->WarpMouseCursor( twoPointMgr.GetEnd(), true );
|
||||
|
||||
if( PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList() )
|
||||
{
|
||||
|
@ -2094,11 +2061,11 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
delete undo;
|
||||
}
|
||||
|
||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
||||
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||
m_view->Update( &preview );
|
||||
m_view->Update( &twoPointAsst );
|
||||
}
|
||||
else if( graphic )
|
||||
else
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
@ -2110,10 +2077,6 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
m_view->Update( &preview );
|
||||
frame()->SetMsgPanel( graphic );
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( graphic && evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
||||
{
|
||||
if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
|
||||
|
@ -2131,7 +2094,8 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
frame()->SetMsgPanel( graphic );
|
||||
break;
|
||||
}
|
||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -2273,7 +2237,7 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ), COORDS_PADDING );
|
||||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
|
||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
||||
if( evt->IsCancelInteractive() || ( started && evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
cleanup();
|
||||
|
||||
|
@ -2406,18 +2370,26 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||
{
|
||||
m_stroke.SetWidth( m_stroke.GetWidth() + WIDTH_STEP );
|
||||
graphic->SetStroke( m_stroke );
|
||||
m_view->Update( &preview );
|
||||
frame()->SetMsgPanel( graphic );
|
||||
|
||||
if( graphic )
|
||||
{
|
||||
graphic->SetStroke( m_stroke );
|
||||
m_view->Update( &preview );
|
||||
frame()->SetMsgPanel( graphic );
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
||||
{
|
||||
if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
|
||||
{
|
||||
m_stroke.SetWidth( m_stroke.GetWidth() - WIDTH_STEP );
|
||||
graphic->SetStroke( m_stroke );
|
||||
m_view->Update( &preview );
|
||||
frame()->SetMsgPanel( graphic );
|
||||
|
||||
if( graphic )
|
||||
{
|
||||
graphic->SetStroke( m_stroke );
|
||||
m_view->Update( &preview );
|
||||
frame()->SetMsgPanel( graphic );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
|
||||
|
@ -2430,11 +2402,8 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||
m_view->Update( &arcAsst );
|
||||
evt->SetPassEvent();
|
||||
}
|
||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
|
@ -2602,7 +2571,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( evt->IsCancelInteractive() )
|
||||
{
|
||||
if( polyGeomMgr.IsPolygonInProgress() )
|
||||
if( started )
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
|
@ -2616,7 +2585,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
else if( evt->IsActivate() )
|
||||
{
|
||||
if( polyGeomMgr.IsPolygonInProgress() )
|
||||
if( started )
|
||||
cleanup();
|
||||
|
||||
if( evt->IsPointEditor() )
|
||||
|
@ -2686,9 +2655,9 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint )
|
||||
|| evt->IsAction( &ACTIONS::doDelete )
|
||||
|| evt->IsAction( &ACTIONS::undo ) )
|
||||
else if( started && ( evt->IsAction( &PCB_ACTIONS::deleteLastPoint )
|
||||
|| evt->IsAction( &ACTIONS::doDelete )
|
||||
|| evt->IsAction( &ACTIONS::undo ) ) )
|
||||
{
|
||||
if( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
|
||||
{
|
||||
|
@ -2697,21 +2666,22 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
m_controls->ForceCursorPosition( true, cursorPos );
|
||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||
}
|
||||
else if( polyGeomMgr.IsPolygonInProgress() )
|
||||
else
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
}
|
||||
else if( polyGeomMgr.IsPolygonInProgress()
|
||||
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
||||
else if( started && ( evt->IsMotion()
|
||||
|| evt->IsDrag( BUT_LEFT ) ) )
|
||||
{
|
||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||
}
|
||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else if( started&& evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||
else if( started && evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||
{
|
||||
frame()->OnEditItemRequest( zoneTool.GetZone() );
|
||||
zoneTool.OnGeometryChange( polyGeomMgr );
|
||||
|
@ -2725,10 +2695,6 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
|||
// m_view->Update( &zoneAsst );
|
||||
evt->SetPassEvent();
|
||||
}*/
|
||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
||||
{
|
||||
wxBell();
|
||||
}
|
||||
else
|
||||
{
|
||||
evt->SetPassEvent();
|
||||
|
|
|
@ -1209,8 +1209,7 @@ int EDIT_TOOL::ModifyLines( const TOOL_EVENT& aEvent )
|
|||
if( !m_isFootprintEditor )
|
||||
{
|
||||
// If the item was "conjured up" it will be added later separately
|
||||
if( std::find( lines_to_add.begin(), lines_to_add.end(), &aItem )
|
||||
== lines_to_add.end() )
|
||||
if( !alg::contains( lines_to_add, &aItem ) )
|
||||
{
|
||||
commit.Modify( &aItem );
|
||||
items_to_select_on_success.push_back( &aItem );
|
||||
|
@ -1270,17 +1269,11 @@ int EDIT_TOOL::ModifyLines( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
// Didn't construct any mofication routine - could be an error or cancellation
|
||||
if( !error_message.empty() )
|
||||
{
|
||||
frame()->ShowInfoBarMsg( error_message );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Only modify one parent in FP editor
|
||||
if( m_isFootprintEditor )
|
||||
commit.Modify( selection.Front() );
|
||||
|
||||
// Apply the tool to every line pair
|
||||
alg::for_all_pairs( selection.begin(), selection.end(),
|
||||
[&]( EDA_ITEM* a, EDA_ITEM* b )
|
||||
|
@ -1478,7 +1471,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
||||
if( !item->IsNew() && !item->IsMoving() )
|
||||
{
|
||||
commit->Modify( item );
|
||||
|
||||
|
@ -1653,7 +1646,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
if( !item->IsType( MirrorableItems ) )
|
||||
continue;
|
||||
|
||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
||||
if( !item->IsNew() && !item->IsMoving() )
|
||||
commit->Modify( item );
|
||||
|
||||
// modify each object as necessary
|
||||
|
@ -1765,8 +1758,7 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
|
||||
{
|
||||
if( !boardItem->IsNew() && !boardItem->IsMoving()
|
||||
&& ( !IsFootprintEditor() || commit->Empty() ) )
|
||||
if( !boardItem->IsNew() && !boardItem->IsMoving() )
|
||||
{
|
||||
commit->Modify( boardItem );
|
||||
|
||||
|
@ -1816,13 +1808,11 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
|
|||
for( EDA_ITEM* item : aItems )
|
||||
{
|
||||
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
||||
|
||||
wxCHECK2( board_item, continue );
|
||||
|
||||
FOOTPRINT* parentFP = board_item->GetParentFootprint();
|
||||
PCB_GROUP* parentGroup = board_item->GetParentGroup();
|
||||
|
||||
if( parentGroup )
|
||||
if( PCB_GROUP* parentGroup = board_item->GetParentGroup() )
|
||||
{
|
||||
commit.Modify( parentGroup );
|
||||
parentGroup->RemoveItem( board_item );
|
||||
|
@ -2097,17 +2087,13 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
|||
if( !frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
|
||||
rotation = -rotation;
|
||||
|
||||
// When editing footprints, all items have the same parent
|
||||
if( IsFootprintEditor() )
|
||||
commit.Modify( selection.Front() );
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
||||
|
||||
wxCHECK2( boardItem, continue );
|
||||
|
||||
if( !boardItem->IsNew() && !IsFootprintEditor() )
|
||||
if( !boardItem->IsNew() )
|
||||
{
|
||||
commit.Modify( boardItem );
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
|
|||
// Save items, so changes can be undone
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
||||
if( !item->IsNew() && !item->IsMoving() )
|
||||
{
|
||||
commit->Modify( item );
|
||||
|
||||
|
@ -369,10 +369,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
|||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
|
||||
|
||||
if( boardItem )
|
||||
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
|
||||
{
|
||||
if( !is_hover )
|
||||
orig_items.push_back( boardItem );
|
||||
|
@ -380,7 +377,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
|||
sel_items.push_back( boardItem );
|
||||
}
|
||||
|
||||
if( footprint )
|
||||
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item ) )
|
||||
{
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
sel_items.push_back( pad );
|
||||
|
@ -569,8 +566,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
|||
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||
continue;
|
||||
|
||||
if( !item->IsNew() && !item->IsMoving()
|
||||
&& ( !IsFootprintEditor() || aCommit->Empty() ) )
|
||||
if( !item->IsNew() && !item->IsMoving() )
|
||||
{
|
||||
aCommit->Modify( item );
|
||||
item->SetFlags( IS_MOVING );
|
||||
|
|
|
@ -532,10 +532,7 @@ int FOOTPRINT_EDITOR_CONTROL::ImportFootprint( const TOOL_EVENT& aEvent )
|
|||
|
||||
int FOOTPRINT_EDITOR_CONTROL::ExportFootprint( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
LIB_ID fpID = m_frame->GetTreeFPID();
|
||||
FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
|
||||
|
||||
if( fp )
|
||||
if( FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint() )
|
||||
m_frame->ExportFootprint( fp );
|
||||
|
||||
return 0;
|
||||
|
@ -604,13 +601,12 @@ int FOOTPRINT_EDITOR_CONTROL::ToggleProperties( const TOOL_EVENT& aEvent )
|
|||
|
||||
int FOOTPRINT_EDITOR_CONTROL::Properties( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint();
|
||||
|
||||
if( footprint )
|
||||
if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
|
||||
{
|
||||
getEditFrame<FOOTPRINT_EDIT_FRAME>()->OnEditItemRequest( footprint );
|
||||
m_frame->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -637,7 +633,6 @@ int FOOTPRINT_EDITOR_CONTROL::CheckFootprint( const TOOL_EVENT& aEvent )
|
|||
if( !m_checkerDialog )
|
||||
{
|
||||
m_checkerDialog = new DIALOG_FOOTPRINT_CHECKER( m_frame );
|
||||
|
||||
m_checkerDialog->Show( true );
|
||||
}
|
||||
else // The dialog is just not visible (because the user has double clicked on an error item)
|
||||
|
|
|
@ -168,7 +168,7 @@ int GLOBAL_EDIT_TOOL::SwapLayers( const TOOL_EVENT& aEvent )
|
|||
if( hasChanges )
|
||||
{
|
||||
frame()->OnModify();
|
||||
m_commit->Push( wxT( "Layers moved" ) );
|
||||
m_commit->Push( wxT( "Swap Layers" ) );
|
||||
frame()->GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
|
|
|
@ -254,47 +254,32 @@ int GROUP_TOOL::Group( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( m_isFootprintEditor )
|
||||
{
|
||||
FOOTPRINT* parentFootprint = board->GetFirstFootprint();
|
||||
group = new PCB_GROUP( board->GetFirstFootprint() );
|
||||
board->GetFirstFootprint()->Add( group );
|
||||
}
|
||||
else
|
||||
{
|
||||
group = new PCB_GROUP( board );
|
||||
board->Add( group );
|
||||
}
|
||||
|
||||
m_frame->SaveCopyInUndoList( parentFootprint, UNDO_REDO::CHANGED );
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::NEWITEM ) );
|
||||
|
||||
group = new PCB_GROUP( parentFootprint );
|
||||
parentFootprint->Add( group );
|
||||
|
||||
for( EDA_ITEM* eda_item : selection )
|
||||
for( EDA_ITEM* eda_item : selection )
|
||||
{
|
||||
if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( eda_item ) )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
|
||||
|
||||
if( item->IsLocked() )
|
||||
lockGroup = true;
|
||||
|
||||
group->AddItem( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
|
||||
group = new PCB_GROUP( board );
|
||||
board->Add( group );
|
||||
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::NEWITEM ) );
|
||||
|
||||
for( EDA_ITEM* eda_item : selection )
|
||||
{
|
||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
|
||||
|
||||
if( item->IsLocked() )
|
||||
lockGroup = true;
|
||||
|
||||
group->AddItem( static_cast<BOARD_ITEM*>( item ) );
|
||||
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, item, UNDO_REDO::REGROUP ) );
|
||||
}
|
||||
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::REGROUP );
|
||||
}
|
||||
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::REGROUP );
|
||||
|
||||
if( lockGroup )
|
||||
group->SetLocked( true );
|
||||
|
||||
|
@ -326,33 +311,23 @@ int GROUP_TOOL::Ungroup( const TOOL_EVENT& aEvent )
|
|||
|
||||
if( group )
|
||||
{
|
||||
if( m_isFootprintEditor )
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
|
||||
for( BOARD_ITEM* member : group->GetItems() )
|
||||
{
|
||||
FOOTPRINT* parentFootprint = board->GetFirstFootprint();
|
||||
|
||||
m_frame->SaveCopyInUndoList( parentFootprint, UNDO_REDO::CHANGED );
|
||||
|
||||
group->RemoveAll();
|
||||
parentFootprint->Remove( group );
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, member, UNDO_REDO::UNGROUP ) );
|
||||
members.push_back( member );
|
||||
}
|
||||
|
||||
group->RemoveAll();
|
||||
|
||||
if( m_isFootprintEditor )
|
||||
board->GetFirstFootprint()->Remove( group );
|
||||
else
|
||||
{
|
||||
PICKED_ITEMS_LIST undoList;
|
||||
|
||||
for( BOARD_ITEM* member : group->GetItems() )
|
||||
{
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, member, UNDO_REDO::UNGROUP ) );
|
||||
members.push_back( member );
|
||||
}
|
||||
|
||||
group->RemoveAll();
|
||||
board->Remove( group );
|
||||
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::DELETED ) );
|
||||
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNGROUP );
|
||||
}
|
||||
|
||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::DELETED ) );
|
||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNGROUP );
|
||||
group->SetSelected();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,7 +194,6 @@ int PCB_CONTROL::ViaDisplayMode( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
canvas()->Refresh();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -301,7 +300,6 @@ int PCB_CONTROL::HighContrastMode( const TOOL_EVENT& aEvent )
|
|||
: HIGH_CONTRAST_MODE::NORMAL;
|
||||
|
||||
m_frame->SetDisplayOptions( opts );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -320,7 +318,6 @@ int PCB_CONTROL::HighContrastModeCycle( const TOOL_EVENT& aEvent )
|
|||
m_frame->SetDisplayOptions( opts );
|
||||
|
||||
m_toolMgr->PostEvent( EVENTS::ContrastModeChangedByKeyEvent );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -343,8 +340,10 @@ int PCB_CONTROL::ContrastModeFeedback( const TOOL_EVENT& aEvent )
|
|||
HOTKEY_CYCLE_POPUP* popup = m_frame->GetHotkeyPopup();
|
||||
|
||||
if( popup )
|
||||
{
|
||||
popup->Popup( _( "Inactive Layer Display" ), labels,
|
||||
static_cast<int>( opts.m_ContrastModeDisplay ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -362,7 +361,6 @@ int PCB_CONTROL::NetColorModeCycle( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
m_frame->SetDisplayOptions( opts );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,7 +166,6 @@ size_t ALIGN_DISTRIBUTE_TOOL::GetSelections( std::vector<std::pair<BOARD_ITEM*,
|
|||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
||||
|
||||
wxCHECK2( boardItem, continue );
|
||||
|
||||
// We do not lock items in the footprint editor
|
||||
|
@ -175,13 +174,9 @@ size_t ALIGN_DISTRIBUTE_TOOL::GetSelections( std::vector<std::pair<BOARD_ITEM*,
|
|||
// Locking a pad but not the footprint means that we align the footprint using
|
||||
// the pad position. So we test for footprint locking here
|
||||
if( boardItem->Type() == PCB_PAD_T && !boardItem->GetParent()->IsLocked() )
|
||||
{
|
||||
itemsToAlign.push_back( boardItem );
|
||||
}
|
||||
else
|
||||
{
|
||||
lockedItems.push_back( boardItem );
|
||||
}
|
||||
}
|
||||
else
|
||||
itemsToAlign.push_back( boardItem );
|
||||
|
@ -202,9 +197,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.GetTop() < right.second.GetTop() );
|
||||
return ( lhs.second.GetTop() < rhs.second.GetTop() );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -235,8 +230,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
|||
item->Move( VECTOR2I( 0, difference ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to top" ) );
|
||||
|
||||
commit.Push( _( "Align to Top" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -247,9 +241,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs)
|
||||
{
|
||||
return ( left.second.GetBottom() > right.second.GetBottom() );
|
||||
return ( lhs.second.GetBottom() > rhs.second.GetBottom() );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -280,8 +274,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
|||
item->Move( VECTOR2I( 0, difference ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to bottom" ) );
|
||||
|
||||
commit.Push( _( "Align to Bottom" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -291,13 +284,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
|
|||
// Because this tool uses bounding boxes and they aren't mirrored even when
|
||||
// the view is mirrored, we need to call the other one if mirrored.
|
||||
if( getView()->IsMirroredX() )
|
||||
{
|
||||
return doAlignRight();
|
||||
}
|
||||
else
|
||||
{
|
||||
return doAlignLeft();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,9 +296,9 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.GetLeft() < right.second.GetLeft() );
|
||||
return ( lhs.second.GetLeft() < rhs.second.GetLeft() );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -340,8 +329,7 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
|||
item->Move( VECTOR2I( difference, 0 ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to left" ) );
|
||||
|
||||
commit.Push( _( "Align to Left" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -351,13 +339,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignRight( const TOOL_EVENT& aEvent )
|
|||
// Because this tool uses bounding boxes and they aren't mirrored even when
|
||||
// the view is mirrored, we need to call the other one if mirrored.
|
||||
if( getView()->IsMirroredX() )
|
||||
{
|
||||
return doAlignLeft();
|
||||
}
|
||||
else
|
||||
{
|
||||
return doAlignRight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -367,9 +351,9 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.GetRight() > right.second.GetRight() );
|
||||
return ( lhs.second.GetRight() > rhs.second.GetRight() );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -400,8 +384,7 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
|||
item->Move( VECTOR2I( difference, 0 ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to right" ) );
|
||||
|
||||
commit.Push( _( "Align to Right" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -412,9 +395,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.Centre().x < right.second.Centre().x );
|
||||
return ( lhs.second.Centre().x < rhs.second.Centre().x );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -445,8 +428,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
|||
item->Move( VECTOR2I( difference, 0 ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to middle" ) );
|
||||
|
||||
commit.Push( _( "Align to Middle" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -457,9 +439,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
|||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||
|
||||
if( !GetSelections( itemsToAlign, locked_items,
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.Centre().y < right.second.Centre().y );
|
||||
return ( lhs.second.Centre().y < rhs.second.Centre().y );
|
||||
} ) )
|
||||
{
|
||||
return 0;
|
||||
|
@ -490,8 +472,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
|||
item->Move( VECTOR2I( 0, difference ) );
|
||||
}
|
||||
|
||||
commit.Push( _( "Align to center" ) );
|
||||
|
||||
commit.Push( _( "Align to Center" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -520,10 +501,9 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
|||
|
||||
// find the last item by reverse sorting
|
||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left,
|
||||
const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.GetRight() > right.second.GetRight() );
|
||||
return ( lhs.second.GetRight() > rhs.second.GetRight() );
|
||||
} );
|
||||
|
||||
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
||||
|
@ -531,10 +511,9 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
|||
|
||||
// sort to get starting order
|
||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left,
|
||||
const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.GetX() < right.second.GetX() );
|
||||
return ( lhs.second.GetX() < rhs.second.GetX() );
|
||||
} );
|
||||
|
||||
const int minX = itemsToDistribute.begin()->second.GetX();
|
||||
|
@ -555,8 +534,7 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
|||
doDistributeGapsHorizontally( itemsToDistribute, commit, lastItem, totalGap );
|
||||
}
|
||||
|
||||
commit.Push( _( "Distribute horizontally" ) );
|
||||
|
||||
commit.Push( _( "Distribute Horizontally" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -596,13 +574,12 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersHorizontally( std::vector<std::pa
|
|||
BOARD_COMMIT& aCommit ) const
|
||||
{
|
||||
std::sort( aItems.begin(), aItems.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( left.second.Centre().x < right.second.Centre().x );
|
||||
return ( lhs.second.Centre().x < rhs.second.Centre().x );
|
||||
} );
|
||||
|
||||
const int totalGap = ( aItems.end() - 1 )->second.Centre().x
|
||||
- aItems.begin()->second.Centre().x;
|
||||
const int totalGap = ( aItems.end()-1 )->second.Centre().x - aItems.begin()->second.Centre().x;
|
||||
const int itemGap = totalGap / ( aItems.size() - 1 );
|
||||
int targetX = aItems.begin()->second.Centre().x;
|
||||
|
||||
|
@ -649,20 +626,20 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
|||
|
||||
// find the last item by reverse sorting
|
||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
{
|
||||
return ( left.second.GetBottom() > right.second.GetBottom() );
|
||||
} );
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( lhs.second.GetBottom() > rhs.second.GetBottom() );
|
||||
} );
|
||||
|
||||
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
||||
const int maxBottom = itemsToDistribute.begin()->second.GetBottom();
|
||||
|
||||
// sort to get starting order
|
||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
{
|
||||
return ( left.second.Centre().y < right.second.Centre().y );
|
||||
} );
|
||||
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||
{
|
||||
return ( lhs.second.Centre().y < rhs.second.Centre().y );
|
||||
} );
|
||||
|
||||
int minY = itemsToDistribute.begin()->second.GetY();
|
||||
int totalGap = maxBottom - minY;
|
||||
|
@ -682,8 +659,7 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
|||
doDistributeGapsVertically( itemsToDistribute, commit, lastItem, totalGap );
|
||||
}
|
||||
|
||||
commit.Push( _( "Distribute vertically" ) );
|
||||
|
||||
commit.Push( _( "Distribute Vertically" ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -723,9 +699,9 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersVertically( std::vector<std::pair
|
|||
BOARD_COMMIT& aCommit ) const
|
||||
{
|
||||
std::sort( aItems.begin(), aItems.end(),
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left, const std::pair<BOARD_ITEM*, BOX2I> right)
|
||||
[] ( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs)
|
||||
{
|
||||
return ( left.second.Centre().y < right.second.Centre().y );
|
||||
return ( lhs.second.Centre().y < rhs.second.Centre().y );
|
||||
} );
|
||||
|
||||
const int totalGap = ( aItems.end() - 1 )->second.Centre().y
|
||||
|
|
|
@ -203,7 +203,7 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE& aZone, const ZONE& aCutout )
|
|||
|
||||
// TODO Refill zones when KiCad supports auto re-fill
|
||||
|
||||
commit.Push( _( "Add a zone cutout" ) );
|
||||
commit.Push( _( "Add Zone Cutout" ) );
|
||||
|
||||
// Select the new zone and set it as the source for the next cutout
|
||||
if( newZones.empty() )
|
||||
|
@ -215,7 +215,6 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE& aZone, const ZONE& aCutout )
|
|||
m_params.m_sourceZone = newZones[0];
|
||||
toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, newZones[0] );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -238,17 +237,16 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE> aZone )
|
|||
commit.Add( aZone.get() );
|
||||
commit.Push( _( "Add a zone" ) );
|
||||
|
||||
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem,
|
||||
aZone.release() );
|
||||
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, aZone.release() );
|
||||
break;
|
||||
}
|
||||
|
||||
case ZONE_MODE::GRAPHIC_POLYGON:
|
||||
{
|
||||
BOARD_COMMIT commit( &m_tool );
|
||||
BOARD* board = m_tool.getModel<BOARD>();
|
||||
PCB_LAYER_ID layer = m_params.m_layer;
|
||||
PCB_SHAPE* poly = new PCB_SHAPE( m_tool.m_frame->GetModel() );
|
||||
BOARD_COMMIT commit( &m_tool );
|
||||
BOARD* board = m_tool.getModel<BOARD>();
|
||||
PCB_LAYER_ID layer = m_params.m_layer;
|
||||
PCB_SHAPE* poly = new PCB_SHAPE( m_tool.m_frame->GetModel() );
|
||||
|
||||
poly->SetShape( SHAPE_T::POLY );
|
||||
|
||||
|
@ -265,8 +263,7 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE> aZone )
|
|||
commit.Add( poly );
|
||||
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, poly );
|
||||
|
||||
commit.Push( _( "Add a graphical polygon" ) );
|
||||
|
||||
commit.Push( _( "Add Polygon" ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
using namespace std::placeholders;
|
||||
#include <macros.h>
|
||||
#include <pcb_edit_frame.h>
|
||||
#include <board.h>
|
||||
#include <pcb_track.h>
|
||||
#include <pcb_group.h>
|
||||
#include <pcb_target.h>
|
||||
|
@ -95,126 +94,14 @@ using namespace std::placeholders;
|
|||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Test if aItem exists somewhere in undo/redo lists of items. Used by PutDataInPreviousState
|
||||
* to be sure an item was not deleted since an undo or redo.
|
||||
*
|
||||
* This could be possible:
|
||||
* - if a call to SaveCopyInUndoList was forgotten in Pcbnew
|
||||
* - in zones outlines, when a change in one zone merges this zone with an other
|
||||
* Before using this function to test existence of items, it must be called with aItem = NULL to
|
||||
* prepare the list.
|
||||
*
|
||||
* @param aPcb is the board to test.
|
||||
* @param aItem is the item to find or NULL to build the list of existing items.
|
||||
*/
|
||||
static bool TestForExistingItem( BOARD* aPcb, BOARD_ITEM* aItem )
|
||||
{
|
||||
for( PCB_TRACK* item : aPcb->Tracks() )
|
||||
{
|
||||
if( aItem == item)
|
||||
return true;
|
||||
}
|
||||
|
||||
for( FOOTPRINT* item : aPcb->Footprints() )
|
||||
{
|
||||
if( aItem == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( BOARD_ITEM* item : aPcb->Drawings() )
|
||||
{
|
||||
if( aItem == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( ZONE* item : aPcb->Zones() )
|
||||
{
|
||||
if( aItem == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( const NETINFO_ITEM* item : aPcb->GetNetInfo() )
|
||||
{
|
||||
if( aItem == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
for( PCB_GROUP* item : aPcb->Groups() )
|
||||
{
|
||||
if( aItem == item )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo,
|
||||
const PICKED_ITEMS_LIST& aItemsList,
|
||||
UNDO_REDO aCommandType )
|
||||
{
|
||||
int preExisting = commandToUndo->GetCount();
|
||||
|
||||
// First, filter unnecessary stuff from the list (i.e. for multiple pads / labels modified),
|
||||
// take the first occurrence of the footprint (we save copies of footprints when one of its
|
||||
// subitems is changed).
|
||||
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
|
||||
{
|
||||
ITEM_PICKER curr_picker = aItemsList.GetItemWrapper(ii);
|
||||
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( aItemsList.GetPickedItem( ii ) );
|
||||
|
||||
// For items belonging to footprints, we need to save state of the parent footprint
|
||||
if( item && item->GetParent() && item->GetParent()->Type() == PCB_FOOTPRINT_T )
|
||||
{
|
||||
item = item->GetParent();
|
||||
|
||||
// Check if the parent footprint has already been saved in another entry
|
||||
bool found = false;
|
||||
|
||||
for( unsigned j = 0; j < commandToUndo->GetCount(); j++ )
|
||||
{
|
||||
if( commandToUndo->GetPickedItem( j ) == item
|
||||
&& commandToUndo->GetPickedItemStatus( j ) == UNDO_REDO::CHANGED )
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !found )
|
||||
{
|
||||
// Create a clean copy of the parent footprint
|
||||
FOOTPRINT* orig = static_cast<FOOTPRINT*>( item );
|
||||
FOOTPRINT* clone = new FOOTPRINT( *orig );
|
||||
clone->SetParent( GetBoard() );
|
||||
clone->SetParentGroup( nullptr );
|
||||
|
||||
// Clear current flags (which can be temporary set by a current edit command)
|
||||
for( BOARD_ITEM* child : clone->GraphicalItems() )
|
||||
child->ClearEditFlags();
|
||||
|
||||
for( PAD* pad : clone->Pads() )
|
||||
pad->ClearEditFlags();
|
||||
|
||||
clone->Reference().ClearEditFlags();
|
||||
clone->Value().ClearEditFlags();
|
||||
|
||||
ITEM_PICKER picker( nullptr, item, UNDO_REDO::CHANGED );
|
||||
picker.SetLink( clone );
|
||||
commandToUndo->PushItem( picker );
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Normal case: all other BOARD_ITEMs, are simply copied to the new list
|
||||
commandToUndo->PushItem( curr_picker );
|
||||
}
|
||||
}
|
||||
commandToUndo->PushItem( aItemsList.GetItemWrapper(ii) );
|
||||
|
||||
for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
|
||||
{
|
||||
|
@ -258,8 +145,7 @@ void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo,
|
|||
break;
|
||||
|
||||
default:
|
||||
wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ),
|
||||
command ) );
|
||||
wxFAIL_MSG( wxString::Format( wxT( "Unrecognized undo command: %X" ), command ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -412,7 +298,7 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList )
|
|||
&& status != UNDO_REDO::GRIDORIGIN // origin markers never on board
|
||||
&& status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
|
||||
{
|
||||
if( !TestForExistingItem( GetBoard(), (BOARD_ITEM*) eda_item ) )
|
||||
if( GetBoard()->GetItem( eda_item->m_Uuid ) == DELETED_BOARD_ITEM::GetInstance() )
|
||||
{
|
||||
// Checking if it ever happens
|
||||
wxASSERT_MSG( false, wxT( "Item in the undo buffer does not exist" ) );
|
||||
|
|
Loading…
Reference in New Issue