Added CHT_DONE flag to COMMIT::Stage to skip add/remove step

This commit is contained in:
Maciej Suminski 2016-08-18 16:28:04 +02:00
parent 6701b80f77
commit 65b1225231
3 changed files with 75 additions and 24 deletions

View File

@ -42,15 +42,19 @@ COMMIT::~COMMIT()
COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
{
switch( 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 );
makeEntry( aItem, CHT_ADD | flag );
return *this;
case CHT_REMOVE:
makeEntry( aItem, CHT_REMOVE );
makeEntry( aItem, CHT_REMOVE | flag );
return *this;
case CHT_MODIFY:
@ -58,9 +62,9 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item already modifed once
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY, parent->Clone() );
makeEntry( parent, CHT_MODIFY | flag, parent->Clone() );
return *this;
}
@ -78,7 +82,7 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, EDA_ITEM* aCopy )
EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() )
return *this; // item already modifed once
return *this; // item has been already modified once
makeEntry( parent, CHT_MODIFY, aCopy );
@ -131,7 +135,7 @@ COMMIT& COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, UNDO_REDO_T aModFlag )
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_MODIFY ) );
assert( !!aCopy == ( ( aType & CHT_TYPE ) == CHT_MODIFY ) );
COMMIT_LINE ent;
@ -144,7 +148,7 @@ void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
}
COMMIT::CHANGE_TYPE COMMIT::convert( UNDO_REDO_T aType ) const
CHANGE_TYPE COMMIT::convert( UNDO_REDO_T aType ) const
{
switch( aType )
{

View File

@ -32,6 +32,32 @@
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
*
@ -44,13 +70,6 @@ class EDA_ITEM;
class COMMIT
{
public:
///> types of changes.
enum CHANGE_TYPE {
CHT_ADD = 0,
CHT_REMOVE = 1,
CHT_MODIFY = 2
};
COMMIT();
virtual ~COMMIT();
@ -60,12 +79,24 @@ public:
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 )

View File

@ -68,6 +68,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
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
@ -82,7 +84,7 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
{
if( !ent.m_copy )
{
assert( ent.m_type != CHT_MODIFY ); // too late to make a copy..
assert( changeType != CHT_MODIFY ); // too late to make a copy..
ent.m_copy = ent.m_item->Clone();
}
@ -99,14 +101,17 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
}
}
switch( ent.m_type )
switch( changeType )
{
case CHT_ADD:
{
if( !m_editModules )
{
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) );
board->Add( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->Add( boardItem );
//ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add()
if( boardItem->Type() == PCB_MODULE_T )
@ -117,8 +122,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
}
else
{
// modules inside modules are not supported yet
assert( boardItem->Type() != PCB_MODULE_T );
board->m_Modules->Add( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->m_Modules->Add( boardItem );
}
view->Add( boardItem );
@ -174,9 +182,12 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
{
view->Remove( boardItem );
MODULE* module = static_cast<MODULE*>( boardItem->GetParent() );
assert( module && module->Type() == PCB_MODULE_T );
module->Delete( 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?)
}
@ -195,7 +206,10 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
case PCB_ZONE_T: // SEG_ZONE items are now deprecated
case PCB_ZONE_AREA_T:
view->Remove( boardItem );
board->Remove( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->Remove( boardItem );
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
break;
@ -209,7 +223,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module );
board->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;