Modified tools to use BOARD_COMMIT.

This commit is contained in:
Maciej Suminski 2016-06-21 17:06:28 +02:00
parent 5c0605f6dc
commit 5a1f52bf30
19 changed files with 415 additions and 724 deletions

View File

@ -28,7 +28,7 @@
#include "array_creator.h"
#include <class_undoredo_container.h>
#include <board_commit.h>
#include <dialogs/dialog_create_array.h>
@ -41,6 +41,7 @@ void ARRAY_CREATOR::Invoke()
if( numItems == 0 )
return;
BOARD_COMMIT commit( &m_parent );
MODULE* const module = getModule();
const bool isModuleEditor = module != NULL;
@ -52,76 +53,63 @@ void ARRAY_CREATOR::Invoke()
DIALOG_CREATE_ARRAY::ARRAY_OPTIONS* const array_opts = dialog.GetArrayOptions();
if( ret == wxID_OK && array_opts != NULL )
if( ret != wxID_OK || array_opts == NULL )
return;
for ( int i = 0; i < numItems; ++i )
{
PICKED_ITEMS_LIST newItemsList;
BOARD_ITEM* item = getNthItemToArray( i );
if( isModuleEditor )
if( item->Type() == PCB_PAD_T && !isModuleEditor )
{
// modedit saves everything upfront
m_parent.SaveCopyInUndoList( getBoard()->m_Modules, UR_CHANGED );
// If it is not the module editor, then duplicate the parent module instead
item = static_cast<MODULE*>( item )->GetParent();
}
for ( int i = 0; i < numItems; ++i )
// The first item in list is the original item. We do not modify it
for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ )
{
BOARD_ITEM* item = getNthItemToArray( i );
BOARD_ITEM* new_item;
if( item->Type() == PCB_PAD_T && !isModuleEditor )
if( isModuleEditor )
{
// If it is not the module editor, then duplicate the parent module instead
item = static_cast<MODULE*>( item )->GetParent();
// increment pad numbers if do any renumbering
// (we will number again later according to the numbering scheme if set)
new_item = module->Duplicate( item, array_opts->ShouldNumberItems() );
}
else
{
// PCB items keep the same numbering
new_item = getBoard()->Duplicate( item );
// @TODO: we should merge zones. This is a bit tricky, because
// the undo command needs saving old area, if it is merged.
}
// The first item in list is the original item. We do not modify it
for( int ptN = 1; ptN < array_opts->GetArraySize(); ptN++ )
if( new_item )
{
BOARD_ITEM* new_item;
array_opts->TransformItem( ptN, new_item, rotPoint );
prePushAction( new_item );
commit.Add( new_item );
postPushAction( new_item );
}
if( isModuleEditor )
// attempt to renumber items if the array parameters define
// a complete numbering scheme to number by (as opposed to
// implicit numbering by incrementing the items during creation
if( new_item && array_opts->NumberingStartIsSpecified() )
{
// Renumber pads. Only new pad number renumbering has meaning,
// in the footprint editor.
if( new_item->Type() == PCB_PAD_T )
{
// increment pad numbers if do any renumbering
// (we will number again later according to the numbering scheme if set)
new_item = module->Duplicate( item, array_opts->ShouldNumberItems(), true );
}
else
{
// PCB items keep the same numbering
new_item = getBoard()->Duplicate( item, true );
// @TODO: we should merge zones. This is a bit tricky, because
// the undo command needs saving old area, if it is merged.
}
if( new_item )
{
array_opts->TransformItem( ptN, new_item, rotPoint );
prePushAction( new_item );
newItemsList.PushItem( new_item ); // For undo list
postPushAction( new_item );
}
// attempt to renumber items if the array parameters define
// a complete numbering scheme to number by (as opposed to
// implicit numbering by incrementing the items during creation
if( new_item && array_opts->NumberingStartIsSpecified() )
{
// Renumber pads. Only new pad number renumbering has meaning,
// in the footprint editor.
if( new_item->Type() == PCB_PAD_T )
{
const wxString padName = array_opts->GetItemNumber( ptN );
static_cast<D_PAD*>( new_item )->SetPadName( padName );
}
const wxString padName = array_opts->GetItemNumber( ptN );
static_cast<D_PAD*>( new_item )->SetPadName( padName );
}
}
}
if( !isModuleEditor )
{
// Add all items as a single undo point for PCB editors
m_parent.SaveCopyInUndoList( newItemsList, UR_NEW );
}
finalise();
}
commit.Push( _( "Create an array" ) );
finalise();
}

View File

@ -229,8 +229,6 @@ void LENGTH_TUNER_TOOL::performTuning()
}
m_router->StopRouting();
m_frame->OnModify();
highlightNet( false );
}

View File

@ -24,6 +24,7 @@
#include <class_board_connected_item.h>
#include <class_module.h>
#include <class_track.h>
#include <board_commit.h>
#include <ratsnest_data.h>
#include <layers_id_colors_and_visibility.h>
#include <geometry/convex_hull.h>
@ -154,7 +155,7 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
int net_b = aB->Net();
int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b].clearance : m_defaultClearance );
bool linesOnly = aA->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::LINE_T )
bool linesOnly = aA->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::LINE_T )
&& aB->OfKind( PNS::ITEM::SEGMENT_T | PNS::ITEM::LINE_T );
if( linesOnly && net_a >= 0 && net_b >= 0 && m_clearanceCache[net_a].coupledNet == net_b )
@ -413,11 +414,13 @@ PNS_KICAD_IFACE::PNS_KICAD_IFACE()
m_world = nullptr;
m_router = nullptr;
m_debugDecorator = nullptr;
m_commit = nullptr;
}
PNS_KICAD_IFACE::~PNS_KICAD_IFACE()
{
delete m_commit;
delete m_ruleResolver;
delete m_debugDecorator;
@ -743,7 +746,7 @@ void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld )
if( type == PCB_TRACE_T ) {
std::unique_ptr< PNS::SEGMENT > segment = syncTrack( t );
if( segment ) {
aWorld->Add( std::move( segment ) );
aWorld->Add( std::move( segment ) );
}
} else if( type == PCB_VIA_T ) {
std::unique_ptr< PNS::VIA > via = syncVia( static_cast<VIA*>( t ) );
@ -821,9 +824,8 @@ void PNS_KICAD_IFACE::RemoveItem( PNS::ITEM* aItem )
if( parent )
{
m_view->Remove( parent );
m_board->Remove( parent );
m_undoBuffer.PushItem( ITEM_PICKER( parent, UR_DELETED ) );
assert( m_commit );
m_commit->Remove( parent );
}
}
@ -871,20 +873,16 @@ void PNS_KICAD_IFACE::AddItem( PNS::ITEM* aItem )
{
aItem->SetParent( newBI );
newBI->ClearFlags();
m_view->Add( newBI );
m_board->Add( newBI );
m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) );
newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
assert( m_commit );
m_commit->Add( newBI );
}
}
void PNS_KICAD_IFACE::Commit()
{
m_board->GetRatsnest()->Recalculate();
m_frame->SaveCopyInUndoList( m_undoBuffer, UR_UNSPECIFIED );
m_undoBuffer.ClearItemsList();
m_frame->OnModify();
m_commit->Push( wxT( "Added a track" ) );
}
@ -909,6 +907,7 @@ void PNS_KICAD_IFACE::SetView( KIGFX::VIEW *aView )
m_debugDecorator->SetView( m_view );
}
void PNS_KICAD_IFACE::UpdateNet( int aNetCode )
{
wxLogTrace( "PNS", "Update-net %d", aNetCode );
@ -924,7 +923,11 @@ void PNS_KICAD_IFACE::SetRouter( PNS::ROUTER* aRouter )
m_router = aRouter;
}
void PNS_KICAD_IFACE::SetHostFrame( PCB_EDIT_FRAME *aFrame )
void PNS_KICAD_IFACE::SetHostFrame( PCB_EDIT_FRAME* aFrame )
{
m_frame = aFrame;
delete m_commit;
m_commit = new BOARD_COMMIT( aFrame );
}

View File

@ -30,6 +30,7 @@ class PNS_PCBNEW_RULE_RESOLVER;
class PNS_PCBNEW_DEBUG_DECORATOR;
class BOARD;
class BOARD_COMMIT;
namespace KIGFX
{
class VIEW;
@ -75,6 +76,7 @@ private:
BOARD* m_board;
PICKED_ITEMS_LIST m_undoBuffer;
PCB_EDIT_FRAME* m_frame;
BOARD_COMMIT* m_commit;
};
#endif

View File

@ -277,8 +277,8 @@ void ROUTER::updateView( NODE* aNode, ITEM_SET& aCurrent )
for ( auto item : added )
m_iface->DisplayItem( item );
for ( auto item : removed )
m_iface->HideItem ( item );
for( auto item : removed )
m_iface->HideItem( item );
}

View File

@ -144,7 +144,7 @@ public:
void SwitchLayer( int layer );
void ToggleViaPlacement();
void SetOrthoMode ( bool aEnable );
void SetOrthoMode( bool aEnable );
int GetCurrentLayer() const;
const std::vector<int> GetCurrentNets() const;
@ -211,8 +211,7 @@ public:
ITEM* QueryItemByParent( const BOARD_ITEM* aItem ) const;
void SetFailureReason ( const wxString& aReason ) { m_failureReason = aReason; }
void SetFailureReason( const wxString& aReason ) { m_failureReason = aReason; }
const wxString& FailureReason() const { return m_failureReason; }
PLACEMENT_ALGO* Placer() { return m_placer.get(); }
@ -270,7 +269,6 @@ private:
bool m_violation;
ROUTING_SETTINGS m_settings;
///> Stores list of modified items in the current operation
SIZES_SETTINGS m_sizes;
ROUTER_MODE m_mode;

View File

@ -105,7 +105,6 @@ void TOOL_BASE::Reset( RESET_REASON aReason )
m_board = getModel<BOARD>();
m_iface = new PNS_KICAD_IFACE;
m_iface->SetBoard( m_board );
m_iface->SetView( getView() );
m_iface->SetHostFrame( m_frame );

View File

@ -23,10 +23,12 @@
#ifndef __PNS_TOOL_BASE_H
#define __PNS_TOOL_BASE_H
#include <memory>
#include <import_export.h>
#include <math/vector2d.h>
#include <tool/tool_interactive.h>
#include <tools/pcb_tool.h>
#include <board_commit.h>
#include <msgpanel.h>

View File

@ -120,7 +120,6 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS::ITEM* aItem )
m_color = COLOR4D( 0, 1, 0, 1 );
ViewSetVisible( true );
ViewUpdate( GEOMETRY | APPEARANCE );
}
@ -276,7 +275,6 @@ void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int a
m_shape = aLine.Clone();
ViewSetVisible( true );
ViewUpdate( GEOMETRY | APPEARANCE );
}

View File

