Merge branch 'undobuffer_refactor'

- BOARD_COMMIT class.
Wrapper around undo buffer to simplify storing changes. Also performs
all the necessary updates (ratsnest, view) once anything changes. A good
entry point to introduce an observer interface.

- Removed BOARD_ITEM::Copy(), switched to C++ copy constructors and
operator=.

- BOARD_ITEM_CONTAINER interface.
A generic interface for adding & removing items, base class for MODULE
and BOARD.

- Removed UR_MODEDIT.
Module editor now uses the same UR_* flags as the layout editor. Now,
together with BOARD_COMMIT is the way to unify undo handling code in
tools (no more ugly 'if(m_editModules) {...} else {...}').

- Common code for handling undo buffer in the layout & module editor.
board_undo_redo.cpp and modedit_undo_redo.cpp are merged to
undo_redo.cpp. A lot of redundant code removed.
This commit is contained in:
Maciej Suminski 2016-09-13 10:07:35 +02:00
commit 64f04ab3e6
112 changed files with 2698 additions and 3138 deletions

View File

@ -203,6 +203,7 @@ set( COMMON_SRCS
class_plotter.cpp
class_undoredo_container.cpp
colors.cpp
commit.cpp
common.cpp
common_plot_functions.cpp
common_plotHPGL_functions.cpp

View File

@ -65,13 +65,7 @@ EDA_ITEM::EDA_ITEM( KICAD_T idType )
EDA_ITEM::EDA_ITEM( const EDA_ITEM& base )
{
initVars();
m_StructType = base.m_StructType;
m_Parent = base.m_Parent;
m_Flags = base.m_Flags;
// A copy of an item cannot have the same time stamp as the original item.
SetTimeStamp( GetNewTimeStamp() );
m_Status = base.m_Status;
*this = base;
}
@ -82,7 +76,6 @@ void EDA_ITEM::initVars()
Pback = NULL; // Linked list: Link (previous struct)
m_Parent = NULL; // Linked list: Link (parent struct)
m_List = NULL; // I am not on any list yet
m_Image = NULL; // Link to an image copy for undelete or abort command
m_Flags = 0; // flags for editions and other
SetTimeStamp( 0 ); // Time stamp used for logical links
m_Status = 0;
@ -224,23 +217,23 @@ bool EDA_ITEM::operator<( const EDA_ITEM& aItem ) const
return false;
}
#ifdef USE_EDA_ITEM_OP_EQ // see base_struct.h for explanations
EDA_ITEM& EDA_ITEM::operator=( const EDA_ITEM& aItem )
{
if( &aItem != this )
{
m_Image = aItem.m_Image;
m_StructType = aItem.m_StructType;
m_Parent = aItem.m_Parent;
m_Flags = aItem.m_Flags;
m_TimeStamp = aItem.m_TimeStamp;
m_Status = aItem.m_Status;
m_forceVisible = aItem.m_forceVisible;
}
// do not call initVars()
m_StructType = aItem.m_StructType;
m_Flags = aItem.m_Flags;
m_Status = aItem.m_Status;
m_Parent = aItem.m_Parent;
m_forceVisible = aItem.m_forceVisible;
// A copy of an item cannot have the same time stamp as the original item.
SetTimeStamp( GetNewTimeStamp() );
// do not copy list related fields (Pnext, Pback, m_List)
return *this;
}
#endif
const BOX2I EDA_ITEM::ViewBBox() const
{

View File

@ -153,10 +153,6 @@ void PICKED_ITEMS_LIST::ClearListAndDeleteItems()
case UR_LIBEDIT: /* Libedit save always a copy of the current item
* So, the picker is always owner of the picked item
*/
case UR_MODEDIT: /* Specific to the module editor (modedit creates a full
* copy of the current module when changed),
* and the picker is owner of this item
*/
delete wrapper.GetItem();
break;

176
common/commit.cpp Normal file
View File

@ -0,0 +1,176 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <commit.h>
#include <base_struct.h>
COMMIT::COMMIT()
{
}
COMMIT::~COMMIT()
{
for( COMMIT_LINE& ent : m_changes )
{
if( ent.m_copy )
delete ent.m_copy;
}
}
COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
{
assert( aChangeType != ( CHT_MODIFY | CHT_DONE ) ); // CHT_MODIFY and CHT_DONE are not compatible
int flag = aChangeType & CHT_FLAGS;
switch( aChangeType & CHT_TYPE )
{
case CHT_ADD:
assert( m_changedItems.find( aItem ) == m_changedItems.end() );
makeEntry( aItem, CHT_ADD | flag );
return *this;
case CHT_REMOVE:
makeEntry( aItem, CHT_REMOVE | flag );
return *this;
case CHT_MODIFY:
{
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY | flag, parent->Clone() );
return *this;
}
default:
assert( false );
}
return *this;
}
COMMIT& COMMIT::Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy )
{
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY, aCopy );
return *this;
}
COMMIT& COMMIT::Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType )
{
for( EDA_ITEM* item : container )
{
Stage( item, aChangeType );
}
return *this;
}
COMMIT& COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag )
{
for( unsigned int i = 0; i < aItems.GetCount(); i++ )
{
UNDO_REDO_T change_type = aItems.GetPickedItemStatus( i );
EDA_ITEM* item = aItems.GetPickedItem( i );
EDA_ITEM* copy = NULL;
if( change_type == UR_UNSPECIFIED )
change_type = aItems.m_Status;
if( change_type == UR_UNSPECIFIED )
change_type = aModFlag;
if( ( copy = aItems.GetPickedItemLink( i ) ) )
{
assert( change_type == UR_CHANGED );
// There was already a copy created, so use it
Modified( item, copy );
}
else
{
Stage( item, convert( change_type ) );
}
}
return *this;
}
void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
{
// Expect an item copy if it is going to be modified
assert( !!aCopy == ( ( aType & CHT_TYPE ) == CHT_MODIFY ) );
COMMIT_LINE ent;
ent.m_item = aItem;
ent.m_type = aType;
ent.m_copy = aCopy;
m_changedItems.insert( aItem );
m_changes.push_back( ent );
}
CHANGE_TYPE COMMIT::convert( UNDO_REDO_T aType ) const
{
switch( aType )
{
case UR_NEW:
return CHT_ADD;
case UR_DELETED:
return CHT_REMOVE;
default:
assert( false );
// fall through
case UR_CHANGED:
case UR_MOVED:
case UR_MIRRORED_X:
case UR_MIRRORED_Y:
case UR_ROTATED:
case UR_ROTATED_CLOCKWISE:
case UR_FLIPPED:
return CHT_MODIFY;
}
}

View File

@ -66,23 +66,6 @@ EDA_TEXT::EDA_TEXT( const wxString& text )
}
EDA_TEXT::EDA_TEXT( const EDA_TEXT& aText )
{
m_Pos = aText.m_Pos;
m_Size = aText.m_Size;
m_Orient = aText.m_Orient;
m_Attributs = aText.m_Attributs;
m_Mirror = aText.m_Mirror;
m_HJustify = aText.m_HJustify;
m_VJustify = aText.m_VJustify;
m_Thickness = aText.m_Thickness;
m_Italic = aText.m_Italic;
m_Bold = aText.m_Bold;
m_MultilineAllowed = aText.m_MultilineAllowed;
m_Text = aText.m_Text;
}
EDA_TEXT::~EDA_TEXT()
{
}

View File

@ -55,18 +55,21 @@ VIEW_GROUP::~VIEW_GROUP()
void VIEW_GROUP::Add( VIEW_ITEM* aItem )
{
m_items.insert( aItem );
ViewUpdate();
}
void VIEW_GROUP::Remove( VIEW_ITEM* aItem )
{
m_items.erase( aItem );
ViewUpdate();
}
void VIEW_GROUP::Clear()
{
m_items.clear();
ViewUpdate();
}
@ -128,7 +131,8 @@ void VIEW_GROUP::FreeItems()
{
delete item;
}
m_items.clear();
Clear();
}

View File

@ -258,7 +258,5 @@ SCH_ITEM* DuplicateStruct( SCH_ITEM* aDrawStruct, bool aClone )
if( aClone )
NewDrawStruct->SetTimeStamp( aDrawStruct->GetTimeStamp() );
NewDrawStruct->SetImage( aDrawStruct );
return NewDrawStruct;
}

View File

@ -102,7 +102,7 @@
/* Used if undo / redo command:
* swap data between Item and its copy, pointed by its .m_Image member
* swap data between Item and its copy, pointed by its picked item link member
* swapped data is data modified by edition, so not all values are swapped
*/

View File

@ -179,9 +179,6 @@ protected:
/// Flag bits for editing and other uses.
STATUS_FLAGS m_Flags;
// Link to an copy of the item use to save the item's state for undo/redo feature.
EDA_ITEM* m_Image;
private:
void initVars();
@ -262,8 +259,6 @@ public:
void ClearFlags( STATUS_FLAGS aMask = EDA_ITEM_ALL_FLAGS ) { m_Flags &= ~aMask; }
STATUS_FLAGS GetFlags() const { return m_Flags; }
void SetImage( EDA_ITEM* aItem ) { m_Image = aItem; }
/**
* Function SetForceVisible
* is used to set and cleag force visible flag used to force the item to be drawn
@ -482,17 +477,11 @@ public:
*/
static bool Sort( const EDA_ITEM* aLeft, const EDA_ITEM* aRight ) { return *aLeft < *aRight; }
#if 0
/**
* Operator assignment
* is used to assign the members of \a aItem to another object.
*
* @warning This is still a work in progress and not ready for prime time. Do not use
* as there is a known issue with wxString buffers.
*/
virtual EDA_ITEM& operator=( const EDA_ITEM& aItem );
#define USE_EDA_ITEM_OP_EQ
#endif
EDA_ITEM& operator=( const EDA_ITEM& aItem );
/// @copydoc VIEW_ITEM::ViewBBox()
virtual const BOX2I ViewBBox() const;

View File

@ -79,7 +79,7 @@ protected:
LAYER_ID m_Layer;
static int getTrailingInt( wxString aStr );
static int getNextNumberInSequence( std::set<int> aSeq, bool aFillSequenceGaps );
static int getNextNumberInSequence( const std::set<int>& aSeq, bool aFillSequenceGaps );
public:
@ -88,7 +88,8 @@ public:
{
}
// Do not create a copy constructor. The one generated by the compiler is adequate.
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
virtual const wxPoint& GetPosition() const = 0;

View File

@ -69,8 +69,6 @@ enum UNDO_REDO_T {
UR_ROTATED_CLOCKWISE, // Rotated item (clockwise), undo by rotating it
UR_FLIPPED, // flipped (board items only), undo by flipping it
UR_WIRE_IMAGE, // Specific to Eeschema for handling wires changes.
UR_MODEDIT, // Specific to the module editor (modedit creates a full copy of
// the current module when changed)
UR_LIBEDIT, // Specific to the component editor (libedit creates a full copy
// of the current component when changed)
UR_EXCHANGE_T ///< Use for changing the schematic text type where swapping

160
include/commit.h Normal file
View File

@ -0,0 +1,160 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __COMMIT_H
#define __COMMIT_H
#include <set>
#include <vector>
#include <class_undoredo_container.h>
class EDA_ITEM;
///> Types of changes
enum CHANGE_TYPE {
CHT_ADD = 1,
CHT_REMOVE = 2,
CHT_MODIFY = 4,
CHT_TYPE = CHT_ADD | CHT_REMOVE | CHT_MODIFY,
///> Flag to indicate the change is already applied,
///> just notify observers (not compatible with CHT_MODIFY)
CHT_DONE = 8,
CHT_FLAGS = CHT_DONE
};
template<typename T>
CHANGE_TYPE operator|( CHANGE_TYPE aTypeA, T aTypeB )
{
return CHANGE_TYPE( (int) aTypeA | (int) aTypeB );
}
template<typename T>
CHANGE_TYPE operator&( CHANGE_TYPE aTypeA, T aTypeB )
{
return CHANGE_TYPE( (int) aTypeA & (int) aTypeB );
}
/**
* Class COMMIT
*
* Represents a set of changes (additions, deletions or modifications)
* of a data model (e.g. the BOARD) class.
*
* The class can be used to propagate changes to subscribed objects (e.g. views, ratsnest),
* and automatically create undo/redo points.
*/
class COMMIT
{
public:
COMMIT();
virtual ~COMMIT();
///> Adds a new item to the model
COMMIT& Add( EDA_ITEM* aItem )
{
return Stage( aItem, CHT_ADD );
}
///> Notifies observers that aItem has been added
COMMIT& Added( EDA_ITEM* aItem )
{
return Stage( aItem, CHT_ADD | CHT_DONE );
}
///> Removes a new item from the model
COMMIT& Remove( EDA_ITEM* aItem )
{
return Stage( aItem, CHT_REMOVE );
}
///> Notifies observers that aItem has been removed
COMMIT& Removed( EDA_ITEM* aItem )
{
return Stage( aItem, CHT_REMOVE | CHT_DONE );
}
///> Modifies a given item in the model.
///> Must be called before modification is performed.
COMMIT& Modify( EDA_ITEM* aItem )
{
return Stage( aItem, CHT_MODIFY );
}
///> Creates an undo entry for an item that has been already modified. Requires a copy done
///> before the modification.
COMMIT& Modified( EDA_ITEM* aItem, EDA_ITEM* aCopy );
///> Adds a change of the item aItem of type aChangeType to the change list.
COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType );
COMMIT& Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType );
COMMIT& Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag = UR_UNSPECIFIED );
///> Executes the changes.
virtual void Push( const wxString& aMessage ) = 0;
///> Revertes the commit by restoring the modifed items state.
virtual void Revert() = 0;
bool Empty() const
{
return m_changes.empty();
}
protected:
struct COMMIT_LINE
{
///> Main item that is added/deleted/modified
EDA_ITEM* m_item;
///> Optional copy of the item
EDA_ITEM* m_copy;
///> Modification type
CHANGE_TYPE m_type;
};
// Should be called in Push() & Revert() methods
void clear()
{
m_changedItems.clear();
m_changes.clear();
}
virtual void makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy = NULL );
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const = 0;
CHANGE_TYPE convert( UNDO_REDO_T aType ) const;
std::set<EDA_ITEM*> m_changedItems;
std::vector<COMMIT_LINE> m_changes;
};
#endif

View File

@ -97,7 +97,10 @@ protected:
public:
EDA_TEXT( const wxString& text = wxEmptyString );
EDA_TEXT( const EDA_TEXT& aText );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
virtual ~EDA_TEXT();
/**

View File

@ -43,7 +43,7 @@
#define _HE_TRIANG_H_
//#define TTL_USE_NODE_ID // Each node gets it's own unique id
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
//#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
#include <list>
#include <unordered_set>
@ -106,6 +106,9 @@ protected:
/// Tag for quick connection resolution
int m_tag;
/// Whether it the node can be a target for ratsnest lines
bool m_noline;
/// List of board items that share this node
std::unordered_set<const BOARD_CONNECTED_ITEM*> m_parents;
@ -124,7 +127,7 @@ public:
#ifdef TTL_USE_NODE_ID
m_id( id_count++ ),
#endif
m_x( aX ), m_y( aY ), m_tag( -1 )
m_x( aX ), m_y( aY ), m_tag( -1 ), m_noline( false )
{
m_layers.reset();
}
@ -156,6 +159,18 @@ public:
m_tag = aTag;
}
/// Decides whether this node can be a ratsnest line target
inline void SetNoLine( bool aEnable )
{
m_noline = aEnable;
}
/// Returns true if this node can be a target for ratsnest lines
inline const bool& GetNoLine() const
{
return m_noline;
}
#ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined)
inline int Id() const

View File

@ -131,6 +131,7 @@ public:
inline virtual void SetLayer( int aLayer )
{
m_layer = aLayer;
ViewUpdate();
}
/**

View File

@ -39,6 +39,8 @@
/* Forward declarations of classes. */
class PCB_SCREEN;
class BOARD;
class BOARD_COMMIT;
class BOARD_ITEM_CONTAINER;
class TEXTE_PCB;
class MODULE;
class TRACK;
@ -637,64 +639,6 @@ public:
void OnSelectOptionToolbar( wxCommandEvent& event );
void ToolOnRightClick( wxCommandEvent& event );
/**
* Function SaveCopyInUndoList.
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItemToCopy = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function SaveCopyInUndoList (overloaded).
* Creates a new entry in undo list of commands.
* add a list of pickers to handle a list of items
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function PutDataInPreviousState
* Used in undo or redo command.
* Put data pointed by List in the previous state, i.e. the state memorized by List
* @param aList = a PICKED_ITEMS_LIST pointer to the list of items to undo/redo
* @param aRedoCommand = a bool: true for redo, false for undo
* @param aRebuildRatsnet = a bool: true to rebuild ratsnest (normal use), false
* to just retrieve last state (used in abort commands that do not need to
* rebuild ratsnest)
*/
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList,
bool aRedoCommand,
bool aRebuildRatsnet = true );
/**
* Function RestoreCopyFromRedoList
* Redo the last edition:
* - Save the current board in Undo list
* - Get an old version of the board from Redo list
* @return none
*/
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromUndoList
* Undo the last edition:
* - Save the current board in Redo list
* - Get an old version of the board from Undo list
* @return none
*/
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
/* Block operations: */
/**
@ -916,6 +860,9 @@ public:
///> @copydoc PCB_BASE_FRAME::SetBoard()
void SetBoard( BOARD* aBoard );
///> @copydoc PCB_BASE_EDIT_FRAME::GetModel()
BOARD_ITEM_CONTAINER* GetModel() const override;
///> @copydoc PCB_BASE_FRAME::SetPageSettings()
void SetPageSettings( const PAGE_INFO& aPageSettings ); // overload
@ -1142,11 +1089,9 @@ public:
* OldModule is deleted or put in undo list.
* @param aOldModule = footprint to replace
* @param aNewModule = footprint to put
* @param aUndoPickList = the undo list used to save OldModule. If null,
* OldModule is deleted
* @param aCommit = commit that should store the changes
*/
void Exchange_Module( MODULE* aOldModule, MODULE* aNewModule,
PICKED_ITEMS_LIST* aUndoPickList );
void Exchange_Module( MODULE* aOldModule, MODULE* aNewModule, BOARD_COMMIT& aCommit );
// loading modules: see PCB_BASE_FRAME

View File

@ -182,6 +182,7 @@ set( PCBNEW_AUTOROUTER_SRCS
)
set( PCBNEW_CLASS_SRCS
board_commit.cpp
tool_modview.cpp
modview_frame.cpp
pcbframe.cpp
@ -190,7 +191,6 @@ set( PCBNEW_CLASS_SRCS
array_creator.cpp
attribut.cpp
board_items_to_polygon_shape_transform.cpp
board_undo_redo.cpp
board_netlist_updater.cpp
block.cpp
block_module_editor.cpp
@ -237,7 +237,6 @@ set( PCBNEW_CLASS_SRCS
modedit.cpp
modedit_onclick.cpp
modeditoptions.cpp
modedit_undo_redo.cpp
moduleframe.cpp
modules.cpp
move-drag_pads.cpp
@ -266,6 +265,7 @@ set( PCBNEW_CLASS_SRCS
toolbars_update_user_interface.cpp
tracepcb.cpp
tr_modif.cpp
undo_redo.cpp
xchgmod.cpp
zones_convert_brd_items_to_polygons_with_Boost.cpp
zones_convert_to_polygons_aux_functions.cpp

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,77 +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_MODEDIT );
// 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->DuplicateAndAddItem(
item, array_opts->ShouldNumberItems() );
}
else
{
// PCB items keep the same numbering
new_item = getBoard()->DuplicateAndAddItem( item );
// @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

@ -196,7 +196,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
if( ret == wxID_OK )
{
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
const wxPoint blockCentre = GetScreen()->m_BlockLocate.Centre();
MoveMarkedItemsExactly( currentModule, blockCentre, translation, rotation );
}
@ -213,7 +213,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
DeleteMarkedItems( currentModule );
break;
@ -226,7 +226,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
@ -237,7 +237,7 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
@ -293,7 +293,7 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_MOVE: // Move
case BLOCK_PRESELECT_MOVE: // Move with preselection list
GetScreen()->m_BlockLocate.ClearItemsList();
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MoveMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector() );
m_canvas->Refresh( true );
break;
@ -301,7 +301,7 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_COPY: // Copy
case BLOCK_COPY_AND_INCREMENT: // Copy and increment pad names
GetScreen()->m_BlockLocate.ClearItemsList();
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
CopyMarkedItems( currentModule, GetScreen()->m_BlockLocate.GetMoveVector(),
command == BLOCK_COPY_AND_INCREMENT );
break;
@ -313,12 +313,12 @@ void FOOTPRINT_EDIT_FRAME::HandleBlockPlace( wxDC* DC )
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
case BLOCK_FLIP: // Mirror by popup menu, from block move
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
MirrorMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
case BLOCK_ROTATE:
SaveCopyInUndoList( currentModule, UR_MODEDIT );
SaveCopyInUndoList( currentModule, UR_CHANGED );
RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;

366
pcbnew/board_commit.cpp Normal file
View File

@ -0,0 +1,366 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <class_board.h>
#include <class_module.h>
#include <wxPcbStruct.h>
#include <tool/tool_manager.h>
#include <ratsnest_data.h>
#include <view/view.h>
#include <board_commit.h>
#include <boost/bind.hpp>
#include <tools/pcb_tool.h>
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL* aTool )
{
m_toolMgr = aTool->GetManager();
m_editModules = aTool->EditingModules();
}
BOARD_COMMIT::BOARD_COMMIT( PCB_BASE_FRAME* aFrame )
{
m_toolMgr = aFrame->GetToolManager();
m_editModules = aFrame->IsType( FRAME_PCB_MODULE_EDITOR );
}
BOARD_COMMIT::~BOARD_COMMIT()
{
}
void BOARD_COMMIT::Push( const wxString& aMessage )
{
// Objects potentially interested in changes:
PICKED_ITEMS_LIST undoList;
KIGFX::VIEW* view = m_toolMgr->GetView();
BOARD* board = (BOARD*) m_toolMgr->GetModel();
PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) m_toolMgr->GetEditFrame();
RN_DATA* ratsnest = board->GetRatsnest();
std::set<EDA_ITEM*> savedModules;
if( Empty() )
return;
for( COMMIT_LINE& ent : m_changes )
{
int changeType = ent.m_type & CHT_TYPE;
int changeFlags = ent.m_type & CHT_FLAGS;
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
// Module items need to be saved in the undo buffer before modification
if( m_editModules )
{
// Be sure that we are storing a module
if( ent.m_item->Type() != PCB_MODULE_T )
ent.m_item = ent.m_item->GetParent();
// We have not saved the module yet, so let's create an entry
if( savedModules.count( ent.m_item ) == 0 )
{
if( !ent.m_copy )
{
assert( changeType != CHT_MODIFY ); // too late to make a copy..
ent.m_copy = ent.m_item->Clone();
}
assert( ent.m_item->Type() == PCB_MODULE_T );
assert( ent.m_copy->Type() == PCB_MODULE_T );
ITEM_PICKER itemWrapper( ent.m_item, UR_CHANGED );
itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper );
frame->SaveCopyInUndoList( undoList, UR_CHANGED );
savedModules.insert( ent.m_item );
static_cast<MODULE*>( ent.m_item )->SetLastEditTime();
}
}
switch( changeType )
{
case CHT_ADD:
{
if( !m_editModules )
{
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) );
if( !( changeFlags & CHT_DONE ) )
board->Add( boardItem );
//ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add()
if( boardItem->Type() == PCB_MODULE_T )
{
MODULE* mod = static_cast<MODULE*>( boardItem );
mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
}
else
{
// modules inside modules are not supported yet
assert( boardItem->Type() != PCB_MODULE_T );
if( !( changeFlags & CHT_DONE ) )
board->m_Modules->Add( boardItem );
}
view->Add( boardItem );
break;
}
case CHT_REMOVE:
{
if( !m_editModules )
{
undoList.PushItem( ITEM_PICKER( boardItem, UR_DELETED ) );
}
switch( boardItem->Type() )
{
// Module items
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T:
{
// Do not allow footprint text removal when not editing a module
if( !m_editModules )
break;
bool remove = true;
if( boardItem->Type() == PCB_MODULE_TEXT_T )
{
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( boardItem );
switch( text->GetType() )
{
case TEXTE_MODULE::TEXT_is_REFERENCE:
//DisplayError( frame, _( "Cannot delete component reference." ) );
remove = false;
break;
case TEXTE_MODULE::TEXT_is_VALUE:
//DisplayError( frame, _( "Cannot delete component value." ) );
remove = false;
break;
case TEXTE_MODULE::TEXT_is_DIVERS: // suppress warnings
break;
default:
assert( false );
break;
}
}
if( remove )
{
view->Remove( boardItem );
if( !( changeFlags & CHT_DONE ) )
{
MODULE* module = static_cast<MODULE*>( boardItem->GetParent() );
assert( module && module->Type() == PCB_MODULE_T );
module->Delete( boardItem );
}
board->m_Status_Pcb = 0; // it is done in the legacy view (ratsnest perhaps?)
}
break;
}
// Board items
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:
view->Remove( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->Remove( boardItem );
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
break;
case PCB_MODULE_T:
{
// There are no modules inside a module yet
assert( !m_editModules );
MODULE* module = static_cast<MODULE*>( boardItem );
module->ClearFlags();
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
if( !( changeFlags & CHT_DONE ) )
board->Remove( module );
// Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
board->m_Status_Pcb = 0;
}
break;
default: // other types do not need to (or should not) be handled
assert( false );
break;
}
break;
}
case CHT_MODIFY:
{
if( !m_editModules )
{
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED );
assert( ent.m_copy );
itemWrapper.SetLink( ent.m_copy );
undoList.PushItem( itemWrapper );
}
boardItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL );
ratsnest->Update( boardItem );
break;
}
default:
assert( false );
break;
}
}
if( !m_editModules )
frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED );
frame->OnModify();
ratsnest->Recalculate();
clear();
}
EDA_ITEM* BOARD_COMMIT::parentObject( EDA_ITEM* aItem ) const
{
switch( aItem->Type() )
{
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
case PCB_MODULE_TEXT_T:
return aItem->GetParent();
default:
return aItem;
}
return aItem;
}
void BOARD_COMMIT::Revert()
{
PICKED_ITEMS_LIST undoList;
KIGFX::VIEW* view = m_toolMgr->GetView();
BOARD* board = (BOARD*) m_toolMgr->GetModel();
RN_DATA* ratsnest = board->GetRatsnest();
for( auto it = m_changes.rbegin(); it != m_changes.rend(); ++it )
{
COMMIT_LINE& ent = *it;
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( ent.m_item );
BOARD_ITEM* copy = static_cast<BOARD_ITEM*>( ent.m_copy );
switch( ent.m_type )
{
case CHT_ADD:
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
view->Remove( item );
ratsnest->Remove( item );
break;
case CHT_REMOVE:
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( boost::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
view->Add( item );
ratsnest->Add( item );
break;
case CHT_MODIFY:
{
if( item->Type() == PCB_MODULE_T )
{
MODULE* oldModule = static_cast<MODULE*>( item );
oldModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
}
view->Remove( item );
ratsnest->Remove( item );
item->SwapData( copy );
item->ClearFlags( SELECTED );
// Update all pads/drawings/texts, as they become invalid
// for the VIEW after SwapData() called for modules
if( item->Type() == PCB_MODULE_T )
{
MODULE* newModule = static_cast<MODULE*>( item );
newModule->RunOnChildren( boost::bind( &EDA_ITEM::ClearFlags, _1, SELECTED ) );
newModule->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) );
}
view->Add( item );
ratsnest->Add( item );
delete copy;
break;
}
default:
assert( false );
break;
}
}
ratsnest->Recalculate();
clear();
}

