Added classes COMMIT & BOARD_COMMIT.

This commit is contained in:
Tomasz Wlostowski 2016-05-10 17:57:21 +02:00 committed by Maciej Suminski
parent ff6bdeee4b
commit 9588a7974c
6 changed files with 475 additions and 0 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

97
common/commit.cpp Normal file
View File

@ -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 );
}

113
common/commit.h Normal file
View File

@ -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

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

215
pcbnew/board_commit.cpp Normal file
View File

@ -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
}

48
pcbnew/board_commit.h Normal file
View File

@ -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