@ -534,8 +534,6 @@ bool ROUTER_TOOL::finishInteractive()
{
m_router->StopRouting();
m_frame->OnModify();
m_ctls->SetAutoPan( false );
m_ctls->ForceCursorPosition( false );
highlightNet( false );
@ -740,7 +738,6 @@ int ROUTER_TOOL::mainLoop( PNS::ROUTER_MODE aMode )
void ROUTER_TOOL::performDragging()
{
PCB_EDIT_FRAME* frame = getEditFrame<PCB_EDIT_FRAME>();
VIEW_CONTROLS* ctls = getViewControls();
if( m_startItem && m_startItem->IsLocked() )
@ -787,9 +784,6 @@ void ROUTER_TOOL::performDragging()
if( m_router->RoutingInProgress() )
m_router->StopRouting();
if( modified )
frame->OnModify();
m_startItem = NULL;
ctls->SetAutoPan( false );
@ -851,9 +845,6 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
if( m_router->RoutingInProgress() )
m_router->StopRouting();
if( modified )
frame->OnModify();
ctls->SetAutoPan( false );
ctls->ShowCursor( false );
frame->UndoRedoBlock( false );

View File

@ -40,6 +40,7 @@
#include <tool/tool_manager.h>
#include <router/direction.h>
#include <ratsnest_data.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_edge_mod.h>
@ -75,6 +76,7 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
boost::optional<VECTOR2D> startingPoint;
BOARD_COMMIT commit( m_frame );
m_frame->SetToolID( m_editModules ? ID_MODEDIT_LINE_TOOL : ID_PCB_ADD_LINE_BUTT,
wxCURSOR_PENCIL, _( "Add graphic line" ) );
@ -83,10 +85,8 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
{
if( line )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( line, UR_NEW );
parent->Add( line );
commit.Add( line );
commit.Push( _( "Draw a line segment" ) );
startingPoint = line->GetEnd();
}
else
@ -107,6 +107,7 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
{
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
BOARD_COMMIT commit( m_frame );
m_frame->SetToolID( m_editModules ? ID_MODEDIT_CIRCLE_TOOL : ID_PCB_CIRCLE_BUTT,
wxCURSOR_PENCIL, _( "Add graphic circle" ) );
@ -115,10 +116,8 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
{
if( circle )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( circle, UR_NEW );
m_frame->GetModel()->Add( circle );
commit.Add( circle );
commit.Push( _( "Draw a circle" ) );
}
circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
@ -134,6 +133,7 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
{
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
BOARD_COMMIT commit( m_frame );
m_frame->SetToolID( m_editModules ? ID_MODEDIT_ARC_TOOL : ID_PCB_ARC_BUTT,
wxCURSOR_PENCIL, _( "Add graphic arc" ) );
@ -142,10 +142,8 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
{
if( arc )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( arc, UR_NEW );
m_frame->GetModel()->Add( arc );
commit.Add( arc );
commit.Push( _( "Draw an arc" ) );
}
arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
@ -161,6 +159,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
{
BOARD_ITEM* text = NULL;
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
BOARD_COMMIT commit( m_frame );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
@ -185,11 +184,10 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
if( text )
{
// Delete the old text and have another try
m_frame->GetModel()->Delete( text ); // it was already added by CreateTextPcb()
delete text;
text = NULL;
preview.Clear();
preview.ViewUpdate();
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
@ -225,6 +223,8 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
if( m_editModules )
{
TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) m_frame->GetModel() );
textMod->SetLayer( m_frame->GetActiveLayer() );
textMod->SetSize( dsnSettings.m_ModuleTextSize );
textMod->SetThickness( dsnSettings.m_ModuleTextWidth );
textMod->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
@ -232,15 +232,34 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
DialogEditModuleText textDialog( m_frame, textMod, NULL );
bool placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
if( placing )
if( !placing )
text = textMod;
else
delete textMod;
}
else
{
assert( !m_editModules );
text = static_cast<PCB_EDIT_FRAME*>( m_frame )->CreateTextePcb( NULL );
TEXTE_PCB* textPcb = new TEXTE_PCB( m_frame->GetModel() );
// TODO we have to set IS_NEW, otherwise InstallTextPCB.. creates an undo entry :| LEGACY_CLEANUP
textPcb->SetFlags( IS_NEW );
LAYER_ID layer = m_frame->GetActiveLayer();
textPcb->SetLayer( layer );
// Set the mirrored option for layers on the BACK side of the board
if( IsBackLayer( layer ) )
textPcb->SetMirrored( true );
textPcb->SetSize( dsnSettings.m_PcbTextSize );
textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
textPcb->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
if( textPcb->GetText().IsEmpty() )
delete textPcb;
else
text = textPcb;
}
if( text == NULL )
@ -258,21 +277,11 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
//assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
text->ClearFlags();
m_view->Add( text );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( text, UR_NEW );
if( m_editModules )
{
m_frame->GetModel()->Add( text );
}
else
{
// m_board->Add( text ); // it is already added by CreateTextePcb()
}
preview.Remove( text );
commit.Add( text );
commit.Push( _( "Place a text" ) );
m_controls->CaptureCursor( false );
m_controls->SetAutoPan( false );
m_controls->ShowCursor( true );
@ -306,6 +315,7 @@ int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
{
DIMENSION* dimension = NULL;
BOARD_COMMIT commit( m_frame );
int maxThickness;
// Add a VIEW_GROUP that serves as a preview for the new item
@ -338,7 +348,6 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
if( step != SET_ORIGIN ) // start from the beginning
{
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
delete dimension;
step = SET_ORIGIN;
@ -422,13 +431,11 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
assert( dimension->GetOrigin() != dimension->GetEnd() );
assert( dimension->GetWidth() > 0 );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( dimension, UR_NEW );
m_view->Add( dimension );
m_board->Add( dimension );
preview.Remove( dimension );
commit.Add( dimension );
commit.Push( _( "Draw a dimension" ) );
}
}
break;
@ -517,6 +524,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
BOARD_COMMIT commit( m_frame );
// Build the undo list & add items to the current view
for( auto it = list.begin(), itEnd = list.end(); it != itEnd; ++it )
@ -554,6 +562,7 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
else if( evt->Category() == TC_COMMAND )
{
// TODO it should be handled by EDIT_TOOL, so add items and select?
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
@ -616,20 +625,10 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
item = converted;
}
ITEM_PICKER itemWrapper( item, UR_NEW );
picklist.PushItem( itemWrapper );
}
m_frame->OnModify();
m_frame->SaveCopyInUndoList( picklist, UR_NEW );
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(); it != preview.End(); ++it )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
parent->Add( item );
m_view->Add( item );
commit.Add( item );
}
commit.Push( _( "Place a DXF drawing" ) );
break;
}
}
@ -664,15 +663,15 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
if( evt->IsClick( BUT_LEFT ) )
{
MODULE* module = (MODULE*) m_frame->GetModel();
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_CHANGED );
BOARD_COMMIT commit( m_frame );
commit.Modify( module );
// set the new relative internal local coordinates of footprint items
VECTOR2I cursorPos = m_controls->GetCursorPosition();
wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
module->MoveAnchorPosition( moveVector );
module->ViewUpdate();
commit.Push( _( "Move the footprint reference anchor" ) );
// Usually, we do not need to change twice the anchor position,
// so deselect the active tool
@ -818,24 +817,14 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
*static_cast<DRAWSEGMENT*>( l ) = line45;
l->SetEnd( aGraphic->GetStart() );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( l, UR_NEW );
parent->Add( l );
m_view->Add( l );
BOARD_COMMIT commit( m_frame );
commit.Add( l );
commit.Push( _( "Draw a line" ) );
}
delete aGraphic;
aGraphic = NULL;
}
else
{
assert( aGraphic->GetLength() > 0 );
assert( aGraphic->GetWidth() > 0 );
m_view->Add( aGraphic );
aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
preview.Clear();
break;
@ -922,7 +911,6 @@ bool DRAWING_TOOL::drawArc( DRAWSEGMENT*& aGraphic )
if( evt->IsCancel() || evt->IsActivate() )
{
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
delete aGraphic;
aGraphic = NULL;
break;
@ -1071,6 +1059,7 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
ZONE_CONTAINER* zone = NULL;
DRAWSEGMENT line45;
DRAWSEGMENT* helperLine = NULL; // we will need more than one helper line
BOARD_COMMIT commit( m_frame );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
@ -1154,17 +1143,11 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
zone->Outline()->CloseLastContour();
zone->Outline()->RemoveNullSegments();
m_frame->OnModify();
m_frame->SaveCopyInUndoList( zone, UR_NEW );
m_board->Add( zone );
m_view->Add( zone );
if( !aKeepout )
static_cast<PCB_EDIT_FRAME*>( m_frame )->Fill_Zone( zone );
zone->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_board->GetRatsnest()->Update( zone );
commit.Add( zone );
commit.Push( _( "Draw a zone" ) );
zone = NULL;
}

View File

@ -56,6 +56,8 @@ using namespace std::placeholders;
#include <dialogs/dialog_move_exact.h>
#include <dialogs/dialog_track_via_properties.h>
#include <board_commit.h>
EDIT_TOOL::EDIT_TOOL() :
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
m_dragging( false ), m_undoInhibit( 0 ), m_updateFlag( KIGFX::VIEW_ITEM::NONE )
@ -67,6 +69,9 @@ void EDIT_TOOL::Reset( RESET_REASON aReason )
{
m_dragging = false;
m_updateFlag = KIGFX::VIEW_ITEM::NONE;
if( aReason != RUN )
m_commit.reset( new BOARD_COMMIT( this ) );
}
@ -214,11 +219,10 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
lockOverride = true;
// Save items, so changes can be undone
if( !isUndoInhibited() )
selection.ForAll<BOARD_ITEM>( [&](BOARD_ITEM* item)
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
}
m_commit->Modify( item );
} );
m_cursor = controls->GetCursorPosition();
@ -243,6 +247,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
controls->SetAutoPan( true );
m_dragging = true;
// Do not save intermediate modifications when an item is dragged
incUndoInhibit();
}
}
@ -254,6 +260,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
// Dispatch TOOL_ACTIONs
else if( evt->Category() == TC_COMMAND )
{
wxPoint modPoint = getModificationPoint( selection );
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
Rotate( aEvent );
@ -301,6 +309,14 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
//MoveExact( aEvent );
break; // exit the loop - we move exactly, so we have finished moving
}
if( m_dragging )
{
// Update dragging offset (distance between cursor and the first dragged item)
m_offset = selection.Item<BOARD_ITEM>( 0 )->GetPosition() - modPoint;
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
updateRatsnest( true );
}
}
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
@ -319,24 +335,13 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
m_offset.x = 0;
m_offset.y = 0;
if( restore )
{
// Modifications have to be rollbacked, so restore the previous state of items
wxCommandEvent dummy;
editFrame->RestoreCopyFromUndoList( dummy );
}
else
{
// Changes are applied, so update the items
selection.group->ItemsViewUpdate( m_updateFlag );
}
if( unselect )
if( unselect || restore )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
ratsnest->ClearSimple();
ratsnest->Recalculate();
if( restore )
m_commit->Revert();
else
m_commit->Push( _( "Drag" ) );
controls->ShowCursor( false );
controls->SetAutoPan( false );
@ -363,17 +368,8 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
if( dlg.ShowModal() )
{
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
dlg.Apply();
selection.ForAll<KIGFX::VIEW_ITEM>( std::bind( &KIGFX::VIEW_ITEM::ViewUpdate,
std::placeholders::_1, KIGFX::VIEW_ITEM::ALL ) );
selection.ForAll<BOARD_ITEM>( std::bind( &RN_DATA::Update, ratsnest,
std::placeholders::_1 ) );
ratsnest->Recalculate();
dlg.Apply( *m_commit );
m_commit->Push( _( "Edit track/via properties" ) );
}
}
else if( selection.Size() == 1 ) // Properties are displayed when there is only one item selected
@ -381,34 +377,18 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
// Display properties dialog
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
// Store the head of the undo list to compare if anything has changed
std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList;
// Some of properties dialogs alter pointers, so we should deselect them
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
// Store flags, so they can be restored later
STATUS_FLAGS flags = item->GetFlags();
item->ClearFlags();
// It is necessary to determine if anything has changed, so store the current undo save point
PICKED_ITEMS_LIST* undoSavePoint = undoList.empty() ? NULL : undoList.back();
// Do not handle undo buffer, it is done by the properties dialogs
// Display properties dialog provided by the legacy canvas frame
editFrame->OnEditItemRequest( NULL, item );
if( !undoList.empty() && undoList.back() != undoSavePoint ) // Undo buffer has changed
{
// Process changes stored after undoSavePoint
processUndoBuffer( undoSavePoint );
// Update the modified item
item->ViewUpdate();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
ratsnest->Recalculate();
// TODO OBSERVER! I miss you so much..
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
}
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
item->SetFlags( flags );
}
@ -432,37 +412,20 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
wxPoint rotatePoint = getModificationPoint( selection );
// If it is being dragged, then it is already saved with UR_CHANGED flag
if( !isUndoInhibited() )
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_ROTATED, rotatePoint );
}
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
m_commit->Modify( item );
item->Rotate( rotatePoint, editFrame->GetRotationAngle() );
if( !m_dragging )
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
updateRatsnest( m_dragging );
// Update dragging offset (distance between cursor and the first dragged item)
m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() -
rotatePoint;
if( m_dragging )
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
else
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( !isUndoInhibited() )
m_commit->Push( _( "Rotate" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
// TODO selectionModified
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
return 0;
@ -472,7 +435,6 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
@ -482,32 +444,15 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
wxPoint flipPoint = getModificationPoint( selection );
if( !isUndoInhibited() ) // If it is being dragged, then it is already saved with UR_CHANGED flag
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_FLIPPED, flipPoint );
}
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
m_commit->Modify( item );
item->Flip( flipPoint );
if( !m_dragging )
item->ViewUpdate( KIGFX::VIEW_ITEM::LAYERS );
}
updateRatsnest( m_dragging );
// Update dragging offset (distance between cursor and the first dragged item)
m_offset = static_cast<BOARD_ITEM*>( selection.items.GetPickedItem( 0 ) )->GetPosition() -
flipPoint;
if( m_dragging )
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
else
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( !isUndoInhibited() )
m_commit->Push( _( "Flip" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
@ -520,94 +465,27 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
// Get a copy of the selected items set
PICKED_ITEMS_LIST selectedItems = selection.items;
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
// Get a copy instead of a reference, as we are going to clear current selection
SELECTION selection = m_selectionTool->GetSelection();
// As we are about to remove items, they have to be removed from the selection first
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selectedItems, UR_DELETED );
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
m_commit->Remove( item );
}
// And now remove
for( unsigned int i = 0; i < selectedItems.GetCount(); ++i )
remove( static_cast<BOARD_ITEM*>( selectedItems.GetPickedItem( i ) ) );
getModel<BOARD>()->GetRatsnest()->Recalculate();
m_commit->Push( _( "Delete" ) );
return 0;
}
void EDIT_TOOL::remove( BOARD_ITEM* aItem )
{
BOARD* board = getModel<BOARD>();
switch( aItem->Type() )
{
case PCB_MODULE_T:
{
MODULE* module = static_cast<MODULE*>( aItem );
module->ClearFlags();
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, getView(), std::placeholders::_1 ) );
// Module itself is deleted after the switch scope is finished
// list of pads is rebuild by BOARD::BuildListOfNets()
// Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
board->m_Status_Pcb = 0;
}
break;
// Default removal procedure
case PCB_MODULE_TEXT_T:
{
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem );
switch( text->GetType() )
{
case TEXTE_MODULE::TEXT_is_REFERENCE:
DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete component reference." ) );
return;
case TEXTE_MODULE::TEXT_is_VALUE:
DisplayError( getEditFrame<PCB_BASE_FRAME>(), _( "Cannot delete component value." ) );
return;
case TEXTE_MODULE::TEXT_is_DIVERS: // suppress warnings
break;
}
}
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
case PCB_LINE_T: // a segment not on copper layers
case PCB_TEXT_T: // a text on a layer
case PCB_TRACE_T: // a track segment (segment on a copper layer)
case PCB_VIA_T: // a via (like track segment on a copper layer)
case PCB_DIMENSION_T: // a dimension (graphic item)
case PCB_TARGET_T: // a target (graphic item)
case PCB_MARKER_T: // a marker used to show something
case PCB_ZONE_T: // SEG_ZONE items are now deprecated
case PCB_ZONE_AREA_T:
break;
default: // other types do not need to (or should not) be handled
assert( false );
return;
}
getView()->Remove( aItem );
getEditFrame<PCB_EDIT_FRAME>()->GetModel()->Remove( aItem );
}
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
@ -628,13 +506,6 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
if( ret == wxID_OK )
{
if( !isUndoInhibited() )
{
editFrame->OnModify();
// Record an action of move and rotate
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
}
VECTOR2I rp = selection.GetCenter();
wxPoint rotPoint( rp.x, rp.y );
@ -642,6 +513,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
m_commit->Modify( item );
item->Move( translation );
item->Rotate( rotPoint, rotation );
@ -649,12 +521,8 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
updateRatsnest( m_dragging );
if( m_dragging )
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
else
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( !isUndoInhibited() )
m_commit->Push( _( "Move exact" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
@ -681,9 +549,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
return 0;
// we have a selection to work on now, so start the tool process
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
editFrame->OnModify();
// prevent other tools making undo points while the duplicate is going on
// so that if you cancel, you don't get a duplicate object hiding over
@ -711,9 +577,8 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
BOARD_ITEM* new_item = NULL;
// TODO move DuplicateAndAddItem() to BOARD_ITEM_CONTAINER? dunno..
if( m_editModules )
new_item = editFrame->GetBoard()->m_Modules->Duplicate( item, increment, true );
new_item = editFrame->GetBoard()->m_Modules->Duplicate( item, increment );
else
{
#if 0
@ -722,18 +587,12 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// so zones are not duplicated
if( item->Type() != PCB_ZONE_AREA_T )
#endif
new_item = editFrame->GetBoard()->Duplicate( item, true );
new_item = editFrame->GetBoard()->Duplicate( item );
}
if( new_item )
{
if( new_item->Type() == PCB_MODULE_T )
{
static_cast<MODULE*>( new_item )->RunOnChildren( std::bind( &KIGFX::VIEW::Add,
getView(), std::placeholders::_1 ) );
}
editFrame->GetGalCanvas()->GetView()->Add( new_item );
m_commit->Add( new_item );
// Select the new item, so we can pick it up
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, new_item );
@ -743,13 +602,11 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
// record the new items as added
if( !selection.Empty() )
{
editFrame->SaveCopyInUndoList( selection.items, UR_NEW );
editFrame->DisplayToolMsg( wxString::Format( _( "Duplicated %d item(s)" ),
(int) old_items.size() ) );
// If items were duplicated, pick them up
// this works well for "dropping" copies around
// this works well for "dropping" copies around and pushes the commit
TOOL_EVENT evt = COMMON_ACTIONS::editActivate.MakeEvent();
Main( evt );
}
@ -766,11 +623,9 @@ class GAL_ARRAY_CREATOR: public ARRAY_CREATOR
public:
GAL_ARRAY_CREATOR( PCB_BASE_FRAME& editFrame, bool editModules,
RN_DATA* ratsnest,
const SELECTION& selection ):
ARRAY_CREATOR( editFrame ),
m_editModules( editModules ),
m_ratsnest( ratsnest ),
m_selection( selection )
{}
@ -813,24 +668,13 @@ private:
void postPushAction( BOARD_ITEM* new_item ) //override
{
KIGFX::VIEW* view = m_parent.GetToolManager()->GetView();
if( new_item->Type() == PCB_MODULE_T)
{
static_cast<MODULE*>(new_item)->RunOnChildren(
std::bind(&KIGFX::VIEW::Add, view, std::placeholders::_1));
}
m_parent.GetGalCanvas()->GetView()->Add( new_item );
m_ratsnest->Update( new_item );
}
void finalise() // override
{
m_ratsnest->Recalculate();
}
bool m_editModules;
RN_DATA* m_ratsnest;
const SELECTION& m_selection;
};
@ -846,14 +690,8 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
return 0;
// we have a selection to work on now, so start the tool process
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
editFrame->OnModify();
GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules,
getModel<BOARD>()->GetRatsnest(),
selection );
GAL_ARRAY_CREATOR array_creator( *editFrame, m_editModules, selection );
array_creator.Invoke();
return 0;
@ -937,73 +775,6 @@ bool EDIT_TOOL::hoverSelection( bool aSanitize )
}
void EDIT_TOOL::processUndoBuffer( const PICKED_ITEMS_LIST* aLastChange )
{
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
const std::vector<PICKED_ITEMS_LIST*>& undoList = editFrame->GetScreen()->m_UndoList.m_CommandsList;
bool process = false;
for( const PICKED_ITEMS_LIST* list : undoList )
{
if( process )
processPickedList( list );
else if( list == aLastChange )
process = true; // Start processing starting with the next undo save point
}
// If we could not find the requested save point in the current undo list
// then the undo list must have been completely altered, so process everything
if( !process )
{
for( const PICKED_ITEMS_LIST* list : undoList )
processPickedList( list );
}
}
void EDIT_TOOL::processPickedList( const PICKED_ITEMS_LIST* aList )
{
KIGFX::VIEW* view = getView();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
for( unsigned int i = 0; i < aList->GetCount(); ++i )
{
UNDO_REDO_T operation = aList->GetPickedItemStatus( i );
BOARD_ITEM* updItem = static_cast<BOARD_ITEM*>( aList->GetPickedItem( i ) );
switch( operation )
{
case UR_CHANGED:
ratsnest->Update( updItem );
updItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
break;
case UR_DELETED:
if( updItem->Type() == PCB_MODULE_T )
static_cast<MODULE*>( updItem )->RunOnChildren( std::bind( &KIGFX::VIEW::Remove,
view, std::placeholders::_1 ) );
view->Remove( updItem );
//ratsnest->Remove( updItem ); // this is done in BOARD::Remove
break;
case UR_NEW:
if( updItem->Type() == PCB_MODULE_T )
static_cast<MODULE*>( updItem )->RunOnChildren( std::bind( &KIGFX::VIEW::Add,
view, std::placeholders::_1 ) );
view->Add( updItem );
//ratsnest->Add( updItem ); // this is done in BOARD::Add
break;
default:
assert( false ); // Not handled
break;
}
}
}
int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
@ -1019,7 +790,7 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
editFrame-> SetCurItem( mod );
editFrame->SetCurItem( mod );
if( editFrame->GetCurItem()->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
{

View File

@ -30,6 +30,7 @@
#include <tools/pcb_tool.h>
#include <view/view_group.h>
class BOARD_COMMIT;
class BOARD_ITEM;
class SELECTION_TOOL;
@ -135,9 +136,6 @@ private:
/// Counter of undo inhibitions. When zero, undo is not inhibited.
int m_undoInhibit;
///> Removes and frees a single BOARD_ITEM.
void remove( BOARD_ITEM* aItem );
///> The required update flag for modified items
KIGFX::VIEW_ITEM::VIEW_UPDATE_FLAGS m_updateFlag;
@ -216,6 +214,8 @@ private:
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
return dyn_cast<T*>( item );
}
std::unique_ptr<BOARD_COMMIT> m_commit;
};
#endif