52
pcbnew/board_commit.h Normal file
View File

@ -0,0 +1,52 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __BOARD_COMMIT_H
#define __BOARD_COMMIT_H
#include <commit.h>
class BOARD_ITEM;
class PICKED_ITEMS_LIST;
class PCB_TOOL;
class PCB_BASE_FRAME;
class TOOL_MANAGER;
class BOARD_COMMIT : public COMMIT
{
public:
BOARD_COMMIT( PCB_TOOL* aTool );
BOARD_COMMIT( PCB_BASE_FRAME* aFrame );
virtual ~BOARD_COMMIT();
virtual void Push( const wxString& aMessage );
virtual void Revert();
private:
TOOL_MANAGER* m_toolMgr;
bool m_editModules;
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const;
};
#endif

View File

@ -0,0 +1,73 @@
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2016 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef BOARD_ITEM_CONTAINER_H
#define BOARD_ITEM_CONTAINER_H
#include <class_board_item.h>
enum ADD_MODE { ADD_INSERT, ADD_APPEND };
/**
* @brief Abstract interface for BOARD_ITEMs capable of storing other items inside.
* @see MODULE
* @see BOARD
*/
class BOARD_ITEM_CONTAINER : public BOARD_ITEM
{
public:
BOARD_ITEM_CONTAINER( BOARD_ITEM* aParent, KICAD_T aType )
: BOARD_ITEM( aParent, aType )
{
}
virtual ~BOARD_ITEM_CONTAINER()
{
}
/**
* @brief Adds an item to the container.
* @param aItem is an item to be added.
* @param aMode decides whether the item is added in the beginning or at the end of the list.
*/
virtual void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_INSERT ) = 0;
/**
* @brief Removes an item from the container.
* @param aItem is an item to be removed.
*/
virtual void Remove( BOARD_ITEM* aItem ) = 0;
/**
* @brief Removes an item from the containter and deletes it.
* @param aItem is an item to be deleted.
*/
virtual void Delete( BOARD_ITEM* aItem )
{
Remove( aItem );
delete aItem;
}
};
#endif /* BOARD_ITEM_CONTAINER_H */

View File

@ -49,42 +49,28 @@
#include <wxPcbStruct.h>
BOARD_NETLIST_UPDATER::BOARD_NETLIST_UPDATER ( PCB_EDIT_FRAME *aFrame, BOARD *aBoard ) :
m_frame ( aFrame ),
BOARD_NETLIST_UPDATER::BOARD_NETLIST_UPDATER( PCB_EDIT_FRAME* aFrame, BOARD* aBoard ) :
m_commit( aFrame ),
m_frame( aFrame ),
m_board( aBoard )
{
m_reporter = &NULL_REPORTER::GetInstance();
m_undoList = new PICKED_ITEMS_LIST;
m_deleteSinglePadNets = true;
m_deleteUnusedComponents = false;
m_isDryRun = false;
m_replaceFootprints = true;
m_lookupByTimestamp = false;
m_deleteSinglePadNets = true;
m_deleteUnusedComponents = false;
m_isDryRun = false;
m_replaceFootprints = true;
m_lookupByTimestamp = false;
m_warningCount = 0;
m_errorCount = 0;
m_warningCount = 0;
m_errorCount = 0;
}
BOARD_NETLIST_UPDATER::~BOARD_NETLIST_UPDATER ()
BOARD_NETLIST_UPDATER::~BOARD_NETLIST_UPDATER()
{
delete m_undoList;
}
void BOARD_NETLIST_UPDATER::pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, BOARD_ITEM* aCopy )
{
ITEM_PICKER picker( aItem, aCommandType );
if( aCommandType == UR_CHANGED )
{
if( m_undoList->FindItem ( aItem ) >= 0 ) // add only once
return;
picker.SetLink( aCopy ? aCopy : aItem->Clone() );
}
m_undoList->PushItem( picker );
}
wxPoint BOARD_NETLIST_UPDATER::estimateComponentInsertionPosition()
{
@ -124,28 +110,24 @@ MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetTimeStamp() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
msg.Printf( _( "Add component %s, footprint: %s.\n" ),
GetChars( aComponent->GetReference() ),
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if( !m_isDryRun )
{
// Owned by NETLIST, can only copy it.
MODULE *footprint = new MODULE( *aComponent->GetModule() );
MODULE* footprint = new MODULE( *aComponent->GetModule() );
footprint->SetParent( m_board );
footprint->SetPosition( estimateComponentInsertionPosition( ) );
footprint->SetTimeStamp( GetNewTimeStamp() );
m_board->Add( footprint, ADD_APPEND );
m_addedComponents.push_back( footprint );
pushUndo( footprint, UR_NEW );
m_commit.Add( footprint );
return footprint;
}
@ -165,23 +147,22 @@ MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
GetChars( aComponent->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
m_errorCount ++;
++m_errorCount;
}
return NULL;
}
MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcbComponent, COMPONENT* aNewComponent )
MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE* aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
if( !m_replaceFootprints )
return NULL;
// Test if the footprint has not changed
if( aNewComponent->GetFPID().empty() ||
aPcbComponent->GetFPID() == aNewComponent->GetFPID() )
// Test if the footprint has not changed
if( aNewComponent->GetFPID().empty() || aPcbComponent->GetFPID() == aNewComponent->GetFPID() )
return NULL;
if( aNewComponent->GetModule() != NULL )
@ -205,7 +186,9 @@ MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcb
if( !m_isDryRun )
{
wxASSERT( aPcbComponent != NULL );
MODULE* newFootprint = new MODULE( *aNewComponent->GetModule() );
newFootprint->SetParent( m_board );
if( aNetlist.IsFindByTimeStamp() )
newFootprint->SetReference( aPcbComponent->GetReference() );
@ -213,16 +196,14 @@ MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcb
newFootprint->SetPath( aPcbComponent->GetPath() );
aPcbComponent->CopyNetlistSettings( newFootprint, false );
m_board->Remove( aPcbComponent );
m_board->Add( newFootprint, ADD_APPEND );
pushUndo( aPcbComponent, UR_DELETED );
pushUndo( newFootprint, UR_NEW );
m_commit.Remove( aPcbComponent );
m_commit.Add( newFootprint );
return newFootprint;
}
} else {
}
else
{
msg.Printf( _( "Cannot change component %s footprint due to missing "
"footprint %s.\n" ),
GetChars( aPcbComponent->GetReference() ),
@ -238,13 +219,14 @@ MODULE* BOARD_NETLIST_UPDATER::replaceComponent( NETLIST& aNetlist, MODULE *aPcb
m_reporter->Report( msg, REPORTER::RPT_INFO );
m_errorCount ++;
++m_errorCount;
}
return NULL;
}
bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, COMPONENT* aNewComponent )
bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE* aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
@ -292,9 +274,10 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
GetChars( aPcbComponent->GetPath() ),
GetChars( aPcbComponent->GetValue() ),
GetChars( aNewComponent->GetValue() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if ( !m_isDryRun )
if( !m_isDryRun )
{
changed = true;
aPcbComponent->SetValue( aNewComponent->GetValue() );
@ -308,9 +291,10 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
GetChars( aPcbComponent->GetReference() ),
GetChars( aPcbComponent->GetPath() ),
GetChars( aNewComponent->GetTimeStamp() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun )
if( !m_isDryRun )
{
changed = true;
aPcbComponent->SetPath( aNewComponent->GetTimeStamp() );
@ -318,14 +302,15 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE *aPcbComponent, CO
}
if( changed )
pushUndo( aPcbComponent, UR_CHANGED, copy );
m_commit.Modified( aPcbComponent, copy );
else
delete copy;
return true;
}
bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent, COMPONENT* aNewComponent )
bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE* aPcbComponent, COMPONENT* aNewComponent )
{
wxString msg;
@ -333,7 +318,7 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
MODULE* copy = (MODULE*) aPcbComponent->Clone();
// At this point, the component footprint is updated. Now update the nets.
for( D_PAD *pad = aPcbComponent->Pads(); pad; pad = pad->Next() )
for( D_PAD* pad = aPcbComponent->Pads(); pad; pad = pad->Next() )
{
COMPONENT_NET net = aNewComponent->GetNet( pad->GetPadName() );
@ -351,7 +336,6 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
GetChars( aPcbComponent->GetPath() ),
GetChars( pad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
}
if( !m_isDryRun )
@ -364,38 +348,46 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
{
if( net.GetNetName() != pad->GetNetname() )
{
NETINFO_ITEM* netinfo = m_board->FindNet( net.GetNetName() );
const wxString& netName = net.GetNetName();
NETINFO_ITEM* netinfo = m_board->FindNet( netName );
if( netinfo == NULL )
if( netinfo == nullptr )
{
// It might be a new net that has not been added to the board yet
auto netIt = m_addedNets.find( netName );
if( netIt != m_addedNets.end() )
netinfo = netIt->second;
}
if( netinfo == nullptr )
{
// It is a new net, we have to add it
if( !m_isDryRun )
{
changed = true;
netinfo = new NETINFO_ITEM( m_board, net.GetNetName() );
m_board->AppendNet( netinfo );
pushUndo( netinfo, UR_NEW );
netinfo = new NETINFO_ITEM( m_board, netName );
m_commit.Add( netinfo );
m_addedNets[netName] = netinfo;
}
msg.Printf( _( "Add net %s.\n" ),
GetChars( net.GetNetName() ) );
msg.Printf( _( "Add net %s.\n" ), GetChars( netName ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
}
if( pad->GetNetname() != wxString("") )
if( !pad->GetNetname().IsEmpty() )
{
msg.Printf( _( "Reconnect component %s pin %s from net %s to net %s.\n"),
GetChars( aPcbComponent->GetReference() ),
GetChars( pad->GetPadName() ),
GetChars( pad->GetNetname() ),
GetChars( net.GetNetName() ) );
GetChars( netName ) );
} else {
msg.Printf( _( "Connect component %s pin %s to net %s.\n"),
GetChars( aPcbComponent->GetReference() ),
GetChars( pad->GetPadName() ),
GetChars( net.GetNetName() ) );
GetChars( netName ) );
}
m_reporter->Report( msg, REPORTER::RPT_ACTION );
@ -406,27 +398,27 @@ bool BOARD_NETLIST_UPDATER::updateComponentPadConnections( MODULE *aPcbComponent
GetChars( aPcbComponent->GetPath() ),
GetChars( pad->GetPadName() ),
GetChars( pad->GetNetname() ),
GetChars( net.GetNetName() ) );
GetChars( netName ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if ( !m_isDryRun )
if( !m_isDryRun )
{
changed = true;
pad->SetNetCode( netinfo->GetNet() );
pad->SetNet( netinfo );
}
}
}
}
if( changed )
pushUndo( aPcbComponent, UR_CHANGED, copy );
m_commit.Modified( aPcbComponent, copy );
else
delete copy;
return true;
}
bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
{
wxString msg;
@ -437,9 +429,6 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
{
nextModule = module->Next();
if( module->IsLocked() )
continue;
if( m_lookupByTimestamp )
component = aNetlist.GetComponentByTimeStamp( module->GetPath() );
else
@ -447,6 +436,14 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
if( component == NULL )
{
if( module->IsLocked() )
{
msg.Printf( _( "Component %s is locked, skipping removal.\n" ),
GetChars( module->GetReference() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
continue;
}
msg.Printf( _( "Remove component %s." ),
GetChars( module->GetReference() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
@ -457,16 +454,14 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
m_reporter->Report( msg, REPORTER::RPT_INFO );
if( !m_isDryRun )
{
pushUndo( module, UR_DELETED );
m_board->Remove( module );
}
m_commit.Remove( module );
}
}
return true;
}
bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
{
int count = 0;
@ -520,7 +515,6 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
{
msg.Printf( _( "Remove single pad net %s." ),
GetChars( previouspad->GetNetname() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
msg.Printf( _( "Remove single pad net \"%s\" on \"%s\" pad '%s'\n" ),
@ -529,7 +523,6 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
GetChars( previouspad->GetPadName() ) );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
//pushUndo( previouspad, UR_CHANGED );
previouspad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
}
@ -547,13 +540,12 @@ bool BOARD_NETLIST_UPDATER::deleteSinglePadNets()
// Examine last pad
if( pad && count == 1 )
{
//pushUndo( pad, UR_CHANGED );
pad->SetNetCode( NETINFO_LIST::UNCONNECTED );
}
return true;
}
bool BOARD_NETLIST_UPDATER::testConnectivity( NETLIST& aNetlist )
{
// Last step: Some tests:
@ -592,7 +584,7 @@ bool BOARD_NETLIST_UPDATER::testConnectivity( NETLIST& aNetlist )
GetChars( padname ),
GetChars( footprint->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_ERROR );
m_errorCount ++;
++m_errorCount;
}
}
@ -611,13 +603,14 @@ bool BOARD_NETLIST_UPDATER::testConnectivity( NETLIST& aNetlist )
msg.Printf( _( "Copper zone (net name %s): net has no pads connected." ),
GetChars( zone->GetNet()->GetNetname() ) );
m_reporter->Report( msg, REPORTER::RPT_WARNING );
m_warningCount ++;
++m_warningCount;
}
}
return true;
}
bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
{
wxString msg;
@ -630,17 +623,15 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
m_board->SetStatus( 0 );
}
for( int i = 0; i < (int) aNetlist.GetCount(); i++ )
{
COMPONENT* component = aNetlist.GetComponent( i );
MODULE *footprint = NULL;
MODULE* footprint = NULL;
msg.Printf( _( "Processing component \"%s:%s:%s\".\n" ),
GetChars( component->GetReference() ),
GetChars( component->GetTimeStamp() ),
GetChars( component->GetFPID().Format() ) );
m_reporter->Report( msg, REPORTER::RPT_INFO );
if( aNetlist.IsFindByTimeStamp() )
@ -650,8 +641,9 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
if( footprint ) // An existing footprint.
{
MODULE *newFootprint = replaceComponent ( aNetlist, footprint, component );
if ( newFootprint )
MODULE* newFootprint = replaceComponent( aNetlist, footprint, component );
if( newFootprint )
footprint = newFootprint;
}
else
@ -666,9 +658,6 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
}
}
//aNetlist.GetDeleteExtraFootprints()
if( m_deleteUnusedComponents )
@ -677,47 +666,40 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
if( m_deleteSinglePadNets )
deleteSinglePadNets();
if ( !m_isDryRun )
if( !m_isDryRun )
{
m_frame->SaveCopyInUndoList( *m_undoList, UR_UNSPECIFIED, wxPoint(0, 0) );
m_frame->OnModify();
m_frame->Compile_Ratsnest( NULL, true );
m_commit.Push( _( "Update netlist" ) );
m_frame->Compile_Ratsnest( NULL, false );
m_board->GetRatsnest()->ProcessBoard();
testConnectivity( aNetlist );
}
// Update the ratsnest
m_reporter->Report( wxT( "" ), REPORTER::RPT_ACTION );
m_reporter->Report( wxT( "" ), REPORTER::RPT_ACTION );
m_reporter->Report( wxT(""), REPORTER::RPT_ACTION );
m_reporter->Report( wxT(""), REPORTER::RPT_ACTION );
msg.Printf( _( "Total warnings: %d, errors: %d." ),
m_warningCount, m_errorCount );
msg.Printf( _( "Total warnings: %d, errors: %d." ), m_warningCount, m_errorCount );
m_reporter->Report( msg, REPORTER::RPT_ACTION );
if ( m_errorCount )
if( m_errorCount )
{
m_reporter->Report( _("Errors occured during the netlist update. Unless you "
"fix them, your board will not be consistent with the schematics." ),
m_reporter->Report( _( "Errors occured during the netlist update. Unless you "
"fix them, your board will not be consistent with the schematics." ),
REPORTER::RPT_ERROR );
return false;
} else {
m_reporter->Report( _("Netlist update successful!" ),
REPORTER::RPT_ACTION );
}
else
{
m_reporter->Report( _( "Netlist update successful!" ), REPORTER::RPT_ACTION );
}
return true;
}
bool BOARD_NETLIST_UPDATER::UpdateNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName )
const wxString& aCmpFileName )
{
return false;
}

View File

