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_CHANGED:
|
||||||
case UR_EXCHANGE_T:
|
case UR_EXCHANGE_T:
|
||||||
|
case UR_DRILLORIGIN:
|
||||||
|
case UR_GRIDORIGIN:
|
||||||
delete wrapper.GetLink(); // the picker is owner of this item
|
delete wrapper.GetLink(); // the picker is owner of this item
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -22,18 +22,26 @@
|
||||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <class_drawpanel.h>
|
||||||
|
#include <draw_frame.h>
|
||||||
#include <origin_viewitem.h>
|
#include <origin_viewitem.h>
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
|
||||||
using namespace KIGFX;
|
using namespace KIGFX;
|
||||||
|
|
||||||
ORIGIN_VIEWITEM::ORIGIN_VIEWITEM( const COLOR4D& aColor, MARKER_STYLE aStyle, int aSize, const VECTOR2D& aPosition ) :
|
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 )
|
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
|
const BOX2I ORIGIN_VIEWITEM::ViewBBox() const
|
||||||
{
|
{
|
||||||
BOX2I bbox;
|
BOX2I bbox;
|
||||||
|
@ -41,7 +49,6 @@ const BOX2I ORIGIN_VIEWITEM::ViewBBox() const
|
||||||
return bbox;
|
return bbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ORIGIN_VIEWITEM::ViewDraw( int, VIEW* aView ) const
|
void ORIGIN_VIEWITEM::ViewDraw( int, VIEW* aView ) const
|
||||||
{
|
{
|
||||||
auto gal = aView->GetGAL();
|
auto gal = aView->GetGAL();
|
||||||
|
|
|
@ -72,8 +72,10 @@ enum UNDO_REDO_T {
|
||||||
UR_LIBEDIT, // Specific to the component editor (libedit creates a full copy
|
UR_LIBEDIT, // Specific to the component editor (libedit creates a full copy
|
||||||
// of the current component when changed)
|
// of the current component when changed)
|
||||||
UR_LIB_RENAME, // As UR_LIBEDIT, but old copy should be removed from library
|
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
|
UR_EXCHANGE_T, ///< Use for changing the schematic text type where swapping
|
||||||
///< data structure is insufficient to restor the change.
|
///< 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 {
|
namespace KIGFX {
|
||||||
|
|
||||||
class ORIGIN_VIEWITEM : public EDA_ITEM
|
class ORIGIN_VIEWITEM : public BOARD_ITEM
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///> Marker symbol styles
|
///> Marker symbol styles
|
||||||
|
@ -48,10 +48,18 @@ public:
|
||||||
MARKER_STYLE aStyle = CIRCLE_X, int aSize = 16,
|
MARKER_STYLE aStyle = CIRCLE_X, int aSize = 16,
|
||||||
const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) );
|
const VECTOR2D& aPosition = VECTOR2D( 0, 0 ) );
|
||||||
|
|
||||||
|
ORIGIN_VIEWITEM* Clone() const override;
|
||||||
|
|
||||||
const BOX2I ViewBBox() const override;
|
const BOX2I ViewBBox() const override;
|
||||||
|
|
||||||
void ViewDraw( int aLayer, VIEW* aView ) 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
|
void ViewGetLayers( int aLayers[], int& aCount ) const override
|
||||||
{
|
{
|
||||||
aLayers[0] = LAYER_GP_OVERLAY;
|
aLayers[0] = LAYER_GP_OVERLAY;
|
||||||
|
@ -88,9 +96,14 @@ public:
|
||||||
m_position = aPosition;
|
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 )
|
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,
|
bool PCB_EDITOR_CONTROL::DoSetDrillOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||||
KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPosition )
|
BOARD_ITEM* originViewItem, const VECTOR2D& aPosition )
|
||||||
{
|
{
|
||||||
aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) );
|
aFrame->SetAuxOrigin( wxPoint( aPosition.x, aPosition.y ) );
|
||||||
aItem->SetPosition( aPosition );
|
originViewItem->SetPosition( wxPoint( aPosition.x, aPosition.y ) );
|
||||||
aView->MarkDirty();
|
aView->MarkDirty();
|
||||||
|
|
||||||
return true;
|
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 )
|
int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
Activate();
|
Activate();
|
||||||
|
@ -850,7 +858,7 @@ int PCB_EDITOR_CONTROL::DrillOrigin( const TOOL_EVENT& aEvent )
|
||||||
assert( picker );
|
assert( picker );
|
||||||
|
|
||||||
m_frame->SetToolID( ID_PCB_PLACE_OFFSET_COORD_BUTT, wxCURSOR_HAND, _( "Adjust zero" ) );
|
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();
|
picker->Activate();
|
||||||
Wait();
|
Wait();
|
||||||
|
|
||||||
|
|
|
@ -89,9 +89,17 @@ public:
|
||||||
///> Reacts to selection change in eeschema.
|
///> Reacts to selection change in eeschema.
|
||||||
int CrossProbeSchToPcb( const TOOL_EVENT& aEvent );
|
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 );
|
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.
|
///> Highlights net belonging to the item under the cursor.
|
||||||
int HighlightNet( const TOOL_EVENT& aEvent );
|
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,
|
bool PCBNEW_CONTROL::DoSetGridOrigin( KIGFX::VIEW* aView, PCB_BASE_FRAME* aFrame,
|
||||||
KIGFX::ORIGIN_VIEWITEM* aItem, const VECTOR2D& aPoint )
|
BOARD_ITEM* originViewItem, const VECTOR2D& aPoint )
|
||||||
{
|
{
|
||||||
aFrame->SetGridOrigin( wxPoint( aPoint.x, aPoint.y ) );
|
aFrame->SetGridOrigin( wxPoint( aPoint.x, aPoint.y ) );
|
||||||
aView->GetGAL()->SetGridOrigin( aPoint );
|
aView->GetGAL()->SetGridOrigin( aPoint );
|
||||||
aItem->SetPosition( aPoint );
|
originViewItem->SetPosition( wxPoint( aPoint.x, aPoint.y ) );
|
||||||
aView->MarkDirty();
|
aView->MarkDirty();
|
||||||
|
|
||||||
return true;
|
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 )
|
int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
|
VECTOR2D* origin = aEvent.Parameter<VECTOR2D*>();
|
||||||
|
|
||||||
if( origin )
|
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;
|
delete origin;
|
||||||
}
|
}
|
||||||
else
|
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..
|
// 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" ) );
|
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();
|
picker->Activate();
|
||||||
Wait();
|
Wait();
|
||||||
}
|
}
|
||||||
|
@ -638,8 +648,7 @@ int PCBNEW_CONTROL::GridSetOrigin( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
int PCBNEW_CONTROL::GridResetOrigin( const TOOL_EVENT& aEvent )
|
int PCBNEW_CONTROL::GridResetOrigin( const TOOL_EVENT& aEvent )
|
||||||
{
|
{
|
||||||
board()->SetGridOrigin( wxPoint( 0, 0 ) );
|
SetGridOrigin( getView(), m_frame, m_gridOrigin.get(), VECTOR2D( 0, 0 ) );
|
||||||
m_gridOrigin->SetPosition( VECTOR2D( 0, 0 ) );
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,14 @@ public:
|
||||||
int GridSetOrigin( const TOOL_EVENT& aEvent );
|
int GridSetOrigin( const TOOL_EVENT& aEvent );
|
||||||
int GridResetOrigin( 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
|
// Miscellaneous
|
||||||
int ResetCoords( const TOOL_EVENT& aEvent );
|
int ResetCoords( const TOOL_EVENT& aEvent );
|
||||||
int SwitchCursor( const TOOL_EVENT& aEvent );
|
int SwitchCursor( const TOOL_EVENT& aEvent );
|
||||||
|
|
|
@ -44,10 +44,13 @@ using namespace std::placeholders;
|
||||||
#include <class_dimension.h>
|
#include <class_dimension.h>
|
||||||
#include <class_zone.h>
|
#include <class_zone.h>
|
||||||
#include <class_edge_mod.h>
|
#include <class_edge_mod.h>
|
||||||
|
#include <origin_viewitem.h>
|
||||||
|
|
||||||
#include <connectivity_data.h>
|
#include <connectivity_data.h>
|
||||||
|
|
||||||
#include <tools/selection_tool.h>
|
#include <tools/selection_tool.h>
|
||||||
|
#include <tools/pcbnew_control.h>
|
||||||
|
#include <tools/pcb_editor_control.h>
|
||||||
#include <tool/tool_manager.h>
|
#include <tool/tool_manager.h>
|
||||||
|
|
||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
|
@ -295,6 +298,8 @@ void PCB_BASE_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsLis
|
||||||
switch( command )
|
switch( command )
|
||||||
{
|
{
|
||||||
case UR_CHANGED:
|
case UR_CHANGED:
|
||||||
|
case UR_DRILLORIGIN:
|
||||||
|
case UR_GRIDORIGIN:
|
||||||
|
|
||||||
/* If needed, create a copy of item, and put in undo list
|
/* If needed, create a copy of item, and put in undo list
|
||||||
* in the picker, as link
|
* 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 );
|
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 )
|
if( build_item_list )
|
||||||
// Build list of existing items, for integrity test
|
// 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 );
|
connectivity->Update( item );
|
||||||
break;
|
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:
|
default:
|
||||||
{
|
{
|
||||||
wxString msg;
|
wxString msg;
|
||||||
|
|
Loading…
Reference in New Issue