View File

@ -43,6 +43,7 @@
#include <class_board.h>
#include <class_module.h>
#include <class_edge_mod.h>
#include <board_commit.h>
#include <functional>
using namespace std::placeholders;
@ -157,18 +158,17 @@ int MODULE_TOOLS::PlacePad( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( pad, UR_NEW );
BOARD_COMMIT commit( m_frame );
commit.Add( pad );
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
m_frame->GetModel()->Add( pad );
// Take the next available pad number
pad->IncrementPadName( true, true );
// Handle the view aspect
preview.Remove( pad );
m_view->Add( pad );
commit.Push( _( "Add a pad" ) );
// Start placing next pad
pad = new D_PAD( m_board->m_Modules );
@ -301,15 +301,17 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
evt->IsDblClick( BUT_LEFT ) )
{
// Accept changes
BOARD_COMMIT commit( m_frame );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_CHANGED );
for( D_PAD* pad : pads )
{
commit.Modify( pad );
pad->SetPadName( wxString::Format( wxT( "%s%d" ), padPrefix.c_str(), padNumber++ ) );
pad->ViewUpdate();
}
commit.Push( _( "Enumerate pads" ) );
break;
}
@ -403,7 +405,6 @@ int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
{
// Parse clipboard
PCB_IO io( CTL_FOR_CLIPBOARD );
MODULE* currentModule = m_board->m_Modules;
MODULE* pastedModule = NULL;
try
@ -469,8 +470,7 @@ int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( currentModule, UR_CHANGED );
BOARD_COMMIT commit( m_frame );
m_board->m_Status_Pcb = 0; // I have no clue why, but it is done in the legacy view
@ -480,8 +480,7 @@ int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
for( D_PAD* pad = pastedModule->Pads(); pad; pad = pad->Next() )
{
D_PAD* clone = static_cast<D_PAD*>( pad->Clone() );
currentModule->Add( clone );
m_view->Add( clone );
commit.Add( clone );
}
for( BOARD_ITEM* drawing = pastedModule->GraphicalItems();
@ -493,20 +492,17 @@ int MODULE_TOOLS::PasteItems( const TOOL_EVENT& aEvent )
{
// Do not add reference/value - convert them to the common type
text->SetType( TEXTE_MODULE::TEXT_is_DIVERS );
currentModule->Add( text );
// Whyyyyyyyyyyyyyyyyyyyyyy?! All other items conform to rotation performed
// on its parent module, but texts are so independent..
text->Rotate( text->GetPosition(), pastedModule->GetOrientation() );
}
else if( EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( clone ) )
{
currentModule->Add( edge );
commit.Add( text );
}
m_view->Add( clone );
commit.Add( clone );
}
commit.Push( _( "Paste clipboard contents" ) );
preview.Clear();
break;

View File

@ -41,6 +41,7 @@
#include <ratsnest_data.h>
#include <collectors.h>
#include <zones_functions_for_undo_redo.h>
#include <board_commit.h>
#include <view/view_group.h>
#include <view/view_controls.h>
@ -253,7 +254,6 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
module = NULL;
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
controls->ShowCursor( true );
}
else
@ -293,18 +293,12 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
// Add all the drawable parts to preview
preview.Add( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW_GROUP::Add, &preview, _1 ) );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( module, UR_NEW );
// Place the selected module
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
module->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
BOARD_COMMIT commit( m_frame );
commit.Add( module );
commit.Push( _( "Place a module" ) );
// Remove from preview
preview.Remove( module );
@ -416,7 +410,6 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
KIGFX::VIEW_GROUP preview( view );
preview.Add( target );
view->Add( &preview );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
controls->SetSnapping( true );
@ -454,12 +447,9 @@ int PCB_EDITOR_CONTROL::PlaceTarget( const TOOL_EVENT& aEvent )
assert( target->GetSize() > 0 );
assert( target->GetWidth() > 0 );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( target, UR_NEW );
view->Add( target );
board->Add( target );
target->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
BOARD_COMMIT commit( m_frame );
commit.Add( target );
commit.Push( _( "Place a layer alignment target" ) );
preview.Remove( target );
@ -579,6 +569,7 @@ int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
BOARD* board = getModel<BOARD>();
RN_DATA* ratsnest = board->GetRatsnest();
KIGFX::VIEW* view = getView();
BOARD_COMMIT commit( m_frame );
if( selection.Size() < 2 )
return 0;
@ -646,7 +637,8 @@ int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
}
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_frame->SaveCopyInUndoList( changes, UR_UNSPECIFIED );
commit.Stage( changes );
for( unsigned i = 0; i < changes.GetCount(); ++i )
{
@ -660,11 +652,12 @@ int PCB_EDITOR_CONTROL::ZoneMerge( const TOOL_EVENT& aEvent )
}
else if( picker.GetStatus() == UR_CHANGED )
{
item->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, item );
}
}
commit.Push( _( "Merge zones" ) );
return 0;
}