@ -39,10 +39,9 @@ class REPORTER;
class NETLIST;
class COMPONENT;
class MODULE;
class PICKED_ITEMS_LIST;
class PCB_EDIT_FRAME;
#include <class_undoredo_container.h>
#include <board_commit.h>
/**
* Class BOARD_NETLIST_UPDATER
@ -72,94 +71,89 @@ class PCB_EDIT_FRAME;
class BOARD_NETLIST_UPDATER
{
public:
BOARD_NETLIST_UPDATER( PCB_EDIT_FRAME* aFrame, BOARD* aBoard );
~BOARD_NETLIST_UPDATER();
BOARD_NETLIST_UPDATER( PCB_EDIT_FRAME *aFrame, BOARD *aBoard );
~BOARD_NETLIST_UPDATER();
/**
* Function UpdateNetlist()
*
* Updates the board's components according to the new netlist.
* See BOARD_NETLIST_UPDATER class description for the details of the process.
* @param aNetlist the new netlist
* @return true if process was completed successfully
*/
bool UpdateNetlist( NETLIST& aNetlist );
/**
* Function UpdateNetlist()
*
* Updates the board's components according to the new netlist.
* See BOARD_NETLIST_UPDATER class description for the details of the process.
* @param aNetlist the new netlist
* @return true if process was completed successfully
*/
bool UpdateNetlist( NETLIST& aNetlist );
// @todo: implement and move NETLIST::ReadPcbNetlist here
bool UpdateNetlist( const wxString& aNetlistFileName, const wxString& aCmpFileName );
// @todo: implement and move NETLIST::ReadPcbNetlist here
bool UpdateNetlist( const wxString& aNetlistFileName,
const wxString& aCmpFileName );
///> Sets the reporter object
void SetReporter( REPORTER* aReporter )
{
m_reporter = aReporter;
}
///> Enables "delete single pad nets" option
void SetDeleteSinglePadNets( bool aEnabled )
{
m_deleteSinglePadNets = aEnabled;
}
///> Sets the reporter object
void SetReporter ( REPORTER *aReporter )
{
m_reporter = aReporter;
}
///> Enables dry run mode (just report, no changes to PCB)
void SetIsDryRun( bool aEnabled )
{
m_isDryRun = aEnabled;
}
///> Enables "delete single pad nets" option
void SetDeleteSinglePadNets( bool aEnabled )
{
m_deleteSinglePadNets = aEnabled;
}
///> Enables replacing footprints with new ones
void SetReplaceFootprints( bool aEnabled )
{
m_replaceFootprints = aEnabled;
}
///> Enables dry run mode (just report, no changes to PCB)
void SetIsDryRun ( bool aEnabled )
{
m_isDryRun = aEnabled;
}
///> Enables removing unused components
void SetDeleteUnusedComponents( bool aEnabled )
{
m_deleteUnusedComponents = aEnabled;
}
///> Enables replacing footprints with new ones
void SetReplaceFootprints ( bool aEnabled )
{
m_replaceFootprints = aEnabled;
}
///> Enables component lookup by timestamp instead of reference
void SetLookupByTimestamp( bool aEnabled )
{
m_lookupByTimestamp = aEnabled;
}
///> Enables removing unused components
void SetDeleteUnusedComponents ( bool aEnabled )
{
m_deleteUnusedComponents = aEnabled;
}
///> Enables component lookup by timestamp instead of reference
void SetLookupByTimestamp ( bool aEnabled )
{
m_lookupByTimestamp = aEnabled;
}
std::vector<MODULE*> GetAddedComponents() const
{
return m_addedComponents;
}
std::vector<MODULE*> GetAddedComponents() const
{
return m_addedComponents;
}
private:
wxPoint estimateComponentInsertionPosition();
MODULE* addNewComponent( COMPONENT* aComponent );
MODULE* replaceComponent( NETLIST& aNetlist, MODULE* aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentParameters( MODULE* aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentPadConnections( MODULE* aPcbComponent, COMPONENT* aNewComponent );
bool deleteUnusedComponents( NETLIST& aNetlist );
bool deleteSinglePadNets();
bool testConnectivity( NETLIST& aNetlist );
void pushUndo( BOARD_ITEM* aItem, UNDO_REDO_T aCommandType, BOARD_ITEM* aCopy = NULL );
BOARD_COMMIT m_commit;
PCB_EDIT_FRAME* m_frame;
BOARD* m_board;
REPORTER* m_reporter;
wxPoint estimateComponentInsertionPosition();
MODULE* addNewComponent( COMPONENT* aComponent );
MODULE* replaceComponent( NETLIST& aNetlist, MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentParameters( MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool updateComponentPadConnections( MODULE *aPcbComponent, COMPONENT* aNewComponent );
bool deleteUnusedComponents( NETLIST& aNetlist );
bool deleteSinglePadNets();
bool testConnectivity( NETLIST& aNetlist );
std::vector<MODULE*> m_addedComponents;
std::map<wxString, NETINFO_ITEM*> m_addedNets;
PICKED_ITEMS_LIST *m_undoList;
PCB_EDIT_FRAME *m_frame;
BOARD *m_board;
REPORTER *m_reporter;
bool m_deleteSinglePadNets;
bool m_deleteUnusedComponents;
bool m_isDryRun;
bool m_replaceFootprints;
bool m_lookupByTimestamp;
std::vector<MODULE*> m_addedComponents;
bool m_deleteSinglePadNets;
bool m_deleteUnusedComponents;
bool m_isDryRun;
bool m_replaceFootprints;
bool m_lookupByTimestamp;
int m_warningCount;
int m_errorCount;
int m_warningCount;
int m_errorCount;
};
#endif

View File

@ -67,7 +67,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
BOARD::BOARD() :
BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ),
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) NULL, PCB_T ),
m_NetInfo( this ),
m_paper( PAGE_INFO::A4 )
{
@ -858,7 +858,7 @@ bool BOARD::IsModuleLayerVisible( LAYER_ID layer )
}
void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
void BOARD::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
{
if( aBoardItem == NULL )
{
@ -869,24 +869,22 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
switch( aBoardItem->Type() )
{
case PCB_NETINFO_T:
aBoardItem->SetParent( this );
m_NetInfo.AppendNet( (NETINFO_ITEM*) aBoardItem );
break;
// this one uses a vector
case PCB_MARKER_T:
aBoardItem->SetParent( this );
m_markers.push_back( (MARKER_PCB*) aBoardItem );
break;
// this one uses a vector
case PCB_ZONE_AREA_T:
aBoardItem->SetParent( this );
m_ZoneDescriptorList.push_back( (ZONE_CONTAINER*) aBoardItem );
break;
case PCB_TRACE_T:
case PCB_VIA_T:
if( aControl & ADD_APPEND )
if( aMode == ADD_APPEND )
{
m_Track.PushBack( (TRACK*) aBoardItem );
}
@ -897,44 +895,36 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
m_Track.Insert( (TRACK*) aBoardItem, insertAid );
}
aBoardItem->SetParent( this );
break;
case PCB_ZONE_T:
if( aControl & ADD_APPEND )
if( aMode == ADD_APPEND )
m_Zone.PushBack( (SEGZONE*) aBoardItem );
else
m_Zone.PushFront( (SEGZONE*) aBoardItem );
aBoardItem->SetParent( this );
break;
case PCB_MODULE_T:
if( aControl & ADD_APPEND )
if( aMode == ADD_APPEND )
m_Modules.PushBack( (MODULE*) aBoardItem );
else
m_Modules.PushFront( (MODULE*) aBoardItem );
aBoardItem->SetParent( this );
// Because the list of pads has changed, reset the status
// This indicate the list of pad and nets must be recalculated before use
m_Status_Pcb = 0;
break;
case PCB_MODULE_EDGE_T:
assert( false ); // TODO Orson: I am just checking if it is supposed to be here
case PCB_DIMENSION_T:
case PCB_LINE_T:
case PCB_TEXT_T:
case PCB_TARGET_T:
if( aControl & ADD_APPEND )
if( aMode == ADD_APPEND )
m_Drawings.PushBack( aBoardItem );
else
m_Drawings.PushFront( aBoardItem );
aBoardItem->SetParent( this );
break;
// other types may use linked list
@ -944,15 +934,17 @@ void BOARD::Add( BOARD_ITEM* aBoardItem, int aControl )
msg.Printf( wxT( "BOARD::Add() needs work: BOARD_ITEM type (%d) not handled" ),
aBoardItem->Type() );
wxFAIL_MSG( msg );
return;
}
break;
}
aBoardItem->SetParent( this );
m_ratsnest->Add( aBoardItem );
}
BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
void BOARD::Remove( BOARD_ITEM* aBoardItem )
{
// find these calls and fix them! Don't send me no stinking' NULL.
wxASSERT( aBoardItem );
@ -965,6 +957,7 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
m_NetInfo.RemoveNet( item );
break;
}
case PCB_MARKER_T:
// find the item in the vector, then remove it
@ -1007,7 +1000,6 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
case PCB_DIMENSION_T:
case PCB_LINE_T:
case PCB_TEXT_T:
case PCB_MODULE_EDGE_T:
case PCB_TARGET_T:
m_Drawings.Remove( aBoardItem );
break;
@ -1018,8 +1010,6 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem )
}
m_ratsnest->Remove( aBoardItem );
return aBoardItem;
}
@ -2605,7 +2595,7 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
{
// It is a new net, we have to add it
netinfo = new NETINFO_ITEM( this, net.GetNetName() );
m_NetInfo.AppendNet( netinfo );
Add( netinfo );
}
pad->SetNetCode( netinfo->GetNet() );
@ -2781,18 +2771,14 @@ void BOARD::ReplaceNetlist( NETLIST& aNetlist, bool aDeleteSinglePadNets,
}
BOARD_ITEM* BOARD::DuplicateAndAddItem( const BOARD_ITEM* aItem )
BOARD_ITEM* BOARD::Duplicate( const BOARD_ITEM* aItem,
bool aAddToBoard )
{
BOARD_ITEM* new_item = NULL;
switch( aItem->Type() )
{
case PCB_MODULE_T:
{
MODULE* new_module = new MODULE( *static_cast<const MODULE*>( aItem ) );
new_item = new_module;
break;
}
case PCB_TEXT_T:
case PCB_LINE_T:
case PCB_TRACE_T:
@ -2809,7 +2795,7 @@ BOARD_ITEM* BOARD::DuplicateAndAddItem( const BOARD_ITEM* aItem )
break;
}
if( new_item )
if( new_item && aAddToBoard )
Add( new_item );
return new_item;

View File

@ -42,6 +42,7 @@
#include <class_title_block.h>
#include <class_zone_settings.h>
#include <pcb_plot_params.h>
#include <board_item_container.h>
class PCB_BASE_FRAME;
@ -162,7 +163,7 @@ DECL_VEC_FOR_SWIG(TRACKS, TRACK*)
* Class BOARD
* holds information pertinent to a Pcbnew printed circuit board.
*/
class BOARD : public BOARD_ITEM
class BOARD : public BOARD_ITEM_CONTAINER
{
friend class PCB_EDIT_FRAME;
@ -212,6 +213,20 @@ private:
*/
void chainMarkedSegments( wxPoint aPosition, const LSET& aLayerSet, TRACKS* aList );
// The default copy constructor & operator= are inadequate,
// either write one or do not use it at all
BOARD( const BOARD& aOther ) :
BOARD_ITEM_CONTAINER( aOther ), m_NetInfo( this )
{
assert( false );
}
BOARD& operator=( const BOARD& aOther )
{
assert( false );
return *this; // just to mute warning
}
public:
static inline bool ClassOf( const EDA_ITEM* aItem )
{
@ -257,46 +272,13 @@ public:
void SetFileFormatVersionAtLoad( int aVersion ) { m_fileFormatVersionAtLoad = aVersion; }
int GetFileFormatVersionAtLoad() const { return m_fileFormatVersionAtLoad; }
/**
* Function Add
* adds the given item to this BOARD and takes ownership of its memory.
* @param aBoardItem The item to add to this board.
* @param aControl An int which can vary how the item is added.
*/
void Add( BOARD_ITEM* aBoardItem, int aControl = 0 );
///> @copydoc BOARD_ITEM_CONTAINER::Add()
void Add( BOARD_ITEM* aItem, ADD_MODE aMode = ADD_INSERT ) override;
#define ADD_APPEND 1 ///< aControl flag for Add( aControl ), appends not inserts
///> @copydoc BOARD_ITEM_CONTAINER::Remove()
void Remove( BOARD_ITEM* aBoardItem ) override;
/**
* Function Delete
* removes the given single item from this BOARD and deletes its memory.
* @param aBoardItem The item to remove from this board and delete
*/
void Delete( BOARD_ITEM* aBoardItem )
{
// developers should run DEBUG versions and fix such calls with NULL
wxASSERT( aBoardItem );
if( aBoardItem )
delete Remove( aBoardItem );
}
/**
* Function Remove
* removes \a aBoardItem from this BOARD and returns it to caller without deleting it.
* @param aBoardItem The item to remove from this board.
* @return BOARD_ITEM* \a aBoardItem which was passed in.
*/
BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem );
/**
* Function DuplicateAndAddItem
* duplicates an item, and add it to the board list.
* @param aItem The item to duplicate.
* @return BOARD_ITEM* \a the new item which was added.
*/
BOARD_ITEM* DuplicateAndAddItem( const BOARD_ITEM* aItem );
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem, bool aAddToBoard = false );
/**
* Function GetRatsnest()
@ -802,16 +784,6 @@ public:
*/
NETINFO_ITEM* FindNet( const wxString& aNetname ) const;
/**
* Function AppendNet
* adds a new net description item to the current board.
* @param aNewNet is the new description item.
*/
void AppendNet( NETINFO_ITEM* aNewNet )
{
m_NetInfo.AppendNet( aNewNet );
}
NETINFO_LIST& GetNetInfo()
{
return m_NetInfo;

View File

@ -34,6 +34,8 @@
#include <class_board.h>
#include <class_board_item.h>
#include <ratsnest_data.cpp>
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_ITEM( aParent, idtype ), m_netinfo( &NETINFO_LIST::ORPHANED_ITEM ),
m_Subnet( 0 ), m_ZoneSubnet( 0 )
@ -41,13 +43,6 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype
}
BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem ) :
BOARD_ITEM( aItem ), m_netinfo( aItem.m_netinfo ), m_Subnet( aItem.m_Subnet ),
m_ZoneSubnet( aItem.m_ZoneSubnet )
{
}
bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
{
// if aNetCode < 0 ( typically NETINFO_LIST::FORCE_ORPHANED )
@ -55,6 +50,11 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
// set the m_netinfo to the dummy NETINFO_LIST::ORPHANED
BOARD* board = GetBoard();
RN_DATA* ratsnest = board ? board->GetRatsnest() : NULL;
bool addRatsnest = false;
if( ratsnest )
addRatsnest = ratsnest->Remove( this );
if( ( aNetCode >= 0 ) && board )
m_netinfo = board->FindNet( aNetCode );
@ -64,6 +64,10 @@ bool BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode, bool aNoAssert )
if( !aNoAssert )
assert( m_netinfo );
// Add only if it was previously added to the ratsnest
if( addRatsnest )
ratsnest->Add( this );
return ( m_netinfo != NULL );
}

View File

@ -56,7 +56,8 @@ public:
BOARD_CONNECTED_ITEM( BOARD_ITEM* aParent, KICAD_T idtype );
BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
static inline bool ClassOf( const EDA_ITEM* aItem )
{
@ -91,6 +92,16 @@ public:
return m_netinfo;
}
/**
* Function SetNet
* Sets a NET_INFO object for the item.
*/
void SetNet( NETINFO_ITEM* aNetInfo )
{
assert( aNetInfo->GetBoard() == GetBoard() );
m_netinfo = aNetInfo;
}
/**
* Function GetNetCode
* @return int - the net code.

View File

@ -219,8 +219,12 @@ int BOARD_ITEM::getTrailingInt( wxString aStr )
return number;
}
int BOARD_ITEM::getNextNumberInSequence( std::set<int> aSeq, bool aFillSequenceGaps)
int BOARD_ITEM::getNextNumberInSequence( const std::set<int>& aSeq, bool aFillSequenceGaps)
{
if( aSeq.empty() )
return 1;
// By default go to the end of the sequence
int candidate = *aSeq.rbegin();
@ -230,16 +234,16 @@ int BOARD_ITEM::getNextNumberInSequence( std::set<int> aSeq, bool aFillSequenceG
// start at the beginning
candidate = *aSeq.begin();
for( std::set<int>::iterator it = aSeq.begin(),
itEnd = aSeq.end(); it != itEnd; ++it )
for( auto it : aSeq )
{
if( *it - candidate > 1 )
if( it - candidate > 1 )
break;
candidate = *it;
candidate = it;
}
}
candidate++;
++candidate;
return candidate;
}

View File

@ -89,30 +89,6 @@ void DIMENSION::SetLayer( LAYER_ID aLayer )
}
void DIMENSION::Copy( DIMENSION* source )
{
m_Value = source->m_Value;
SetLayer( source->GetLayer() );
m_Width = source->m_Width;
m_Shape = source->m_Shape;
m_Height = source->m_Height;
m_Unit = source->m_Unit;
SetTimeStamp( GetNewTimeStamp() );
m_Text.Copy( &source->m_Text );
m_crossBarO = source->m_crossBarO;
m_crossBarF = source->m_crossBarF;
m_featureLineGO = source->m_featureLineGO;
m_featureLineGF = source->m_featureLineGF;
m_featureLineDO = source->m_featureLineDO;
m_featureLineDF = source->m_featureLineDF;
m_arrowD1F = source->m_arrowD1F;
m_arrowD2F = source->m_arrowD2F;
m_arrowG1F = source->m_arrowG1F;
m_arrowG2F = source->m_arrowG2F;
}
void DIMENSION::Move( const wxPoint& offset )
{
m_Text.SetTextPosition( m_Text.GetTextPosition() + offset );

View File

@ -78,7 +78,8 @@ public:
DIMENSION( BOARD_ITEM* aParent );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~DIMENSION();
@ -182,8 +183,6 @@ public:
TEXTE_PCB& Text() { return m_Text; }
TEXTE_PCB& Text() const { return *(const_cast<TEXTE_PCB*> (&m_Text)); }
void Copy( DIMENSION* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aColorMode, const wxPoint& offset = ZeroOffset );

View File

@ -64,34 +64,6 @@ DRAWSEGMENT::~DRAWSEGMENT()
}
const DRAWSEGMENT& DRAWSEGMENT::operator = ( const DRAWSEGMENT& rhs )
{
// skip the linked list stuff, and parent
m_Type = rhs.m_Type;
m_Layer = rhs.m_Layer;
m_Width = rhs.m_Width;
m_Start = rhs.m_Start;
m_End = rhs.m_End;
m_Shape = rhs.m_Shape;
m_Angle = rhs.m_Angle;
m_TimeStamp = rhs.m_TimeStamp;
m_BezierC1 = rhs.m_BezierC1;
m_BezierC2 = rhs.m_BezierC1;
m_BezierPoints = rhs.m_BezierPoints;
return *this;
}
void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
{
if( source == NULL ) // who would do this?
return;
*this = *source; // operator = ()
}
void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, double aAngle )
{
switch( m_Shape )

View File

@ -65,13 +65,11 @@ protected:
public:
DRAWSEGMENT( BOARD_ITEM* aParent = NULL, KICAD_T idtype = PCB_LINE_T );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~DRAWSEGMENT();
/// skip the linked list stuff, and parent
const DRAWSEGMENT& operator = ( const DRAWSEGMENT& rhs );
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && PCB_LINE_T == aItem->Type();
@ -181,8 +179,6 @@ public:
m_PolyPoints = aPoints;
}
void Copy( DRAWSEGMENT* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& aOffset = ZeroOffset );

View File

@ -65,30 +65,6 @@ EDGE_MODULE::~EDGE_MODULE()
}
const EDGE_MODULE& EDGE_MODULE::operator = ( const EDGE_MODULE& rhs )
{
if( &rhs == this )
return *this;
DRAWSEGMENT::operator=( rhs );
m_Start0 = rhs.m_Start0;
m_End0 = rhs.m_End0;
m_PolyPoints = rhs.m_PolyPoints; // std::vector copy
return *this;
}
void EDGE_MODULE::Copy( EDGE_MODULE* source )
{
if( source == NULL )
return;
*this = *source;
}
void EDGE_MODULE::SetLocalCoord()
{
MODULE* module = (MODULE*) m_Parent;

View File

@ -46,21 +46,16 @@ class EDGE_MODULE : public DRAWSEGMENT
public:
EDGE_MODULE( MODULE* parent, STROKE_T aShape = S_SEGMENT );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// EDGE_MODULE( const EDGE_MODULE& );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~EDGE_MODULE();
/// skip the linked list stuff, and parent
const EDGE_MODULE& operator = ( const EDGE_MODULE& rhs );
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return aItem && PCB_MODULE_EDGE_T == aItem->Type();
}
void Copy( EDGE_MODULE* source ); // copy structure
/**
* Move an edge of the footprint.
* This is a footprint shape modification.

View File

@ -69,16 +69,6 @@ PCB_TARGET::~PCB_TARGET()
{
}
void PCB_TARGET::Copy( PCB_TARGET* source )
{
m_Layer = source->m_Layer;
m_Width = source->m_Width;
m_Pos = source->m_Pos;
m_Shape = source->m_Shape;
m_Size = source->m_Size;
SetTimeStamp( GetNewTimeStamp() );
}
/* Draw PCB_TARGET object: 2 segments + 1 circle
* The circle radius is half the radius of the target

View File

@ -54,6 +54,9 @@ public:
PCB_TARGET( BOARD_ITEM* aParent, int aShape, LAYER_ID aLayer,
const wxPoint& aPos, int aSize, int aWidth );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~PCB_TARGET();
void SetPosition( const wxPoint& aPos ) { m_Pos = aPos; } // override
@ -77,8 +80,6 @@ public:
void Flip( const wxPoint& aCentre );
void Copy( PCB_TARGET* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );

View File

@ -50,7 +50,7 @@
MODULE::MODULE( BOARD* parent ) :
BOARD_ITEM( (BOARD_ITEM*) parent, PCB_MODULE_T ),
BOARD_ITEM_CONTAINER( (BOARD_ITEM*) parent, PCB_MODULE_T ),
m_initial_comments( 0 )
{
m_Attributs = MOD_DEFAULT;
@ -79,11 +79,10 @@ MODULE::MODULE( BOARD* parent ) :
MODULE::MODULE( const MODULE& aModule ) :
BOARD_ITEM( aModule )
BOARD_ITEM_CONTAINER( aModule )
{
m_Pos = aModule.m_Pos;
m_fpid = aModule.m_fpid;
m_Layer = aModule.m_Layer;
m_Attributs = aModule.m_Attributs;
m_ModuleStatus = aModule.m_ModuleStatus;
m_Orient = aModule.m_Orient;
@ -105,35 +104,27 @@ MODULE::MODULE( const MODULE& aModule ) :
// Copy reference and value.
m_Reference = new TEXTE_MODULE( *aModule.m_Reference );
m_Reference->SetParent( this );
m_Value = new TEXTE_MODULE( *aModule.m_Value );
m_Value->SetParent( this );
// Copy auxiliary data: Pads
for( D_PAD* pad = aModule.m_Pads; pad; pad = pad->Next() )
{
D_PAD* newpad = new D_PAD( *pad );
assert( newpad->GetNet() == pad->GetNet() );
newpad->SetParent( this );
m_Pads.PushBack( newpad );
Add( new D_PAD( *pad ) );
}
// Copy auxiliary data: Drawings
for( BOARD_ITEM* item = aModule.m_Drawings; item; item = item->Next() )
{
BOARD_ITEM* newItem;
switch( item->Type() )
{
case PCB_MODULE_TEXT_T:
case PCB_MODULE_EDGE_T:
newItem = static_cast<BOARD_ITEM*>( item->Clone() );
newItem->SetParent( this );
m_Drawings.PushBack( newItem );
Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
break;
default:
wxLogMessage( wxT( "MODULE::Copy() Internal Err: unknown type" ) );
wxLogMessage( wxT( "Class MODULE copy constructor internal error: unknown type" ) );
break;
}
}
@ -161,13 +152,76 @@ MODULE::~MODULE()
delete m_initial_comments;
}
/**
* Function ClearAllNets
* Clear (i.e. force the ORPHANED dummy net info) the net info which
* depends on a given board for all pads of the footprint.
* This is needed when a footprint is copied between the fp editor and
* the board editor for instance, because net info become fully broken
*/
MODULE& MODULE::operator=( const MODULE& aOther )
{
BOARD_ITEM::operator=( aOther );
m_Pos = aOther.m_Pos;
m_fpid = aOther.m_fpid;
m_Attributs = aOther.m_Attributs;
m_ModuleStatus = aOther.m_ModuleStatus;
m_Orient = aOther.m_Orient;
m_BoundaryBox = aOther.m_BoundaryBox;
m_CntRot90 = aOther.m_CntRot90;
m_CntRot180 = aOther.m_CntRot180;
m_LastEditTime = aOther.m_LastEditTime;
m_Link = aOther.m_Link;
m_Path = aOther.m_Path; //is this correct behavior?
m_LocalClearance = aOther.m_LocalClearance;
m_LocalSolderMaskMargin = aOther.m_LocalSolderMaskMargin;
m_LocalSolderPasteMargin = aOther.m_LocalSolderPasteMargin;
m_LocalSolderPasteMarginRatio = aOther.m_LocalSolderPasteMarginRatio;
m_ZoneConnection = aOther.m_ZoneConnection;
m_ThermalWidth = aOther.m_ThermalWidth;
m_ThermalGap = aOther.m_ThermalGap;
// Copy reference and value
*m_Reference = *aOther.m_Reference;
m_Reference->SetParent( this );
*m_Value = *aOther.m_Value;
m_Value->SetParent( this );
// Copy auxiliary data: Pads
m_Pads.DeleteAll();
for( D_PAD* pad = aOther.m_Pads; pad; pad = pad->Next() )
{
Add( new D_PAD( *pad ) );
}
// Copy auxiliary data: Drawings
m_Drawings.DeleteAll();
for( BOARD_ITEM* item = aOther.m_Drawings; item; item = item->Next() )
{
switch( item->Type() )
{
case PCB_MODULE_TEXT_T:
case PCB_MODULE_EDGE_T:
Add( static_cast<BOARD_ITEM*>( item->Clone() ) );
break;
default:
wxLogMessage( wxT( "MODULE::operator=() internal error: unknown type" ) );
break;
}
}
// Copy auxiliary data: 3D_Drawings info
m_3D_Drawings.clear();
m_3D_Drawings = aOther.m_3D_Drawings;
m_Doc = aOther.m_Doc;
m_KeyWord = aOther.m_KeyWord;
// Ensure auxiliary data is up to date
CalculateBoundingBox();
return *this;
}
void MODULE::ClearAllNets()
{
// Force the ORPHANED dummy net info for all pads.
@ -177,10 +231,6 @@ void MODULE::ClearAllNets()
}
/* Draw the anchor cross (vertical)
* Must be done after the pads, because drawing the hole will erase overwrite
* every thing already drawn.
*/
void MODULE::DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
int dim_ancre, GR_DRAWMODE draw_mode )
{
@ -195,86 +245,7 @@ void MODULE::DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
}
void MODULE::Copy( MODULE* aModule )
{
m_Pos = aModule->m_Pos;
m_Layer = aModule->m_Layer;
m_fpid = aModule->m_fpid;
m_Attributs = aModule->m_Attributs;
m_ModuleStatus = aModule->m_ModuleStatus;
m_Orient = aModule->m_Orient;
m_BoundaryBox = aModule->m_BoundaryBox;
m_CntRot90 = aModule->m_CntRot90;
m_CntRot180 = aModule->m_CntRot180;
m_LastEditTime = aModule->m_LastEditTime;
m_Link = aModule->m_Link;
m_Path = aModule->m_Path; //is this correct behavior?
SetTimeStamp( GetNewTimeStamp() );
m_LocalClearance = aModule->m_LocalClearance;
m_LocalSolderMaskMargin = aModule->m_LocalSolderMaskMargin;
m_LocalSolderPasteMargin = aModule->m_LocalSolderPasteMargin;
m_LocalSolderPasteMarginRatio = aModule->m_LocalSolderPasteMarginRatio;
m_ZoneConnection = aModule->m_ZoneConnection;
m_ThermalWidth = aModule->m_ThermalWidth;
m_ThermalGap = aModule->m_ThermalGap;
// Copy reference and value.
m_Reference->Copy( aModule->m_Reference );
m_Value->Copy( aModule->m_Value );
// Copy auxiliary data: Pads
m_Pads.DeleteAll();
for( D_PAD* pad = aModule->m_Pads; pad; pad = pad->Next() )
{
D_PAD* newpad = new D_PAD( this );
newpad->Copy( pad );
m_Pads.PushBack( newpad );
}
// Copy auxiliary data: Drawings
m_Drawings.DeleteAll();
for( BOARD_ITEM* item = aModule->m_Drawings; item; item = item->Next() )
{
switch( item->Type() )
{
case PCB_MODULE_TEXT_T:
{
TEXTE_MODULE* textm = new TEXTE_MODULE( this );
textm->Copy( static_cast<TEXTE_MODULE*>( item ) );
m_Drawings.PushBack( textm );
break;
}
case PCB_MODULE_EDGE_T:
{
EDGE_MODULE * edge;
edge = new EDGE_MODULE( this );
edge->Copy( (EDGE_MODULE*) item );
m_Drawings.PushBack( edge );
break;
}
default:
wxLogMessage( wxT( "MODULE::Copy() Internal Err: unknown type" ) );
break;
}
}
// Copy auxiliary data: 3D_Drawings info
m_3D_Drawings.clear();
m_3D_Drawings = aModule->m_3D_Drawings;
m_Doc = aModule->m_Doc;
m_KeyWord = aModule->m_KeyWord;
// Ensure auxiliary data is up to date
CalculateBoundingBox();
}
void MODULE::Add( BOARD_ITEM* aBoardItem, bool doAppend )
void MODULE::Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode )
{
switch( aBoardItem->Type() )
{
@ -285,14 +256,14 @@ void MODULE::Add( BOARD_ITEM* aBoardItem, bool doAppend )
// no break
case PCB_MODULE_EDGE_T:
if( doAppend )
if( aMode == ADD_APPEND )
m_Drawings.PushBack( aBoardItem );
else
m_Drawings.PushFront( aBoardItem );
break;
case PCB_PAD_T:
if( doAppend )
if( aMode == ADD_APPEND )
m_Pads.PushBack( static_cast<D_PAD*>( aBoardItem ) );
else
m_Pads.PushFront( static_cast<D_PAD*>( aBoardItem ) );
@ -310,10 +281,32 @@ void MODULE::Add( BOARD_ITEM* aBoardItem, bool doAppend )
}
aBoardItem->SetParent( this );
SetLastEditTime();
// Update relative coordinates, it can be done only after there is a parent object assigned
switch( aBoardItem->Type() )
{
case PCB_MODULE_TEXT_T:
static_cast<TEXTE_MODULE*>( aBoardItem )->SetLocalCoord();
break;
case PCB_MODULE_EDGE_T:
static_cast<EDGE_MODULE*>( aBoardItem )->SetLocalCoord();
break;
case PCB_PAD_T:
static_cast<D_PAD*>( aBoardItem )->SetLocalCoord();
break;
default:
// Huh? It should have been filtered out by the previous switch
assert(false);
break;
}
}
BOARD_ITEM* MODULE::Remove( BOARD_ITEM* aBoardItem )
void MODULE::Remove( BOARD_ITEM* aBoardItem )
{
switch( aBoardItem->Type() )
{
@ -324,10 +317,12 @@ BOARD_ITEM* MODULE::Remove( BOARD_ITEM* aBoardItem )
// no break
case PCB_MODULE_EDGE_T:
return m_Drawings.Remove( aBoardItem );
m_Drawings.Remove( aBoardItem );
break;
case PCB_PAD_T:
return m_Pads.Remove( static_cast<D_PAD*>( aBoardItem ) );
m_Pads.Remove( static_cast<D_PAD*>( aBoardItem ) );
break;
default:
{
@ -337,8 +332,6 @@ BOARD_ITEM* MODULE::Remove( BOARD_ITEM* aBoardItem )
wxFAIL_MSG( msg );
}
}
return NULL;
}
@ -516,9 +509,6 @@ const EDA_RECT MODULE::GetBoundingBox() const
}
/* Virtual function, from EDA_ITEM.
* display module info on MsgPanel
*/
void MODULE::GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList )
{
int nbpad;
@ -902,11 +892,6 @@ const BOX2I MODULE::ViewBBox() const
}
/* Test for validity of the name in a library of the footprint
* ( no spaces, dir separators ... )
* return true if the given name is valid
* static function
*/
bool MODULE::IsLibNameValid( const wxString & aName )
{
const wxChar * invalids = StringLibNameInvalidChars( false );
@ -918,13 +903,6 @@ bool MODULE::IsLibNameValid( const wxString & aName )
}
/* Test for validity of the name of a footprint to be used in a footprint library
* ( no spaces, dir separators ... )
* param bool aUserReadable = false to get the list of invalid chars
* true to get a readable form (i.e ' ' = 'space' '\t'= 'tab')
* return a constant string giving the list of invalid chars in lib name
* static function
*/
const wxChar* MODULE::StringLibNameInvalidChars( bool aUserReadable )
{
static const wxChar invalidChars[] = wxT("%$\t \"\\/");
@ -1132,8 +1110,9 @@ void MODULE::SetOrientation( double newangle )
CalculateBoundingBox();
}
BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem,
bool aIncrementPadNumbers )
BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem,
bool aIncrementPadNumbers,
bool aAddToModule )
{
BOARD_ITEM* new_item = NULL;
D_PAD* new_pad = NULL;
@ -1144,7 +1123,9 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem,
{
new_pad = new D_PAD( *static_cast<const D_PAD*>( aItem ) );
Pads().PushBack( new_pad );
if( aAddToModule )
Pads().PushBack( new_pad );
new_item = new_pad;
break;
}
@ -1159,7 +1140,9 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem,
{
TEXTE_MODULE* new_text = new TEXTE_MODULE( *old_text );
GraphicalItems().PushBack( new_text );
if( aAddToModule )
GraphicalItems().PushBack( new_text );
new_item = new_text;
}
break;
@ -1170,7 +1153,9 @@ BOARD_ITEM* MODULE::DuplicateAndAddItem( const BOARD_ITEM* aItem,
EDGE_MODULE* new_edge = new EDGE_MODULE(
*static_cast<const EDGE_MODULE*>(aItem) );
GraphicalItems().PushBack( new_edge );
if( aAddToModule )
GraphicalItems().PushBack( new_edge );
new_item = new_edge;
break;
}

View File

@ -36,6 +36,7 @@
#include <dlist.h>
#include <layers_id_colors_and_visibility.h> // ALL_LAYERS definition.
#include <class_board_item.h>
#include <board_item_container.h>
#include <fpid.h>
#include <class_text_mod.h>
@ -75,7 +76,7 @@ enum MODULE_ATTR_T
};
class MODULE : public BOARD_ITEM
class MODULE : public BOARD_ITEM_CONTAINER
{
public:
MODULE( BOARD* parent );
@ -84,6 +85,8 @@ public:
~MODULE();
MODULE& operator=( const MODULE& aOther );
static inline bool ClassOf( const EDA_ITEM* aItem )
{
return PCB_MODULE_T == aItem->Type();
@ -92,37 +95,11 @@ public:
MODULE* Next() const { return static_cast<MODULE*>( Pnext ); }
MODULE* Back() const { return static_cast<MODULE*>( Pback ); }
void Copy( MODULE* Module ); // Copy structure
///> @copydoc BOARD_ITEM_CONTAINER::Add()
void Add( BOARD_ITEM* aBoardItem, ADD_MODE aMode = ADD_INSERT ) override;
/**
* Function Add
* adds the given item to this MODULE and takes ownership of its memory.
* @param aBoardItem The item to add to this board.
* @param doAppend If true, then append, else insert.
*/
void Add( BOARD_ITEM* aBoardItem, bool doAppend = true );
/**
* Function Delete
* removes the given single item from this MODULE and deletes its memory.
* @param aBoardItem The item to remove from this module and delete
*/
void Delete( BOARD_ITEM* aBoardItem )
{
// developers should run DEBUG versions and fix such calls with NULL
wxASSERT( aBoardItem );
if( aBoardItem )
delete Remove( aBoardItem );
}
/**
* Function Remove
* removes \a aBoardItem from this MODULE and returns it to caller without deleting it.
* @param aBoardItem The item to remove from this module.
* @return BOARD_ITEM* \a aBoardItem which was passed in.
*/
BOARD_ITEM* Remove( BOARD_ITEM* aBoardItem );
///> @copydoc BOARD_ITEM_CONTAINER::Remove()
void Remove( BOARD_ITEM* aBoardItem ) override;
/**
* Function ClearAllNets
@ -404,9 +381,16 @@ public:
void DrawEdgesOnly( EDA_DRAW_PANEL* panel, wxDC* DC, const wxPoint& offset,
GR_DRAWMODE draw_mode );
/**
* Function DrawAncre
* Draw the anchor cross (vertical)
* Must be done after the pads, because drawing the hole will erase overwrite
* every thing already drawn.
*/
void DrawAncre( EDA_DRAW_PANEL* panel, wxDC* DC,
const wxPoint& offset, int dim_ancre, GR_DRAWMODE draw_mode );
///> @copydoc EDA_ITEM::GetMsgPanelInfo
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
bool HitTest( const wxPoint& aPosition ) const;
@ -536,12 +520,13 @@ public:
void SetPlacementCost90( int aCost ) { m_CntRot90 = aCost; }
/**
* Function DuplicateAndAddItem
* Duplicate a given item within the module
* Function Duplicate
* Duplicate a given item within the module, without adding to the board
* @return the new item, or NULL if the item could not be duplicated
*/
BOARD_ITEM* DuplicateAndAddItem( const BOARD_ITEM* item,
bool aIncrementPadNumbers );
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem,
bool aIncrementPadNumbers,
bool aAddToModule = false );
/**
* Function Add3DModel

View File

@ -423,41 +423,6 @@ bool D_PAD::IncrementPadName( bool aSkipUnconnectable, bool aFillSequenceGaps )
}
void D_PAD::Copy( D_PAD* source )
{
if( source == NULL )
return;
m_Pos = source->m_Pos;
m_layerMask = source->m_layerMask;
m_NumPadName = source->m_NumPadName;
m_netinfo = source->m_netinfo;
m_Drill = source->m_Drill;
m_drillShape = source->m_drillShape;
m_Offset = source->m_Offset;
m_Size = source->m_Size;
m_DeltaSize = source->m_DeltaSize;
m_Pos0 = source->m_Pos0;
m_boundingRadius = source->m_boundingRadius;
m_padShape = source->m_padShape;
m_Attribute = source->m_Attribute;
m_Orient = source->m_Orient;
m_LengthPadToDie = source->m_LengthPadToDie;
m_LocalClearance = source->m_LocalClearance;
m_LocalSolderMaskMargin = source->m_LocalSolderMaskMargin;
m_LocalSolderPasteMargin = source->m_LocalSolderPasteMargin;
m_LocalSolderPasteMarginRatio = source->m_LocalSolderPasteMarginRatio;
m_ZoneConnection = source->m_ZoneConnection;
m_ThermalWidth = source->m_ThermalWidth;
m_ThermalGap = source->m_ThermalGap;
m_padRoundRectRadiusScale = source->m_padRoundRectRadiusScale;
SetSubRatsnest( 0 );
SetSubNet( 0 );
}
void D_PAD::CopyNetlistSettings( D_PAD* aPad, bool aCopyLocalSettings )
{
// Don't do anything foolish like trying to copy to yourself.

View File

@ -82,8 +82,8 @@ public:
public:
D_PAD( MODULE* parent );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// D_PAD( const D_PAD& o );
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
/* Default layers used for pads, according to the pad type.
* this is default values only, they can be changed for a given pad
@ -99,8 +99,6 @@ public:
return aItem && PCB_PAD_T == aItem->Type();
}
void Copy( D_PAD* source );
D_PAD* Next() const { return static_cast<D_PAD*>( Pnext ); }
MODULE* GetParent() const { return (MODULE*) m_Parent; }

View File

@ -60,27 +60,6 @@ TEXTE_PCB:: ~TEXTE_PCB()
}
void TEXTE_PCB::Copy( TEXTE_PCB* source )
{
m_Parent = source->m_Parent;
Pback = Pnext = NULL;
m_Mirror = source->m_Mirror;
m_Size = source->m_Size;
m_Orient = source->m_Orient;
m_Pos = source->m_Pos;
m_Layer = source->m_Layer;
m_Thickness = source->m_Thickness;
m_Attributs = source->m_Attributs;
m_Italic = source->m_Italic;
m_Bold = source->m_Bold;
m_HJustify = source->m_HJustify;
m_VJustify = source->m_VJustify;
m_MultilineAllowed = source->m_MultilineAllowed;
m_Text = source->m_Text;
}
void TEXTE_PCB::Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE DrawMode, const wxPoint& offset )
{

View File

@ -45,7 +45,8 @@ class TEXTE_PCB : public BOARD_ITEM, public EDA_TEXT
public:
TEXTE_PCB( BOARD_ITEM* parent );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~TEXTE_PCB();
@ -73,9 +74,6 @@ public:
void Flip( const wxPoint& aCentre );
/* duplicate structure */
void Copy( TEXTE_PCB* source );
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC,
GR_DRAWMODE aDrawMode, const wxPoint& offset = ZeroOffset );

View File

