Implement undo/redo for drill and grid origins.
The undo/redo operations are essentially the same as for UR_CHANGED: we store both the origin marker item and a copy of it and flip back and forth between the two. This also required the implementation of clone() for the markers. The ORIGIN_VIEWMARKER is moved from being a subclass of EDA_ITEM to BOARD_ITEM to facilitate the use of a UR_CHANGE- like implementation without having to know the internals of the ORIGIN_VIEWMARKER. In the command processors, the setting of the origins is broken into two parts: one for UI-level access which includes setting up undo, and one for low-level access which does not. The undo/redo code itself of course uses the lower level. Fixes: lp:1542018 * https://bugs.launchpad.net/kicad/+bug/1542018
This commit is contained in:
parent
f88c4ccb02
commit
4784ee7fe4
|
@ -144,6 +144,8 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
|
|||
|
||||
case UR_CHANGED:
|
||||
case UR_EXCHANGE_T:
|
||||
case UR_DRILLORIGIN:
|
||||
case UR_GRIDORIGIN:
|
||||
delete wrapper.GetLink(); // the picker is owner of this item
|
||||
break;
|
||||
|
||||
|
|
|
@ -22,18 +22,26 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <class_drawpanel.h>
|
||||
#include <draw_frame.h>
|
||||
#include <origin_viewitem.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
|
||||
using namespace KIGFX;
|
||||
|
||||
ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, int aSize, const VECTOR2D& aPosition ) :
|
||||
EDA_ITEM( NOT_USED ), // this item is never added to a BOARD so it needs no type
|
||||
BOARD_ITEM( nullptr, NOT_USED ), // this item is never added to a BOARD so it needs no type
|
||||
m_position( aPosition ), m_size( aSize ), m_color( aColor ), m_style( aStyle ), m_drawAtZero( false )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ORIGIN_VIEWITEM* ORIGIN_VIEWITEM::Clone() const
|
||||
{
|
||||
return new ORIGIN_VIEWITEM( m_color, m_style, m_size, m_position );
|
||||
}
|
||||
|
||||
|
||||
const BOX2I ORIGIN_VIEWITEM::ViewBBox() const
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
@ -41,7 +49,6 @@ const BOX2I ORIGIN_VIEWITEM::ViewBBox() const
|
|||
return bbox;
|
||||
}
|
||||
|
||||
|
||||
void ORIGIN_VIEWITEM::ViewDraw( int, VIEW* aView ) const
|
||||
{
|
||||
auto gal = aView->GetGAL();
|
||||
|
|
|
@ -72,8 +72,10 @@ enum UNDO_REDO_T {
|
|||
UR_LIBEDIT, // Specific to the component editor (libedit creates a full copy
|
||||
// of the current component when changed)
|
||||
UR_LIB_RENAME, // As UR_LIBEDIT, but old copy should be removed from library
|
||||
UR_EXCHANGE_T ///< Use for changing the schematic text type where swapping
|
||||
///< data structure is insufficient to restor the change.
|
||||
UR_EXCHANGE_T, ///< Use for changing the schematic text type where swapping
|
||||
///< data structure is insufficient to restore the change.
|
||||
UR_DRILLORIGIN, // origin changed (like UR_CHANGED, contains the origin and a copy)
|
||||
UR_GRIDORIGIN // origin changed (like UR_CHANGED, contains the origin and a copy)
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
*/
|
||||
namespace KIGFX {
|
||||
|
||||
class ORIGIN_VIEWITEM : public EDA_ITEM
|
||||
class ORIGIN_VIEWITEM : public BOARD_ITEM
|
||||
{
|
||||
public:
|
||||
///> Marker symbol styles
|
||||
|
@ -48,10 +48,18 @@ public:
|
|||
MARKER_STYLE aStyle = CIRCLE_X, int aSize = 16,
|
||||
const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) );
|
||||
|
||||
ORIGIN_VIEWITEM* Clone() const override;
|
||||
|
||||
const BOX2I ViewBBox() const override;
|
||||
|
||||
void ViewDraw( int aLayer, VIEW* aView ) const override;
|
||||
|
||||
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
|
||||
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset ) override
|
||||
{
|
||||
wxASSERT( 0 ); // ORIGIN_VIEWITEM never added to BOARD; drawn directly through ViewDraw().
|
||||
}
|
||||
|
||||
void ViewGetLayers( int aLayers[], int& aCount ) const override
|
||||
{
|
||||
aLayers[0] = LAYER_GP_OVERLAY;
|
||||
|
@ -88,9 +96,14 @@ public:
|
|||
m_position = aPosition;
|
||||
}
|
||||
|
||||
inline const VECTOR2D& GetPosition() const
|
||||
inline void SetPosition( const wxPoint& aPosition ) override
|
||||
{
|
||||
return m_position;
|
||||
m_position = VECTOR2D( aPosition );
|
||||
}
|
||||
|
||||
inline const wxPoint GetPosition() const override
|
||||
{
|
||||
return wxPoint( m_position.x, m_position.y );
|
||||
}
|
||||
|
||||
inline void SetSize( int aSize )
|
||||
|
|
|
@ -831,17 +831,25 @@ int PCB_EDITOR_CONTROL::CrossProbeSchToPcb( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
static bool setDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPosition )
|
||||
bool PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPosition )
|
||||
{
|
||||
aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) );
|
||||
aItem->SetPosition( aPosition );
|
||||
originViewItem->SetPosition( wxPoint( aPosition.x, aPosition.y ) );
|
||||
aView->MarkDirty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PCB_EDITOR_CONTROL::SetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPosition )
|
||||
{
|
||||
aFrame->SaveCopyInUndoList( originViewItem, UR_DRILLORIGIN );
|
||||
DoSetDrillOrigin( aView, aFrame, originViewItem, aPosition );
|
||||
}
|
||||
|
||||
|
||||
int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
Activate();
|
||||
|
@ -850,7 +858,7 @@ int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
|
|||
assert( picker );
|
||||
|
||||
m_frame->SetToolID( ID_PCB_PLACE_OFFSET_COORD_BUTT, wxCURSOR_HAND, _( "Adjust zero" ) );
|
||||
picker->SetClickHandler( std::bind( setDrillOrigin, getView(), m_frame, m_placeOrigin.get(), _1 ) );
|
||||
picker->SetClickHandler( std::bind( SetDrillOrigin, getView(), m_frame, m_placeOrigin.get(), _1 ) );
|
||||
picker->Activate();
|
||||
Wait();
|
||||
|
||||
|
|
|
@ -89,9 +89,17 @@ public:
|
|||
///> Reacts to selection change in eeschema.
|
||||
int CrossProbeSchToPcb( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> Places the origin point for drill and pick-and-place files.
|
||||
///> Runs the drill origin tool for setting the origin for drill and pick-and-place files.
|
||||
int DrillOrigin( const TOOL_EVENT& aEvent );
|
||||
|
||||
///> UI-level access (including undo) to setting the drill origin
|
||||
static bool SetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* aItem, const VECTOR2D& aPoint );
|
||||
|
||||
///> Low-level access (below undo) to setting the drill origin
|
||||
static bool DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* aItem, const VECTOR2D& aPoint );
|
||||
|
||||
///> Highlights net belonging to the item under the cursor.
|
||||
int HighlightNet( const TOOL_EVENT& aEvent );
|
||||
|
||||
|
|
|
@ -597,25 +597,35 @@ int PCBNEW_CONTROL::GridFast2( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
|
||||
static bool setOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPoint )
|
||||
bool PCBNEW_CONTROL::DoSetGridOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPoint )
|
||||
{
|
||||
aFrame->SetGridOrigin( wxPoint( aPoint.x, aPoint.y ) );
|
||||
aView->GetGAL()->SetGridOrigin( aPoint );
|
||||
aItem->SetPosition( aPoint );
|
||||
originViewItem->SetPosition( wxPoint( aPoint.x, aPoint.y ) );
|
||||
aView->MarkDirty();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PCBNEW_CONTROL::SetGridOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPoint )
|
||||
{
|
||||
aFrame->SaveCopyInUndoList( originViewItem, UR_GRIDORIGIN );
|
||||
return DoSetGridOrigin( aView, aFrame, originViewItem, aPoint );
|
||||
}
|
||||
|
||||
|
||||
int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
|
||||
|
||||
if( origin )
|
||||
{
|
||||
setOrigin( getView(), m_frame, m_gridOrigin.get(), *origin );
|
||||
// We can't undo the other grid dialog settings, so no sense undoing just the origin
|
||||
|
||||
DoSetGridOrigin( getView(), m_frame, m_gridOrigin.get(), *origin );
|
||||
delete origin;
|
||||
}
|
||||
else
|
||||
|
@ -627,7 +637,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
|
|||
|
||||
// TODO it will not check the toolbar button in module editor, as it uses a different ID..
|
||||
m_frame->SetToolID( ID_PCB_PLACE_GRID_COORD_BUTT, wxCURSOR_PENCIL, _( "Adjust grid origin" ) );
|
||||
picker->SetClickHandler( std::bind( setOrigin, getView(), m_frame, m_gridOrigin.get(), _1 ) );
|
||||
picker->SetClickHandler( std::bind( SetGridOrigin, getView(), m_frame, m_gridOrigin.get(), _1 ) );
|
||||
picker->Activate();
|
||||
Wait();
|
||||
}
|
||||
|
@ -638,8 +648,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
|
|||
|
||||
int PCBNEW_CONTROL::GridResetOrigin( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
board()->SetGridOrigin( wxPoint( 0, 0 ) );
|
||||
m_gridOrigin->SetPosition( VECTOR2D( 0, 0 ) );
|
||||
SetGridOrigin( getView(), m_frame, m_gridOrigin.get(), VECTOR2D( 0, 0 ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -76,6 +76,14 @@ public:
|
|||
int GridSetOrigin( const TOOL_EVENT& aEvent );
|
||||
int GridResetOrigin( const TOOL_EVENT& aEvent );
|
||||
|
||||
// UI-level access (including undo) to setting the grid origin
|
||||
static bool SetGridOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPoint );
|
||||
|
||||
// Low-level access (below undo) to setting the grid origin
|
||||
static bool DoSetGridOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||
BOARD_ITEM* originViewItem, const VECTOR2D& aPoint );
|
||||
|
||||
// Miscellaneous
|
||||
int ResetCoords( const TOOL_EVENT& aEvent );
|
||||
int SwitchCursor( const TOOL_EVENT& aEvent );
|
||||
|
|
|
@ -44,10 +44,13 @@ using namespace std::placeholders;
|
|||
#include <class_dimension.h>
|
||||
#include <class_zone.h>
|
||||
#include <class_edge_mod.h>
|
||||
#include <origin_viewitem.h>
|
||||
|
||||
#include <connectivity_data.h>
|
||||
|
||||
#include <tools/selection_tool.h>
|
||||
#include <tools/pcbnew_control.h>
|
||||
#include <tools/pcb_editor_control.h>
|
||||
#include <tool/tool_manager.h>
|
||||
|
||||
#include <view/view.h>
|
||||
|
@ -295,6 +298,8 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis
|
|||
switch( command )
|
||||
{
|
||||
case UR_CHANGED:
|
||||
case UR_DRILLORIGIN:
|
||||
case UR_GRIDORIGIN:
|
||||
|
||||
/* If needed, create a copy of item, and put in undo list
|
||||
* in the picker, as link
|
||||
|
@ -432,7 +437,9 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
*/
|
||||
UNDO_REDO_T status = aList->GetPickedItemStatus( ii );
|
||||
|
||||
if( status != UR_DELETED )
|
||||
if( status != UR_DELETED
|
||||
&& status != UR_DRILLORIGIN // origin markers never on board
|
||||
&& status != UR_GRIDORIGIN ) // origin markers never on board
|
||||
{
|
||||
if( build_item_list )
|
||||
// Build list of existing items, for integrity test
|
||||
|
@ -547,6 +554,20 @@ void PCB_BASE_EDIT_FRAME::PutDataInPreviousState( PICKED_ITEMS_LIST* aList, bool
|
|||
connectivity->Update( item );
|
||||
break;
|
||||
|
||||
case UR_DRILLORIGIN:
|
||||
case UR_GRIDORIGIN:
|
||||
{
|
||||
BOARD_ITEM* image = (BOARD_ITEM*) aList->GetPickedItemLink( ii );
|
||||
VECTOR2D origin = image->GetPosition();
|
||||
image->SetPosition( item->GetPosition() );
|
||||
|
||||
if( aList->GetPickedItemStatus( ii ) == UR_DRILLORIGIN )
|
||||
PCB_EDITOR_CONTROL::DoSetDrillOrigin( view, this, item, origin );
|
||||
else
|
||||
PCBNEW_CONTROL::DoSetGridOrigin( view, this, item, origin );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
wxString msg;
|
||||
|
|
Loading…
Reference in New Issue