View File

@ -48,6 +48,7 @@
#include <view/view_controls.h>
#include <pcb_painter.h>
#include <origin_viewitem.h>
#include <board_commit.h>
#include <functional>
using namespace std::placeholders;
@ -770,11 +771,10 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
{
int open_ctl;
wxString fileName;
PICKED_ITEMS_LIST undoListPicker;
PCB_EDIT_FRAME* editFrame = dynamic_cast<PCB_EDIT_FRAME*>( m_frame );
BOARD* board = getModel<BOARD>();
KIGFX::VIEW* view = getView();
BOARD_COMMIT commit( editFrame );
if( !editFrame )
return 0;
@ -838,8 +838,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
continue;
}
undoListPicker.PushItem( ITEM_PICKER( track, UR_NEW ) );
view->Add( track );
commit.Add( track );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, track );
}
@ -847,11 +846,7 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
for( ; module; module = module->Next() )
{
undoListPicker.PushItem( ITEM_PICKER( module, UR_NEW ) );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
commit.Add( module );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, module );
}
@ -859,24 +854,22 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
for( ; drawing; drawing = drawing->Next() )
{
undoListPicker.PushItem( ITEM_PICKER( drawing, UR_NEW ) );
view->Add( drawing );
commit.Add( drawing );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, drawing );
}
for( ZONE_CONTAINER* zone = board->GetArea( zonescount ); zone;
zone = board->GetArea( zonescount ) )
{
undoListPicker.PushItem( ITEM_PICKER( zone, UR_NEW ) );
zonescount++;
view->Add( zone );
++zonescount;
commit.Add( zone );
m_toolMgr->RunAction( COMMON_ACTIONS::selectItem, true, zone );
}
if( undoListPicker.GetCount() == 0 )
if( commit.Empty() )
return 0;
editFrame->SaveCopyInUndoList( undoListPicker, UR_NEW );
commit.Push( _( "Append a board" ) );
// Synchronize layers
// we should not ask PLUGINs to do these items:
@ -900,7 +893,9 @@ int PCBNEW_CONTROL::AppendBoard( const TOOL_EVENT& aEvent )
board->GetRatsnest()->Recalculate();
// Start dragging the appended board
VECTOR2D v( static_cast<BOARD_ITEM*>( undoListPicker.GetPickedItem( 0 ) )->GetPosition() );
SELECTION_TOOL* selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
const SELECTION& selection = selectionTool->GetSelection();
VECTOR2D v( selection.Item<BOARD_ITEM>( 0 )->GetPosition() );
getViewControls()->WarpCursor( v, true, true );
m_toolMgr->InvokeTool( "pcbnew.InteractiveEdit" );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* Copyright (C) 2014-2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -30,6 +30,7 @@
#include <wxPcbStruct.h>
#include <class_board.h>
#include <ratsnest_data.h>
#include <board_commit.h>
#include <confirm.h>
@ -75,39 +76,34 @@ int PLACEMENT_TOOL::AlignTop( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Compute the highest point of selection - it will be the edge of alignment
int top = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetY();
for( int i = 1; i < selection.Size(); ++i )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int currentTop = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetY();
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
// Compute the highest point of selection - it will be the edge of alignment
int top = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetY();
for( int i = 1; i < selection.Size(); ++i )
{
int currentTop = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetY();
if( top > currentTop ) // Y decreases when going up
top = currentTop;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = top - item->GetBoundingBox().GetY();
item->Move( wxPoint( 0, difference ) );
item->ViewUpdate();
ratsnest->Update( item );
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( top > currentTop ) // Y decreases when going up
top = currentTop;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = top - item->GetBoundingBox().GetY();
item->Move( wxPoint( 0, difference ) );
}
commit.Push( _( "Align to top" ) );
return 0;
}
@ -116,39 +112,34 @@ int PLACEMENT_TOOL::AlignBottom( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Compute the lowest point of selection - it will be the edge of alignment
int bottom = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetBottom();
for( int i = 1; i < selection.Size(); ++i )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int currentBottom = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetBottom();
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
// Compute the lowest point of selection - it will be the edge of alignment
int bottom = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetBottom();
for( int i = 1; i < selection.Size(); ++i )
{
int currentBottom = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetBottom();
if( bottom < currentBottom ) // Y increases when going down
bottom = currentBottom;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = bottom - item->GetBoundingBox().GetBottom();
item->Move( wxPoint( 0, difference ) );
item->ViewUpdate();
ratsnest->Update( item );
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( bottom < currentBottom ) // Y increases when going down
bottom = currentBottom;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = bottom - item->GetBoundingBox().GetBottom();
item->Move( wxPoint( 0, difference ) );
}
commit.Push( _( "Align to bottom" ) );
return 0;
}
@ -157,39 +148,34 @@ int PLACEMENT_TOOL::AlignLeft( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Compute the leftmost point of selection - it will be the edge of alignment
int left = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetX();
for( int i = 1; i < selection.Size(); ++i )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int currentLeft = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetX();
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
// Compute the leftmost point of selection - it will be the edge of alignment
int left = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetX();
for( int i = 1; i < selection.Size(); ++i )
{
int currentLeft = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetX();
if( left > currentLeft ) // X decreases when going left
left = currentLeft;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = left - item->GetBoundingBox().GetX();
item->Move( wxPoint( difference, 0 ) );
item->ViewUpdate();
ratsnest->Update( item );
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( left > currentLeft ) // X decreases when going left
left = currentLeft;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = left - item->GetBoundingBox().GetX();
item->Move( wxPoint( difference, 0 ) );
}
commit.Push( _( "Align to left" ) );
return 0;
}
@ -198,39 +184,34 @@ int PLACEMENT_TOOL::AlignRight( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Compute the rightmost point of selection - it will be the edge of alignment
int right = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetRight();
for( int i = 1; i < selection.Size(); ++i )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int currentRight = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetRight();
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
// Compute the rightmost point of selection - it will be the edge of alignment
int right = selection.Item<BOARD_ITEM>( 0 )->GetBoundingBox().GetRight();
for( int i = 1; i < selection.Size(); ++i )
{
int currentRight = selection.Item<BOARD_ITEM>( i )->GetBoundingBox().GetRight();
if( right < currentRight ) // X increases when going right
right = currentRight;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = right - item->GetBoundingBox().GetRight();
item->Move( wxPoint( difference, 0 ) );
item->ViewUpdate();
ratsnest->Update( item );
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
if( right < currentRight ) // X increases when going right
right = currentRight;
}
// Move the selected items
for( int i = 0; i < selection.Size(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
int difference = right - item->GetBoundingBox().GetRight();
item->Move( wxPoint( difference, 0 ) );
}
commit.Push( _( "Align to right" ) );
return 0;
}
@ -251,45 +232,40 @@ int PLACEMENT_TOOL::DistributeHorizontally( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Prepare a list, so the items can be sorted by their X coordinate
std::list<BOARD_ITEM*> itemsList;
for( int i = 0; i < selection.Size(); ++i )
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
// Sort items by X coordinate
itemsList.sort( compareX );
// Expected X coordinate for the next item (=minX)
int position = (*itemsList.begin())->GetBoundingBox().Centre().x;
// X coordinate for the last item
const int maxX = (*itemsList.rbegin())->GetBoundingBox().Centre().x;
// Distance between items
const int distance = ( maxX - position ) / ( itemsList.size() - 1 );
for( BOARD_ITEM* item : itemsList )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int difference = position - item->GetBoundingBox().Centre().x;
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
item->Move( wxPoint( difference, 0 ) );
// Prepare a list, so the items can be sorted by their X coordinate
std::list<BOARD_ITEM*> itemsList;
for( int i = 0; i < selection.Size(); ++i )
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
// Sort items by X coordinate
itemsList.sort( compareX );
// Expected X coordinate for the next item (=minX)
int position = (*itemsList.begin())->GetBoundingBox().Centre().x;
// X coordinate for the last item
const int maxX = (*itemsList.rbegin())->GetBoundingBox().Centre().x;
// Distance between items
const int distance = ( maxX - position ) / ( itemsList.size() - 1 );
for( BOARD_ITEM* item : itemsList )
{
int difference = position - item->GetBoundingBox().Centre().x;
item->Move( wxPoint( difference, 0 ) );
item->ViewUpdate();
ratsnest->Update( item );
position += distance;
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
position += distance;
}
commit.Push( _( "Distribute horizontally" ) );
return 0;
}
@ -298,45 +274,40 @@ int PLACEMENT_TOOL::DistributeVertically( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Size() > 1 )
if( selection.Size() <= 1 )
return 0;
BOARD_COMMIT commit( getEditFrame<PCB_BASE_FRAME>() );
commit.Stage( selection.items, UR_CHANGED );
// Prepare a list, so the items can be sorted by their Y coordinate
std::list<BOARD_ITEM*> itemsList;
for( int i = 0; i < selection.Size(); ++i )
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
// Sort items by Y coordinate
itemsList.sort( compareY );
// Expected Y coordinate for the next item (=minY)
int position = (*itemsList.begin())->GetBoundingBox().Centre().y;
// Y coordinate for the last item
const int maxY = (*itemsList.rbegin())->GetBoundingBox().Centre().y;
// Distance between items
const int distance = ( maxY - position ) / ( itemsList.size() - 1 );
for( BOARD_ITEM* item : itemsList )
{
PCB_BASE_FRAME* editFrame = getEditFrame<PCB_BASE_FRAME>();
RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
int difference = position - item->GetBoundingBox().Centre().y;
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
item->Move( wxPoint( 0, difference ) );
// Prepare a list, so the items can be sorted by their Y coordinate
std::list<BOARD_ITEM*> itemsList;
for( int i = 0; i < selection.Size(); ++i )
itemsList.push_back( selection.Item<BOARD_ITEM>( i ) );
// Sort items by Y coordinate
itemsList.sort( compareY );
// Expected Y coordinate for the next item (=minY)
int position = (*itemsList.begin())->GetBoundingBox().Centre().y;
// Y coordinate for the last item
const int maxY = (*itemsList.rbegin())->GetBoundingBox().Centre().y;
// Distance between items
const int distance = ( maxY - position ) / ( itemsList.size() - 1 );
for( BOARD_ITEM* item : itemsList )
{
int difference = position - item->GetBoundingBox().Centre().y;
item->Move( wxPoint( 0, difference ) );
item->ViewUpdate();
ratsnest->Update( item );
position += distance;
}
getModel<BOARD>()->GetRatsnest()->Recalculate();
position += distance;
}
commit.Push( _( "Distribute vertically" ) );
return 0;
}

View File

@ -34,6 +34,7 @@ using namespace std::placeholders;
#include "common_actions.h"
#include "selection_tool.h"
#include "point_editor.h"
#include <board_commit.h>
#include <wxPcbStruct.h>
#include <class_edge_mod.h>
@ -259,6 +260,8 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
m_editedPoint = NULL;
bool modified = false;
BOARD_COMMIT commit( editFrame );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
@ -292,8 +295,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
{
if( !modified )
{
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
commit.Stage( selection.items, UR_CHANGED );
controls->ForceCursorPosition( false );
m_original = *m_editedPoint; // Save the original position
@ -302,6 +304,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
}
bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
setAltConstraint( enableAltConstraint );
@ -314,10 +317,9 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
updateItem();
updatePoints();
m_editPoints->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
// TODO necessary?
else if( evt->IsAction( &COMMON_ACTIONS::pointEditorUpdate ) )
{
updatePoints();
@ -327,7 +329,13 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
{
controls->SetAutoPan( false );
setAltConstraint( false );
modified = false;
if( modified )
{
commit.Push( _( "Drag a line ending" ) );
modified = false;
}
m_toolMgr->PassEvent();
}
@ -335,9 +343,7 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
{
if( modified ) // Restore the last change
{
wxCommandEvent dummy;
editFrame->RestoreCopyFromUndoList( dummy );
commit.Revert();
updatePoints();
modified = false;
}
@ -357,7 +363,6 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
if( m_editPoints )
{
finishItem();
item->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
view->Remove( m_editPoints.get() );
m_editPoints.reset();
}
@ -615,6 +620,8 @@ void POINT_EDITOR::updatePoints()
default:
break;
}
m_editPoints->ViewUpdate();
}
@ -719,17 +726,16 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const
void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
{
EDA_ITEM* item = m_editPoints->GetParent();
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_EDIT_FRAME* frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
BOARD_COMMIT commit( frame );
if( item->Type() == PCB_ZONE_AREA_T )
{
frame->OnModify();
frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
CPolyLine* outline = zone->Outline();
commit.Modify( zone );
// Handle the last segment, so other segments can be easily handled in a loop
unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0;
SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ),
@ -761,6 +767,8 @@ void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
nearestPoint = ( sideOrigin + sideEnd ) / 2;
outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y );
commit.Push( _( "Add a zone corner" ) );
}
else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T )
@ -771,8 +779,8 @@ void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
if( segment->GetShape() == S_SEGMENT )
{
ITEM_PICKER old_segment( segment, UR_CHANGED );
old_segment.SetLink( segment->Clone() );
BOARD_COMMIT commit( frame );
commit.Modify( segment );
SEG seg( segment->GetStart(), segment->GetEnd() );
VECTOR2I nearestPoint = seg.NearestPoint( aBreakPoint );
@ -799,14 +807,8 @@ void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint )
newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) );
newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) );
PICKED_ITEMS_LIST changes;
changes.PushItem( old_segment );
changes.PushItem( ITEM_PICKER( newSegment, UR_NEW ) );
frame->OnModify();
frame->SaveCopyInUndoList( changes, UR_UNSPECIFIED );
frame->GetModel()->Add( newSegment );
getView()->Add( newSegment );
commit.Add( newSegment );
commit.Push( _( "Split segment" ) );
}
}
}
@ -818,21 +820,20 @@ void POINT_EDITOR::removeCorner( EDIT_POINT* aPoint )
if( item->Type() == PCB_ZONE_AREA_T )
{
const SELECTION& selection = m_selectionTool->GetSelection();
PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();
BOARD_COMMIT commit( frame );
ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
CPolyLine* outline = zone->Outline();
commit.Modify( zone );
for( int i = 0; i < outline->GetCornersCount(); ++i )
{
if( VECTOR2I( outline->GetPos( i ) ) == aPoint->GetPosition() )
{
frame->OnModify();
frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
outline->DeleteCorner( i );
setEditedPoint( NULL );
commit.Push( _( "Remove a zone corner" ) );
break;
}
}

View File

@ -33,6 +33,7 @@
#include <class_drawpanel.h>
#include <confirm.h>
#include <wxPcbStruct.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_zone.h>
@ -859,13 +860,14 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
ZONE_EDIT_T edited;
ZONE_SETTINGS zoneInfo = GetZoneSettings();
BOARD_COMMIT commit( this );
m_canvas->SetIgnoreMouseEvents( true );
// Save initial zones configuration, for undo/redo, before adding new zone
// note the net name and the layer can be changed, so we must save all zones
s_AuxiliaryList.ClearListAndDeleteItems();
s_PickedList.ClearListAndDeleteItems();
SaveCopyOfZones(s_PickedList, GetBoard(), -1, UNDEFINED_LAYER );
SaveCopyOfZones( s_PickedList, GetBoard(), -1, UNDEFINED_LAYER );
if( aZone->GetIsKeepout() )
{
@ -901,7 +903,8 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
if( edited == ZONE_EXPORT_VALUES )
{
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
commit.Stage( s_PickedList );
commit.Push( _( "Modify zone properties" ) );
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
return;
}
@ -927,11 +930,10 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( wxDC* DC, ZONE_CONTAINER* aZone )
GetBoard()->RedrawAreasOutlines( m_canvas, DC, GR_OR, UNDEFINED_LAYER );
UpdateCopyOfZonesList( s_PickedList, s_AuxiliaryList, GetBoard() );
SaveCopyInUndoList(s_PickedList, UR_UNSPECIFIED);
commit.Stage( s_PickedList );
commit.Push( _( "Modify zone properties" ) );
s_PickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
OnModify();
}