@ -124,27 +124,6 @@ void TEXTE_MODULE::Move( const wxPoint& aMoveVector )
}
void TEXTE_MODULE::Copy( TEXTE_MODULE* source )
{
if( source == NULL )
return;
m_Pos = source->m_Pos;
SetLayer( source->GetLayer() );
m_Mirror = source->m_Mirror;
m_NoShow = source->m_NoShow;
m_Type = source->m_Type;
m_Orient = source->m_Orient;
m_Pos0 = source->m_Pos0;
m_Size = source->m_Size;
m_Thickness = source->m_Thickness;
m_Italic = source->m_Italic;
m_Bold = source->m_Bold;
m_Text = source->m_Text;
}
int TEXTE_MODULE::GetLength() const
{
return m_Text.Len();

View File

@ -64,7 +64,8 @@ public:
TEXTE_MODULE( MODULE* parent, TEXT_TYPE text_type = TEXT_is_DIVERS );
// Do not create a copy constructor. The one generated by the compiler is adequate.
// Do not create a copy constructor & operator=.
// The ones generated by the compiler are adequate.
~TEXTE_MODULE();
@ -112,8 +113,6 @@ public:
void SetPos0( const wxPoint& aPos ) { m_Pos0 = aPos; SetDrawCoord(); }
const wxPoint& GetPos0() const { return m_Pos0; }
void Copy( TEXTE_MODULE* source ); // copy structure
int GetLength() const; // text length
/**

View File

@ -105,6 +105,32 @@ ZONE_CONTAINER::ZONE_CONTAINER( const ZONE_CONTAINER& aZone ) :
}
ZONE_CONTAINER& ZONE_CONTAINER::operator=( const ZONE_CONTAINER& aOther )
{
BOARD_CONNECTED_ITEM::operator=( aOther );
m_Poly->RemoveAllContours();
m_Poly->Copy( aOther.m_Poly ); // copy outlines
m_CornerSelection = -1; // for corner moving, corner index to drag or -1 if no selection
m_ZoneClearance = aOther.m_ZoneClearance; // clearance value
m_ZoneMinThickness = aOther.m_ZoneMinThickness;
m_FillMode = aOther.m_FillMode; // filling mode (segments/polygons)
m_ArcToSegmentsCount = aOther.m_ArcToSegmentsCount;
m_PadConnection = aOther.m_PadConnection;
m_ThermalReliefGap = aOther.m_ThermalReliefGap;
m_ThermalReliefCopperBridge = aOther.m_ThermalReliefCopperBridge;
m_Poly->SetHatchStyle( aOther.m_Poly->GetHatchStyle() );
m_Poly->SetHatchPitch( aOther.m_Poly->GetHatchPitch() );
m_Poly->m_HatchLines = aOther.m_Poly->m_HatchLines; // copy vector <CSegment>
m_FilledPolysList.RemoveAllContours();
m_FilledPolysList.Append( aOther.m_FilledPolysList );
m_FillSegmList.clear();
m_FillSegmList = aOther.m_FillSegmList;
return *this;
}
ZONE_CONTAINER::~ZONE_CONTAINER()
{
delete m_Poly;
@ -751,33 +777,6 @@ void ZONE_CONTAINER::Mirror( const wxPoint& mirror_ref )
}
void ZONE_CONTAINER::Copy( ZONE_CONTAINER* src )
{
m_Parent = src->m_Parent;
m_Layer = src->m_Layer;
SetNetCode( src->GetNetCode() );
SetTimeStamp( src->m_TimeStamp );
m_Poly->RemoveAllContours();
m_Poly->Copy( src->m_Poly ); // copy outlines
m_CornerSelection = -1; // For corner moving, corner index to drag,
// or -1 if no selection
m_ZoneClearance = src->m_ZoneClearance; // clearance value
m_ZoneMinThickness = src->m_ZoneMinThickness;
m_FillMode = src->m_FillMode; // Filling mode (segments/polygons)
m_ArcToSegmentsCount = src->m_ArcToSegmentsCount;
m_PadConnection = src->m_PadConnection;
m_ThermalReliefGap = src->m_ThermalReliefGap;
m_ThermalReliefCopperBridge = src->m_ThermalReliefCopperBridge;
m_Poly->SetHatchStyle( src->m_Poly->GetHatchStyle() );
m_Poly->SetHatchPitch( src->m_Poly->GetHatchPitch() );
m_Poly->m_HatchLines = src->m_Poly->m_HatchLines; // Copy vector <CSegment>
m_FilledPolysList.RemoveAllContours();
m_FilledPolysList.Append( src->m_FilledPolysList );
m_FillSegmList.clear();
m_FillSegmList = src->m_FillSegmList;
}
ZoneConnection ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const
{
if( aPad == NULL || aPad->GetZoneConnection() == PAD_ZONE_CONN_INHERITED )

View File

@ -82,6 +82,7 @@ public:
ZONE_CONTAINER( BOARD* parent );
ZONE_CONTAINER( const ZONE_CONTAINER& aZone );
ZONE_CONTAINER& operator=( const ZONE_CONTAINER &aOther );
~ZONE_CONTAINER();
@ -104,13 +105,6 @@ public:
*/
unsigned GetPriority() const { return m_priority; }
/**
* Function copy
* copy useful data from the source.
* flags and linked list pointers are NOT copied
*/
void Copy( ZONE_CONTAINER* src );
void GetMsgPanelInfo( std::vector< MSG_PANEL_ITEM >& aList );
/**

View File

@ -942,6 +942,10 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
}
}
/// @todo LEGACY tracks might have changed their nets, so we need to refresh labels in GAL
for( TRACK* track = m_Pcb->m_Track; track; track = track->Next() )
track->ViewUpdate();
// Sort the track list by net codes:
RebuildTrackChain( m_Pcb );
}

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Mar 9 2016)
// C++ code generated with wxFormBuilder (version Jun 21 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -290,19 +290,19 @@ DIALOG_CREATE_ARRAY_BASE::DIALOG_CREATE_ARRAY_BASE( wxWindow* parent, wxWindowID
// Connect Events
this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CREATE_ARRAY_BASE::OnClose ) );
m_entryNx->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNy->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDx->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDy->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetX->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetY->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryStagger->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNx->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNy->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDx->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDy->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryStagger->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_rbGridStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_radioBoxGridNumberingScheme->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreX->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreY->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircCount->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_rbCircStartNumberingOpt->Connect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_stdButtonsOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );
}
@ -311,19 +311,19 @@ DIALOG_CREATE_ARRAY_BASE::~DIALOG_CREATE_ARRAY_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DIALOG_CREATE_ARRAY_BASE::OnClose ) );
m_entryNx->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNy->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDx->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDy->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetX->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetY->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryStagger->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNx->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryNy->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDx->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryDy->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryOffsetY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryStagger->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_rbGridStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_radioBoxGridNumberingScheme->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreX->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCentreY->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_ENTER, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircAngle->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_entryCircCount->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_rbCircStartNumberingOpt->Disconnect( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnParameterChanged ), NULL, this );
m_stdButtonsOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_CREATE_ARRAY_BASE::OnOkClick ), NULL, this );

View File

@ -446,8 +446,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -626,8 +626,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -806,8 +806,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -1072,8 +1072,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -1338,8 +1338,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -1604,8 +1604,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -1870,8 +1870,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -3937,8 +3937,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -4203,8 +4203,8 @@
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter">OnParameterChanged</event>
<event name="OnText">OnParameterChanged</event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
@ -4399,6 +4399,7 @@
<property name="minimum_size"></property>
<property name="name">m_circPadNumberingSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">protected</property>
<event name="OnUpdateUI"></event>
<object class="sizeritem" expanded="1">

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Mar 9 2016)
// C++ code generated with wxFormBuilder (version Jun 21 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!

View File

@ -41,6 +41,7 @@
#include <wxPcbStruct.h>
#include <base_units.h>
#include <project.h>
#include <board_commit.h>
#include <class_module.h>
#include <class_text_mod.h>
@ -325,10 +326,10 @@ void DIALOG_MODULE_BOARD_EDITOR::InitModeditProperties()
}
m_ReferenceCopy = new TEXTE_MODULE( NULL );
m_ValueCopy = new TEXTE_MODULE( NULL );
m_ReferenceCopy->Copy( &m_CurrentModule->Reference() );
m_ValueCopy->Copy( &m_CurrentModule->Value() );
m_ReferenceCopy = new TEXTE_MODULE( m_CurrentModule->Reference() );
m_ReferenceCopy->SetParent( m_CurrentModule );
m_ValueCopy = new TEXTE_MODULE( m_CurrentModule->Value() );
m_ValueCopy->SetParent( m_CurrentModule );
m_ReferenceCtrl->SetValue( m_ReferenceCopy->GetText() );
m_ValueCtrl->SetValue( m_ValueCopy->GetText() );
@ -610,6 +611,9 @@ bool DIALOG_MODULE_BOARD_EDITOR::TransferDataFromWindow()
wxPoint modpos;
wxString msg;
BOARD_COMMIT commit( m_Parent );
commit.Modify( m_CurrentModule );
if( !Validate() || !DIALOG_MODULE_BOARD_EDITOR_BASE::TransferDataFromWindow() ||
!m_PanelProperties->TransferDataFromWindow() )
{
@ -623,10 +627,6 @@ bool DIALOG_MODULE_BOARD_EDITOR::TransferDataFromWindow()
return false;
}
if( m_CurrentModule->GetFlags() == 0 ) // this is a simple edition, we
// must create an undo entry
m_Parent->SaveCopyInUndoList( m_CurrentModule, UR_CHANGED );
if( m_DC )
{
m_Parent->GetCanvas()->CrossHairOff( m_DC );
@ -634,8 +634,10 @@ bool DIALOG_MODULE_BOARD_EDITOR::TransferDataFromWindow()
}
// Init Fields (should be first, because they can be moved or/and flipped later):
m_CurrentModule->Reference().Copy( m_ReferenceCopy );
m_CurrentModule->Value().Copy( m_ValueCopy );
TEXTE_MODULE& reference = m_CurrentModule->Reference();
reference = *m_ReferenceCopy;
TEXTE_MODULE& value = m_CurrentModule->Value();
value = *m_ValueCopy;
// Initialize masks clearances
m_CurrentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
@ -739,7 +741,9 @@ bool DIALOG_MODULE_BOARD_EDITOR::TransferDataFromWindow()
m_CurrentModule->CalculateBoundingBox();
m_Parent->OnModify();
// This is a simple edition, we must create an undo entry
if( m_CurrentModule->GetFlags() == 0 )
commit.Push( _( "Modify module properties" ) );
SetReturnCode( PRM_EDITOR_EDIT_OK );

View File

@ -43,6 +43,7 @@
#include <macros.h>
#include <validators.h>
#include <kicad_string.h>
#include <board_commit.h>
#include <class_module.h>
#include <class_text_mod.h>
@ -165,10 +166,10 @@ void DIALOG_MODULE_MODULE_EDITOR::initModeditProperties()
m_DocCtrl->SetValue( m_currentModule->GetDescription() );
m_KeywordCtrl->SetValue( m_currentModule->GetKeywords() );
m_referenceCopy = new TEXTE_MODULE( NULL );
m_valueCopy = new TEXTE_MODULE( NULL );
m_referenceCopy->Copy( &m_currentModule->Reference() );
m_valueCopy->Copy( &m_currentModule->Value() );
m_referenceCopy = new TEXTE_MODULE( m_currentModule->Reference() );
m_referenceCopy->SetParent( m_currentModule );
m_valueCopy = new TEXTE_MODULE( m_currentModule->Value() );
m_valueCopy->SetParent( m_currentModule );
m_ReferenceCtrl->SetValue( m_referenceCopy->GetText() );
m_ValueCtrl->SetValue( m_valueCopy->GetText() );
m_FootprintNameCtrl->SetValue( m_currentModule->GetFPID().Format() );
@ -440,6 +441,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnCancelClick( wxCommandEvent& event )
void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
{
BOARD_COMMIT commit( m_parent );
wxString msg;
// First, test for invalid chars in module name
@ -465,7 +467,8 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
return;
}
m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT );
commit.Modify( m_currentModule );
m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 );
switch( m_AttributsCtrl->GetSelection() )
@ -493,8 +496,10 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
m_currentModule->SetFPID( FPID( footprintName ) );
// Init Fields:
m_currentModule->Reference().Copy( m_referenceCopy );
m_currentModule->Value().Copy( m_valueCopy );
TEXTE_MODULE& reference = m_currentModule->Reference();
reference = *m_referenceCopy;
TEXTE_MODULE& value = m_currentModule->Value();
value = *m_valueCopy;
// Initialize masks clearances
m_currentModule->SetLocalClearance( ValueFromTextCtrl( *m_NetClearanceValueCtrl ) );
@ -520,7 +525,7 @@ void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event )
m_currentModule->CalculateBoundingBox();
m_parent->OnModify();
commit.Push( _( "Modify module properties" ) );
EndModal( 1 );
}

View File

@ -41,6 +41,7 @@
#include <wxBasePcbFrame.h>
#include <base_units.h>
#include <wx/numformatter.h>
#include <board_commit.h>
#include <class_module.h>
#include <class_text_mod.h>
@ -207,11 +208,13 @@ bool DialogEditModuleText::TransferDataToWindow()
bool DialogEditModuleText::TransferDataFromWindow()
{
BOARD_COMMIT commit( m_parent );
if( !Validate() || !DialogEditModuleText_base::TransferDataFromWindow() )
return false;
if( m_module )
m_parent->SaveCopyInUndoList( m_module, UR_CHANGED );
commit.Modify( m_currentText );
#ifndef USE_WX_OVERLAY
if( m_dc ) //Erase old text on screen
@ -325,7 +328,7 @@ bool DialogEditModuleText::TransferDataFromWindow()
m_parent->Refresh();
#endif
m_parent->OnModify();
commit.Push( _( "Modify module text" ) );
if( m_module )
m_module->SetLastEditTime();

View File

@ -30,6 +30,7 @@ using namespace std::placeholders;
#include <pcbnew.h>
#include <wxPcbStruct.h>
#include <ratsnest_data.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_module.h>
@ -108,11 +109,9 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
return;
BOARD* pcb = m_Parent->GetBoard();
PICKED_ITEMS_LIST pickersList;
ITEM_PICKER itemPicker( NULL, UR_DELETED );
BOARD_COMMIT commit( m_Parent );
BOARD_ITEM* item;
BOARD_ITEM* nextitem;
RN_DATA* ratsnest = pcb->GetRatsnest();
LSET layers_filter = LSET().set();
@ -128,11 +127,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
{
if( delAll || layers_filter[item->GetLayer()] )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
pcb->Remove( item );
item->ViewRelease();
ratsnest->Remove( item );
commit.Remove( item );
gen_rastnest = true;
}
else
@ -160,13 +155,9 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
{
nextitem = item->Next();
if( delAll ||
( item->Type() == PCB_LINE_T && masque_layer[item->GetLayer()] ) )
if( delAll || ( item->Type() == PCB_LINE_T && masque_layer[item->GetLayer()] ) )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink();
commit.Remove( item );
}
}
}
@ -179,13 +170,9 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
{
nextitem = item->Next();
if( delAll ||
( item->Type() == PCB_TEXT_T && del_text_layers[item->GetLayer()] ) )
if( delAll || ( item->Type() == PCB_TEXT_T && del_text_layers[item->GetLayer()] ) )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
item->ViewRelease();
item->UnLink();
commit.Remove( item );
}
}
}
@ -205,13 +192,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
if( del_fp )
{
itemPicker.SetItem( item );
pickersList.PushItem( itemPicker );
static_cast<MODULE*>( item )->RunOnChildren(
std::bind( &KIGFX::VIEW_ITEM::ViewRelease, _1 ) );
ratsnest->Remove( item );
item->ViewRelease();
item->UnLink();
commit.Remove( item );
gen_rastnest = true;
}
}
@ -249,17 +230,12 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
continue;
}
itemPicker.SetItem( track );
pickersList.PushItem( itemPicker );
track->ViewRelease();
ratsnest->Remove( track );
track->UnLink();
commit.Remove( track );
gen_rastnest = true;
}
}
if( pickersList.GetCount() )
m_Parent->SaveCopyInUndoList( pickersList, UR_DELETED );
commit.Push( wxT( "Global delete" ) );
if( m_DelMarkers->GetValue() )
pcb->DeleteMARKERs();
@ -268,9 +244,7 @@ void DIALOG_GLOBAL_DELETION::AcceptPcbDelete()
m_Parent->Compile_Ratsnest( NULL, true );
// There is a chance that some of tracks have changed their nets, so rebuild ratsnest from scratch
if( m_Parent->IsGalCanvasActive() )
pcb->GetRatsnest()->ProcessBoard();
m_Parent->GetCanvas()->Refresh();
m_Parent->OnModify();
// TODO necessary? if not, remove rn_data.h header as well
//if( m_Parent->IsGalCanvasActive() )
//pcb->GetRatsnest()->ProcessBoard();
}

View File

@ -34,6 +34,7 @@
#include <base_units.h>
#include <kicad_string.h>
#include <macros.h>
#include <board_commit.h>
#include <pcbnew.h>
#include <wxPcbStruct.h>
@ -134,35 +135,21 @@ void DIALOG_GLOBAL_MODULES_FIELDS_EDITION::OnOKClick( wxCommandEvent& event )
void PCB_EDIT_FRAME::OnResetModuleTextSizes( wxCommandEvent& event )
{
DIALOG_GLOBAL_MODULES_FIELDS_EDITION dlg(this);
DIALOG_GLOBAL_MODULES_FIELDS_EDITION dlg( this );
dlg.ShowModal();
if( IsGalCanvasActive() )
{
for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
{
module->Value().ViewUpdate();
module->Reference().ViewUpdate();
}
}
m_canvas->Refresh();
}
void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef,
bool aValue, bool aOthers )
{
MODULE* module;
BOARD_ITEM* boardItem;
ITEM_PICKER itemWrapper( NULL, UR_CHANGED );
PICKED_ITEMS_LIST undoItemList;
unsigned int ii;
BOARD_COMMIT commit( this );
int modTextWidth = GetDesignSettings().m_ModuleTextWidth;
const wxSize& modTextSize = GetDesignSettings().m_ModuleTextSize;
// Prepare undo list
for( module = GetBoard()->m_Modules; module; module = module->Next() )
for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() )
{
itemWrapper.SetItem( module );
if( ! aFilter.IsEmpty() )
{
if( ! WildCompareString( aFilter, FROM_UTF8( module->GetFPID().Format().c_str() ),
@ -173,81 +160,50 @@ void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef,
if( aRef )
{
TEXTE_MODULE *item = &module->Reference();
TEXTE_MODULE* item = &module->Reference();
if( item->GetSize() != GetDesignSettings().m_ModuleTextSize ||
item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
{
undoItemList.PushItem( itemWrapper );
commit.Modify( item );
item->SetThickness( modTextWidth );
item->SetSize( modTextSize );
}
}
if( aValue )
{
TEXTE_MODULE *item = &module->Value();
TEXTE_MODULE* item = &module->Value();
if( item->GetSize() != GetDesignSettings().m_ModuleTextSize ||
item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
{
undoItemList.PushItem( itemWrapper );
commit.Modify( item );
item->SetThickness( modTextWidth );
item->SetSize( modTextSize );
}
}
if( aOthers )
{
// Go through all other module text fields
for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() )
for( BOARD_ITEM* boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() )
{
if( boardItem->Type() == PCB_MODULE_TEXT_T )
{
TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem );
TEXTE_MODULE* item = static_cast<TEXTE_MODULE*>( boardItem );
if( item->GetSize() != GetDesignSettings().m_ModuleTextSize
|| item->GetThickness() != GetDesignSettings().m_ModuleTextWidth )
{
undoItemList.PushItem( itemWrapper );
commit.Modify( item );
item->SetThickness( modTextWidth );
item->SetSize( modTextSize );
}
}
}
}
}
// Exit if there's nothing to do
if( !undoItemList.GetCount() )
return;
SaveCopyInUndoList( undoItemList, UR_CHANGED );
// Apply changes to modules in the undo list
for( ii = 0; ii < undoItemList.GetCount(); ii++ )
{
module = (MODULE*) undoItemList.GetPickedItem( ii );
if( aRef )
{
module->Reference().SetThickness( GetDesignSettings().m_ModuleTextWidth );
module->Reference().SetSize( GetDesignSettings().m_ModuleTextSize );
}
if( aValue )
{
module->Value().SetThickness( GetDesignSettings().m_ModuleTextWidth );
module->Value().SetSize( GetDesignSettings().m_ModuleTextSize );
}
if( aOthers )
{
for( boardItem = module->GraphicalItems(); boardItem; boardItem = boardItem->Next() )
{
if( boardItem->Type() == PCB_MODULE_TEXT_T )
{
TEXTE_MODULE *item = static_cast<TEXTE_MODULE*>( boardItem );
item->SetThickness( GetDesignSettings().m_ModuleTextWidth );
item->SetSize( GetDesignSettings().m_ModuleTextSize );
}
}
}
}
OnModify();
commit.Push( wxT( "Reset module text size" ) );
}

View File

@ -44,6 +44,7 @@
#include <class_board_design_settings.h>
#include <base_units.h>
#include <wx/valnum.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_drawsegment.h>
@ -227,7 +228,8 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
return false;
m_parent->SaveCopyInUndoList( m_item, UR_CHANGED );
BOARD_COMMIT commit( m_parent );
commit.Modify( m_item );
wxString msg;
@ -264,7 +266,7 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataFromWindow()
m_item->SetAngle( m_AngleValue * 10.0 );
}
m_parent->OnModify();
commit.Push( _( "Modify drawing properties" ) );
if( m_DC )
m_item->Draw( m_parent->GetCanvas(), m_DC, GR_OR );

View File

@ -43,6 +43,7 @@
#include <module_editor_frame.h>
#include <base_units.h>
#include <wx/valnum.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_module.h>
@ -212,6 +213,9 @@ void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnLayerChoice( wxCommandEvent& even
bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataFromWindow()
{
BOARD_COMMIT commit( m_parent );
commit.Modify( m_module );
if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() )
return false;
@ -223,14 +227,10 @@ bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataFromWindow()
* confirmation is requested */
if( !IsOK( NULL,
_( "The graphic item will be on a copper layer. This is very dangerous. Are you sure?" ) ) )
return false;;
return false;
}
m_parent->SaveCopyInUndoList( m_module, UR_MODEDIT );
m_module->SetLastEditTime();
wxString msg;
wxPoint coord;
msg = m_Center_StartXCtrl->GetValue();
@ -262,7 +262,8 @@ bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataFromWindow()
m_item->SetAngle( m_AngleValue * 10.0 );
}
m_parent->OnModify();
commit.Push( _( "Modify module graphic item" ) );
m_parent->SetMsgPanel( m_item );
return true;

View File

@ -38,6 +38,7 @@
#include <wxBasePcbFrame.h>
#include <pcbcommon.h>
#include <base_units.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_module.h>
@ -117,9 +118,9 @@ DIALOG_PAD_PROPERTIES::DIALOG_PAD_PROPERTIES( PCB_BASE_FRAME* aParent, D_PAD* aP
m_dummyPad = new D_PAD( (MODULE*) NULL );
if( aPad )
m_dummyPad->Copy( aPad );
*m_dummyPad = *aPad;
else // We are editing a "master" pad, i.e. a template to create new pads
m_dummyPad->Copy( m_padMaster );
*m_dummyPad = *m_padMaster;
// Show the X and Y axis. It is usefull because pad shape can have an offset
// or be a complex shape.
@ -921,6 +922,8 @@ bool DIALOG_PAD_PROPERTIES::TransferDataToWindow()
bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
{
BOARD_COMMIT commit( m_parent );
if( !wxDialog::TransferDataFromWindow() )
return false;
@ -940,114 +943,116 @@ bool DIALOG_PAD_PROPERTIES::TransferDataFromWindow()
// m_padMaster is a pattern: ensure there is no net for this pad:
m_padMaster->SetNetCode( NETINFO_LIST::UNCONNECTED );
if( m_currentPad ) // Set current Pad parameters
if( !m_currentPad ) // Set current Pad parameters
return false;
commit.Modify( m_currentPad );
wxSize size;
MODULE* footprint = m_currentPad->GetParent();
footprint->SetLastEditTime();
// redraw the area where the pad was, without pad (delete pad on screen)
m_currentPad->SetFlags( DO_NOT_DRAW );
m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
m_currentPad->ClearFlags( DO_NOT_DRAW );
// Update values
m_currentPad->SetShape( m_padMaster->GetShape() );
m_currentPad->SetAttribute( m_padMaster->GetAttribute() );
if( m_currentPad->GetPosition() != m_padMaster->GetPosition() )
{
wxSize size;
MODULE* footprint = m_currentPad->GetParent();
m_parent->SaveCopyInUndoList( footprint, UR_CHANGED );
footprint->SetLastEditTime();
// redraw the area where the pad was, without pad (delete pad on screen)
m_currentPad->SetFlags( DO_NOT_DRAW );
m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
m_currentPad->ClearFlags( DO_NOT_DRAW );
// Update values
m_currentPad->SetShape( m_padMaster->GetShape() );
m_currentPad->SetAttribute( m_padMaster->GetAttribute() );
if( m_currentPad->GetPosition() != m_padMaster->GetPosition() )
{
m_currentPad->SetPosition( m_padMaster->GetPosition() );
rastnestIsChanged = true;
}
// compute the pos 0 value, i.e. pad position for footprint with orientation = 0
// i.e. relative to footprint origin (footprint position)
wxPoint pt = m_currentPad->GetPosition() - footprint->GetPosition();
RotatePoint( &pt, -footprint->GetOrientation() );
m_currentPad->SetPos0( pt );
m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign
+ footprint->GetOrientation() );
m_currentPad->SetSize( m_padMaster->GetSize() );
size = m_padMaster->GetDelta();
size.y *= isign;
m_currentPad->SetDelta( size );
m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() );
m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() );
wxPoint offset = m_padMaster->GetOffset();
offset.y *= isign;
m_currentPad->SetOffset( offset );
m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() );
if( m_currentPad->GetLayerSet() != m_padMaster->GetLayerSet() )
{
rastnestIsChanged = true;
m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() );
}
if( m_isFlipped )
{
m_currentPad->SetLayerSet( FlipLayerMask( m_currentPad->GetLayerSet() ) );
}
m_currentPad->SetPadName( m_padMaster->GetPadName() );
wxString padNetname;
// For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
if( m_padMaster->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
padNetname = m_PadNetNameCtrl->GetValue();
if( m_currentPad->GetNetname() != padNetname )
{
const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname );
if( !padNetname.IsEmpty() && netinfo == NULL )
{
DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
}
else if( netinfo )
{
rastnestIsChanged = true;
m_currentPad->SetNetCode( netinfo->GetNet() );
}
}
m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() );
m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() );
m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() );
m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() );
m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() );
m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() );
m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() );
m_currentPad->SetRoundRectRadiusRatio( m_padMaster->GetRoundRectRadiusRatio() );
// rounded rect pads with radius ratio = 0 are in fact rect pads.
// So set the right shape (and perhaps issues with a radius = 0)
if( m_currentPad->GetShape() == PAD_SHAPE_ROUNDRECT &&
m_currentPad->GetRoundRectRadiusRatio() == 0.0 )
{
m_currentPad->SetShape( PAD_SHAPE_RECT );
}
footprint->CalculateBoundingBox();
m_parent->SetMsgPanel( m_currentPad );
// redraw the area where the pad was
m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
m_parent->OnModify();
m_currentPad->SetPosition( m_padMaster->GetPosition() );
rastnestIsChanged = true;
}
// compute the pos 0 value, i.e. pad position for footprint with orientation = 0
// i.e. relative to footprint origin (footprint position)
wxPoint pt = m_currentPad->GetPosition() - footprint->GetPosition();
RotatePoint( &pt, -footprint->GetOrientation() );
m_currentPad->SetPos0( pt );
m_currentPad->SetOrientation( m_padMaster->GetOrientation() * isign
+ footprint->GetOrientation() );
m_currentPad->SetSize( m_padMaster->GetSize() );
size = m_padMaster->GetDelta();
size.y *= isign;
m_currentPad->SetDelta( size );
m_currentPad->SetDrillSize( m_padMaster->GetDrillSize() );
m_currentPad->SetDrillShape( m_padMaster->GetDrillShape() );
wxPoint offset = m_padMaster->GetOffset();
offset.y *= isign;
m_currentPad->SetOffset( offset );
m_currentPad->SetPadToDieLength( m_padMaster->GetPadToDieLength() );
if( m_currentPad->GetLayerSet() != m_padMaster->GetLayerSet() )
{
rastnestIsChanged = true;
m_currentPad->SetLayerSet( m_padMaster->GetLayerSet() );
}
if( m_isFlipped )
{
m_currentPad->SetLayerSet( FlipLayerMask( m_currentPad->GetLayerSet() ) );
}
m_currentPad->SetPadName( m_padMaster->GetPadName() );
wxString padNetname;
// For PAD_ATTRIB_HOLE_NOT_PLATED, ensure there is no net name selected
if( m_padMaster->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
padNetname = m_PadNetNameCtrl->GetValue();
if( m_currentPad->GetNetname() != padNetname )
{
const NETINFO_ITEM* netinfo = m_board->FindNet( padNetname );
if( !padNetname.IsEmpty() && netinfo == NULL )
{
DisplayError( NULL, _( "Unknown netname, netname not changed" ) );
}
else if( netinfo )
{
rastnestIsChanged = true;
m_currentPad->SetNetCode( netinfo->GetNet() );
}
}
m_currentPad->SetLocalClearance( m_padMaster->GetLocalClearance() );
m_currentPad->SetLocalSolderMaskMargin( m_padMaster->GetLocalSolderMaskMargin() );
m_currentPad->SetLocalSolderPasteMargin( m_padMaster->GetLocalSolderPasteMargin() );
m_currentPad->SetLocalSolderPasteMarginRatio( m_padMaster->GetLocalSolderPasteMarginRatio() );
m_currentPad->SetZoneConnection( m_padMaster->GetZoneConnection() );
m_currentPad->SetThermalWidth( m_padMaster->GetThermalWidth() );
m_currentPad->SetThermalGap( m_padMaster->GetThermalGap() );
m_currentPad->SetRoundRectRadiusRatio( m_padMaster->GetRoundRectRadiusRatio() );
// rounded rect pads with radius ratio = 0 are in fact rect pads.
// So set the right shape (and perhaps issues with a radius = 0)
if( m_currentPad->GetShape() == PAD_SHAPE_ROUNDRECT &&
m_currentPad->GetRoundRectRadiusRatio() == 0.0 )
{
m_currentPad->SetShape( PAD_SHAPE_RECT );
}
footprint->CalculateBoundingBox();
m_parent->SetMsgPanel( m_currentPad );
// redraw the area where the pad was
m_parent->GetCanvas()->RefreshDrawingRect( m_currentPad->GetBoundingBox() );
commit.Push( _( "Modify pad" ) );
if( rastnestIsChanged ) // The net ratsnest must be recalculated
m_board->m_Status_Pcb = 0;

View File

@ -43,6 +43,7 @@
#include <wx/wx.h>
#include <dialog_pcb_text_properties_base.h>
#include <class_pcb_layer_box_selector.h>
#include <board_commit.h>
class PCB_EDIT_FRAME;
@ -188,10 +189,12 @@ bool DIALOG_PCB_TEXT_PROPERTIES::TransferDataToWindow()
bool DIALOG_PCB_TEXT_PROPERTIES::TransferDataFromWindow()
{
if( !DIALOG_PCB_TEXT_PROPERTIES_BASE::TransferDataFromWindow() )
return false;
BOARD_COMMIT commit( m_Parent );
commit.Modify( m_SelectedPCBText );
// Test for acceptable layer.
// Incorrect layer can happen for old boards,
// having texts on edge cut layer for instance
@ -206,8 +209,7 @@ bool DIALOG_PCB_TEXT_PROPERTIES::TransferDataFromWindow()
// If no other command in progress, prepare undo command
// (for a command in progress, will be made later, at the completion of command)
if( m_SelectedPCBText->GetFlags() == 0 )
m_Parent->SaveCopyInUndoList( m_SelectedPCBText, UR_CHANGED );
bool pushCommit = ( m_SelectedPCBText->GetFlags() == 0 );
/* set flag in edit to force undo/redo/abort proper operation,
* and avoid new calls to SaveCopyInUndoList for the same text
@ -303,9 +305,11 @@ bool DIALOG_PCB_TEXT_PROPERTIES::TransferDataFromWindow()
m_SelectedPCBText->Draw( m_Parent->GetCanvas(), m_DC, GR_OR );
}
#else
m_parent->Refresh();
m_Parent->Refresh();
#endif
m_Parent->OnModify();
if( pushCommit )
commit.Push( _( "Change text properties" ) );
return true;
}

View File

@ -29,6 +29,8 @@
#include <wxPcbStruct.h>
#include <confirm.h>
#include <board_commit.h>
DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems ) :
DIALOG_TRACK_VIA_PROPERTIES_BASE( aParent ), m_items( aItems ),
m_trackStartX( aParent, m_TrackStartXCtrl, m_TrackStartXUnit ),
@ -202,7 +204,7 @@ DIALOG_TRACK_VIA_PROPERTIES::DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParen
}
bool DIALOG_TRACK_VIA_PROPERTIES::Apply()
bool DIALOG_TRACK_VIA_PROPERTIES::Apply( COMMIT& aCommit )
{
if( !check() )
return false;
@ -214,6 +216,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::Apply()
for( int i = 0; i < m_items.Size(); ++i )
{
BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i );
aCommit.Modify( item );
switch( item->Type() )
{

View File

@ -28,6 +28,8 @@
#include <layers_id_colors_and_visibility.h>
struct SELECTION;
class COMMIT;
class PCB_BASE_FRAME;
class DIALOG_TRACK_VIA_PROPERTIES : public DIALOG_TRACK_VIA_PROPERTIES_BASE
@ -36,7 +38,7 @@ public:
DIALOG_TRACK_VIA_PROPERTIES( PCB_BASE_FRAME* aParent, const SELECTION& aItems );
///> Applies values from the dialog to the selected items.
bool Apply();
bool Apply( COMMIT& aCommit );
private:
void onClose( wxCloseEvent& aEvent );

View File

@ -19,35 +19,29 @@ DIALOG_UPDATE_PCB::DIALOG_UPDATE_PCB( PCB_EDIT_FRAME* aParent, NETLIST *aNetlist
m_netlist (aNetlist)
{
m_messagePanel->SetLabel( _("Changes to be applied:") );
m_messagePanel->SetLazyUpdate ( true );
m_messagePanel->SetLazyUpdate( true );
m_netlist->SortByReference();
m_btnPerformUpdate->SetFocus();
m_messagePanel->SetVisibleSeverities( REPORTER::RPT_WARNING | REPORTER::RPT_ERROR | REPORTER::RPT_ACTION );
}
DIALOG_UPDATE_PCB::~DIALOG_UPDATE_PCB()
{
}
void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
{
m_messagePanel->Clear();
REPORTER &reporter = m_messagePanel->Reporter();
KIGFX::VIEW* view = m_frame->GetGalCanvas()->GetView();
TOOL_MANAGER *toolManager = m_frame->GetToolManager();
BOARD *board = m_frame->GetBoard();
REPORTER& reporter = m_messagePanel->Reporter();
TOOL_MANAGER* toolManager = m_frame->GetToolManager();
BOARD* board = m_frame->GetBoard();
if( !aDryRun )
{
// Remove old modules
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
}
// Clear selection, just in case a selected item has to be removed
toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
@ -57,7 +51,8 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
m_netlist->SetFindByTimeStamp( m_matchByTimestamp->GetValue() );
m_netlist->SetReplaceFootprints( true );
try {
try
{
m_frame->LoadFootprints( *m_netlist, &reporter );
}
catch( IO_ERROR &error )
@ -70,14 +65,12 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
}
BOARD_NETLIST_UPDATER updater( m_frame, m_frame->GetBoard() );
updater.SetReporter ( &reporter );
updater.SetIsDryRun( aDryRun);
updater.SetLookupByTimestamp( m_matchByTimestamp->GetValue() );
updater.SetDeleteUnusedComponents ( true );
updater.SetReplaceFootprints( true );
updater.SetDeleteSinglePadNets ( false );
updater.SetDeleteSinglePadNets( false );
updater.UpdateNetlist( *m_netlist );
m_messagePanel->Flush();
@ -85,30 +78,14 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
if( aDryRun )
return;
std::vector<MODULE*> newFootprints = updater.GetAddedComponents();
m_frame->OnModify();
m_frame->SetCurItem( NULL );
// Reload modules
for( MODULE* module = board->m_Modules; module; module = module->Next() )
{
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
view->Add( module );
module->ViewUpdate();
}
// Rebuild the board connectivity:
if( m_frame->IsGalCanvasActive() )
board->GetRatsnest()->ProcessBoard();
m_frame->Compile_Ratsnest( NULL, true );
m_frame->SetMsgPanel( board );
if( m_frame->IsGalCanvasActive() )
{
std::vector<MODULE*> newFootprints = updater.GetAddedComponents();
// Place the new modules
m_frame->SpreadFootprints( &newFootprints, false, false, m_frame->GetCrossHairPosition() );
if( !newFootprints.empty() )
@ -117,30 +94,33 @@ void DIALOG_UPDATE_PCB::PerformUpdate( bool aDryRun )
{
toolManager->RunAction( COMMON_ACTIONS::selectItem, true, footprint );
}
toolManager->InvokeTool( "pcbnew.InteractiveEdit" );
}
}
m_btnPerformUpdate->Enable( false );
m_btnPerformUpdate->SetLabel( _( "Update complete" ) );
m_btnCancel->SetLabel ( _("Close") );
m_btnCancel->SetLabel( _( "Close" ) );
m_btnCancel->SetFocus();
}
void DIALOG_UPDATE_PCB::OnMatchChange( wxCommandEvent& event )
{
PerformUpdate( true );
}
void DIALOG_UPDATE_PCB::OnCancelClick( wxCommandEvent& event )
{
EndModal( wxID_CANCEL );
}
void DIALOG_UPDATE_PCB::OnUpdateClick( wxCommandEvent& event )
{
m_messagePanel->SetLabel( _("Changes applied to the PCB:") );
m_messagePanel->SetLabel( _( "Changes applied to the PCB:" ) );
PerformUpdate( false );
m_btnCancel->SetFocus( );
m_btnCancel->SetFocus();
}

View File

@ -37,6 +37,7 @@
#include <dialog_helpers.h>
#include <macros.h>
#include <base_units.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_pcb_text.h>
@ -161,6 +162,8 @@ DIALOG_DIMENSION_EDITOR::DIALOG_DIMENSION_EDITOR( PCB_EDIT_FRAME* aParent,
void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
{
BOARD_COMMIT commit( m_parent );
LAYER_ID newlayer = ToLAYER_ID( m_SelLayerBox->GetLayerSelection() );
if( !m_parent->GetBoard()->IsLayerEnabled( newlayer ) )
@ -177,7 +180,7 @@ void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
}
#endif
m_parent->SaveCopyInUndoList(m_currentDimension, UR_CHANGED);
commit.Modify( m_currentDimension );
if( m_Name->GetValue() != wxEmptyString )
{
@ -228,7 +231,7 @@ void DIALOG_DIMENSION_EDITOR::OnOKClick( wxCommandEvent& event )
m_parent->Refresh();
#endif
m_parent->OnModify();
commit.Push( _( "Modifed dimensions properties" ) );
event.Skip(); // ends returning wxID_OK (default behavior)
}

View File

@ -2622,7 +2622,7 @@ void EAGLE_PLUGIN::loadSignals( CPTREE& aSignals )
const string& nname = net->second.get<string>( "<xmlattr>.name" );
wxString netName = FROM_UTF8( nname.c_str() );
m_board->AppendNet( new NETINFO_ITEM( m_board, netName, netCode ) );
m_board->Add( new NETINFO_ITEM( m_board, netName, netCode ) );
m_xpath->Value( nname.c_str() );

View File

@ -163,7 +163,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge )
{
MODULE* module = GetBoard()->m_Modules;
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
if( aEdge == NULL )
{
@ -225,7 +225,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
if( aEdge && (aEdge->GetLayer() != new_layer) )
{
if( ! modified ) // save only once
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge->SetLayer( new_layer );
modified = true;
}
@ -233,7 +233,7 @@ void FOOTPRINT_EDIT_FRAME::Edit_Edge_Layer( EDGE_MODULE* aEdge )
}
else if( aEdge->GetLayer() != new_layer )
{
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge->SetLayer( new_layer );
modified = true;
}
@ -330,7 +330,7 @@ EDGE_MODULE* FOOTPRINT_EDIT_FRAME::Begin_Edge_Module( EDGE_MODULE* aEdge,
if( aEdge == NULL ) // Start a new edge item
{
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
aEdge = new EDGE_MODULE( module );
MoveVector.x = MoveVector.y = 0;

View File

@ -136,7 +136,7 @@ void PCB_EDIT_FRAME::StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aE
// if it is an existing item: prepare a copy to undo/abort command
if( !aTextePcb->IsNew() )
s_TextCopy.Copy( aTextePcb );
s_TextCopy = *aTextePcb;
aTextePcb->SetFlags( IS_MOVED );
SetMsgPanel( aTextePcb );
@ -192,7 +192,7 @@ TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
if( aText )
{
textePcb->Copy( aText );
*textePcb = *aText;
GetBoard()->Add( textePcb );
textePcb->SetFlags( IS_NEW );
if( aDC )

View File

@ -243,7 +243,7 @@ void PCB_BASE_FRAME::PlaceTexteModule( TEXTE_MODULE* Text, wxDC* DC )
if( IsType( FRAME_PCB ) )
SaveCopyInUndoList( Module, UR_CHANGED );
else
SaveCopyInUndoList( Module, UR_MODEDIT );
SaveCopyInUndoList( Module, UR_CHANGED );
Text->SetOrientation( tmp );

View File

@ -245,7 +245,7 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
{
const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();
aCaller->SaveCopyInUndoList( aModule, UR_MODEDIT );
aCaller->SaveCopyInUndoList( aModule, UR_CHANGED );
aCaller->OnModify();
std::list<BOARD_ITEM*>::const_iterator it, itEnd;
@ -264,7 +264,6 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
converted = new EDGE_MODULE( aModule );
*static_cast<DRAWSEGMENT*>( converted ) = *static_cast<DRAWSEGMENT*>( item );
aModule->Add( converted );
static_cast<EDGE_MODULE*>( converted )->SetLocalCoord();
delete item;
break;
}
@ -274,7 +273,6 @@ bool InvokeDXFDialogModuleImport( PCB_BASE_FRAME* aCaller, MODULE* aModule )
converted = new TEXTE_MODULE( aModule );
*static_cast<TEXTE_PCB*>( converted ) = *static_cast<TEXTE_PCB*>( item );
aModule->Add( converted );
static_cast<TEXTE_MODULE*>( converted )->SetLocalCoord();
delete item;
break;
}

View File

@ -2080,7 +2080,7 @@ void LEGACY_PLUGIN::loadNETINFO_ITEM()
// if it is not the net 0, or if the net 0 does not exists.
if( net && ( net->GetNet() > 0 || m_board->FindNet( 0 ) == NULL ) )
{
m_board->AppendNet( net );
m_board->Add( net );
// Be sure we have room to store the net in m_netCodes
if( (int)m_netCodes.size() <= netCode )

View File

@ -40,6 +40,7 @@
#include <macros.h>
#include <invoke_pcb_dialog.h>
#include <class_pcb_layer_widget.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_module.h>
@ -436,66 +437,42 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
}
m_toolManager->RunAction( COMMON_ACTIONS::selectionClear, true );
pcbframe->GetToolManager()->RunAction( COMMON_ACTIONS::selectionClear, true );
BOARD_COMMIT commit( pcbframe );
// Create the "new" module
MODULE* newmodule = new MODULE( *module_in_edit );
newmodule->SetParent( mainpcb );
newmodule->SetLink( 0 );
// Put the footprint in the main pcb linked list.
mainpcb->Add( newmodule );
if( source_module ) // this is an update command
{
// In the main board,
// the new module replace the old module (pos, orient, ref, value
// and connexions are kept)
// and the source_module (old module) is deleted
PICKED_ITEMS_LIST pickList;
if( pcbframe->IsGalCanvasActive() )
{
KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
source_module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view,
std::placeholders::_1 ) );
view->Remove( source_module );
}
pcbframe->Exchange_Module( source_module, newmodule, &pickList );
pcbframe->Exchange_Module( source_module, newmodule, commit );
newmodule->SetTimeStamp( module_in_edit->GetLink() );
if( pickList.GetCount() )
pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
commit.Push( wxT( "Update module" ) );
}
else // This is an insert command
{
wxPoint cursor_pos = pcbframe->GetCrossHairPosition();
commit.Add( newmodule );
pcbframe->SetCrossHairPosition( wxPoint( 0, 0 ) );
pcbframe->PlaceModule( newmodule, NULL );
newmodule->SetPosition( wxPoint( 0, 0 ) );
pcbframe->SetCrossHairPosition( cursor_pos );
newmodule->SetTimeStamp( GetNewTimeStamp() );
pcbframe->SaveCopyInUndoList( newmodule, UR_NEW );
commit.Push( wxT( "Insert module" ) );
}
newmodule->ClearFlags();
GetScreen()->ClrModify();
pcbframe->SetCurItem( NULL );
// @todo LEGACY should be unnecessary
mainpcb->m_Status_Pcb = 0;
if( pcbframe->IsGalCanvasActive() )
{
RN_DATA* ratsnest = pcbframe->GetBoard()->GetRatsnest();
ratsnest->Update( newmodule );
ratsnest->Recalculate();
KIGFX::VIEW* view = pcbframe->GetGalCanvas()->GetView();
newmodule->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view,
std::placeholders::_1 ) );
view->Add( newmodule );
pcbframe->GetGalCanvas()->ForceRefresh();
}
}
break;
@ -651,7 +628,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_PAD:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
SetCurItem( NULL );
m_canvas->MoveCursorToCrossHair();
@ -674,13 +651,13 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
m_canvas->MoveCursorToCrossHair();
Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
break;
case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
// Calls the global change dialog:
DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
m_canvas->MoveCursorToCrossHair();
@ -707,7 +684,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_TEXTMODULE:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
DeleteTextModule( static_cast<TEXTE_MODULE*>( GetScreen()->GetCurItem() ) );
SetCurItem( NULL );
m_canvas->MoveCursorToCrossHair();
@ -765,7 +742,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_POPUP_PCB_DELETE_EDGE:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
m_canvas->MoveCursorToCrossHair();
RemoveStruct( GetScreen()->GetCurItem() );
SetCurItem( NULL );
@ -774,7 +751,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
case ID_MODEDIT_MODULE_ROTATE:
case ID_MODEDIT_MODULE_MIRROR:
case ID_MODEDIT_MODULE_MOVE_EXACT:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
Transform( (MODULE*) GetScreen()->GetCurItem(), id );
m_canvas->Refresh();
break;
@ -870,7 +847,7 @@ void FOOTPRINT_EDIT_FRAME::moveExact()
if( ret == wxID_OK )
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
BOARD_ITEM* item = GetScreen()->GetCurItem();

View File

@ -61,7 +61,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
break;
case PCB_MODULE_EDGE_T:
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
Place_EdgeMod( static_cast<EDGE_MODULE*>( item ) );
break;
@ -147,7 +147,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( item && item->Type() != PCB_MODULE_T ) // Cannot delete the module itself
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
RemoveStruct( item );
SetCurItem( NULL );
}
@ -162,7 +162,7 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
|| (module->GetFlags() != 0) )
break;
SaveCopyInUndoList( module, UR_MODEDIT );
SaveCopyInUndoList( module, UR_CHANGED );
// set the new relative internal local coordinates of footprint items
wxPoint moveVector = module->GetPosition() - GetCrossHairPosition();
@ -187,14 +187,14 @@ void FOOTPRINT_EDIT_FRAME::OnLeftClick( wxDC* DC, const wxPoint& MousePos )
if( GetBoard()->m_Modules == NULL )
break;
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
CreateTextModule( GetBoard()->m_Modules, DC );
break;
case ID_MODEDIT_PAD_TOOL:
if( GetBoard()->m_Modules )
{
SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
SaveCopyInUndoList( GetBoard()->m_Modules, UR_CHANGED );
AddPad( GetBoard()->m_Modules, true );
}

View File

@ -1,176 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2007-2014 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <functional>
using namespace std::placeholders;
#include <fctsys.h>
#include <class_drawpanel.h>
#include <class_draw_panel_gal.h>
#include <tool/tool_manager.h>
#include <wxPcbStruct.h>
#include <class_board.h>
#include <class_module.h>
#include <pcbnew.h>
#include <protos.h>
#include <module_editor_frame.h>
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( BOARD_ITEM* aItem,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
EDA_ITEM* item;
MODULE* CopyItem;
PICKED_ITEMS_LIST* lastcmd;
CopyItem = new MODULE( *( (MODULE*) aItem ) );
CopyItem->SetParent( GetBoard() );
lastcmd = new PICKED_ITEMS_LIST();
ITEM_PICKER wrapper( CopyItem, UR_MODEDIT );
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd );
/* Clear current flags (which can be temporary set by a current edit command) */
for( item = CopyItem->GraphicalItems(); item != NULL; item = item->Next() )
item->ClearFlags();
for( D_PAD* pad = CopyItem->Pads(); pad; pad = pad->Next() )
pad->ClearFlags();
CopyItem->Reference().ClearFlags();
CopyItem->Value().ClearFlags();
/* Clear redo list, because after new save there is no redo to do */
GetScreen()->ClearUndoORRedoList( GetScreen()->m_RedoList );
}
void FOOTPRINT_EDIT_FRAME::SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint )
{
assert( aItemsList.GetPickedItem( 0 )->GetParent()->Type() == PCB_MODULE_T );
MODULE* owner = static_cast<MODULE*>( aItemsList.GetPickedItem( 0 )->GetParent() );
#ifndef NDEBUG
// All items should have the same parent (MODULE) to make undo/redo entry valid
for( unsigned int i = 0; i < aItemsList.GetCount(); ++i )
assert( aItemsList.GetPickedItem( i )->GetParent() == owner );
#endif /* not NDEBUG */
SaveCopyInUndoList( owner, aTypeCommand, aTransformPoint );
}
void FOOTPRINT_EDIT_FRAME::RestoreCopyFromRedoList( wxCommandEvent& aEvent )
{
if( GetScreen()->GetRedoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
// Save current module state in undo list
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
MODULE* module = GetBoard()->m_Modules.PopFront();
ITEM_PICKER wrapper( module, UR_MODEDIT );
KIGFX::VIEW* view = GetGalCanvas()->GetView();
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToUndoList( lastcmd );
view->Remove( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
// Retrieve last module state from undo list
lastcmd = GetScreen()->PopCommandFromRedoList();
wrapper = lastcmd->PopItem();
module = (MODULE*) wrapper.GetItem();
delete lastcmd;
if( module )
{
GetBoard()->Add( module );
GetGalCanvas()->GetView()->Add( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
module->ViewUpdate();
}
SetCurItem( NULL );
OnModify();
m_canvas->Refresh();
}
void FOOTPRINT_EDIT_FRAME::RestoreCopyFromUndoList( wxCommandEvent& aEvent )
{
if( UndoRedoBlocked() )
return;
if( GetScreen()->GetUndoCommandCount() <= 0 )
return;
// Inform tools that undo command was issued
TOOL_EVENT event( TC_MESSAGE, TA_UNDO_REDO, AS_GLOBAL );
m_toolManager->ProcessEvent( event );
if( UndoRedoBlocked() )
return;
// Save current module state in redo list
PICKED_ITEMS_LIST* lastcmd = new PICKED_ITEMS_LIST();
MODULE* module = GetBoard()->m_Modules.PopFront();
ITEM_PICKER wrapper( module, UR_MODEDIT );
KIGFX::VIEW* view = GetGalCanvas()->GetView();
lastcmd->PushItem( wrapper );
GetScreen()->PushCommandToRedoList( lastcmd );
view->Remove( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Remove, view, _1 ) );
// Retrieve last module state from undo list
lastcmd = GetScreen()->PopCommandFromUndoList();
wrapper = lastcmd->PopItem();
module = (MODULE*) wrapper.GetItem();
delete lastcmd;
if( module )
{
GetBoard()->Add( module, ADD_APPEND );
view->Add( module );
module->RunOnChildren( std::bind( &KIGFX::VIEW::Add, view, _1 ) );
module->ViewUpdate();
}
SetCurItem( NULL );
OnModify();
m_canvas->Refresh();
}

View File

@ -54,6 +54,9 @@ public:
*/
static const wxChar* GetFootprintEditorFrameName();
///> @copydoc PCB_BASE_FRAME::GetModel()
BOARD_ITEM_CONTAINER* GetModel() const override;
BOARD_DESIGN_SETTINGS& GetDesignSettings() const; // overload PCB_BASE_FRAME, get parent's
void SetDesignSettings( const BOARD_DESIGN_SETTINGS& aSettings ); // overload
@ -267,50 +270,6 @@ public:
BOARD_ITEM* ModeditLocateAndDisplay( int aHotKeyCode = 0 );
/* Undo and redo functions */
/**
* Function SaveCopyInUndoList.
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItem = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( BOARD_ITEM* aItem,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function SaveCopyInUndoList (overloaded).
* Creates a new entry in undo list of commands.
* add a list of pickers to handle a list of items
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
virtual void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList,
UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) );
/**
* Function RestoreCopyFromUndoList
* performs an undo operation on the last edition:
* - Place the current edited library component in Redo list
* - Get old version of the current edited library component
*/
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromRedoList
* performs a redo operation on the the last edition:
* - Place the current edited library component in undo list
* - Get old version of the current edited library component
*/
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/// Return the current library nickname.
const wxString GetCurrentLib() const;

View File

@ -350,6 +350,12 @@ FOOTPRINT_EDIT_FRAME::~FOOTPRINT_EDIT_FRAME()
}
BOARD_ITEM_CONTAINER* FOOTPRINT_EDIT_FRAME::GetModel() const
{
return GetBoard()->m_Modules;
}
const wxString FOOTPRINT_EDIT_FRAME::getLibPath()
{
try
@ -948,13 +954,12 @@ void FOOTPRINT_EDIT_FRAME::setupTools()
m_toolManager->RegisterTool( new PLACEMENT_TOOL );
m_toolManager->RegisterTool( new PICKER_TOOL );
m_toolManager->GetTool<SELECTION_TOOL>()->EditModules( true );
m_toolManager->GetTool<EDIT_TOOL>()->EditModules( true );
m_toolManager->GetTool<DRAWING_TOOL>()->EditModules( true );
m_toolManager->GetTool<SELECTION_TOOL>()->SetEditModules( true );
m_toolManager->GetTool<EDIT_TOOL>()->SetEditModules( true );
m_toolManager->GetTool<DRAWING_TOOL>()->SetEditModules( true );
m_toolManager->ResetTools( TOOL_BASE::RUN );
m_toolManager->InvokeTool( "pcbnew.InteractiveSelection" );
}

View File

@ -52,7 +52,7 @@ void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad )
D_PAD& mp = GetDesignSettings().m_Pad_Master;
// Copy all settings. Some of them are not used, but they break anything
mp.Copy( aPad );
mp = *aPad;
// The pad orientation, for historical reasons is the
// pad rotation + parent rotation.
// store only the pad rotation.

View File

@ -925,7 +925,7 @@ void PCB::AddToBoard()
{
net = m_pcbNetlist[i];
m_board->AppendNet( new NETINFO_ITEM( m_board, net->m_name, net->m_netCode ) );
m_board->Add( new NETINFO_ITEM( m_board, net->m_name, net->m_netCode ) );
}
for( i = 0; i < (int) m_pcbComponents.GetCount(); i++ )

View File

@ -278,7 +278,7 @@ void PCB_PAD::AddToModule( MODULE* aModule, int aRotation, bool aEncapsulatedPad
{
// It is a new net
netinfo = new NETINFO_ITEM( m_board, m_net );
m_board->AppendNet( netinfo );
m_board->Add( netinfo );
}
pad->SetNetCode( netinfo->GetNet() );

View File

@ -27,6 +27,8 @@
#include <wxBasePcbFrame.h>
class BOARD_ITEM_CONTAINER;
/**
* Common, abstract interface for edit frames.
*/
@ -42,6 +44,12 @@ public:
virtual ~PCB_BASE_EDIT_FRAME() {};
/**
* Function GetModel()
* returns the primary data model.
*/
virtual BOARD_ITEM_CONTAINER* GetModel() const = 0;
/**
* Function CreateNewLibrary
* prompts user for a library path, then creates a new footprint library at that
@ -61,26 +69,62 @@ public:
*/
virtual void OnEditItemRequest( wxDC* aDC, BOARD_ITEM* aItem ) = 0;
// Undo buffer handling
/**
* Function SaveCopyInUndoList
* Creates a new entry in undo list of commands.
* add a picker to handle aItemToCopy
* @param aItemToCopy = the board item modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation, for
* commands like move
*/
void SaveCopyInUndoList( BOARD_ITEM* aItemToCopy, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) override;
/**
* Function SaveCopyInUndoList
* Creates a new entry in undo list of commands.
* add a list of pickers to handle a list of items
* @param aItemsList = the list of items modified by the command to undo
* @param aTypeCommand = command type (see enum UNDO_REDO_T)
* @param aTransformPoint = the reference point of the transformation,
* for commands like move
*/
void SaveCopyInUndoList( const PICKED_ITEMS_LIST& aItemsList, UNDO_REDO_T aTypeCommand,
const wxPoint& aTransformPoint = wxPoint( 0, 0 ) ) override;
/**
* Function RestoreCopyFromRedoList
* Redo the last edition:
* - Save the current data in Undo list
* - Get an old version of the data from Redo list
* - Save the current board in Undo list
* - Get an old version of the board from Redo list
* @return none
*/
virtual void RestoreCopyFromRedoList( wxCommandEvent& aEvent ) = 0;
void RestoreCopyFromRedoList( wxCommandEvent& aEvent );
/**
* Function RestoreCopyFromUndoList
* Undo the last edition:
* - Save the current board in Redo list
* - Get an old version of the data from Undo list
* - Get an old version of the board from Undo list
* @return none
*/
virtual void RestoreCopyFromUndoList( wxCommandEvent& aEvent ) = 0;
void RestoreCopyFromUndoList( wxCommandEvent& aEvent );
int GetRotationAngle() const { return m_rotationAngle; }
void SetRotationAngle( int aRotationAngle );
bool PostCommandMenuEvent( int evt_type );
/**
* Function PutDataInPreviousState
* Used in undo or redo command.
* Put data pointed by List in the previous state, i.e. the state memorized by List
* @param aList = a PICKED_ITEMS_LIST pointer to the list of items to undo/redo
* @param aRedoCommand = a bool: true for redo, false for undo
* @param aRebuildRatsnet = a bool: true to rebuild ratsnest (normal use), false
* to just retrieve last state (used in abort commands that do not need to
* rebuild ratsnest)
*/
void PutDataInPreviousState( PICKED_ITEMS_LIST* aList,
bool aRedoCommand,
bool aRebuildRatsnet = true );
/**
* Function UndoRedoBlocked
@ -100,6 +144,20 @@ public:
m_undoRedoBlocked = aBlock;
}
/**
* Function GetRotationAngle()
* Returns the angle used for rotate operations.
*/
int GetRotationAngle() const { return m_rotationAngle; }
/**
* Function SetRotationAngle()
* Sets the angle used for rotate operations.
*/
void SetRotationAngle( int aRotationAngle );
bool PostCommandMenuEvent( int evt_type );
///> @copydoc EDA_DRAW_FRAME::UseGalCanvas()
void UseGalCanvas( bool aEnable );

View File

@ -1242,10 +1242,10 @@ void PCB_PARSER::parseNETINFO_ITEM() throw( IO_ERROR, PARSE_ERROR )
// net 0 should be already in list, so store this net
// if it is not the net 0, or if the net 0 does not exists.
// (TODO: a better test.)
if( netCode > 0 || m_board->FindNet( 0 ) == NULL )
if( netCode > NETINFO_LIST::UNCONNECTED || !m_board->FindNet( NETINFO_LIST::UNCONNECTED ) )
{
NETINFO_ITEM* net = new NETINFO_ITEM( m_board, name, netCode );
m_board->AppendNet( net );
m_board->Add( net );
// Store the new code mapping
pushValueIntoMap( netCode, net->GetNet() );
@ -2988,7 +2988,7 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER() throw( IO_ERROR, PARSE_ERROR )
{
int newnetcode = m_board->GetNetCount();
net = new NETINFO_ITEM( m_board, netnameFromfile, newnetcode );
m_board->AppendNet( net );
m_board->Add( net );
// Store the new code mapping
pushValueIntoMap( newnetcode, net->GetNet() );

View File

@ -196,8 +196,8 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME )
EVT_TOOL( wxID_CUT, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_COPY, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_PASTE, PCB_EDIT_FRAME::Process_Special_Functions )
EVT_TOOL( wxID_UNDO, PCB_EDIT_FRAME::RestoreCopyFromUndoList )
EVT_TOOL( wxID_REDO, PCB_EDIT_FRAME::RestoreCopyFromRedoList )
EVT_TOOL( wxID_UNDO, PCB_BASE_EDIT_FRAME::RestoreCopyFromUndoList )
EVT_TOOL( wxID_REDO, PCB_BASE_EDIT_FRAME::RestoreCopyFromRedoList )
EVT_TOOL( wxID_PRINT, PCB_EDIT_FRAME::ToPrinter )
EVT_TOOL( ID_GEN_PLOT_SVG, PCB_EDIT_FRAME::SVG_Print )
EVT_TOOL( ID_GEN_PLOT, PCB_EDIT_FRAME::Process_Special_Functions )
@ -481,7 +481,7 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
if( IsGalCanvasActive() )
{
aBoard->GetRatsnest()->Recalculate();
aBoard->GetRatsnest()->ProcessBoard();
// reload the worksheet
SetPageSettings( aBoard->GetPageSettings() );
@ -489,6 +489,12 @@ void PCB_EDIT_FRAME::SetBoard( BOARD* aBoard )
}
BOARD_ITEM_CONTAINER* PCB_EDIT_FRAME::GetModel() const
{
return m_Pcb;
}
void PCB_EDIT_FRAME::SetPageSettings( const PAGE_INFO& aPageSettings )
{
PCB_BASE_FRAME::SetPageSettings( aPageSettings );
@ -667,17 +673,8 @@ void PCB_EDIT_FRAME::Show3D_Frame( wxCommandEvent& event )
void PCB_EDIT_FRAME::UseGalCanvas( bool aEnable )
{
if( aEnable )
{
BOARD* board = GetBoard();
if( board )
board->GetRatsnest()->ProcessBoard();
}
else
{
if( !aEnable )
Compile_Ratsnest( NULL, true );
}
PCB_BASE_EDIT_FRAME::UseGalCanvas( aEnable );

View File

@ -215,11 +215,11 @@ void RN_NET::validateEdge( RN_EDGE_MST_PTR& aEdge )
// If any of nodes belonging to the edge has the flag set,
// change it to the closest node that has flag cleared
if( source->GetFlag() )
if( source->GetNoLine() )
{
valid = false;
std::list<RN_NODE_PTR> closest = GetClosestNodes( source, LINE_TARGET() );
std::list<RN_NODE_PTR> closest = GetClosestNodes( source, WITHOUT_FLAG() );
for( RN_NODE_PTR& node : closest )
{
if( node && node != target )
@ -230,11 +230,11 @@ void RN_NET::validateEdge( RN_EDGE_MST_PTR& aEdge )
}
}
if( target->GetFlag() )
if( target->GetNoLine() )
{
valid = false;
std::list<RN_NODE_PTR> closest = GetClosestNodes( target, LINE_TARGET() );
std::list<RN_NODE_PTR> closest = GetClosestNodes( target, WITHOUT_FLAG() );
for( RN_NODE_PTR& node : closest )
{
if( node && node != source )
@ -398,7 +398,7 @@ RN_POLY::RN_POLY( const SHAPE_POLY_SET* aParent,
// Mark it as not appropriate as a destination of ratsnest edges
// (edges coming out from a polygon vertex look weird)
m_node->SetFlag( true );
m_node->SetNoLine( true );
}
@ -761,7 +761,7 @@ void RN_NET::GetAllItems( std::list<BOARD_CONNECTED_ITEM*>& aOutput, RN_ITEM_TYP
void RN_NET::ClearSimple()
{
for( const RN_NODE_PTR& node : m_blockedNodes )
node->SetFlag( false );
node->SetNoLine( false );
m_blockedNodes.clear();
m_simpleNodes.clear();
@ -1033,22 +1033,25 @@ void RN_NET::processPads()
}
void RN_DATA::Add( const BOARD_ITEM* aItem )
bool RN_DATA::Add( const BOARD_ITEM* aItem )
{
int net;
if( aItem->IsConnected() )
{
net = static_cast<const BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode();
if( net < 1 ) // do not process unconnected items
return;
if( net >= (int) m_nets.size() ) // Autoresize
if( net < 1 ) // do not process unconnected items
return false;
// Autoresize is necessary e.g. for module editor
if( net >= (int) m_nets.size() )
m_nets.resize( net + 1 );
}
else if( aItem->Type() == PCB_MODULE_T )
{
const MODULE* module = static_cast<const MODULE*>( aItem );
for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
net = pad->GetNetCode();
@ -1056,16 +1059,24 @@ void RN_DATA::Add( const BOARD_ITEM* aItem )
if( net < 1 ) // do not process unconnected items
continue;
if( net >= (int) m_nets.size() ) // Autoresize
// Autoresize is necessary e.g. for module editor
if( net >= (int) m_nets.size() )
m_nets.resize( net + 1 );
m_nets[net].AddItem( pad );
}
return;
return true;
}
else if( aItem->Type() == PCB_NETINFO_T )
{
int netCount = m_board->GetNetCount();
if( (unsigned) netCount > m_nets.size() )
m_nets.resize( netCount );
return true;
}
else
return;
switch( aItem->Type() )
{
@ -1086,12 +1097,15 @@ void RN_DATA::Add( const BOARD_ITEM* aItem )
break;
default:
return false;
break;
}
return true;
}
void RN_DATA::Remove( const BOARD_ITEM* aItem )
bool RN_DATA::Remove( const BOARD_ITEM* aItem )
{
int net;
@ -1100,21 +1114,19 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem )
net = static_cast<const BOARD_CONNECTED_ITEM*>( aItem )->GetNetCode();
if( net < 1 ) // do not process unconnected items
return;
return false;
#ifdef NDEBUG
if( net >= (int) m_nets.size() ) // Autoresize
// Autoresize is necessary e.g. for module editor
if( net >= (int) m_nets.size() )
{
m_nets.resize( net + 1 );
return; // if it was resized, then surely the item had not been added before
return false; // if it was resized, then surely the item had not been added before
}
#endif
assert( net < (int) m_nets.size() );
}
else if( aItem->Type() == PCB_MODULE_T )
{
const MODULE* module = static_cast<const MODULE*>( aItem );
for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
{
net = pad->GetNetCode();
@ -1122,23 +1134,22 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem )
if( net < 1 ) // do not process unconnected items
continue;
#ifdef NDEBUG
if( net >= (int) m_nets.size() ) // Autoresize
// Autoresize is necessary e.g. for module editor
if( net >= (int) m_nets.size() )
{
m_nets.resize( net + 1 );
return; // if it was resized, then surely the item had not been added before
return false; // if it was resized, then surely the item had not been added before
}
#endif
assert( net < (int) m_nets.size() );
m_nets[net].RemoveItem( pad );
}
return;
return true;
}
else
return;
{
return false;
}
switch( aItem->Type() )
{
@ -1159,15 +1170,24 @@ void RN_DATA::Remove( const BOARD_ITEM* aItem )
break;
default:
return false;
break;
}
return true;
}
void RN_DATA::Update( const BOARD_ITEM* aItem )
bool RN_DATA::Update( const BOARD_ITEM* aItem )
{
Remove( aItem );
Add( aItem );
if( Remove( aItem ) )
{
bool res = Add( aItem );
assert( res );
return true;
}
return false;
}
@ -1227,9 +1247,6 @@ void RN_DATA::Recalculate( int aNet )
{
unsigned int netCount = m_board->GetNetCount();
if( netCount > m_nets.size() )
m_nets.resize( netCount );
if( aNet < 0 && netCount > 1 ) // Recompute everything
{
#ifdef PROFILE

View File

@ -92,19 +92,19 @@ struct RN_NODE_FILTER : public std::unary_function<const RN_NODE_PTR&, bool>
RN_NODE_AND_FILTER operator&&( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
RN_NODE_OR_FILTER operator||( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 );
///> Filters out nodes that have the flag set.
struct WITHOUT_FLAG : public RN_NODE_FILTER
///> Filters out nodes that cannot be a ratsnest line target
struct LINE_TARGET : public RN_NODE_FILTER
{
bool operator()( const RN_NODE_PTR& aNode ) const
{
return !aNode->GetFlag();
return !aNode->GetNoLine();
}
};
///> Filters out nodes with a specific tag
struct DIFFERENT_TAG : public RN_NODE_FILTER
struct DIFF_TAG : public RN_NODE_FILTER
{
DIFFERENT_TAG( int aTag ) :
DIFF_TAG( int aTag ) :
m_tag( aTag )
{}
@ -515,7 +515,7 @@ public:
inline void AddBlockedNode( RN_NODE_PTR& aNode )
{
m_blockedNodes.insert( aNode );
aNode->SetFlag( true );
aNode->SetNoLine( true );
}
/**
@ -647,22 +647,26 @@ public:
* Function Add()
* Adds an item to the ratsnest data.
* @param aItem is an item to be added.
* @return True if operation succeeded.
*/
void Add( const BOARD_ITEM* aItem );
bool Add( const BOARD_ITEM* aItem );
/**
* Function Remove()
* Removes an item from the ratsnest data.
* @param aItem is an item to be updated.
* @return True if operation succeeded.
*/
void Remove( const BOARD_ITEM* aItem );
bool Remove( const BOARD_ITEM* aItem );
/**
* Function Update()
* Updates the ratsnest data for an item.
* @param aItem is an item to be updated.
* @return True if operation succeeded. The item will not be updated if it was not previously
* added to the ratsnest.
*/
void Update( const BOARD_ITEM* aItem );
bool Update( const BOARD_ITEM* aItem );
/**
* Function AddSimple()

View File

@ -79,7 +79,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
if( node->GetRefCount() > 1 )
continue;
RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() );
RN_NODE_PTR dest = net.GetClosestNode( node, LINE_TARGET() );
if( dest )
{

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;
@ -738,12 +741,11 @@ void PNS_KICAD_IFACE::SyncWorld( PNS::NODE *aWorld )
for( TRACK* t = m_board->m_Track; t; t = t->Next() )
{
KICAD_T type = t->Type();
PNS::ITEM* item = NULL;
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 +823,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 +872,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 +906,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 +922,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() )
@ -759,8 +756,6 @@ void ROUTER_TOOL::performDragging()
ctls->SetAutoPan( true );
bool modified = false;
while( OPT_TOOL_EVENT evt = Wait() )
{
ctls->ForceCursorPosition( false );
@ -775,10 +770,7 @@ void ROUTER_TOOL::performDragging()
else if( evt->IsClick( BUT_LEFT ) )
{
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
{
modified = true;
break;
}
}
handleCommonEvents( *evt );
@ -787,9 +779,6 @@ void ROUTER_TOOL::performDragging()
if( m_router->RoutingInProgress() )
m_router->StopRouting();
if( modified )
frame->OnModify();
m_startItem = NULL;
ctls->SetAutoPan( false );
@ -829,8 +818,6 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
ctls->SetAutoPan( true );
frame->UndoRedoBlock( true );
bool modified = false;
while( OPT_TOOL_EVENT evt = Wait() )
{
p0 = ctls->GetCursorPosition();
@ -845,7 +832,7 @@ int ROUTER_TOOL::InlineDrag( const TOOL_EVENT& aEvent )
}
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
{
modified = m_router->FixRoute( p0, NULL );
m_router->FixRoute( p0, NULL );
break;
}
}
@ -853,9 +840,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

@ -34,6 +34,7 @@
#include <dialog_helpers.h>
#include <base_units.h>
#include <gr_basic.h>
#include <board_commit.h>
#include <class_board.h>
#include <class_mire.h>
@ -128,12 +129,14 @@ void TARGET_PROPERTIES_DIALOG_EDITOR::OnCancelClick( wxCommandEvent& event )
*/
void TARGET_PROPERTIES_DIALOG_EDITOR::OnOkClick( wxCommandEvent& event )
{
BOARD_COMMIT commit( m_Parent );
commit.Modify( m_Target );
if( m_DC )
m_Target->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR );
// Save old item in undo list, if is is not currently edited (will be later if so)
if( m_Target->GetFlags() == 0 )
m_Parent->SaveCopyInUndoList( m_Target, UR_CHANGED );
bool pushCommit = ( m_Target->GetFlags() == 0 );
if( m_Target->GetFlags() != 0 ) // other edition in progress (MOVE, NEW ..)
m_Target->SetFlags( IN_EDIT ); // set flag in edit to force
@ -150,7 +153,9 @@ void TARGET_PROPERTIES_DIALOG_EDITOR::OnOkClick( wxCommandEvent& event )
if( m_DC )
m_Target->Draw( m_Parent->GetCanvas(), m_DC, ( m_Target->IsMoving() ) ? GR_XOR : GR_OR );
m_Parent->OnModify();
if( pushCommit )
commit.Push( _( "Modified alignment target" ) );
EndModal( 1 );
}

View File

@ -138,6 +138,10 @@ TOOL_ACTION COMMON_ACTIONS::properties( "pcbnew.InteractiveEdit.properties",
AS_GLOBAL, TOOL_ACTION::LegacyHotKey( HK_EDIT_ITEM ),
_( "Properties..." ), _( "Displays item properties dialog" ), editor_xpm );
TOOL_ACTION COMMON_ACTIONS::editModifiedSelection( "pcbnew.InteractiveEdit.ModifiedSelection",
AS_GLOBAL, 0,
"", "" );
// Drawing tool actions
TOOL_ACTION COMMON_ACTIONS::drawLine( "pcbnew.InteractiveDrawing.line",
@ -564,10 +568,6 @@ TOOL_ACTION COMMON_ACTIONS::routerInlineDrag( "pcbnew.InteractiveRouter.InlineDr
"", "" );
// Point editor
TOOL_ACTION COMMON_ACTIONS::pointEditorUpdate( "pcbnew.PointEditor.update",
AS_GLOBAL, 0,
"", "" ); // No description, it is not supposed to be shown anywhere
TOOL_ACTION COMMON_ACTIONS::pointEditorAddCorner( "pcbnew.PointEditor.addCorner",
AS_GLOBAL, 0,
_( "Create corner" ), _( "Create corner" ), add_corner_xpm );

View File

@ -79,6 +79,9 @@ public:
/// Activation of the edit tool
static TOOL_ACTION properties;
/// Modified selection notification
static TOOL_ACTION editModifiedSelection;
/// Activation of the exact move tool
static TOOL_ACTION moveExact;
@ -161,9 +164,6 @@ public:
static TOOL_ACTION routerInlineDrag;
// Point Editor
/// Update edit points
static TOOL_ACTION pointEditorUpdate;
/// Break outline (insert additional points to an edge)
static TOOL_ACTION pointEditorAddCorner;

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>
@ -49,8 +50,8 @@
#include <class_module.h>
DRAWING_TOOL::DRAWING_TOOL() :
TOOL_INTERACTIVE( "pcbnew.InteractiveDrawing" ), m_view( NULL ),
m_controls( NULL ), m_board( NULL ), m_frame( NULL ), m_editModules( false ), m_lineWidth( 1 )
PCB_TOOL( "pcbnew.InteractiveDrawing" ), m_view( NULL ),
m_controls( NULL ), m_board( NULL ), m_frame( NULL ), m_lineWidth( 1 )
{
}
@ -66,61 +67,34 @@ void DRAWING_TOOL::Reset( RESET_REASON aReason )
m_view = getView();
m_controls = getViewControls();
m_board = getModel<BOARD>();
m_frame = getEditFrame<PCB_EDIT_FRAME>();
m_frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
}
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 );
if( m_editModules )
m_frame->SetToolID( m_editModules ? ID_MODEDIT_LINE_TOOL : ID_PCB_ADD_LINE_BUTT,
wxCURSOR_PENCIL, _( "Add graphic line" ) );
while( drawSegment( S_SEGMENT, line, startingPoint ) )
{
m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) );
EDGE_MODULE* line = new EDGE_MODULE( m_board->m_Modules );
while( drawSegment( S_SEGMENT, reinterpret_cast<DRAWSEGMENT*&>( line ), startingPoint ) )
if( line )
{
if( line )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
line->SetParent( m_board->m_Modules );
line->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( line );
startingPoint = line->GetEnd();
}
else
{
startingPoint = boost::none;
}
line = new EDGE_MODULE( m_board->m_Modules );
commit.Add( line );
commit.Push( _( "Draw a line segment" ) );
startingPoint = line->GetEnd();
}
}
else // !m_editModules case
{
m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) );
DRAWSEGMENT* line = new DRAWSEGMENT;
while( drawSegment( S_SEGMENT, line, startingPoint ) )
else
{
if( line )
{
m_board->Add( line );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( line, UR_NEW );
startingPoint = line->GetEnd();
}
else
{
startingPoint = boost::none;
}
line = new DRAWSEGMENT;
startingPoint = boost::none;
}
line = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
}
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
@ -131,43 +105,22 @@ int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
{
if( m_editModules )
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" ) );
while( drawSegment( S_CIRCLE, circle ) )
{
m_frame->SetToolID( ID_MODEDIT_CIRCLE_TOOL, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
EDGE_MODULE* circle = new EDGE_MODULE( m_board->m_Modules );
while( drawSegment( S_CIRCLE, reinterpret_cast<DRAWSEGMENT*&>( circle ) ) )
if( circle )
{
if( circle )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
circle->SetParent( m_board->m_Modules );
circle->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( circle );
}
circle = new EDGE_MODULE( m_board->m_Modules );
commit.Add( circle );
commit.Push( _( "Draw a circle" ) );
}
}
else // !m_editModules case
{
m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) );
DRAWSEGMENT* circle = new DRAWSEGMENT;
while( drawSegment( S_CIRCLE, circle ) )
{
if( circle )
{
m_board->Add( circle );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( circle, UR_NEW );
}
circle = new DRAWSEGMENT;
}
circle = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
}
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
@ -178,43 +131,22 @@ int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
{
if( m_editModules )
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" ) );
while( drawArc( arc ) )
{
m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
EDGE_MODULE* arc = new EDGE_MODULE( m_board->m_Modules );
while( drawArc( reinterpret_cast<DRAWSEGMENT*&>( arc ) ) )
if( arc )
{
if( arc )
{
m_frame->OnModify();
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
arc->SetParent( m_board->m_Modules );
arc->SetLocalCoord();
m_board->m_Modules->GraphicalItems().PushFront( arc );
}
arc = new EDGE_MODULE( m_board->m_Modules );
commit.Add( arc );
commit.Push( _( "Draw an arc" ) );
}
}
else // !m_editModules case
{
m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) );
DRAWSEGMENT* arc = new DRAWSEGMENT;
while( drawArc( arc ) )
{
if( arc )
{
m_board->Add( arc );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( arc, UR_NEW );
}
arc = new DRAWSEGMENT;
}
arc = m_editModules ? new EDGE_MODULE( (MODULE*) parent ) : new DRAWSEGMENT;
}
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
@ -225,22 +157,167 @@ int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
{
if( m_editModules )
return placeTextModule();
else
return placeTextPcb();
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 );
m_view->Add( &preview );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
// do not capture or auto-pan until we start placing some text
Activate();
m_frame->SetToolID( m_editModules ? ID_MODEDIT_TEXT_TOOL : ID_PCB_ADD_TEXT_BUTT,
wxCURSOR_PENCIL, _( "Add text" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
{
if( text )
{
// Delete the old text and have another try
delete text;
text = NULL;
preview.Clear();
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_controls->ShowCursor( true );
}
else
break;
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( text && evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
preview.ViewUpdate();
}
// TODO rotate CCW
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
{
text->Flip( text->GetPosition() );
preview.ViewUpdate();
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !text )
{
// Init the new item attributes
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 ) );
DialogEditModuleText textDialog( m_frame, textMod, NULL );
bool placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
if( !placing )
text = textMod;
else
delete textMod;
}
else
{
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 )
continue;
m_controls->CaptureCursor( true );
m_controls->SetAutoPan( true );
//m_controls->ShowCursor( false );
preview.Add( text );
}
else
{
//assert( text->GetText().Length() > 0 );
//assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
text->ClearFlags();
preview.Remove( text );
commit.Add( text );
commit.Push( _( "Place a text" ) );
m_controls->CaptureCursor( false );
m_controls->SetAutoPan( false );
m_controls->ShowCursor( true );
text = NULL;
}
}
else if( text && evt->IsMotion() )
{
text->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Show a preview of the item
preview.ViewUpdate();
}
}
m_controls->ShowCursor( false );
m_controls->SetSnapping( false );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_view->Remove( &preview );
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
{
DIMENSION* dimension = NULL;
BOARD_COMMIT commit( m_frame );
int maxThickness;
// if one day it is possible to draw dimensions in the footprint editor,
// then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
assert( !m_editModules );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
@ -271,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;
@ -355,14 +431,11 @@ int DRAWING_TOOL::DrawDimension( const TOOL_EVENT& aEvent )
assert( dimension->GetOrigin() != dimension->GetEnd() );
assert( dimension->GetWidth() > 0 );
m_view->Add( dimension );
m_board->Add( dimension );
//dimension->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( dimension, UR_NEW );
preview.Remove( dimension );
commit.Add( dimension );
commit.Push( _( "Draw a dimension" ) );
}
}
break;
@ -435,7 +508,7 @@ int DRAWING_TOOL::DrawKeepout( const TOOL_EVENT& aEvent )
int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
{
if( m_editModules && !m_board->m_Modules )
if( !m_frame->GetModel() )
return 0;
DIALOG_DXF_IMPORT dlg( m_frame );
@ -451,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 )
@ -488,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 )
@ -513,33 +588,32 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
else if( evt->IsClick( BUT_LEFT ) )
{
// Place the drawing
if( m_editModules )
PICKED_ITEMS_LIST picklist;
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(); it != preview.End(); ++it )
{
assert( m_board->m_Modules );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_board->m_Modules->SetLastEditTime();
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
if( m_editModules )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
BOARD_ITEM* converted = NULL;
// Modules use different types for the same things,
// so we need to convert imported items to appropriate classes.
BOARD_ITEM* converted = NULL;
switch( item->Type() )
{
case PCB_TEXT_T:
converted = new TEXTE_MODULE( m_board->m_Modules );
converted = new TEXTE_MODULE( (MODULE*) parent );
// Copy coordinates, layer, etc.
*static_cast<TEXTE_PCB*>( converted ) = *static_cast<TEXTE_PCB*>( item );
static_cast<TEXTE_MODULE*>( converted )->SetLocalCoord();
*static_cast<BOARD_ITEM*>( converted ) = *static_cast<BOARD_ITEM*>( item );
break;
case PCB_LINE_T:
converted = new EDGE_MODULE( m_board->m_Modules );
converted = new EDGE_MODULE( (MODULE*) parent );
// Copy coordinates, layer, etc.
*static_cast<DRAWSEGMENT*>( converted ) = *static_cast<DRAWSEGMENT*>( item );
static_cast<EDGE_MODULE*>( converted )->SetLocalCoord();
break;
default:
@ -548,33 +622,13 @@ int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
}
delete item;
if( converted )
{
m_board->m_Modules->Add( converted );
m_view->Add( converted );
}
}
}
else // !m_editModules case
{
PICKED_ITEMS_LIST picklist;
for( KIGFX::VIEW_GROUP::const_iter it = preview.Begin(), end = preview.End(); it != end; ++it )
{
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( *it );
m_board->Add( item );
ITEM_PICKER itemWrapper( item, UR_NEW );
picklist.PushItem( itemWrapper );
m_view->Add( item );
item = converted;
}
m_frame->SaveCopyInUndoList( picklist, UR_NEW );
commit.Add( item );
}
m_frame->OnModify();
commit.Push( _( "Place a DXF drawing" ) );
break;
}
}
@ -608,15 +662,16 @@ int DRAWING_TOOL::SetAnchor( const TOOL_EVENT& aEvent )
{
if( evt->IsClick( BUT_LEFT ) )
{
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_board->m_Modules->SetLastEditTime();
MODULE* module = (MODULE*) m_frame->GetModel();
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 = m_board->m_Modules->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
m_board->m_Modules->MoveAnchorPosition( moveVector );
wxPoint moveVector = module->GetPosition() - wxPoint( cursorPos.x, cursorPos.y );
module->MoveAnchorPosition( moveVector );
m_board->m_Modules->ViewUpdate();
commit.Push( _( "Move the footprint reference anchor" ) );
// Usually, we do not need to change twice the anchor position,
// so deselect the active tool
@ -751,51 +806,25 @@ bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic,
( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) )
// User has clicked twice in the same spot
{ // a clear sign that the current drawing is finished
// Now we have to add the helper line as well
if( direction45 )
{
// Now we have to add the helper line as well
if( m_editModules )
{
EDGE_MODULE* l = new EDGE_MODULE( m_board->m_Modules );
BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();
DRAWSEGMENT* l = m_editModules ? new EDGE_MODULE( (MODULE*) parent )
: new DRAWSEGMENT;
// Copy coordinates, layer, etc.
*static_cast<DRAWSEGMENT*>( l ) = line45;
l->SetEnd( aGraphic->GetStart() );
l->SetLocalCoord();
// Copy coordinates, layer, etc.
*static_cast<DRAWSEGMENT*>( l ) = line45;
l->SetEnd( aGraphic->GetStart() );
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_board->m_Modules->SetLastEditTime();
m_board->m_Modules->GraphicalItems().PushFront( l );
m_view->Add( l );
l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else
{
DRAWSEGMENT* l = static_cast<DRAWSEGMENT*>( line45.Clone() );
l->SetEnd( aGraphic->GetStart() );
m_frame->SaveCopyInUndoList( l, UR_NEW );
m_board->Add( l );
m_view->Add( l );
l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
m_frame->OnModify();
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;
@ -882,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;
@ -1031,10 +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
// if one day it is possible to draw zones in the footprint editor,
// then hereby I'm letting you know that this tool does not handle UR_MODEDIT undo yet
assert( !m_editModules );
BOARD_COMMIT commit( m_frame );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
@ -1118,17 +1143,11 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
zone->Outline()->CloseLastContour();
zone->Outline()->RemoveNullSegments();
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 );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( zone, UR_NEW );
commit.Add( zone );
commit.Push( _( "Draw a zone" ) );
zone = NULL;
}
@ -1246,248 +1265,6 @@ int DRAWING_TOOL::drawZone( bool aKeepout )
}
int DRAWING_TOOL::placeTextModule()
{
TEXTE_MODULE* text = new TEXTE_MODULE( NULL );
const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
assert( m_editModules );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
// do not capture or auto-pan until we start placing some text
Activate();
m_frame->SetToolID( ID_MODEDIT_TEXT_TOOL, wxCURSOR_PENCIL, _( "Add text" ) );
bool placing = false;
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
{
preview.Clear();
preview.ViewUpdate();
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_controls->ShowCursor( true );
if( !placing || evt->IsActivate() )
{
delete text;
break;
}
else
{
placing = false; // start from the beginning
}
}
else if( text && evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
{
text->Flip( text->GetPosition() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !placing )
{
text->SetSize( dsnSettings.m_ModuleTextSize );
text->SetThickness( dsnSettings.m_ModuleTextWidth );
text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
DialogEditModuleText textDialog( m_frame, text, NULL );
placing = textDialog.ShowModal() && ( text->GetText().Length() > 0 );
if( !placing )
continue;
m_controls->CaptureCursor( true );
m_controls->SetAutoPan( true );
m_controls->ShowCursor( false );
text->SetParent( m_board->m_Modules ); // it has to set after the settings dialog
// otherwise the dialog stores it in undo buffer
preview.Add( text );
}
else
{
assert( text->GetText().Length() > 0 );
assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
text->SetLocalCoord();
text->ClearFlags();
// Module has to be saved before any modification is made
m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT );
m_board->m_Modules->SetLastEditTime();
m_board->m_Modules->GraphicalItems().PushFront( text );
m_view->Add( text );
text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
preview.Remove( text );
m_controls->CaptureCursor( false );
m_controls->SetAutoPan( false );
m_controls->ShowCursor( true );
text = new TEXTE_MODULE( NULL );
placing = false;
}
}
else if( text && evt->IsMotion() )
{
text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Show a preview of the item
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
m_controls->ShowCursor( false );
m_controls->SetSnapping( false );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_view->Remove( &preview );
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
int DRAWING_TOOL::placeTextPcb()
{
TEXTE_PCB* text = NULL;
assert( !m_editModules );
// Add a VIEW_GROUP that serves as a preview for the new item
KIGFX::VIEW_GROUP preview( m_view );
m_view->Add( &preview );
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_controls->ShowCursor( true );
m_controls->SetSnapping( true );
// do not capture or auto-pan until we start placing some text
Activate();
m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) );
// Main loop: keep receiving events
while( OPT_TOOL_EVENT evt = Wait() )
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();
if( evt->IsCancel() || evt->IsActivate() )
{
if( text )
{
// Delete the old text and have another try
m_board->Delete( text ); // it was already added by CreateTextPcb()
text = NULL;
preview.Clear();
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_controls->ShowCursor( true );
}
else
break;
if( evt->IsActivate() ) // now finish unconditionally
break;
}
else if( text && evt->Category() == TC_COMMAND )
{
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
{
text->Flip( text->GetPosition() );
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
else if( evt->IsClick( BUT_LEFT ) )
{
if( !text )
{
// Init the new item attributes
text = static_cast<PCB_EDIT_FRAME*>( m_frame )->CreateTextePcb( NULL );
if( text == NULL )
continue;
m_controls->CaptureCursor( true );
m_controls->SetAutoPan( true );
preview.Add( text );
}
else
{
assert( text->GetText().Length() > 0 );
assert( text->GetSize().x > 0 && text->GetSize().y > 0 );
text->ClearFlags();
m_view->Add( text );
// m_board->Add( text ); // it is already added by CreateTextePcb()
text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_frame->OnModify();
m_frame->SaveCopyInUndoList( text, UR_NEW );
preview.Remove( text );
m_controls->CaptureCursor( false );
m_controls->SetAutoPan( false );
text = NULL;
}
}
else if( text && evt->IsMotion() )
{
text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );
// Show a preview of the item
preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
}
}
m_controls->ShowCursor( false );
m_controls->SetSnapping( false );
m_controls->SetAutoPan( false );
m_controls->CaptureCursor( false );
m_view->Remove( &preview );
m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );
return 0;
}
void DRAWING_TOOL::make45DegLine( DRAWSEGMENT* aSegment, DRAWSEGMENT* aHelper ) const
{
VECTOR2I cursorPos = m_controls->GetCursorPosition();

View File

@ -25,7 +25,7 @@
#ifndef __DRAWING_TOOL_H
#define __DRAWING_TOOL_H
#include <tool/tool_interactive.h>
#include <tools/pcb_tool.h>
#include <boost/optional.hpp>
namespace KIGFX
@ -34,7 +34,7 @@ namespace KIGFX
class VIEW_CONTROLS;
}
class BOARD;
class PCB_EDIT_FRAME;
class PCB_BASE_EDIT_FRAME;
class DRAWSEGMENT;
/**
@ -43,7 +43,7 @@ class DRAWSEGMENT;
* Tool responsible for drawing graphical elements like lines, arcs, circles, etc.
*/
class DRAWING_TOOL : public TOOL_INTERACTIVE
class DRAWING_TOOL : public PCB_TOOL
{
public:
DRAWING_TOOL();
@ -121,17 +121,6 @@ public:
*/
int SetAnchor( const TOOL_EVENT& aEvent );
/**
* Function EditModules()
* Toggles edit module mode. When enabled, one may select parts of modules individually
* (graphics, pads, etc.), so they can be modified.
* @param aEnabled decides if the mode should be enabled.
*/
void EditModules( bool aEnabled )
{
m_editModules = aEnabled;
}
///> Sets up handlers for various events.
void SetTransitions();
@ -156,20 +145,6 @@ private:
///> @param aKeepout decides if the drawn polygon is a zone or a keepout area.
int drawZone( bool aKeepout );
/**
* Function placeTextModule()
* Displays a dialog that allows to input text and its settings and then lets the user decide
* where to place the text in module .
*/
int placeTextModule();
/**
* Function placeTextPcb()
* Displays a dialog that allows to input text and its settings and then lets the user decide
* where to place the text in board editor.
*/
int placeTextPcb();
/**
* Function make45DegLine()
* Forces a DRAWSEGMENT to be drawn at multiple of 45 degrees. The origin stays the same,
@ -185,10 +160,7 @@ private:
KIGFX::VIEW* m_view;
KIGFX::VIEW_CONTROLS* m_controls;
BOARD* m_board;
PCB_EDIT_FRAME* m_frame;
/// Edit module mode flag
bool m_editModules;
PCB_BASE_EDIT_FRAME* m_frame;
/// Stores the current line width for multisegment drawing.
unsigned int m_lineWidth;

View File

@ -56,10 +56,11 @@ 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() :
TOOL_INTERACTIVE( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
m_dragging( false ), m_editModules( false ), m_undoInhibit( 0 ),
m_updateFlag( KIGFX::VIEW_ITEM::NONE )
PCB_TOOL( "pcbnew.InteractiveEdit" ), m_selectionTool( NULL ),
m_dragging( false ), m_updateFlag( KIGFX::VIEW_ITEM::NONE )
{
}
@ -68,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 ) );
}
@ -111,9 +115,6 @@ bool EDIT_TOOL::invokeInlineRouter()
TRACK* track = uniqueSelected<TRACK>();
VIA* via = uniqueSelected<VIA>();
if( isUndoInhibited() )
return false;
if( track || via )
{
ROUTER_TOOL* theRouter = static_cast<ROUTER_TOOL*>( m_toolMgr->FindTool( "pcbnew.InteractiveRouter" ) );
@ -143,7 +144,7 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
// Be sure that there is at least one item that we can modify. If nothing was selected before,
// try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
if( !hoverSelection( selection ) )
if( !hoverSelection() )
return 0;
Activate();
@ -215,11 +216,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();
@ -244,17 +244,18 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
controls->SetAutoPan( true );
m_dragging = true;
incUndoInhibit();
}
}
selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
}
// Dispatch TOOL_ACTIONs
else if( evt->Category() == TC_COMMAND )
{
wxPoint modPoint = getModificationPoint( selection );
if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
{
Rotate( aEvent );
@ -302,6 +303,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 ) )
@ -313,31 +322,17 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
}
} while( ( evt = Wait() ) ); //Should be assignment not equality test
if( m_dragging )
decUndoInhibit();
m_dragging = false;
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 );
@ -354,7 +349,7 @@ int EDIT_TOOL::Properties( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection, false ) )
if( !hoverSelection( false ) )
return 0;
// Tracks & vias are treated in a special way:
@ -364,17 +359,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
@ -382,34 +368,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 @todo LEGACY
// 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::editModifiedSelection, true );
item->SetFlags( flags );
}
@ -428,43 +398,26 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
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( !m_dragging )
m_commit->Push( _( "Rotate" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
// TODO selectionModified
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
return 0;
}
@ -473,47 +426,29 @@ 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();
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
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( !m_dragging )
m_commit->Push( _( "Flip" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
return 0;
}
@ -521,126 +456,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( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
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 );
// Save them
for( unsigned int i = 0; i < selectedItems.GetCount(); ++i )
selectedItems.SetPickedItemStatus( UR_DELETED, i );
for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
{
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
m_commit->Remove( item );
}
editFrame->OnModify();
editFrame->SaveCopyInUndoList( selectedItems, UR_DELETED );
// 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;
}
if( m_editModules )
{
MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
module->SetLastEditTime();
board->m_Status_Pcb = 0; // it is done in the legacy view
aItem->DeleteStructure();
}
return;
}
case PCB_PAD_T:
case PCB_MODULE_EDGE_T:
{
MODULE* module = static_cast<MODULE*>( aItem->GetParent() );
module->SetLastEditTime();
board->m_Status_Pcb = 0; // it is done in the legacy view
if( !m_editModules )
{
getView()->Remove( aItem );
board->Remove( aItem );
}
aItem->DeleteStructure();
return;
}
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 );
board->Remove( aItem );
}
int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
{
const SELECTION& selection = m_selectionTool->GetSelection();
@ -648,7 +484,7 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent )
// Shall the selection be cleared at the end?
bool unselect = selection.Empty();
if( !hoverSelection( selection ) || m_selectionTool->CheckLock() == SELECTION_LOCKED )
if( !hoverSelection() || m_selectionTool->CheckLock() == SELECTION_LOCKED )
return 0;
wxPoint translation;
@ -661,13 +497,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 );
@ -675,6 +504,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 );
@ -682,17 +512,12 @@ 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();
m_commit->Push( _( "Move exact" ) );
if( unselect )
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
m_toolMgr->RunAction( COMMON_ACTIONS::editModifiedSelection, true );
}
return 0;
@ -710,21 +535,11 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
const SELECTION& selection = selTool->GetSelection();
// Be sure that there is at least one item that we can modify
if( !hoverSelection( selection ) )
if( !hoverSelection() )
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();
// 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
// the original
incUndoInhibit();
if( m_editModules )
editFrame->SaveCopyInUndoList( editFrame->GetBoard()->m_Modules, UR_MODEDIT );
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
std::vector<BOARD_ITEM*> old_items;
@ -748,7 +563,7 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
BOARD_ITEM* new_item = NULL;
if( m_editModules )
new_item = editFrame->GetBoard()->m_Modules->DuplicateAndAddItem( item, increment );
new_item = editFrame->GetBoard()->m_Modules->Duplicate( item, increment );
else
{
#if 0
@ -757,18 +572,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()->DuplicateAndAddItem( item );
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 );
@ -776,22 +585,17 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
}
// record the new items as added
if( !m_editModules && !selection.Empty() )
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 );
}
// and re-enable undos
decUndoInhibit();
return 0;
};
@ -801,11 +605,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 )
{}
@ -848,24 +650,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;
};
@ -877,18 +668,12 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent )
const SELECTION& selection = selTool->GetSelection();
// pick up items under the cursor if needed
if( !hoverSelection( selection ) )
if( !hoverSelection() )
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;
@ -947,9 +732,11 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
}
bool EDIT_TOOL::hoverSelection( const SELECTION& aSelection, bool aSanitize )
bool EDIT_TOOL::hoverSelection( bool aSanitize )
{
if( aSelection.Empty() ) // Try to find an item that could be modified
const SELECTION& selection = m_selectionTool->GetSelection();
if( selection.Empty() ) // Try to find an item that could be modified
{
m_toolMgr->RunAction( COMMON_ACTIONS::selectionCursor, true );
@ -963,79 +750,10 @@ bool EDIT_TOOL::hoverSelection( const SELECTION& aSelection, bool aSanitize )
if( aSanitize )
m_selectionTool->SanitizeSelection();
if( aSelection.Empty() ) // TODO is it necessary?
if( selection.Empty() ) // TODO is it necessary?
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
return !aSelection.Empty();
}
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 );
// fall through
case UR_MODEDIT:
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;
}
}
return !selection.Empty();
}
@ -1044,7 +762,7 @@ int EDIT_TOOL::editFootprintInFpEditor( const TOOL_EVENT& aEvent )
const SELECTION& selection = m_selectionTool->GetSelection();
bool unselect = selection.Empty();
if( !hoverSelection( selection ) )
if( !hoverSelection() )
return 0;
MODULE* mod = uniqueSelected<MODULE>();
@ -1054,7 +772,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

@ -27,9 +27,10 @@
#define __EDIT_TOOL_H
#include <math/vector2d.h>
#include <tool/tool_interactive.h>
#include <tools/pcb_tool.h>
#include <view/view_group.h>
class BOARD_COMMIT;
class BOARD_ITEM;
class SELECTION_TOOL;
@ -45,7 +46,7 @@ class VIEW_GROUP;
* using the pcbnew.InteractiveSelection tool.
*/
class EDIT_TOOL : public TOOL_INTERACTIVE
class EDIT_TOOL : public PCB_TOOL
{
public:
EDIT_TOOL();
@ -114,17 +115,6 @@ public:
*/
int CreateArray( const TOOL_EVENT& aEvent );
/**
* Function EditModules()
*
* Toggles edit module mode. When enabled, one may select parts of modules individually
* (graphics, pads, etc.), so they can be modified.
* @param aEnabled decides if the mode should be enabled.
*/
void EditModules( bool aEnabled )
{
m_editModules = aEnabled;
}
///> Sets up handlers for various events.
void SetTransitions();
@ -143,15 +133,6 @@ private:
///> of edit reference point).
VECTOR2I m_cursor;
/// Edit module mode flag
bool m_editModules;
/// 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;
@ -172,49 +153,8 @@ private:
wxPoint getModificationPoint( const SELECTION& aSelection );
///> If there are no items currently selected, it tries to choose the item that is under
///> the cursor or displays a disambiguation menu if there are multpile items.
bool hoverSelection( const SELECTION& aSelection, bool aSanitize = true );
///> Processes the current undo buffer since the last change. If the last change does not occur
///> in the current buffer, then the whole list is processed.
void processUndoBuffer( const PICKED_ITEMS_LIST* aLastChange );
///> Updates items stored in the list.
void processPickedList( const PICKED_ITEMS_LIST* aList );
/**
* Increments the undo inhibit counter. This will indicate that tools
* should not create an undo point, as another tool is doing it already,
* and considers that its operation is atomic, even if it calls another one
* (for example a duplicate calls a move).
*/
inline void incUndoInhibit()
{
m_undoInhibit++;
}
/**
* Decrements the inhibit counter. An assert is raised if the counter drops
* below zero.
*/
inline void decUndoInhibit()
{
m_undoInhibit--;
wxASSERT_MSG( m_undoInhibit >= 0, wxT( "Undo inhibit count decremented past zero" ) );
}
/**
* Report if the tool manager has been told at least once that undo
* points should not be created. This can be ignored if the undo point
* is still required.
*
* @return true if undo are inhibited
*/
inline bool isUndoInhibited() const
{
return m_undoInhibit > 0;
}
///> the cursor or displays a disambiguation menu if there are multiple items.
bool hoverSelection( bool aSanitize = true );
int editFootprintInFpEditor( const TOOL_EVENT& aEvent );
@ -230,6 +170,8 @@ private:
BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );
return dyn_cast<T*>( item );
}
std::unique_ptr<BOARD_COMMIT> m_commit;
};
#endif

Some files were not shown because too many files have changed in this diff Show More