committed by
Maciej Suminski
6 changed files with 475 additions and 0 deletions
-
1common/CMakeLists.txt
-
97common/commit.cpp
-
113common/commit.h
-
1pcbnew/CMakeLists.txt
-
215pcbnew/board_commit.cpp
-
48pcbnew/board_commit.h
@ -0,0 +1,97 @@ |
|||||
|
/*
|
||||
|
* 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 <commit.h>
|
||||
|
#include <class_undoredo_container.h>
|
||||
|
|
||||
|
#include <boost/foreach.hpp>
|
||||
|
|
||||
|
COMMIT::COMMIT() |
||||
|
{ |
||||
|
m_committed = false; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
COMMIT::~COMMIT() |
||||
|
{ |
||||
|
if( !m_committed ) |
||||
|
{ |
||||
|
BOOST_FOREACH( COMMIT_LINE& ent, m_changes ) |
||||
|
{ |
||||
|
if( ent.m_copy ) |
||||
|
delete ent.m_copy; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void COMMIT::makeEntry( EDA_ITEM* aItem, CHANGE_TYPE type, bool saveCopy ) |
||||
|
{ |
||||
|
COMMIT_LINE ent; |
||||
|
|
||||
|
ent.m_item = aItem; |
||||
|
ent.m_type = type; |
||||
|
ent.m_copy = saveCopy ? (EDA_ITEM*) aItem->Clone() : NULL; |
||||
|
|
||||
|
m_changedItems.insert( aItem ); |
||||
|
m_changes.push_back( ent ); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
COMMIT& COMMIT::Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ) |
||||
|
{ |
||||
|
switch( aChangeType ) |
||||
|
{ |
||||
|
case CHT_ADD: |
||||
|
assert( m_changedItems.find( aItem ) == m_changedItems.end() ); |
||||
|
makeEntry( aItem, CHT_ADD, false ); |
||||
|
return *this; |
||||
|
|
||||
|
case CHT_REMOVE: |
||||
|
makeEntry( aItem, CHT_REMOVE, false ); |
||||
|
return *this; |
||||
|
|
||||
|
case CHT_MODIFY: |
||||
|
{ |
||||
|
EDA_ITEM* parent = parentObject( aItem ); |
||||
|
|
||||
|
if( m_changedItems.find( parent ) != m_changedItems.end() ) |
||||
|
return *this; // item already modifed once
|
||||
|
|
||||
|
makeEntry( aItem, CHT_MODIFY, true ); |
||||
|
return *this; |
||||
|
} |
||||
|
|
||||
|
default: |
||||
|
assert( false ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void COMMIT::Stage( const PICKED_ITEMS_LIST& aItems, CHANGE_TYPE aChangeType ) |
||||
|
{ |
||||
|
for( int i = 0; i < aItems.GetCount(); i++ ) |
||||
|
Stage( aItems.GetPickedItem( i ), aChangeType ); |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,113 @@ |
|||||
|
/* |
||||
|
* 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 __COMMIT_H |
||||
|
#define __COMMIT_H |
||||
|
|
||||
|
#include <set> |
||||
|
#include <vector> |
||||
|
#include <base_struct.h> |
||||
|
|
||||
|
#include <boost/foreach.hpp> |
||||
|
|
||||
|
class PICKED_ITEMS_LIST; |
||||
|
|
||||
|
/** |
||||
|
* 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: |
||||
|
///> types of changes. |
||||
|
enum CHANGE_TYPE { |
||||
|
CHT_ADD = 0, |
||||
|
CHT_REMOVE = 1, |
||||
|
CHT_MODIFY = 2 |
||||
|
}; |
||||
|
|
||||
|
COMMIT(); |
||||
|
virtual ~COMMIT(); |
||||
|
|
||||
|
///> Adds a new item to the model |
||||
|
COMMIT& Add( EDA_ITEM* aItem ) |
||||
|
{ |
||||
|
return Stage( aItem, CHT_ADD ); |
||||
|
} |
||||
|
|
||||
|
///> Removes a new item from the model |
||||
|
COMMIT& Remove( EDA_ITEM* aItem ) |
||||
|
{ |
||||
|
return Stage( aItem, CHT_REMOVE ); |
||||
|
} |
||||
|
|
||||
|
///> Modifies a given item in the model. |
||||
|
///> Must be called before modification is performed. |
||||
|
COMMIT& Modify( EDA_ITEM* aItem ) |
||||
|
{ |
||||
|
return Stage( aItem, CHT_MODIFY ); |
||||
|
} |
||||
|
|
||||
|
///> Adds a change of the item aItem of type aChangeType to the change list. |
||||
|
virtual COMMIT& Stage( EDA_ITEM* aItem, CHANGE_TYPE aChangeType ); |
||||
|
|
||||
|
void Stage( std::vector<EDA_ITEM*>& container, CHANGE_TYPE aChangeType ) |
||||
|
{ |
||||
|
BOOST_FOREACH( EDA_ITEM* item, container ) |
||||
|
{ |
||||
|
Stage( item, aChangeType ); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void Stage( const PICKED_ITEMS_LIST& aItems, CHANGE_TYPE aChangeType ); |
||||
|
|
||||
|
///> Executes the changes. |
||||
|
virtual void Push( const wxString& aMessage ) = 0; |
||||
|
|
||||
|
///> Revertes the commit by restoring the modifed items state. |
||||
|
virtual void Revert() = 0; |
||||
|
|
||||
|
protected: |
||||
|
struct COMMIT_LINE |
||||
|
{ |
||||
|
EDA_ITEM *m_item; |
||||
|
EDA_ITEM *m_copy; |
||||
|
CHANGE_TYPE m_type; |
||||
|
}; |
||||
|
|
||||
|
virtual void makeEntry( EDA_ITEM* aItem, CHANGE_TYPE type, bool saveCopy ); |
||||
|
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const = 0; |
||||
|
|
||||
|
bool m_committed; |
||||
|
|
||||
|
std::set<EDA_ITEM*> m_changedItems; |
||||
|
std::vector<COMMIT_LINE> m_changes; |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
@ -0,0 +1,215 @@ |
|||||
|
/*
|
||||
|
* 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/foreach.hpp>
|
||||
|
#include <boost/bind.hpp>
|
||||
|
|
||||
|
#include <tools/pcb_tool.h>
|
||||
|
|
||||
|
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL* aTool ) |
||||
|
{ |
||||
|
m_tool = aTool; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
BOARD_COMMIT::~BOARD_COMMIT() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
void BOARD_COMMIT::Push( const wxString& aMessage ) |
||||
|
{ |
||||
|
// Objects potentially interested in changes:
|
||||
|
PICKED_ITEMS_LIST undoList; |
||||
|
TOOL_MANAGER* toolMgr = m_tool->GetManager(); |
||||
|
KIGFX::VIEW* view = toolMgr->GetView(); |
||||
|
BOARD* board = (BOARD*) toolMgr->GetModel(); |
||||
|
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) toolMgr->GetEditFrame(); |
||||
|
RN_DATA* ratsnest = board->GetRatsnest(); |
||||
|
|
||||
|
bool editModules = m_tool->EditingModules(); |
||||
|
|
||||
|
// Module items need to be saved in the undo buffer before modification
|
||||
|
if( editModules ) |
||||
|
{ |
||||
|
frame->SaveCopyInUndoList( board->m_Modules, UR_CHANGED ); |
||||
|
} |
||||
|
|
||||
|
BOOST_FOREACH( COMMIT_LINE& ent, m_changes ) |
||||
|
{ |
||||
|
BOARD_ITEM* boardItem = static_cast<BOARD_ITEM*>( ent.m_item ); |
||||
|
|
||||
|
switch( ent.m_type ) |
||||
|
{ |
||||
|
case CHT_ADD: |
||||
|
{ |
||||
|
if( !editModules ) |
||||
|
{ |
||||
|
ITEM_PICKER itemWrapper( boardItem, UR_NEW ); |
||||
|
undoList.PushItem( itemWrapper ); |
||||
|
board->Add( boardItem ); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
board->m_Modules->Add( boardItem ); |
||||
|
} |
||||
|
|
||||
|
if( boardItem->Type() == PCB_MODULE_T ) |
||||
|
{ |
||||
|
MODULE* mod = static_cast<MODULE*>( boardItem ); |
||||
|
mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Add, view, _1 ) ); |
||||
|
} |
||||
|
|
||||
|
view->Add( boardItem ); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
case CHT_REMOVE: |
||||
|
{ |
||||
|
if( !editModules ) |
||||
|
{ |
||||
|
ITEM_PICKER itemWrapper( boardItem, UR_DELETED ); |
||||
|
undoList.PushItem( itemWrapper ); |
||||
|
board->Remove( boardItem ); |
||||
|
} else { |
||||
|
board->m_Modules->Remove( boardItem ); |
||||
|
} |
||||
|
|
||||
|
if(boardItem->Type() == PCB_MODULE_T ) |
||||
|
{ |
||||
|
MODULE* mod = static_cast<MODULE*>( boardItem ); |
||||
|
mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) ); |
||||
|
} |
||||
|
|
||||
|
view->Remove( boardItem ); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
case CHT_MODIFY: |
||||
|
{ |
||||
|
if( !editModules ) |
||||
|
{ |
||||
|
ITEM_PICKER itemWrapper( boardItem, UR_CHANGED ); |
||||
|
itemWrapper.SetLink( ent.m_copy ); |
||||
|
undoList.PushItem( itemWrapper ); |
||||
|
} |
||||
|
|
||||
|
if( boardItem->Type() == PCB_MODULE_T ) |
||||
|
{ |
||||
|
MODULE* mod = static_cast<MODULE*>( boardItem ); |
||||
|
//mod->RunOnChildren( boost::bind( &KIGFX::VIEW::Remove, view, _1 ) );
|
||||
|
mod->RunOnChildren( boost::bind( &RN_DATA::Update, ratsnest, _1 ) ); |
||||
|
} |
||||
|
|
||||
|
boardItem->ViewUpdate( KIGFX::VIEW_ITEM::ALL ); |
||||
|
ratsnest->Update( boardItem ); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
default: |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if( !editModules ) |
||||
|
frame->SaveCopyInUndoList( undoList, UR_UNSPECIFIED ); |
||||
|
|
||||
|
frame->OnModify(); |
||||
|
ratsnest->Recalculate(); |
||||
|
|
||||
|
m_committed = true; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
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() |
||||
|
{ |
||||
|
#if 0
|
||||
|
PICKED_ITEMS_LIST undoList; |
||||
|
KIGFX::VIEW* view = m_toolMgr->GetView(); |
||||
|
BOARD *board = (BOARD*) m_toolMgr->GetModel(); |
||||
|
PCB_EDIT_FRAME *frame = (PCB_EDIT_FRAME*) m_toolMgr->GetEditFrame(); |
||||
|
|
||||
|
|
||||
|
BOOST_FOREACH( COMMIT_LINE& ent, m_changes ) |
||||
|
{ |
||||
|
BOARD_ITEM *item = static_cast<BOARD_ITEM *> (ent.m_item); |
||||
|
BOARD_ITEM *copy = static_cast<BOARD_ITEM *> (ent.m_copy); |
||||
|
|
||||
|
if(ent.m_type == CHT_MODIFY) |
||||
|
{ |
||||
|
printf("revert %p\n", item ); |
||||
|
RN_DATA *ratsnest = board->GetRatsnest(); |
||||
|
|
||||
|
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( static_cast<BOARD_ITEM*> ( item ) ); |
||||
|
|
||||
|
item->SwapData( copy ); |
||||
|
|
||||
|
// 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( &KIGFX::VIEW::Add, view, _1 ) ); |
||||
|
} |
||||
|
view->Add( item ); |
||||
|
ratsnest->Add( item ); |
||||
|
|
||||
|
item->ClearFlags( SELECTED ); |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
#endif
|
||||
|
} |
||||
|
|
||||
@ -0,0 +1,48 @@ |
|||||
|
/* |
||||
|
* 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 BOARD_COMMIT : public COMMIT |
||||
|
{ |
||||
|
public: |
||||
|
BOARD_COMMIT( PCB_TOOL* aTool ); |
||||
|
virtual ~BOARD_COMMIT(); |
||||
|
|
||||
|
virtual void Push( const wxString& aMessage ); |
||||
|
virtual void Revert(); |
||||
|
|
||||
|
private: |
||||
|
PCB_TOOL* m_tool; |
||||
|
virtual EDA_ITEM* parentObject( EDA_ITEM* aItem ) const; |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue