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 ) 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: case CHT_ADD:
assert( m_changedItems.find( aItem ) == m_changedItems.end() ); assert( m_changedItems.find( aItem ) == m_changedItems.end() );
makeEntry( aItem, CHT_ADD ); makeEntry( aItem, CHT_ADD | flag );
return *this; return *this;
case CHT_REMOVE: case CHT_REMOVE:
makeEntry( aItem, CHT_REMOVE ); makeEntry( aItem, CHT_REMOVE | flag );
return *this; return *this;
case CHT_MODIFY: case CHT_MODIFY:
@ -58,9 +62,9 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType )
EDA_ITEM* parent = parentObject( aItem ); EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() ) 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; return *this;
} }
@ -78,7 +82,7 @@ COMMIT& COMMIT::Stage( EDA_ITEM* aItem, EDA_ITEM* aCopy )
EDA_ITEM* parent = parentObject( aItem ); EDA_ITEM* parent = parentObject( aItem );
if( m_changedItems.find( parent ) != m_changedItems.end() ) 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 ); 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 ) void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE aType, EDA_ITEM* aCopy )
{ {
// Expect an item copy if it is going to be modified // 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; 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 ) switch( aType )
{ {

View File

@ -32,6 +32,32 @@
class EDA_ITEM; 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 * Class COMMIT
* *
@ -44,13 +70,6 @@ class EDA_ITEM;
class COMMIT class COMMIT
{ {
public: public:
///> types of changes.
enum CHANGE_TYPE {
CHT_ADD = 0,
CHT_REMOVE = 1,
CHT_MODIFY = 2
};
COMMIT(); COMMIT();
virtual ~COMMIT(); virtual ~COMMIT();
@ -60,12 +79,24 @@ public:
return Stage( aItem, CHT_ADD ); 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 ///> Removes a new item from the model
COMMIT& Remove( EDA_ITEM* aItem ) COMMIT& Remove( EDA_ITEM* aItem )
{ {
return Stage( aItem, CHT_REMOVE ); 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. ///> Modifies a given item in the model.
///> Must be called before modification is performed. ///> Must be called before modification is performed.
COMMIT& Modify( EDA_ITEM* aItem ) COMMIT& Modify( EDA_ITEM* aItem )

View File

@ -68,6 +68,8 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
for( COMMIT_LINE& ent : m_changes ) 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 ); BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item );
// Module items need to be saved in the undo buffer before modification // 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 ) 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(); 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: case CHT_ADD:
{ {
if( !m_editModules ) if( !m_editModules )
{ {
undoList.PushItem( ITEM_PICKER( boardItem, UR_NEW ) ); 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() //ratsnest->Add( boardItem ); // TODO currently done by BOARD::Add()
if( boardItem->Type() == PCB_MODULE_T ) if( boardItem->Type() == PCB_MODULE_T )
@ -117,8 +122,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
} }
else else
{ {
// modules inside modules are not supported yet
assert( boardItem->Type() != PCB_MODULE_T ); assert( boardItem->Type() != PCB_MODULE_T );
board->m_Modules->Add( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->m_Modules->Add( boardItem );
} }
view->Add( boardItem ); view->Add( boardItem );
@ -174,9 +182,12 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
{ {
view->Remove( boardItem ); view->Remove( boardItem );
MODULE* module = static_cast<MODULE*>( boardItem->GetParent() ); if( !( changeFlags & CHT_DONE ) )
assert( module && module->Type() == PCB_MODULE_T ); {
module->Delete( boardItem ); 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?) 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_T: // SEG_ZONE items are now deprecated
case PCB_ZONE_AREA_T: case PCB_ZONE_AREA_T:
view->Remove( boardItem ); view->Remove( boardItem );
board->Remove( boardItem );
if( !( changeFlags & CHT_DONE ) )
board->Remove( boardItem );
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove() //ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
break; break;
@ -209,7 +223,9 @@ void BOARD_COMMIT::Push( const wxString& aMessage )
module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); module->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
view->Remove( module ); 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 // Clear flags to indicate, that the ratsnest, list of nets & pads are not valid anymore
board->m_Status_Pcb = 0; board->m_Status_Pcb = 0;