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()
|
bool isSyntheticClick = symbol && evt->IsActivate() && evt->HasPosition()
|
||||||
&& evt->Matches( aEvent );
|
&& evt->Matches( aEvent );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( symbol && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
m_frame->GetInfoBar()->Dismiss();
|
m_frame->GetInfoBar()->Dismiss();
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ int SCH_DRAWING_TOOLS::PlaceSymbol( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
else if( symbol && evt->IsAction( &ACTIONS::redo ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -550,7 +550,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
bool isSyntheticClick = image && evt->IsActivate() && evt->HasPosition()
|
bool isSyntheticClick = image && evt->IsActivate() && evt->HasPosition()
|
||||||
&& evt->Matches( aEvent );
|
&& evt->Matches( aEvent );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
m_frame->GetInfoBar()->Dismiss();
|
m_frame->GetInfoBar()->Dismiss();
|
||||||
|
|
||||||
|
@ -689,7 +689,7 @@ int SCH_DRAWING_TOOLS::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
else if( image && evt->IsAction( &ACTIONS::redo ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -806,7 +806,7 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
|
||||||
cursorPos = grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr );
|
cursorPos = grid.BestSnapAnchor( cursorPos, LAYER_CONNECTABLE, nullptr );
|
||||||
controls->ForceCursorPosition( true, cursorPos );
|
controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() )
|
||||||
{
|
{
|
||||||
m_frame->PopTool( aEvent );
|
m_frame->PopTool( aEvent );
|
||||||
break;
|
break;
|
||||||
|
@ -934,10 +934,6 @@ int SCH_DRAWING_TOOLS::SingleClickPlace( const TOOL_EVENT& aEvent )
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
|
@ -1551,7 +1547,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
|
bool isSyntheticClick = item && evt->IsActivate() && evt->HasPosition()
|
||||||
&& evt->Matches( aEvent );
|
&& evt->Matches( aEvent );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( item && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
if( item )
|
if( item )
|
||||||
{
|
{
|
||||||
|
@ -1700,7 +1696,7 @@ int SCH_DRAWING_TOOLS::DrawShape( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
else if( item && evt->IsAction( &ACTIONS::redo ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -1771,7 +1767,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
||||||
bool isSyntheticClick = sheet && evt->IsActivate() && evt->HasPosition()
|
bool isSyntheticClick = sheet && evt->IsActivate() && evt->HasPosition()
|
||||||
&& evt->Matches( aEvent );
|
&& evt->Matches( aEvent );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( sheet && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
m_frame->GetInfoBar()->Dismiss();
|
m_frame->GetInfoBar()->Dismiss();
|
||||||
|
|
||||||
|
@ -1897,7 +1893,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
m_menu.ShowContextMenu( m_selectionTool->GetSelection() );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
else if( sheet && evt->IsAction( &ACTIONS::redo ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <wx/string.h>
|
#include <wx/string.h>
|
||||||
#include <undo_redo_container.h>
|
#include <undo_redo_container.h>
|
||||||
|
#include <kiid.h>
|
||||||
|
|
||||||
class EDA_ITEM;
|
class EDA_ITEM;
|
||||||
class BASE_SCREEN;
|
class BASE_SCREEN;
|
||||||
|
@ -43,9 +44,7 @@ enum CHANGE_TYPE {
|
||||||
CHT_MODIFY = 4,
|
CHT_MODIFY = 4,
|
||||||
CHT_TYPE = CHT_ADD | CHT_REMOVE | CHT_MODIFY,
|
CHT_TYPE = CHT_ADD | CHT_REMOVE | CHT_MODIFY,
|
||||||
|
|
||||||
///< Flag to indicate the change is already applied,
|
CHT_DONE = 8, ///< Flag to indicate the change is already applied
|
||||||
///< just notify observers (not compatible with CHT_MODIFY)
|
|
||||||
CHT_DONE = 8,
|
|
||||||
CHT_FLAGS = CHT_DONE
|
CHT_FLAGS = CHT_DONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,9 +150,10 @@ public:
|
||||||
protected:
|
protected:
|
||||||
struct COMMIT_LINE
|
struct COMMIT_LINE
|
||||||
{
|
{
|
||||||
EDA_ITEM* m_item; ///< Main item that is added/deleted/modified
|
EDA_ITEM* m_item; ///< Main item that is added/deleted/modified
|
||||||
EDA_ITEM* m_copy; ///< Optional copy of the item
|
EDA_ITEM* m_copy; ///< Optional copy of the item
|
||||||
CHANGE_TYPE m_type; ///< Modification type
|
CHANGE_TYPE m_type; ///< Modification type
|
||||||
|
KIID m_parent = NilUuid(); ///< Parent item (primarily for undo of deleted items)
|
||||||
BASE_SCREEN* m_screen;
|
BASE_SCREEN* m_screen;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,30 +44,20 @@ using namespace std::placeholders;
|
||||||
|
|
||||||
BOARD_COMMIT::BOARD_COMMIT( TOOL_BASE* aTool ) :
|
BOARD_COMMIT::BOARD_COMMIT( TOOL_BASE* aTool ) :
|
||||||
m_toolMgr( aTool->GetManager() ),
|
m_toolMgr( aTool->GetManager() ),
|
||||||
m_isFootprintEditor( false ),
|
|
||||||
m_isBoardEditor( false )
|
m_isBoardEditor( false )
|
||||||
{
|
{
|
||||||
if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
|
if( PCB_TOOL_BASE* pcb_tool = dynamic_cast<PCB_TOOL_BASE*>( aTool ) )
|
||||||
{
|
|
||||||
m_isFootprintEditor = pcb_tool->IsFootprintEditor();
|
|
||||||
m_isBoardEditor = pcb_tool->IsBoardEditor();
|
m_isBoardEditor = pcb_tool->IsBoardEditor();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame ) :
|
BOARD_COMMIT::BOARD_COMMIT( EDA_DRAW_FRAME* aFrame ) :
|
||||||
m_toolMgr( aFrame->GetToolManager() ),
|
m_toolMgr( aFrame->GetToolManager() ),
|
||||||
m_isFootprintEditor( aFrame->IsType( FRAME_FOOTPRINT_EDITOR ) ),
|
|
||||||
m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) )
|
m_isBoardEditor( aFrame->IsType( FRAME_PCB_EDITOR ) )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOARD_COMMIT::~BOARD_COMMIT()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BOARD* BOARD_COMMIT::GetBoard() const
|
BOARD* BOARD_COMMIT::GetBoard() const
|
||||||
{
|
{
|
||||||
return static_cast<BOARD*>( m_toolMgr->GetModel() );
|
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 );
|
wxCHECK( aItem, *this );
|
||||||
|
|
||||||
aItem->ClearFlags( IS_MODIFIED_CHILD );
|
if( aChangeType == CHT_MODIFY && aItem->Type() == PCB_GROUP_T )
|
||||||
|
|
||||||
// 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( aItem->Type() == PCB_FOOTPRINT_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<FOOTPRINT*>( aItem )->RunOnChildren(
|
static_cast<PCB_GROUP*>( aItem )->RunOnChildren(
|
||||||
[&]( BOARD_ITEM* child )
|
[&]( BOARD_ITEM* child )
|
||||||
{
|
{
|
||||||
child->SetFlags( IS_MODIFIED_CHILD );
|
COMMIT::Stage( child, aChangeType );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return COMMIT::Stage( aItem, 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 )
|
if( item->Type() == PCB_ZONE_T )
|
||||||
zoneFillerTool->DirtyZone( static_cast<ZONE*>( item ) );
|
zoneFillerTool->DirtyZone( static_cast<ZONE*>( item ) );
|
||||||
|
|
||||||
if( item->Type() == PCB_FOOTPRINT_T )
|
if( item->Type() == PCB_GROUP_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 )
|
|
||||||
{
|
{
|
||||||
static_cast<PCB_GROUP*>( item )->RunOnChildren(
|
static_cast<PCB_GROUP*>( item )->RunOnChildren(
|
||||||
[&]( BOARD_ITEM* child )
|
[&]( BOARD_ITEM* child )
|
||||||
{
|
{
|
||||||
dirtyIntersectingZones( child, aChangeType );
|
dirtyIntersectingZones( child, aChangeType );
|
||||||
child->ClearFlags( IS_MODIFIED_CHILD );
|
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
else
|
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
|
// Notification info
|
||||||
PICKED_ITEMS_LIST undoList;
|
PICKED_ITEMS_LIST undoList;
|
||||||
std::set<EDA_ITEM*> savedModules;
|
|
||||||
bool itemsDeselected = false;
|
bool itemsDeselected = false;
|
||||||
bool selectedModified = 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();
|
std::shared_ptr<CONNECTIVITY_DATA> connectivity = board->GetConnectivity();
|
||||||
|
|
||||||
// Note:
|
// Note: frame == nullptr happens in QA tests
|
||||||
// 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
|
|
||||||
|
|
||||||
std::vector<BOARD_ITEM*> bulkAddedItems;
|
std::vector<BOARD_ITEM*> bulkAddedItems;
|
||||||
std::vector<BOARD_ITEM*> bulkRemovedItems;
|
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 );
|
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( ent.m_item );
|
||||||
|
|
||||||
wxASSERT( 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 );
|
wxCHECK2( boardItem, continue );
|
||||||
|
|
||||||
if( m_isBoardEditor )
|
if( m_isBoardEditor )
|
||||||
|
@ -354,43 +238,25 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||||
if( boardItem->IsSelected() )
|
if( boardItem->IsSelected() )
|
||||||
selectedModified = true;
|
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 )
|
switch( changeType )
|
||||||
{
|
{
|
||||||
case CHT_ADD:
|
case CHT_ADD:
|
||||||
{
|
|
||||||
if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
|
if( selTool && selTool->GetEnteredGroup() && !boardItem->GetParentGroup()
|
||||||
&& PCB_GROUP::IsGroupableType( boardItem->Type() ) )
|
&& PCB_GROUP::IsGroupableType( boardItem->Type() ) )
|
||||||
{
|
{
|
||||||
selTool->GetEnteredGroup()->AddItem( boardItem );
|
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
|
if( FOOTPRINT* parentFP = boardItem->GetParentFootprint() )
|
||||||
wxASSERT( boardItem->Type() != PCB_FOOTPRINT_T );
|
{
|
||||||
|
parentFP->Add( boardItem );
|
||||||
boardItem->SetParent( board->Footprints().front() );
|
}
|
||||||
|
else
|
||||||
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 ) )
|
|
||||||
{
|
{
|
||||||
board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
|
board->Add( boardItem, ADD_MODE::BULK_INSERT ); // handles connectivity
|
||||||
bulkAddedItems.push_back( boardItem );
|
bulkAddedItems.push_back( boardItem );
|
||||||
|
@ -404,14 +270,13 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||||
view->Add( boardItem );
|
view->Add( boardItem );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case CHT_REMOVE:
|
case CHT_REMOVE:
|
||||||
{
|
{
|
||||||
FOOTPRINT* parentFP = boardItem->GetParentFootprint();
|
FOOTPRINT* parentFP = boardItem->GetParentFootprint();
|
||||||
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
|
PCB_GROUP* parentGroup = boardItem->GetParentGroup();
|
||||||
|
|
||||||
if( !m_isFootprintEditor && !( aCommitFlags & SKIP_UNDO ) )
|
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||||
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
|
undoList.PushItem( ITEM_PICKER( nullptr, boardItem, UNDO_REDO::DELETED ) );
|
||||||
|
|
||||||
if( boardItem->IsSelected() )
|
if( boardItem->IsSelected() )
|
||||||
|
@ -425,6 +290,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||||
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
|
if( parentGroup && !( parentGroup->GetFlags() & STRUCT_DELETED ) )
|
||||||
parentGroup->RemoveItem( boardItem );
|
parentGroup->RemoveItem( boardItem );
|
||||||
|
|
||||||
|
if( parentFP && !( parentFP->GetFlags() & STRUCT_DELETED ) )
|
||||||
|
ent.m_parent = parentFP->m_Uuid;
|
||||||
|
|
||||||
if( autofillZones )
|
if( autofillZones )
|
||||||
dirtyIntersectingZones( boardItem, changeType );
|
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_TARGET_T: // a target (graphic item)
|
||||||
case PCB_MARKER_T: // a marker used to show something
|
case PCB_MARKER_T: // a marker used to show something
|
||||||
case PCB_ZONE_T:
|
case PCB_ZONE_T:
|
||||||
|
case PCB_FOOTPRINT_T:
|
||||||
if( view )
|
if( view )
|
||||||
view->Remove( boardItem );
|
view->Remove( boardItem );
|
||||||
|
|
||||||
|
@ -465,27 +334,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||||
|
|
||||||
break;
|
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:
|
case PCB_GROUP_T:
|
||||||
if( view )
|
if( view )
|
||||||
view->Remove( boardItem );
|
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 );
|
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 );
|
ITEM_PICKER itemWrapper( nullptr, boardItem, UNDO_REDO::CHANGED );
|
||||||
wxASSERT( boardItemCopy );
|
wxASSERT( boardItemCopy );
|
||||||
|
@ -539,26 +387,15 @@ void BOARD_COMMIT::Push( const wxString& aMessage, int aCommitFlags )
|
||||||
connectivity->Update( boardItem );
|
connectivity->Update( boardItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( autofillZones )
|
if( m_isBoardEditor && autofillZones )
|
||||||
{
|
{
|
||||||
dirtyIntersectingZones( boardItemCopy, changeType ); // before
|
dirtyIntersectingZones( boardItemCopy, changeType ); // before
|
||||||
dirtyIntersectingZones( boardItem, changeType ); // after
|
dirtyIntersectingZones( boardItem, changeType ); // after
|
||||||
}
|
}
|
||||||
|
|
||||||
if( view )
|
if( view )
|
||||||
{
|
|
||||||
view->Update( boardItem );
|
view->Update( boardItem );
|
||||||
|
|
||||||
if( m_isFootprintEditor )
|
|
||||||
{
|
|
||||||
static_cast<FOOTPRINT*>( boardItem )->RunOnChildren(
|
|
||||||
[&]( BOARD_ITEM* aChild )
|
|
||||||
{
|
|
||||||
view->Update( aChild );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
itemsChanged.push_back( boardItem );
|
itemsChanged.push_back( boardItem );
|
||||||
|
|
||||||
// if no undo entry is needed, the copy would create a memory leak
|
// 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();
|
boardItem->ClearEditFlags();
|
||||||
|
|
||||||
if( m_isFootprintEditor && boardItem->Type() == PCB_FOOTPRINT_T )
|
|
||||||
{
|
|
||||||
static_cast<FOOTPRINT*>( boardItem )->RunOnChildren(
|
|
||||||
[&]( BOARD_ITEM* aChild )
|
|
||||||
{
|
|
||||||
aChild->ClearEditFlags();
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bulkAddedItems.size() > 0 )
|
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 )
|
if( !( aCommitFlags & SKIP_UNDO ) )
|
||||||
frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
{
|
||||||
else
|
if( aCommitFlags & APPEND_UNDO )
|
||||||
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
frame->AppendCopyToUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||||
|
else
|
||||||
|
frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNSPECIFIED );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
|
m_toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
|
||||||
|
@ -742,8 +573,17 @@ void BOARD_COMMIT::Revert()
|
||||||
|
|
||||||
view->Remove( boardItem );
|
view->Remove( boardItem );
|
||||||
connectivity->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;
|
break;
|
||||||
|
|
||||||
case CHT_REMOVE:
|
case CHT_REMOVE:
|
||||||
|
@ -752,8 +592,17 @@ void BOARD_COMMIT::Revert()
|
||||||
|
|
||||||
view->Add( boardItem );
|
view->Add( boardItem );
|
||||||
connectivity->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;
|
break;
|
||||||
|
|
||||||
case CHT_MODIFY:
|
case CHT_MODIFY:
|
||||||
|
@ -801,7 +650,7 @@ void BOARD_COMMIT::Revert()
|
||||||
if( itemsChanged.size() > 0 )
|
if( itemsChanged.size() > 0 )
|
||||||
board->OnItemsChanged( itemsChanged );
|
board->OnItemsChanged( itemsChanged );
|
||||||
|
|
||||||
if ( !m_isFootprintEditor )
|
if( m_isBoardEditor )
|
||||||
{
|
{
|
||||||
connectivity->RecalculateRatsnest();
|
connectivity->RecalculateRatsnest();
|
||||||
board->UpdateRatsnestExclusions();
|
board->UpdateRatsnestExclusions();
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
BOARD_COMMIT( EDA_DRAW_FRAME* aFrame );
|
BOARD_COMMIT( EDA_DRAW_FRAME* aFrame );
|
||||||
BOARD_COMMIT( TOOL_BASE *aTool );
|
BOARD_COMMIT( TOOL_BASE *aTool );
|
||||||
|
|
||||||
virtual ~BOARD_COMMIT();
|
virtual ~BOARD_COMMIT() {}
|
||||||
|
|
||||||
BOARD* GetBoard() const;
|
BOARD* GetBoard() const;
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TOOL_MANAGER* m_toolMgr;
|
TOOL_MANAGER* m_toolMgr;
|
||||||
bool m_isFootprintEditor;
|
|
||||||
bool m_isBoardEditor;
|
bool m_isBoardEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1046,7 +1046,7 @@ int BOARD_EDITOR_CONTROL::PlaceFootprint( const TOOL_EVENT& aEvent )
|
||||||
if( reselect && fp )
|
if( reselect && fp )
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, fp );
|
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, fp );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() )
|
if( evt->IsCancelInteractive() || ( fp && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
if( fp )
|
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
|
// Calling 'Properties' action clears the selection, so we need to restore it
|
||||||
reselect = true;
|
reselect = true;
|
||||||
}
|
}
|
||||||
else if( fp && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( fp && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -1227,7 +1228,6 @@ int BOARD_EDITOR_CONTROL::modifyLockSelected( MODIFY_MODE aMode )
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
||||||
|
|
||||||
wxCHECK2( board_item, continue );
|
wxCHECK2( board_item, continue );
|
||||||
|
|
||||||
commit.Modify( board_item );
|
commit.Modify( board_item );
|
||||||
|
@ -1369,7 +1369,7 @@ int BOARD_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
if( mergeZones( m_frame, commit, toMerge, merged ) )
|
if( mergeZones( m_frame, commit, toMerge, merged ) )
|
||||||
{
|
{
|
||||||
commit.Push( wxT( "Merge zones" ) );
|
commit.Push( wxT( "Merge Zones" ) );
|
||||||
|
|
||||||
for( EDA_ITEM* item : merged )
|
for( EDA_ITEM* item : merged )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, item );
|
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 ) );
|
newZone->Move( VECTOR2I( pcbIUScale.IU_PER_MM, pcbIUScale.IU_PER_MM ) );
|
||||||
|
|
||||||
commit.Add( newZone.release() );
|
commit.Add( newZone.release() );
|
||||||
commit.Push( _( "Duplicate zone" ) );
|
commit.Push( _( "Duplicate Zone" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1434,6 @@ int BOARD_EDITOR_CONTROL::ZoneDuplicate( const TOOL_EVENT& aEvent )
|
||||||
int BOARD_EDITOR_CONTROL::CrossProbeToSch( const TOOL_EVENT& aEvent )
|
int BOARD_EDITOR_CONTROL::CrossProbeToSch( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
doCrossProbePcbToSch( aEvent, false );
|
doCrossProbePcbToSch( aEvent, false );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1442,7 +1441,6 @@ int BOARD_EDITOR_CONTROL::CrossProbeToSch( const TOOL_EVENT& aEvent )
|
||||||
int BOARD_EDITOR_CONTROL::ExplicitCrossProbeToSch( const TOOL_EVENT& aEvent )
|
int BOARD_EDITOR_CONTROL::ExplicitCrossProbeToSch( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
doCrossProbePcbToSch( aEvent, true );
|
doCrossProbePcbToSch( aEvent, true );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1618,20 +1616,17 @@ void BOARD_EDITOR_CONTROL::setTransitions()
|
||||||
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::BoardSetup, PCB_ACTIONS::boardSetup.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::BoardSetup, PCB_ACTIONS::boardSetup.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::ImportNetlist, PCB_ACTIONS::importNetlist.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::ImportNetlist, PCB_ACTIONS::importNetlist.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::ImportSpecctraSession,
|
Go( &BOARD_EDITOR_CONTROL::ImportSpecctraSession, PCB_ACTIONS::importSpecctraSession.MakeEvent() );
|
||||||
PCB_ACTIONS::importSpecctraSession.MakeEvent() );
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::ExportSpecctraDSN, PCB_ACTIONS::exportSpecctraDSN.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::ExportSpecctraDSN, PCB_ACTIONS::exportSpecctraDSN.MakeEvent() );
|
||||||
|
|
||||||
if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame &&
|
if( ADVANCED_CFG::GetCfg().m_ShowPcbnewExportNetlist && m_frame &&
|
||||||
m_frame->GetExportNetlistAction() )
|
m_frame->GetExportNetlistAction() )
|
||||||
Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::ExportNetlist, m_frame->GetExportNetlistAction()->MakeEvent() );
|
||||||
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::GenerateDrillFiles,
|
Go( &BOARD_EDITOR_CONTROL::GenerateDrillFiles, PCB_ACTIONS::generateDrillFiles.MakeEvent() );
|
||||||
PCB_ACTIONS::generateDrillFiles.MakeEvent() );
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateGerbers.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateGerbers.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::GeneratePosFile, PCB_ACTIONS::generatePosFile.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::GeneratePosFile, PCB_ACTIONS::generatePosFile.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles,
|
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateReportFile.MakeEvent() );
|
||||||
PCB_ACTIONS::generateReportFile.MakeEvent() );
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateD356File.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateD356File.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::GenerateFabFiles, PCB_ACTIONS::generateBOM.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::AssignNetclass, PCB_ACTIONS::assignNetClass.MakeEvent() );
|
||||||
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::UpdatePCBFromSchematic,
|
Go( &BOARD_EDITOR_CONTROL::UpdatePCBFromSchematic, ACTIONS::updatePcbFromSchematic.MakeEvent() );
|
||||||
ACTIONS::updatePcbFromSchematic.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB, ACTIONS::updateSchematicFromPcb.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::UpdateSchematicFromPCB,
|
|
||||||
ACTIONS::updateSchematicFromPcb.MakeEvent() );
|
|
||||||
Go( &BOARD_EDITOR_CONTROL::ShowEeschema, PCB_ACTIONS::showEeschema.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::ShowEeschema, PCB_ACTIONS::showEeschema.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::ToggleLayersManager, PCB_ACTIONS::showLayersManager.MakeEvent() );
|
Go( &BOARD_EDITOR_CONTROL::ToggleLayersManager, PCB_ACTIONS::showLayersManager.MakeEvent() );
|
||||||
Go( &BOARD_EDITOR_CONTROL::ToggleProperties, ACTIONS::showProperties.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 ) )
|
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
|
else
|
||||||
commit.Push( _( "Convert shapes to zone" ) );
|
{
|
||||||
|
if( m_userSettings.m_DeleteOriginals )
|
||||||
|
commit.Push( _( "Convert to Zone" ) );
|
||||||
|
else
|
||||||
|
commit.Push( _( "Create Zone" ) );
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1105,7 +1115,7 @@ int CONVERT_TOOL::SegmentToArc( const TOOL_EVENT& aEvent )
|
||||||
commit.Add( arc );
|
commit.Add( arc );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Create arc from line segment" ) );
|
commit.Push( _( "Create Arc" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -344,7 +344,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
|
||||||
if( line )
|
if( line )
|
||||||
{
|
{
|
||||||
commit.Add( line );
|
commit.Add( line );
|
||||||
commit.Push( _( "Draw a line segment" ) );
|
commit.Push( _( "Draw Line" ) );
|
||||||
startingPoint = VECTOR2D( line->GetEnd() );
|
startingPoint = VECTOR2D( line->GetEnd() );
|
||||||
committedLines.push( line );
|
committedLines.push( line );
|
||||||
}
|
}
|
||||||
|
@ -408,7 +408,7 @@ int DRAWING_TOOL::DrawRectangle( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
rect->NormalizeRect();
|
rect->NormalizeRect();
|
||||||
commit.Add( rect );
|
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 );
|
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, rect );
|
||||||
}
|
}
|
||||||
|
@ -456,7 +456,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
|
||||||
if( circle )
|
if( circle )
|
||||||
{
|
{
|
||||||
commit.Add( circle );
|
commit.Add( circle );
|
||||||
commit.Push( _( "Draw a circle" ) );
|
commit.Push( _( "Draw Circle" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, circle );
|
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, circle );
|
||||||
}
|
}
|
||||||
|
@ -503,7 +503,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
|
||||||
if( arc )
|
if( arc )
|
||||||
{
|
{
|
||||||
commit.Add( arc );
|
commit.Add( arc );
|
||||||
commit.Push( _( "Draw an arc" ) );
|
commit.Push( _( "Draw Arc" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, arc );
|
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, arc );
|
||||||
}
|
}
|
||||||
|
@ -601,7 +601,7 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
COORDS_PADDING );
|
COORDS_PADDING );
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( image && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
if( image )
|
if( image )
|
||||||
{
|
{
|
||||||
|
@ -703,7 +703,7 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
commit.Add( image );
|
commit.Add( image );
|
||||||
commit.Push( _( "Place an image" ) );
|
commit.Push( _( "Place Image" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, 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() );
|
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 );
|
image->SetPosition( cursorPos );
|
||||||
m_view->ClearPreview();
|
m_view->ClearPreview();
|
||||||
|
@ -738,11 +739,8 @@ int DRAWING_TOOL::PlaceImage( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
else if( image && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( image && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
{
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -837,7 +835,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
COORDS_PADDING );
|
COORDS_PADDING );
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( text && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
if( text )
|
if( text )
|
||||||
{
|
{
|
||||||
|
@ -891,15 +889,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
textAttrs.m_Halign = GR_TEXT_H_ALIGN_LEFT;
|
||||||
textAttrs.m_Valign = GR_TEXT_V_ALIGN_BOTTOM;
|
textAttrs.m_Valign = GR_TEXT_V_ALIGN_BOTTOM;
|
||||||
|
|
||||||
// Init the new item attributes
|
|
||||||
if( m_isFootprintEditor )
|
if( m_isFootprintEditor )
|
||||||
{
|
|
||||||
text = new PCB_TEXT( static_cast<FOOTPRINT*>( m_frame->GetModel() ) );
|
text = new PCB_TEXT( static_cast<FOOTPRINT*>( m_frame->GetModel() ) );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
text = new PCB_TEXT( m_frame->GetModel() );
|
text = new PCB_TEXT( m_frame->GetModel() );
|
||||||
}
|
|
||||||
|
|
||||||
text->SetLayer( layer );
|
text->SetLayer( layer );
|
||||||
text->SetAttributes( textAttrs );
|
text->SetAttributes( textAttrs );
|
||||||
|
@ -948,7 +941,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
|
||||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear );
|
||||||
|
|
||||||
commit.Add( text );
|
commit.Add( text );
|
||||||
commit.Push( _( "Place a text" ) );
|
commit.Push( _( "Place Text" ) );
|
||||||
|
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, 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->CaptureCursor( text != nullptr );
|
||||||
m_controls->SetAutoPan( 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 );
|
text->SetPosition( cursorPos );
|
||||||
selection().SetReferencePoint( cursorPos );
|
selection().SetReferencePoint( cursorPos );
|
||||||
m_view->Update( &selection() );
|
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();
|
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()->OnEditItemRequest( text );
|
frame()->SetMsgPanel( text );
|
||||||
m_view->Update( &selection() );
|
|
||||||
frame()->SetMsgPanel( text );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
evt->SetPassEvent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
|
||||||
wxBell();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1124,7 +1108,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( dimension && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
m_controls->SetAutoPan( false );
|
m_controls->SetAutoPan( false );
|
||||||
|
|
||||||
|
@ -1283,7 +1267,7 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||||
preview.Remove( dimension );
|
preview.Remove( dimension );
|
||||||
|
|
||||||
commit.Add( dimension );
|
commit.Add( dimension );
|
||||||
commit.Push( _( "Draw a dimension" ) );
|
commit.Push( _( "Draw Dimension" ) );
|
||||||
|
|
||||||
// Run the edit immediately to set the leader text
|
// Run the edit immediately to set the leader text
|
||||||
if( t == PCB_DIM_LEADER_T )
|
if( t == PCB_DIM_LEADER_T )
|
||||||
|
@ -1443,11 +1427,8 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( dimension && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( dimension && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
{
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -1525,7 +1506,6 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||||
for( std::unique_ptr<EDA_ITEM>& ptr : list )
|
for( std::unique_ptr<EDA_ITEM>& ptr : list )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( ptr.get() );
|
BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( ptr.get() );
|
||||||
|
|
||||||
wxCHECK2( item, continue );
|
wxCHECK2( item, continue );
|
||||||
|
|
||||||
newItems.push_back( item );
|
newItems.push_back( item );
|
||||||
|
@ -1545,7 +1525,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||||
for( BOARD_ITEM* item : newItems )
|
for( BOARD_ITEM* item : newItems )
|
||||||
commit.Add( item );
|
commit.Add( item );
|
||||||
|
|
||||||
commit.Push( _( "Place a DXF_SVG drawing" ) );
|
commit.Push( _( "Import Graphic" ) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,7 +1612,7 @@ int DRAWING_TOOL::PlaceImportedGraphics( const TOOL_EVENT& aEvent )
|
||||||
for( BOARD_ITEM* item : newItems )
|
for( BOARD_ITEM* item : newItems )
|
||||||
commit.Add( item );
|
commit.Add( item );
|
||||||
|
|
||||||
commit.Push( _( "Place a DXF_SVG drawing" ) );
|
commit.Push( _( "Import Graphic" ) );
|
||||||
break; // This is a one-shot command, not a tool
|
break; // This is a one-shot command, not a tool
|
||||||
}
|
}
|
||||||
else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
||||||
|
@ -1713,7 +1693,7 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
|
||||||
VECTOR2I moveVector = footprint->GetPosition() - cursorPos;
|
VECTOR2I moveVector = footprint->GetPosition() - cursorPos;
|
||||||
footprint->MoveAnchorPosition( moveVector );
|
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,
|
// Usually, we do not need to change twice the anchor position,
|
||||||
// so deselect the active tool
|
// so deselect the active tool
|
||||||
|
@ -1807,12 +1787,12 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// geometric construction manager
|
// geometric construction manager
|
||||||
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointManager;
|
KIGFX::PREVIEW::TWO_POINT_GEOMETRY_MANAGER twoPointMgr;
|
||||||
|
|
||||||
// drawing assistant overlay
|
// drawing assistant overlay
|
||||||
// TODO: workaround because EDA_SHAPE_TYPE_T is not visible from commons.
|
// 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::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
|
// Add a VIEW_GROUP that serves as a preview for the new item
|
||||||
PCB_SELECTION preview;
|
PCB_SELECTION preview;
|
||||||
|
@ -1976,8 +1956,8 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
|
|
||||||
grid.SetSkipPoint( cursorPos );
|
grid.SetSkipPoint( cursorPos );
|
||||||
|
|
||||||
twoPointManager.SetOrigin( cursorPos );
|
twoPointMgr.SetOrigin( cursorPos );
|
||||||
twoPointManager.SetEnd( cursorPos );
|
twoPointMgr.SetEnd( cursorPos );
|
||||||
|
|
||||||
if( !isLocalOriginSet )
|
if( !isLocalOriginSet )
|
||||||
m_frame->GetScreen()->m_LocalOrigin = cursorPos;
|
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();
|
m_frame->GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
}
|
}
|
||||||
else if( shape == SHAPE_T::CIRCLE )
|
|
||||||
{
|
|
||||||
// No clever logic if drawing a circle
|
|
||||||
preview.Clear();
|
|
||||||
twoPointManager.Reset();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PCB_SHAPE* snapItem = dynamic_cast<PCB_SHAPE*>( grid.GetSnapped() );
|
PCB_SHAPE* snapItem = dynamic_cast<PCB_SHAPE*>( grid.GetSnapped() );
|
||||||
|
|
||||||
if( twoPointManager.GetOrigin() == twoPointManager.GetEnd()
|
if( shape == SHAPE_T::SEGMENT && ( twoPointMgr.GetOrigin() == twoPointMgr.GetEnd()
|
||||||
|| ( evt->IsDblClick( BUT_LEFT ) && shape == SHAPE_T::SEGMENT )
|
|| evt->IsDblClick( BUT_LEFT )
|
||||||
|| snapItem )
|
|| snapItem ) )
|
||||||
// User has clicked twice in the same spot
|
|
||||||
// or clicked on the end of an existing segment (closing a path)
|
|
||||||
{
|
{
|
||||||
|
// 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 );
|
BOARD_COMMIT commit( m_frame );
|
||||||
|
|
||||||
// If the user clicks on an existing snap point from a drawsegment
|
// If the user clicks on an existing snap point from a drawsegment
|
||||||
// we finish the segment as they are likely closing a path
|
// 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.Add( graphic );
|
||||||
commit.Push( _( "Draw a line segment" ) );
|
commit.Push( _( "Draw Line" ) );
|
||||||
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, graphic );
|
m_toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, graphic );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2033,59 +2006,53 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
}
|
}
|
||||||
|
|
||||||
preview.Clear();
|
preview.Clear();
|
||||||
twoPointManager.Reset();
|
twoPointMgr.Reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
twoPointManager.SetEnd( GetClampedCoords( cursorPos ) );
|
twoPointMgr.SetEnd( GetClampedCoords( cursorPos ) );
|
||||||
}
|
}
|
||||||
else if( evt->IsMotion() )
|
else if( evt->IsMotion() )
|
||||||
{
|
{
|
||||||
VECTOR2I clampedCursorPos = cursorPos;
|
VECTOR2I clampedCursorPos = cursorPos;
|
||||||
|
|
||||||
if( shape == SHAPE_T::CIRCLE || shape == SHAPE_T::ARC )
|
if( shape == SHAPE_T::CIRCLE || shape == SHAPE_T::ARC )
|
||||||
{
|
clampedCursorPos = getClampedRadiusEnd( twoPointMgr.GetOrigin(), cursorPos );
|
||||||
clampedCursorPos = getClampedRadiusEnd( twoPointManager.GetOrigin(), cursorPos );
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
clampedCursorPos = getClampedDifferenceEnd( twoPointMgr.GetOrigin(), cursorPos );
|
||||||
clampedCursorPos = getClampedDifferenceEnd( twoPointManager.GetOrigin(),
|
|
||||||
cursorPos );
|
|
||||||
}
|
|
||||||
|
|
||||||
// 45 degree lines
|
// 45 degree lines
|
||||||
if( started && Is45Limited() )
|
if( started && Is45Limited() )
|
||||||
{
|
{
|
||||||
const VECTOR2I lineVector( clampedCursorPos
|
const VECTOR2I lineVector( clampedCursorPos - VECTOR2I( twoPointMgr.GetOrigin() ) );
|
||||||
- VECTOR2I( twoPointManager.GetOrigin() ) );
|
|
||||||
|
|
||||||
// get a restricted 45/H/V line from the last fixed point to the cursor
|
// get a restricted 45/H/V line from the last fixed point to the cursor
|
||||||
VECTOR2I newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECT ) );
|
VECTOR2I newEnd = GetVectorSnapped45( lineVector, ( shape == SHAPE_T::RECT ) );
|
||||||
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointManager.GetEnd() ) );
|
m_controls->ForceCursorPosition( true, VECTOR2I( twoPointMgr.GetEnd() ) );
|
||||||
twoPointManager.SetEnd( twoPointManager.GetOrigin() + newEnd );
|
twoPointMgr.SetEnd( twoPointMgr.GetOrigin() + newEnd );
|
||||||
twoPointManager.SetAngleSnap( true );
|
twoPointMgr.SetAngleSnap( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
twoPointManager.SetEnd( clampedCursorPos );
|
twoPointMgr.SetEnd( clampedCursorPos );
|
||||||
twoPointManager.SetAngleSnap( false );
|
twoPointMgr.SetAngleSnap( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
m_view->Update( &twoPointAsst );
|
m_view->Update( &twoPointAsst );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::undo )
|
else if( started && ( evt->IsAction( &ACTIONS::undo )
|
||||||
|| evt->IsAction( &PCB_ACTIONS::doDelete )
|
|| evt->IsAction( &PCB_ACTIONS::doDelete )
|
||||||
|| evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) )
|
|| evt->IsAction( &PCB_ACTIONS::deleteLastPoint ) ) )
|
||||||
{
|
{
|
||||||
if( graphic && !aCommittedGraphics->empty() )
|
if( aCommittedGraphics && !aCommittedGraphics->empty() )
|
||||||
{
|
{
|
||||||
twoPointManager.SetOrigin( aCommittedGraphics->top()->GetStart() );
|
twoPointMgr.SetOrigin( aCommittedGraphics->top()->GetStart() );
|
||||||
twoPointManager.SetEnd( aCommittedGraphics->top()->GetEnd() );
|
twoPointMgr.SetEnd( aCommittedGraphics->top()->GetEnd() );
|
||||||
aCommittedGraphics->pop();
|
aCommittedGraphics->pop();
|
||||||
|
|
||||||
getViewControls()->WarpMouseCursor( twoPointManager.GetEnd(), true );
|
getViewControls()->WarpMouseCursor( twoPointMgr.GetEnd(), true );
|
||||||
|
|
||||||
if( PICKED_ITEMS_LIST* undo = m_frame->PopCommandFromUndoList() )
|
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;
|
delete undo;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSegmentFromGeometryMgr( twoPointManager, graphic );
|
updateSegmentFromGeometryMgr( twoPointMgr, graphic );
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
m_view->Update( &twoPointAsst );
|
m_view->Update( &twoPointAsst );
|
||||||
}
|
}
|
||||||
else if( graphic )
|
else
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
@ -2110,10 +2077,6 @@ bool DRAWING_TOOL::drawShape( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
frame()->SetMsgPanel( graphic );
|
frame()->SetMsgPanel( graphic );
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else if( graphic && evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
else if( graphic && evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
||||||
{
|
{
|
||||||
if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
|
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 );
|
frame()->SetMsgPanel( graphic );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -2273,7 +2237,7 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ), COORDS_PADDING );
|
grid.BestSnapAnchor( m_controls->GetMousePosition(), graphic ), COORDS_PADDING );
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() || evt->IsAction( &ACTIONS::undo ) )
|
if( evt->IsCancelInteractive() || ( started && evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
@ -2406,18 +2370,26 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
else if( evt->IsAction( &PCB_ACTIONS::incWidth ) )
|
||||||
{
|
{
|
||||||
m_stroke.SetWidth( m_stroke.GetWidth() + WIDTH_STEP );
|
m_stroke.SetWidth( m_stroke.GetWidth() + WIDTH_STEP );
|
||||||
graphic->SetStroke( m_stroke );
|
|
||||||
m_view->Update( &preview );
|
if( graphic )
|
||||||
frame()->SetMsgPanel( graphic );
|
{
|
||||||
|
graphic->SetStroke( m_stroke );
|
||||||
|
m_view->Update( &preview );
|
||||||
|
frame()->SetMsgPanel( graphic );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
else if( evt->IsAction( &PCB_ACTIONS::decWidth ) )
|
||||||
{
|
{
|
||||||
if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
|
if( (unsigned) m_stroke.GetWidth() > WIDTH_STEP )
|
||||||
{
|
{
|
||||||
m_stroke.SetWidth( m_stroke.GetWidth() - WIDTH_STEP );
|
m_stroke.SetWidth( m_stroke.GetWidth() - WIDTH_STEP );
|
||||||
graphic->SetStroke( m_stroke );
|
|
||||||
m_view->Update( &preview );
|
if( graphic )
|
||||||
frame()->SetMsgPanel( graphic );
|
{
|
||||||
|
graphic->SetStroke( m_stroke );
|
||||||
|
m_view->Update( &preview );
|
||||||
|
frame()->SetMsgPanel( graphic );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::arcPosture ) )
|
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 );
|
m_view->Update( &arcAsst );
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
}
|
}
|
||||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
{
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
|
@ -2602,7 +2571,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( evt->IsCancelInteractive() )
|
if( evt->IsCancelInteractive() )
|
||||||
{
|
{
|
||||||
if( polyGeomMgr.IsPolygonInProgress() )
|
if( started )
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
|
@ -2616,7 +2585,7 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
else if( evt->IsActivate() )
|
else if( evt->IsActivate() )
|
||||||
{
|
{
|
||||||
if( polyGeomMgr.IsPolygonInProgress() )
|
if( started )
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
if( evt->IsPointEditor() )
|
if( evt->IsPointEditor() )
|
||||||
|
@ -2686,9 +2655,9 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( evt->IsAction( &PCB_ACTIONS::deleteLastPoint )
|
else if( started && ( evt->IsAction( &PCB_ACTIONS::deleteLastPoint )
|
||||||
|| evt->IsAction( &ACTIONS::doDelete )
|
|| evt->IsAction( &ACTIONS::doDelete )
|
||||||
|| evt->IsAction( &ACTIONS::undo ) )
|
|| evt->IsAction( &ACTIONS::undo ) ) )
|
||||||
{
|
{
|
||||||
if( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
|
if( std::optional<VECTOR2I> last = polyGeomMgr.DeleteLastCorner() )
|
||||||
{
|
{
|
||||||
|
@ -2697,21 +2666,22 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||||
m_controls->ForceCursorPosition( true, cursorPos );
|
m_controls->ForceCursorPosition( true, cursorPos );
|
||||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||||
}
|
}
|
||||||
else if( polyGeomMgr.IsPolygonInProgress() )
|
else
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( polyGeomMgr.IsPolygonInProgress()
|
else if( started && ( evt->IsMotion()
|
||||||
&& ( evt->IsMotion() || evt->IsDrag( BUT_LEFT ) ) )
|
|| evt->IsDrag( BUT_LEFT ) ) )
|
||||||
{
|
{
|
||||||
polyGeomMgr.SetCursorPosition( cursorPos );
|
polyGeomMgr.SetCursorPosition( cursorPos );
|
||||||
}
|
}
|
||||||
else if( started && ZONE_FILLER_TOOL::IsZoneFillAction( evt ) )
|
else if( started && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
else if( started&& evt->IsAction( &PCB_ACTIONS::properties ) )
|
else if( started && evt->IsAction( &PCB_ACTIONS::properties ) )
|
||||||
{
|
{
|
||||||
frame()->OnEditItemRequest( zoneTool.GetZone() );
|
frame()->OnEditItemRequest( zoneTool.GetZone() );
|
||||||
zoneTool.OnGeometryChange( polyGeomMgr );
|
zoneTool.OnGeometryChange( polyGeomMgr );
|
||||||
|
@ -2725,10 +2695,6 @@ int DRAWING_TOOL::DrawZone( const TOOL_EVENT& aEvent )
|
||||||
// m_view->Update( &zoneAsst );
|
// m_view->Update( &zoneAsst );
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
}*/
|
}*/
|
||||||
else if( evt->IsAction( &ACTIONS::redo ) )
|
|
||||||
{
|
|
||||||
wxBell();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
|
|
|
@ -1209,8 +1209,7 @@ int EDIT_TOOL::ModifyLines( const TOOL_EVENT& aEvent )
|
||||||
if( !m_isFootprintEditor )
|
if( !m_isFootprintEditor )
|
||||||
{
|
{
|
||||||
// If the item was "conjured up" it will be added later separately
|
// If the item was "conjured up" it will be added later separately
|
||||||
if( std::find( lines_to_add.begin(), lines_to_add.end(), &aItem )
|
if( !alg::contains( lines_to_add, &aItem ) )
|
||||||
== lines_to_add.end() )
|
|
||||||
{
|
{
|
||||||
commit.Modify( &aItem );
|
commit.Modify( &aItem );
|
||||||
items_to_select_on_success.push_back( &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
|
// Didn't construct any mofication routine - could be an error or cancellation
|
||||||
if( !error_message.empty() )
|
if( !error_message.empty() )
|
||||||
{
|
|
||||||
frame()->ShowInfoBarMsg( error_message );
|
frame()->ShowInfoBarMsg( error_message );
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only modify one parent in FP editor
|
|
||||||
if( m_isFootprintEditor )
|
|
||||||
commit.Modify( selection.Front() );
|
|
||||||
|
|
||||||
// Apply the tool to every line pair
|
// Apply the tool to every line pair
|
||||||
alg::for_all_pairs( selection.begin(), selection.end(),
|
alg::for_all_pairs( selection.begin(), selection.end(),
|
||||||
[&]( EDA_ITEM* a, EDA_ITEM* b )
|
[&]( EDA_ITEM* a, EDA_ITEM* b )
|
||||||
|
@ -1478,7 +1471,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
if( !item->IsNew() && !item->IsMoving() )
|
||||||
{
|
{
|
||||||
commit->Modify( item );
|
commit->Modify( item );
|
||||||
|
|
||||||
|
@ -1653,7 +1646,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||||
if( !item->IsType( MirrorableItems ) )
|
if( !item->IsType( MirrorableItems ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
if( !item->IsNew() && !item->IsMoving() )
|
||||||
commit->Modify( item );
|
commit->Modify( item );
|
||||||
|
|
||||||
// modify each object as necessary
|
// 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( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
|
||||||
{
|
{
|
||||||
if( !boardItem->IsNew() && !boardItem->IsMoving()
|
if( !boardItem->IsNew() && !boardItem->IsMoving() )
|
||||||
&& ( !IsFootprintEditor() || commit->Empty() ) )
|
|
||||||
{
|
{
|
||||||
commit->Modify( boardItem );
|
commit->Modify( boardItem );
|
||||||
|
|
||||||
|
@ -1816,13 +1808,11 @@ void EDIT_TOOL::DeleteItems( const PCB_SELECTION& aItems, bool aIsCut )
|
||||||
for( EDA_ITEM* item : aItems )
|
for( EDA_ITEM* item : aItems )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
BOARD_ITEM* board_item = dynamic_cast<BOARD_ITEM*>( item );
|
||||||
|
|
||||||
wxCHECK2( board_item, continue );
|
wxCHECK2( board_item, continue );
|
||||||
|
|
||||||
FOOTPRINT* parentFP = board_item->GetParentFootprint();
|
FOOTPRINT* parentFP = board_item->GetParentFootprint();
|
||||||
PCB_GROUP* parentGroup = board_item->GetParentGroup();
|
|
||||||
|
|
||||||
if( parentGroup )
|
if( PCB_GROUP* parentGroup = board_item->GetParentGroup() )
|
||||||
{
|
{
|
||||||
commit.Modify( parentGroup );
|
commit.Modify( parentGroup );
|
||||||
parentGroup->RemoveItem( board_item );
|
parentGroup->RemoveItem( board_item );
|
||||||
|
@ -2097,17 +2087,13 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
|
||||||
if( !frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
|
if( !frame()->GetPcbNewSettings()->m_Display.m_DisplayInvertYAxis )
|
||||||
rotation = -rotation;
|
rotation = -rotation;
|
||||||
|
|
||||||
// When editing footprints, all items have the same parent
|
|
||||||
if( IsFootprintEditor() )
|
|
||||||
commit.Modify( selection.Front() );
|
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
||||||
|
|
||||||
wxCHECK2( boardItem, continue );
|
wxCHECK2( boardItem, continue );
|
||||||
|
|
||||||
if( !boardItem->IsNew() && !IsFootprintEditor() )
|
if( !boardItem->IsNew() )
|
||||||
{
|
{
|
||||||
commit.Modify( boardItem );
|
commit.Modify( boardItem );
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ int EDIT_TOOL::Swap( const TOOL_EVENT& aEvent )
|
||||||
// Save items, so changes can be undone
|
// Save items, so changes can be undone
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
if( !item->IsNew() && !item->IsMoving() && ( !IsFootprintEditor() || commit->Empty() ) )
|
if( !item->IsNew() && !item->IsMoving() )
|
||||||
{
|
{
|
||||||
commit->Modify( item );
|
commit->Modify( item );
|
||||||
|
|
||||||
|
@ -369,10 +369,7 @@ bool EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, BOARD_COMMIT* aCommit
|
||||||
|
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
if( BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item ) )
|
||||||
FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item );
|
|
||||||
|
|
||||||
if( boardItem )
|
|
||||||
{
|
{
|
||||||
if( !is_hover )
|
if( !is_hover )
|
||||||
orig_items.push_back( boardItem );
|
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 );
|
sel_items.push_back( boardItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( footprint )
|
if( FOOTPRINT* footprint = dynamic_cast<FOOTPRINT*>( item ) )
|
||||||
{
|
{
|
||||||
for( PAD* pad : footprint->Pads() )
|
for( PAD* pad : footprint->Pads() )
|
||||||
sel_items.push_back( pad );
|
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() )
|
if( item->GetParent() && item->GetParent()->IsSelected() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if( !item->IsNew() && !item->IsMoving()
|
if( !item->IsNew() && !item->IsMoving() )
|
||||||
&& ( !IsFootprintEditor() || aCommit->Empty() ) )
|
|
||||||
{
|
{
|
||||||
aCommit->Modify( item );
|
aCommit->Modify( item );
|
||||||
item->SetFlags( IS_MOVING );
|
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 )
|
int FOOTPRINT_EDITOR_CONTROL::ExportFootprint( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
LIB_ID fpID = m_frame->GetTreeFPID();
|
if( FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint() )
|
||||||
FOOTPRINT* fp = m_frame->GetBoard()->GetFirstFootprint();
|
|
||||||
|
|
||||||
if( fp )
|
|
||||||
m_frame->ExportFootprint( fp );
|
m_frame->ExportFootprint( fp );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -604,13 +601,12 @@ int FOOTPRINT_EDITOR_CONTROL::ToggleProperties( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int FOOTPRINT_EDITOR_CONTROL::Properties( const TOOL_EVENT& aEvent )
|
int FOOTPRINT_EDITOR_CONTROL::Properties( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint();
|
if( FOOTPRINT* footprint = m_frame->GetBoard()->GetFirstFootprint() )
|
||||||
|
|
||||||
if( footprint )
|
|
||||||
{
|
{
|
||||||
getEditFrame<FOOTPRINT_EDIT_FRAME>()->OnEditItemRequest( footprint );
|
getEditFrame<FOOTPRINT_EDIT_FRAME>()->OnEditItemRequest( footprint );
|
||||||
m_frame->GetCanvas()->Refresh();
|
m_frame->GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,7 +633,6 @@ int FOOTPRINT_EDITOR_CONTROL::CheckFootprint( const TOOL_EVENT& aEvent )
|
||||||
if( !m_checkerDialog )
|
if( !m_checkerDialog )
|
||||||
{
|
{
|
||||||
m_checkerDialog = new DIALOG_FOOTPRINT_CHECKER( m_frame );
|
m_checkerDialog = new DIALOG_FOOTPRINT_CHECKER( m_frame );
|
||||||
|
|
||||||
m_checkerDialog->Show( true );
|
m_checkerDialog->Show( true );
|
||||||
}
|
}
|
||||||
else // The dialog is just not visible (because the user has double clicked on an error item)
|
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 )
|
if( hasChanges )
|
||||||
{
|
{
|
||||||
frame()->OnModify();
|
frame()->OnModify();
|
||||||
m_commit->Push( wxT( "Layers moved" ) );
|
m_commit->Push( wxT( "Swap Layers" ) );
|
||||||
frame()->GetCanvas()->Refresh();
|
frame()->GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,47 +254,32 @@ int GROUP_TOOL::Group( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( m_isFootprintEditor )
|
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 );
|
for( EDA_ITEM* eda_item : selection )
|
||||||
parentFootprint->Add( group );
|
{
|
||||||
|
if( BOARD_ITEM* item = dynamic_cast<BOARD_ITEM*>( eda_item ) )
|
||||||
for( EDA_ITEM* eda_item : selection )
|
|
||||||
{
|
{
|
||||||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( eda_item );
|
|
||||||
|
|
||||||
if( item->IsLocked() )
|
if( item->IsLocked() )
|
||||||
lockGroup = true;
|
lockGroup = true;
|
||||||
|
|
||||||
group->AddItem( item );
|
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 ) );
|
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 )
|
if( lockGroup )
|
||||||
group->SetLocked( true );
|
group->SetLocked( true );
|
||||||
|
|
||||||
|
@ -326,33 +311,23 @@ int GROUP_TOOL::Ungroup( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
if( group )
|
if( group )
|
||||||
{
|
{
|
||||||
if( m_isFootprintEditor )
|
PICKED_ITEMS_LIST undoList;
|
||||||
|
|
||||||
|
for( BOARD_ITEM* member : group->GetItems() )
|
||||||
{
|
{
|
||||||
FOOTPRINT* parentFootprint = board->GetFirstFootprint();
|
undoList.PushItem( ITEM_PICKER( nullptr, member, UNDO_REDO::UNGROUP ) );
|
||||||
|
members.push_back( member );
|
||||||
m_frame->SaveCopyInUndoList( parentFootprint, UNDO_REDO::CHANGED );
|
|
||||||
|
|
||||||
group->RemoveAll();
|
|
||||||
parentFootprint->Remove( group );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group->RemoveAll();
|
||||||
|
|
||||||
|
if( m_isFootprintEditor )
|
||||||
|
board->GetFirstFootprint()->Remove( group );
|
||||||
else
|
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 );
|
board->Remove( group );
|
||||||
|
|
||||||
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::DELETED ) );
|
undoList.PushItem( ITEM_PICKER( nullptr, group, UNDO_REDO::DELETED ) );
|
||||||
|
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNGROUP );
|
||||||
m_frame->SaveCopyInUndoList( undoList, UNDO_REDO::UNGROUP );
|
|
||||||
}
|
|
||||||
|
|
||||||
group->SetSelected();
|
group->SetSelected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,7 +194,6 @@ int PCB_CONTROL::ViaDisplayMode( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas()->Refresh();
|
canvas()->Refresh();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,7 +300,6 @@ int PCB_CONTROL::HighContrastMode( const TOOL_EVENT& aEvent )
|
||||||
: HIGH_CONTRAST_MODE::NORMAL;
|
: HIGH_CONTRAST_MODE::NORMAL;
|
||||||
|
|
||||||
m_frame->SetDisplayOptions( opts );
|
m_frame->SetDisplayOptions( opts );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +318,6 @@ int PCB_CONTROL::HighContrastModeCycle( const TOOL_EVENT& aEvent )
|
||||||
m_frame->SetDisplayOptions( opts );
|
m_frame->SetDisplayOptions( opts );
|
||||||
|
|
||||||
m_toolMgr->PostEvent( EVENTS::ContrastModeChangedByKeyEvent );
|
m_toolMgr->PostEvent( EVENTS::ContrastModeChangedByKeyEvent );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,8 +340,10 @@ int PCB_CONTROL::ContrastModeFeedback( const TOOL_EVENT& aEvent )
|
||||||
HOTKEY_CYCLE_POPUP* popup = m_frame->GetHotkeyPopup();
|
HOTKEY_CYCLE_POPUP* popup = m_frame->GetHotkeyPopup();
|
||||||
|
|
||||||
if( popup )
|
if( popup )
|
||||||
|
{
|
||||||
popup->Popup( _( "Inactive Layer Display" ), labels,
|
popup->Popup( _( "Inactive Layer Display" ), labels,
|
||||||
static_cast<int>( opts.m_ContrastModeDisplay ) );
|
static_cast<int>( opts.m_ContrastModeDisplay ) );
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -362,7 +361,6 @@ int PCB_CONTROL::NetColorModeCycle( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
m_frame->SetDisplayOptions( opts );
|
m_frame->SetDisplayOptions( opts );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,6 @@ size_t ALIGN_DISTRIBUTE_TOOL::GetSelections( std::vector<std::pair<BOARD_ITEM*,
|
||||||
for( EDA_ITEM* item : selection )
|
for( EDA_ITEM* item : selection )
|
||||||
{
|
{
|
||||||
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( item );
|
||||||
|
|
||||||
wxCHECK2( boardItem, continue );
|
wxCHECK2( boardItem, continue );
|
||||||
|
|
||||||
// We do not lock items in the footprint editor
|
// 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
|
// Locking a pad but not the footprint means that we align the footprint using
|
||||||
// the pad position. So we test for footprint locking here
|
// the pad position. So we test for footprint locking here
|
||||||
if( boardItem->Type() == PCB_PAD_T && !boardItem->GetParent()->IsLocked() )
|
if( boardItem->Type() == PCB_PAD_T && !boardItem->GetParent()->IsLocked() )
|
||||||
{
|
|
||||||
itemsToAlign.push_back( boardItem );
|
itemsToAlign.push_back( boardItem );
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
lockedItems.push_back( boardItem );
|
lockedItems.push_back( boardItem );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
itemsToAlign.push_back( boardItem );
|
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;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -235,8 +230,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignTop( const TOOL_EVENT& aEvent )
|
||||||
item->Move( VECTOR2I( 0, difference ) );
|
item->Move( VECTOR2I( 0, difference ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to top" ) );
|
commit.Push( _( "Align to Top" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,9 +241,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -280,8 +274,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
|
||||||
item->Move( VECTOR2I( 0, difference ) );
|
item->Move( VECTOR2I( 0, difference ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to bottom" ) );
|
commit.Push( _( "Align to Bottom" ) );
|
||||||
|
|
||||||
return 0;
|
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
|
// 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.
|
// the view is mirrored, we need to call the other one if mirrored.
|
||||||
if( getView()->IsMirroredX() )
|
if( getView()->IsMirroredX() )
|
||||||
{
|
|
||||||
return doAlignRight();
|
return doAlignRight();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return doAlignLeft();
|
return doAlignLeft();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,9 +296,9 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -340,8 +329,7 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignLeft()
|
||||||
item->Move( VECTOR2I( difference, 0 ) );
|
item->Move( VECTOR2I( difference, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to left" ) );
|
commit.Push( _( "Align to Left" ) );
|
||||||
|
|
||||||
return 0;
|
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
|
// 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.
|
// the view is mirrored, we need to call the other one if mirrored.
|
||||||
if( getView()->IsMirroredX() )
|
if( getView()->IsMirroredX() )
|
||||||
{
|
|
||||||
return doAlignLeft();
|
return doAlignLeft();
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
return doAlignRight();
|
return doAlignRight();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -367,9 +351,9 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -400,8 +384,7 @@ int ALIGN_DISTRIBUTE_TOOL::doAlignRight()
|
||||||
item->Move( VECTOR2I( difference, 0 ) );
|
item->Move( VECTOR2I( difference, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to right" ) );
|
commit.Push( _( "Align to Right" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -412,9 +395,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
||||||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -445,8 +428,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterX( const TOOL_EVENT& aEvent )
|
||||||
item->Move( VECTOR2I( difference, 0 ) );
|
item->Move( VECTOR2I( difference, 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to middle" ) );
|
commit.Push( _( "Align to Middle" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,9 +439,9 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
||||||
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
std::vector<std::pair<BOARD_ITEM*, BOX2I>> locked_items;
|
||||||
|
|
||||||
if( !GetSelections( itemsToAlign, 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;
|
return 0;
|
||||||
|
@ -490,8 +472,7 @@ int ALIGN_DISTRIBUTE_TOOL::AlignCenterY( const TOOL_EVENT& aEvent )
|
||||||
item->Move( VECTOR2I( 0, difference ) );
|
item->Move( VECTOR2I( 0, difference ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Align to center" ) );
|
commit.Push( _( "Align to Center" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,10 +501,9 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
// find the last item by reverse sorting
|
// find the last item by reverse sorting
|
||||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left,
|
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||||
const std::pair<BOARD_ITEM*, BOX2I> right)
|
|
||||||
{
|
{
|
||||||
return ( left.second.GetRight() > right.second.GetRight() );
|
return ( lhs.second.GetRight() > rhs.second.GetRight() );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
||||||
|
@ -531,10 +511,9 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
// sort to get starting order
|
// sort to get starting order
|
||||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
||||||
[] ( const std::pair<BOARD_ITEM*, BOX2I> left,
|
[]( const std::pair<BOARD_ITEM*, BOX2I>& lhs, const std::pair<BOARD_ITEM*, BOX2I>& rhs )
|
||||||
const std::pair<BOARD_ITEM*, BOX2I> right)
|
|
||||||
{
|
{
|
||||||
return ( left.second.GetX() < right.second.GetX() );
|
return ( lhs.second.GetX() < rhs.second.GetX() );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
const int minX = itemsToDistribute.begin()->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 );
|
doDistributeGapsHorizontally( itemsToDistribute, commit, lastItem, totalGap );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Distribute horizontally" ) );
|
commit.Push( _( "Distribute Horizontally" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,13 +574,12 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersHorizontally( std::vector<std::pa
|
||||||
BOARD_COMMIT& aCommit ) const
|
BOARD_COMMIT& aCommit ) const
|
||||||
{
|
{
|
||||||
std::sort( aItems.begin(), aItems.end(),
|
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
|
const int totalGap = ( aItems.end()-1 )->second.Centre().x - aItems.begin()->second.Centre().x;
|
||||||
- aItems.begin()->second.Centre().x;
|
|
||||||
const int itemGap = totalGap / ( aItems.size() - 1 );
|
const int itemGap = totalGap / ( aItems.size() - 1 );
|
||||||
int targetX = aItems.begin()->second.Centre().x;
|
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
|
// find the last item by reverse sorting
|
||||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
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.GetBottom() > right.second.GetBottom() );
|
return ( lhs.second.GetBottom() > rhs.second.GetBottom() );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
BOARD_ITEM* lastItem = itemsToDistribute.begin()->first;
|
||||||
const int maxBottom = itemsToDistribute.begin()->second.GetBottom();
|
const int maxBottom = itemsToDistribute.begin()->second.GetBottom();
|
||||||
|
|
||||||
// sort to get starting order
|
// sort to get starting order
|
||||||
std::sort( itemsToDistribute.begin(), itemsToDistribute.end(),
|
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.Centre().y < right.second.Centre().y );
|
return ( lhs.second.Centre().y < rhs.second.Centre().y );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
int minY = itemsToDistribute.begin()->second.GetY();
|
int minY = itemsToDistribute.begin()->second.GetY();
|
||||||
int totalGap = maxBottom - minY;
|
int totalGap = maxBottom - minY;
|
||||||
|
@ -682,8 +659,7 @@ int ALIGN_DISTRIBUTE_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
|
||||||
doDistributeGapsVertically( itemsToDistribute, commit, lastItem, totalGap );
|
doDistributeGapsVertically( itemsToDistribute, commit, lastItem, totalGap );
|
||||||
}
|
}
|
||||||
|
|
||||||
commit.Push( _( "Distribute vertically" ) );
|
commit.Push( _( "Distribute Vertically" ) );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,9 +699,9 @@ void ALIGN_DISTRIBUTE_TOOL::doDistributeCentersVertically( std::vector<std::pair
|
||||||
BOARD_COMMIT& aCommit ) const
|
BOARD_COMMIT& aCommit ) const
|
||||||
{
|
{
|
||||||
std::sort( aItems.begin(), aItems.end(),
|
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
|
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
|
// 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
|
// Select the new zone and set it as the source for the next cutout
|
||||||
if( newZones.empty() )
|
if( newZones.empty() )
|
||||||
|
@ -215,7 +215,6 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE& aZone, const ZONE& aCutout )
|
||||||
m_params.m_sourceZone = newZones[0];
|
m_params.m_sourceZone = newZones[0];
|
||||||
toolMgr->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, 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.Add( aZone.get() );
|
||||||
commit.Push( _( "Add a zone" ) );
|
commit.Push( _( "Add a zone" ) );
|
||||||
|
|
||||||
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem,
|
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, aZone.release() );
|
||||||
aZone.release() );
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ZONE_MODE::GRAPHIC_POLYGON:
|
case ZONE_MODE::GRAPHIC_POLYGON:
|
||||||
{
|
{
|
||||||
BOARD_COMMIT commit( &m_tool );
|
BOARD_COMMIT commit( &m_tool );
|
||||||
BOARD* board = m_tool.getModel<BOARD>();
|
BOARD* board = m_tool.getModel<BOARD>();
|
||||||
PCB_LAYER_ID layer = m_params.m_layer;
|
PCB_LAYER_ID layer = m_params.m_layer;
|
||||||
PCB_SHAPE* poly = new PCB_SHAPE( m_tool.m_frame->GetModel() );
|
PCB_SHAPE* poly = new PCB_SHAPE( m_tool.m_frame->GetModel() );
|
||||||
|
|
||||||
poly->SetShape( SHAPE_T::POLY );
|
poly->SetShape( SHAPE_T::POLY );
|
||||||
|
|
||||||
|
@ -265,8 +263,7 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE> aZone )
|
||||||
commit.Add( poly );
|
commit.Add( poly );
|
||||||
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, poly );
|
m_tool.GetManager()->RunAction<EDA_ITEM*>( PCB_ACTIONS::selectItem, poly );
|
||||||
|
|
||||||
commit.Push( _( "Add a graphical polygon" ) );
|
commit.Push( _( "Add Polygon" ) );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
using namespace std::placeholders;
|
using namespace std::placeholders;
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <pcb_edit_frame.h>
|
#include <pcb_edit_frame.h>
|
||||||
#include <board.h>
|
|
||||||
#include <pcb_track.h>
|
#include <pcb_track.h>
|
||||||
#include <pcb_group.h>
|
#include <pcb_group.h>
|
||||||
#include <pcb_target.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,
|
void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo,
|
||||||
const PICKED_ITEMS_LIST& aItemsList,
|
const PICKED_ITEMS_LIST& aItemsList,
|
||||||
UNDO_REDO aCommandType )
|
UNDO_REDO aCommandType )
|
||||||
{
|
{
|
||||||
int preExisting = commandToUndo->GetCount();
|
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++ )
|
for( unsigned ii = 0; ii < aItemsList.GetCount(); ii++ )
|
||||||
{
|
commandToUndo->PushItem( aItemsList.GetItemWrapper(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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
|
for( unsigned ii = preExisting; ii < commandToUndo->GetCount(); ii++ )
|
||||||
{
|
{
|
||||||
|
@ -258,8 +145,7 @@ void PCB_BASE_EDIT_FRAME::saveCopyInUndoList( PICKED_ITEMS_LIST* commandToUndo,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( wxString::Format( wxT( "SaveCopyInUndoList() error (unknown code %X)" ),
|
wxFAIL_MSG( wxString::Format( wxT( "Unrecognized undo command: %X" ), command ) );
|
||||||
command ) );
|
|
||||||
break;
|
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::GRIDORIGIN // origin markers never on board
|
||||||
&& status != UNDO_REDO::PAGESETTINGS ) // nor are page settings proxy items
|
&& 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
|
// Checking if it ever happens
|
||||||
wxASSERT_MSG( false, wxT( "Item in the undo buffer does not exist" ) );
|
wxASSERT_MSG( false, wxT( "Item in the undo buffer does not exist" ) );
|
||||||
|
|
Loading…
Reference in New Issue