r19416 by jghali - rework undotransaction api in order to reduce manual memory management

scribus-commit scribus-commit at lists.scribus.net
Mon Aug 11 04:59:24 UTC 2014


Author: jghali
Date: Mon Aug 11 04:59:24 2014
New Revision: 19416

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=19416
Log:
rework undotransaction api in order to reduce manual memory management

Added:
    trunk/Scribus/scribus/undotransaction.cpp
    trunk/Scribus/scribus/undotransaction.h
Modified:
    trunk/Scribus/scribus/CMakeLists.txt
    trunk/Scribus/scribus/canvasgesture_resize.cpp
    trunk/Scribus/scribus/canvasgesture_resize.h
    trunk/Scribus/scribus/transaction.cpp
    trunk/Scribus/scribus/transaction.h
    trunk/Scribus/scribus/undomanager.cpp
    trunk/Scribus/scribus/undomanager.h
    trunk/Scribus/scribus/undostate.cpp
    trunk/Scribus/scribus/undostate.h
    trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj
    trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj.filters
    trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj
    trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj.filters

Modified: trunk/Scribus/scribus/CMakeLists.txt
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/CMakeLists.txt
==============================================================================
--- trunk/Scribus/scribus/CMakeLists.txt (original)
+++ trunk/Scribus/scribus/CMakeLists.txt Mon Aug 11 04:59:24 2014
@@ -724,6 +724,7 @@
 	undoobject.cpp
 	undostack.cpp
 	undostate.cpp
+	undotransaction.cpp
 	units.cpp
 	updatemanager.cpp
 	upgradechecker.cpp

Modified: trunk/Scribus/scribus/canvasgesture_resize.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/canvasgesture_resize.cpp
==============================================================================
--- trunk/Scribus/scribus/canvasgesture_resize.cpp (original)
+++ trunk/Scribus/scribus/canvasgesture_resize.cpp Mon Aug 11 04:59:24 2014
@@ -37,7 +37,7 @@
 
 ResizeGesture::ResizeGesture (CanvasMode* parent) : CanvasGesture(parent)
 {
-	m_transactionStarted = NULL;
+	m_transaction = UndoTransaction();
 }
 
 void ResizeGesture::prepare(Canvas::FrameHandle framehandle)
@@ -100,11 +100,10 @@
 void ResizeGesture::clear()
 {
 	m_handle = Canvas::OUTSIDE;
-	if (m_transactionStarted)
-	{
-		m_transactionStarted->cancel();
-		delete m_transactionStarted;
-		m_transactionStarted = NULL;
+	if (m_transaction.isStarted())
+	{
+		m_transaction.cancel();
+		m_transaction.reset();
 	}
 }
 
@@ -263,11 +262,10 @@
 			m_doc->changed();
 		}
 	}
-	if (m_transactionStarted)
-	{
-		m_transactionStarted->commit();
-		delete m_transactionStarted;
-		m_transactionStarted = NULL;
+	if (m_transaction.isStarted())
+	{
+		m_transaction.commit();
+		m_transaction.reset();
 	}
 	m->accept();
 	m_canvas->update();
@@ -287,8 +285,8 @@
 		targetName = currItem->getUName();
 		targetIcon = currItem->getUPixmap();
 	}
-	if (!m_transactionStarted)
-		m_transactionStarted = new UndoTransaction(Um::instance()->beginTransaction(targetName, targetIcon, Um::Resize, "", Um::IResize));
+	if (!m_transaction)
+		m_transaction = Um::instance()->beginTransaction(targetName, targetIcon, Um::Resize, "", Um::IResize);
 	QRectF newBounds = m_bounds.normalized();
 	double dw = (newBounds.width() - m_extraWidth) - currItem->width();
 	double dh = (newBounds.height() - m_extraHeight) - currItem->height();

Modified: trunk/Scribus/scribus/canvasgesture_resize.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/canvasgesture_resize.h
==============================================================================
--- trunk/Scribus/scribus/canvasgesture_resize.h (original)
+++ trunk/Scribus/scribus/canvasgesture_resize.h Mon Aug 11 04:59:24 2014
@@ -24,6 +24,7 @@
 #include "canvas.h"
 #include "canvasgesture.h"
 #include "canvasmode.h"
+#include "undotransaction.h"
 
 class QDragEnterEvent;
 class QDragMoveEvent;
@@ -36,7 +37,6 @@
 class QPainter;
 class QRubberBand;
 class PageItem;
-class UndoTransaction;
 
 /**
   This class realizes resizing of selected items on behalf of its parent mode.
@@ -80,7 +80,7 @@
 	QRectF m_bounds;
 	QRectF m_origBounds;
 	QRectF m_mousePressBounds;
-	UndoTransaction* m_transactionStarted;
+	UndoTransaction m_transaction;
 	double m_extraWidth;
 	double m_extraHeight;
 	double m_extraX;

Modified: trunk/Scribus/scribus/transaction.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/transaction.cpp
==============================================================================
--- trunk/Scribus/scribus/transaction.cpp (original)
+++ trunk/Scribus/scribus/transaction.cpp Mon Aug 11 04:59:24 2014
@@ -26,16 +26,7 @@
 
 
 
-#include "transaction.h"
-
-Transaction::~Transaction() 
-{ 
-	if (m_data) 
-	{ 
-// we must not call virtual functions from destructor:		commit(); 
-		delete m_data; 
-	} 
-}	
+#include "transaction.h"	
 
 void Transaction::markFailed()
 {
@@ -47,3 +38,15 @@
 { 
 	return m_data->m_status; 
 }
+
+bool Transaction::isOpened() const
+{
+	if (m_data)
+		return (m_data->m_status == STATE_OPEN);
+	return false;
+}
+
+void Transaction::reset()
+{
+	m_data.reset();
+}

Modified: trunk/Scribus/scribus/transaction.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/transaction.h
==============================================================================
--- trunk/Scribus/scribus/transaction.h (original)
+++ trunk/Scribus/scribus/transaction.h Mon Aug 11 04:59:24 2014
@@ -29,6 +29,8 @@
 
 #include "scribusapi.h"
 
+#include <QSharedData>
+#include <QExplicitlySharedDataPointer>
 
 /**
   Interface class for objects representing a going transaction.
@@ -45,7 +47,11 @@
 		STATE_COMMITTED
 	};
 	
-	struct TransactionStateBase {
+	class TransactionStateBase : public QSharedData
+	{
+	public:
+		virtual ~TransactionStateBase() {};
+
 		Status m_status;
 	};
 	
@@ -55,19 +61,18 @@
 			m_data->m_status = STATE_OPEN;
 	}
 	
-	Transaction(const Transaction& other) : m_data(other.m_data)
-	{
-		const_cast<Transaction&>(other).m_data = 0;  // mean, but necessary so that not both destructors commit/close
-	}
-	
-	
 	/**
 		Automatically commits if forgotten.
 		Override as appropiate. Since the superclass destructor is called last, you
 	    can cancel in the subclass destructor; the commit here then will do nothing.
 	    Don't forget to set m_data to NULL if you free the m_data pointer!
 	 */
-	virtual ~Transaction();
+	virtual ~Transaction() {};
+
+	/**
+		Test if transaction has some valid data 
+	 */
+	operator bool() const { return (m_data.constData() != 0); }
 	
 	/**
 	  Commits this transaction if in STATE_OPEN.
@@ -86,17 +91,24 @@
 		Marks this transaction as failed.
 	 */
 	virtual void markFailed();
-	
+
+	/**
+		Reset underlyng transaciton data
+	 */
+	virtual void reset();
+
 	int getState() const;
+
+	bool isNull() const { return (m_data.constData() == 0); }
+
+	bool isStarted() const { return (m_data.constData() != 0); }
+
+	bool isOpened() const;
 	
 protected:
 	// if you subclass, do *not* add any data members but use this pointer instead,
 	// otherwise the copy initializer will strip your objects.
-	TransactionStateBase*    m_data;
-	
-private:
-	// blocked
-	Transaction& operator= (const Transaction&) { return *this; }
+	QExplicitlySharedDataPointer<TransactionStateBase>    m_data;
 };
 
 #endif

Modified: trunk/Scribus/scribus/undomanager.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/undomanager.cpp
==============================================================================
--- trunk/Scribus/scribus/undomanager.cpp (original)
+++ trunk/Scribus/scribus/undomanager.cpp Mon Aug 11 04:59:24 2014
@@ -39,39 +39,8 @@
 #include "scribuscore.h"
 #include "undogui.h"
 #include "undostack.h"
+#include "undotransaction.h"
 #include "util_icon.h"
-
-
-/**************************************************************************************/
-
-/**
-  This struct is use instead of std::pair<TransactionObject*, TransactionState*> now.
-  Just data, no methods.
-*/
-struct TransactionData : public Transaction::TransactionStateBase
-{
-	TransactionData() {
-		transactionObject = 0;
-		transactionState = 0;
-	}
-
-	~TransactionData() {
-		if (transactionObject)
-			delete transactionObject;
-		if (transactionState)
-			delete transactionState;
-	}
-
-	int stackLevel;
-	UndoManager* UM;
-	UndoObject* transactionObject;  // will be DummyUndoObject
-	TransactionState* transactionState;
-};
-
-
-/**************************************************************************************/
-
-
 
 UndoManager* UndoManager::instance_          = 0;
 bool         UndoManager::undoEnabled_       = true;
@@ -156,133 +125,6 @@
 	
 //	qDebug() << "UndoManager::beginTransaction" << targetName << name << transaction;
 	return UndoTransaction(transaction);
-}
-
-UndoTransaction::UndoTransaction(TransactionData* data) : Transaction(data) 
-{};
-
-UndoTransaction::~UndoTransaction() 
-{
-	if (m_data)
-	{
-		UndoTransaction::cancel(); // no virtual calls in destructor
-		delete m_data; 
-		m_data = 0;
-	}
-}
-
-bool UndoTransaction::cancel()
-{
-	if (!m_data)
-		return false;
-	
-	TransactionData* data = static_cast<TransactionData*>(m_data);
-	UndoManager* UM = data->UM;
-	int stackLevel = data->stackLevel;
-
-	switch (m_data->m_status)
-	{
-		case Transaction::STATE_OPEN:
-		case Transaction::STATE_WILLFAIL:
-//			qDebug() << "UndoManager::cancelTransaction" << data << data->transactionObject->getUName() << data->transactionState->getName() << stackLevel;
-			data->m_status = Transaction::STATE_FAILED;
-			delete data->transactionObject;
-			data->transactionObject = 0;
-			delete data->transactionState;
-			data->transactionState = 0;
-			//brutal for now:
-			assert (stackLevel + 1 == signed(UM->transactions_.size()));
-			if (stackLevel < signed(UM->transactions_.size()))
-			{
-				UM->transactions_.erase(UM->transactions_.begin() + stackLevel);
-			}
-			return true;
-		default:
-			// do nothing;
-//			qDebug() << "UndoManager::cancelTransaction ** already closed **";
-			return false;
-	}
-}
-
-bool UndoTransaction::commit(const QString &targetName,
-							 QPixmap *targetPixmap,
-							 const QString &name,
-							 const QString &description,
-							 QPixmap *actionPixmap)
-{
-	if (m_data && m_data->m_status == Transaction::STATE_OPEN)
-	{
-		TransactionData* data = static_cast<TransactionData*>(m_data);
-		if (targetName.length() > 0)
-			data->transactionObject->setUName(targetName);
-		if (targetPixmap)
-			data->transactionObject->setUPixmap(targetPixmap);
-		if (name.length() > 0)
-			data->transactionState->setName(name);
-		if (description.length() > 0)
-			data->transactionState->setDescription(description);
-		if (actionPixmap)
-			data->transactionState->setPixmap(actionPixmap);
-	}
-	return commit();
-}
-				
-	
-bool UndoTransaction::commit()
-{
-	if (!m_data)
-		return false;
-	TransactionData* data = static_cast<TransactionData*>(m_data);
-	UndoManager* UM = data->UM;
-	int stackLevel = data->stackLevel;
-
-	if (!UM->undoEnabled_)
-	{
-		cancel();
-		return false;
-	}
-	
-	UndoObject *tmpu = UM->transactions_.at(stackLevel)->transactionObject;
-	TransactionState *tmps = UM->transactions_.at(stackLevel)->transactionState;
-	
-	switch (m_data->m_status)
-	{
-		case Transaction::STATE_OPEN:
-//			qDebug() << "UndoManager::commitTransaction" << data << data->transactionObject->getUName() << data->transactionState->getName() << stackLevel;
-			m_data->m_status = Transaction::STATE_COMMITTED;
-
-			// brutal for now:
-			assert (stackLevel + 1 == signed(UM->transactions_.size()));
-			
-			if (stackLevel < signed(UM->transactions_.size()))
-			{
-				UM->transactions_.erase(UM->transactions_.begin() + stackLevel);
-			}
-				
-			if (tmps->sizet() > 0) // are there any actions inside the commited transaction
-			{
-				if (tmps->getName().isEmpty())
-					tmps->useActionName();
-				UM->action(tmpu, tmps);
-			} // if not just delete objects
-			else
-			{
-				delete tmpu;
-				tmpu = 0;
-				delete tmps;
-				tmps = 0;
-			}
-			return true;
-			break;
-		case STATE_WILLFAIL:
-			return cancel();
-			break;
-		default:
-//			qDebug() << "UndoManager::commitTransaction ** already closed **";
-			// nothing
-			break;
-	}
-	return false;
 }
 
 bool UndoManager::isTransactionMode()
@@ -716,135 +558,6 @@
 		}
 	}
 	stacks_.clear();
-}
-
-/*** TransactionState *****************************************************/
-
-TransactionState::TransactionState() : UndoState("")
-{
-	size_ = 0;
-}
-
-UndoState* TransactionState::at(int index)
-{
-	if (index >= 0 && static_cast<uint>(index) < sizet())
-		return states_[index];
-	else
-		return 0;
-}
-
-bool TransactionState::contains(int uid) const
-{
-	for (uint i = 0; i < states_.size(); ++i)
-	{
-		UndoObject* undoObject = states_[i]->undoObject();
-		if (undoObject && undoObject->getUId() == static_cast<uint>(uid))
-			return true;
-	}
-	return false;
-}
-
-bool TransactionState::containsOnly(int uid) const
-{
-	for (uint i = 0; i < states_.size(); ++i)
-	{
-		UndoObject* undoObject = states_[i]->undoObject();
-		if (undoObject && undoObject->getUId() != static_cast<uint>(uid))
-			return false;
-	}
-	return true;
-}
-
-void TransactionState::pushBack(UndoObject *target, UndoState *state)
-{
-	if (target && state)
-	{
-		state->setUndoObject(target);
-		states_.push_back(state);
-		++size_;
-	}
-}
-
-uint TransactionState::sizet()
-{
-	return size_;
-}
-
-void TransactionState::useActionName()
-{
-	if (size_ > 0)
-		setName(states_[size_ - 1]->getName());
-}
-
-UndoObject* TransactionState::replace(ulong uid, UndoObject *newUndoObject)
-{
-	UndoObject *tmp = 0;
-	for (uint i = 0; i < states_.size(); ++i)
-	{
-		TransactionState *ts = dynamic_cast<TransactionState*>(states_[i]);
-		if (ts) // are we having a transaction_inside a transaction
-			ts->replace(uid, newUndoObject);
-		else if (states_[i]->undoObject() && states_[i]->undoObject()->getUId() == uid)
-		{
-			tmp = states_[i]->undoObject();
-			states_[i]->setUndoObject(newUndoObject);
-		}
-	}
-	return tmp;
-}
-
-void TransactionState::undo() // undo all attached states
-{
-	for (int i = sizet() - 1; i > -1; --i)
-	{
-		if ((sizet() - 1) == 0)
-			at(i)->transactionCode = 0;
-		else
-		{
-			if (i == static_cast<int>(sizet() - 1))
-				at(i)->transactionCode = 1;
-			else if (i == 0)
-				at(i)->transactionCode = 2;
-			else
-				at(i)->transactionCode = 3;
-		}
-		if (transactionCode != 0)
-			at(i)->transactionCode = transactionCode;
-		at(i)->undo();
-	}
-}
-
-void TransactionState::redo() // redo all attached states
-{
-	for (uint i = 0; i < sizet(); ++i)
-	{
-		if ((sizet() - 1) == 0)
-			at(i)->transactionCode = 0;
-		else
-		{
-			if (i == 0)
-				at(i)->transactionCode = 1;
-			else if (i == static_cast<uint>(sizet() - 1))
-				at(i)->transactionCode = 2;
-			else
-				at(i)->transactionCode = 3;
-		}
-		if (transactionCode != 0)
-			at(i)->transactionCode = transactionCode;
-		at(i)->redo();
-	}
-}
-
-TransactionState::~TransactionState()
-{
-	for (uint i = 0; i < states_.size(); ++i)
-	{
-		if (states_[i])
-		{
-			delete states_[i];
-			states_[i] = 0;
-		}
-	}
 }
 
 /*************************************************************************************/

Modified: trunk/Scribus/scribus/undomanager.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/undomanager.h
==============================================================================
--- trunk/Scribus/scribus/undomanager.h (original)
+++ trunk/Scribus/scribus/undomanager.h Mon Aug 11 04:59:24 2014
@@ -30,20 +30,21 @@
 #include <vector>
 #include <utility>
 #include <QObject>
-#include <QPixmap>
 
 #include "scribusapi.h"
 #include "transaction.h"
 #include "undostate.h"
 #include "undoobject.h"
 #include "undostack.h"
+#include "undotransaction.h"
 
 class QString;
 class QPixmap;
 class UndoGui;
 class PrefsContext;
 
-struct TransactionData;
+class TransactionData;
+class UndoTransaction;
 
 /** @brief Key is the doc name, value is it's undo stack */
 typedef QMap<QString, UndoStack> StackMap;
@@ -59,99 +60,6 @@
 
 	TransactionSettings(void) { targetPixmap = actionPixmap = NULL; }  
 };
-
-/**
- * @brief TransactionState provides a container where multiple UndoStates can be stored
- * @brief as a single action which then appears in the attached <code>UndoGui</code>s.
- * @author Riku Leino riku at scribus.info
- * @date January 2005
- */
-class TransactionState : public UndoState
-{
-public:
-	/** @brief Creates a new TransactionState instance */
-	TransactionState();
-	/** @brief Destroys the TransactionState instance */
-	~TransactionState();
-	/** @brief To know if the state is a Transaction */
-	bool isTransaction(){return true;}
-
-	/**
-	 * @brief Add a new <code>UndoState</code> object to the transaction.
-	 * @param state state to be added to the transaction
-	 */
-	void pushBack(UndoObject *target, UndoState *state);
-	/**
-	 * @brief Returns the count of the <code>UndoState</code> objects in this transaction.
-	 * @return count of the <code>UndoState</code> objects in this transaction
-	 */
-	uint sizet();
-	/** @brief Use the name from last action added to this <code>TransactionState</code> */
-	void useActionName();
-	/**
-	 * @brief Returns an <code>UndoState</code> object at <code>index</code>.
-	 * @param index index from where an <code>UndoState</code> object is returned.
-	 * If <code>index</code> is out of scope <code>NULL</code> will be rerturned.
-	 * @return <code>UndoState</code> object from <code>index</code> or <code>NULL</code>
-	 * if <code>index</code> is out of scope.
-	 */
-	UndoState* at(int index);
-	/**
-	 * @brief Returns true if this transaction contains UndoObject with the id <code>uid</code>
-	 * @brief otherwise returns false.
-	 * @return true if this transaction contains UndoObject with the ide <code>uid</code>
-	 * @return otherwise returns false.
-	 */
-	bool contains(int uid) const;
-	
-	/**
-	 * @brief Tells if this transaction contains only UndoObject with ID uid
-	 * 
-	 * If a transaction contains only single UndoObject it will be safe to include
-	 * it in the object specific undo.
-	 * @param uid UndoObject's id to look for
-	 * @return true if this transaction only contains actions of the UndoObject whose
-	 *         id is uid
-	 */
-	bool containsOnly(int uid) const;
-	/**
-	 * @brief Replace object with id uid with new UndoObject newUndoObject.
-	 * @param uid id of the object that is wanted to be replaced
-	 * @param newUndoObject object that is used for replacing
-	 * @return UndoObject which was replaced
-	 */
-	UndoObject* replace(ulong uid, UndoObject *newUndoObject);
-
-	/** @brief undo all UndoStates in this transaction */
-	void undo();
-	/** @brief redo all UndoStates in this transaction */
-	void redo();
-private:
-	/** @brief Number of undo states stored in this transaction */
-	uint size_;
-	/** @brief vector to keep the states in */
-	std::vector<UndoState*> states_;
-};
-
-
-
-/**
-    Class which handles Undo transactions. No data, just methods.
- */
-class SCRIBUS_API UndoTransaction : public Transaction
-{
-public:
-	UndoTransaction(TransactionData* data);
-	virtual ~UndoTransaction();
-	virtual bool commit();
-	virtual bool cancel();
-	bool commit(const QString &targetName,
-				QPixmap *targetPixmap,
-				const QString &name = "",
-				const QString &description = "",
-				QPixmap *actionPixmap = 0);
-};
-
 
 /**
  * @brief UndoManager handles the undo stack.

Modified: trunk/Scribus/scribus/undostate.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/undostate.cpp
==============================================================================
--- trunk/Scribus/scribus/undostate.cpp (original)
+++ trunk/Scribus/scribus/undostate.cpp Mon Aug 11 04:59:24 2014
@@ -197,3 +197,132 @@
 {
 
 }
+
+/*** TransactionState *****************************************************/
+
+TransactionState::TransactionState() : UndoState("")
+{
+	size_ = 0;
+}
+
+UndoState* TransactionState::at(int index)
+{
+	if (index >= 0 && static_cast<uint>(index) < sizet())
+		return states_[index];
+	else
+		return 0;
+}
+
+bool TransactionState::contains(int uid) const
+{
+	for (uint i = 0; i < states_.size(); ++i)
+	{
+		UndoObject* undoObject = states_[i]->undoObject();
+		if (undoObject && undoObject->getUId() == static_cast<uint>(uid))
+			return true;
+	}
+	return false;
+}
+
+bool TransactionState::containsOnly(int uid) const
+{
+	for (uint i = 0; i < states_.size(); ++i)
+	{
+		UndoObject* undoObject = states_[i]->undoObject();
+		if (undoObject && undoObject->getUId() != static_cast<uint>(uid))
+			return false;
+	}
+	return true;
+}
+
+void TransactionState::pushBack(UndoObject *target, UndoState *state)
+{
+	if (target && state)
+	{
+		state->setUndoObject(target);
+		states_.push_back(state);
+		++size_;
+	}
+}
+
+uint TransactionState::sizet()
+{
+	return size_;
+}
+
+void TransactionState::useActionName()
+{
+	if (size_ > 0)
+		setName(states_[size_ - 1]->getName());
+}
+
+UndoObject* TransactionState::replace(ulong uid, UndoObject *newUndoObject)
+{
+	UndoObject *tmp = 0;
+	for (uint i = 0; i < states_.size(); ++i)
+	{
+		TransactionState *ts = dynamic_cast<TransactionState*>(states_[i]);
+		if (ts) // are we having a transaction_inside a transaction
+			ts->replace(uid, newUndoObject);
+		else if (states_[i]->undoObject() && states_[i]->undoObject()->getUId() == uid)
+		{
+			tmp = states_[i]->undoObject();
+			states_[i]->setUndoObject(newUndoObject);
+		}
+	}
+	return tmp;
+}
+
+void TransactionState::undo() // undo all attached states
+{
+	for (int i = sizet() - 1; i > -1; --i)
+	{
+		if ((sizet() - 1) == 0)
+			at(i)->transactionCode = 0;
+		else
+		{
+			if (i == static_cast<int>(sizet() - 1))
+				at(i)->transactionCode = 1;
+			else if (i == 0)
+				at(i)->transactionCode = 2;
+			else
+				at(i)->transactionCode = 3;
+		}
+		if (transactionCode != 0)
+			at(i)->transactionCode = transactionCode;
+		at(i)->undo();
+	}
+}
+
+void TransactionState::redo() // redo all attached states
+{
+	for (uint i = 0; i < sizet(); ++i)
+	{
+		if ((sizet() - 1) == 0)
+			at(i)->transactionCode = 0;
+		else
+		{
+			if (i == 0)
+				at(i)->transactionCode = 1;
+			else if (i == static_cast<uint>(sizet() - 1))
+				at(i)->transactionCode = 2;
+			else
+				at(i)->transactionCode = 3;
+		}
+		if (transactionCode != 0)
+			at(i)->transactionCode = transactionCode;
+		at(i)->redo();
+	}
+}
+
+TransactionState::~TransactionState()
+{
+	for (uint i = 0; i < states_.size(); ++i)
+	{
+		if (states_[i])
+		{
+			delete states_[i];
+			states_[i] = 0;
+		}
+	}
+}

Modified: trunk/Scribus/scribus/undostate.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/scribus/undostate.h
==============================================================================
--- trunk/Scribus/scribus/undostate.h (original)
+++ trunk/Scribus/scribus/undostate.h Mon Aug 11 04:59:24 2014
@@ -27,6 +27,8 @@
 #ifndef UNDOSTATE_H
 #define UNDOSTATE_H
 
+#include <vector>
+
 #include <QMap>
 #include <QPair>
 #include <QPixmap>
@@ -297,6 +299,7 @@
 private:
 	C item_;
 };
+
 /**** ItemsState for list of pointers to items *****/
 //template<class C>
 class ScItemsState : public SimpleState
@@ -312,4 +315,79 @@
 	QMap<QString,void*> pointerMap;
 };
 
+/*** TransactionState ********************************************************************/
+
+/**
+ * @brief TransactionState provides a container where multiple UndoStates can be stored
+ * @brief as a single action which then appears in the attached <code>UndoGui</code>s.
+ * @author Riku Leino riku at scribus.info
+ * @date January 2005
+ */
+class TransactionState : public UndoState
+{
+public:
+	/** @brief Creates a new TransactionState instance */
+	TransactionState();
+	/** @brief Destroys the TransactionState instance */
+	~TransactionState();
+	/** @brief To know if the state is a Transaction */
+	bool isTransaction(){return true;}
+
+	/**
+	 * @brief Add a new <code>UndoState</code> object to the transaction.
+	 * @param state state to be added to the transaction
+	 */
+	void pushBack(UndoObject *target, UndoState *state);
+	/**
+	 * @brief Returns the count of the <code>UndoState</code> objects in this transaction.
+	 * @return count of the <code>UndoState</code> objects in this transaction
+	 */
+	uint sizet();
+	/** @brief Use the name from last action added to this <code>TransactionState</code> */
+	void useActionName();
+	/**
+	 * @brief Returns an <code>UndoState</code> object at <code>index</code>.
+	 * @param index index from where an <code>UndoState</code> object is returned.
+	 * If <code>index</code> is out of scope <code>NULL</code> will be rerturned.
+	 * @return <code>UndoState</code> object from <code>index</code> or <code>NULL</code>
+	 * if <code>index</code> is out of scope.
+	 */
+	UndoState* at(int index);
+	/**
+	 * @brief Returns true if this transaction contains UndoObject with the id <code>uid</code>
+	 * @brief otherwise returns false.
+	 * @return true if this transaction contains UndoObject with the ide <code>uid</code>
+	 * @return otherwise returns false.
+	 */
+	bool contains(int uid) const;
+	
+	/**
+	 * @brief Tells if this transaction contains only UndoObject with ID uid
+	 * 
+	 * If a transaction contains only single UndoObject it will be safe to include
+	 * it in the object specific undo.
+	 * @param uid UndoObject's id to look for
+	 * @return true if this transaction only contains actions of the UndoObject whose
+	 *         id is uid
+	 */
+	bool containsOnly(int uid) const;
+	/**
+	 * @brief Replace object with id uid with new UndoObject newUndoObject.
+	 * @param uid id of the object that is wanted to be replaced
+	 * @param newUndoObject object that is used for replacing
+	 * @return UndoObject which was replaced
+	 */
+	UndoObject* replace(ulong uid, UndoObject *newUndoObject);
+
+	/** @brief undo all UndoStates in this transaction */
+	void undo();
+	/** @brief redo all UndoStates in this transaction */
+	void redo();
+private:
+	/** @brief Number of undo states stored in this transaction */
+	uint size_;
+	/** @brief vector to keep the states in */
+	std::vector<UndoState*> states_;
+};
+
 #endif

Modified: trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj
==============================================================================
--- trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj (original)
+++ trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj Mon Aug 11 04:59:24 2014
@@ -454,6 +454,7 @@
     <moc Include="..\..\..\scribus\upgradechecker.h" />
     <moc Include="..\..\..\scribus\ui\proptree.h" />
     <moc Include="..\..\..\scribus\ui\viewtoolbar.h" />
+    <ClInclude Include="..\..\..\scribus\undotransaction.h" />
     <ClInclude Include="..\..\..\scribus\util_debug.h" />
     <ClInclude Include="..\..\..\scribus\util_os.h" />
     <ClInclude Include="resource.h" />
@@ -1208,6 +1209,7 @@
     <ClCompile Include="..\..\..\scribus\scribuscore.cpp" />
     <ClCompile Include="..\..\..\scribus\scribusdoc.cpp" />
     <ClCompile Include="..\..\..\scribus\ui\viewtoolbar.cpp" />
+    <ClCompile Include="..\..\..\scribus\undotransaction.cpp" />
     <ClCompile Include="..\..\..\scribus\upgradechecker.cpp" />
     <ClCompile Include="..\..\..\scribus\util_debug.cpp" />
     <ClCompile Include="..\..\..\scribus\util_os.cpp" />

Modified: trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj.filters
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj.filters
==============================================================================
--- trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj.filters (original)
+++ trunk/Scribus/win32/vc10/scribus-main/Scribus.vcxproj.filters Mon Aug 11 04:59:24 2014
@@ -1017,6 +1017,9 @@
     <ClInclude Include="..\..\..\scribus\util_os.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\scribus\undotransaction.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\scribus\desaxe\digester.cpp">
@@ -3471,6 +3474,9 @@
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="..\..\..\scribus\util_os.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\scribus\undotransaction.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>

Modified: trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj
==============================================================================
--- trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj (original)
+++ trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj Mon Aug 11 04:59:24 2014
@@ -567,6 +567,7 @@
     <moc Include="..\..\..\scribus\upgradechecker.h" />
     <moc Include="..\..\..\scribus\ui\proptree.h" />
     <moc Include="..\..\..\scribus\ui\viewtoolbar.h" />
+    <ClInclude Include="..\..\..\scribus\undotransaction.h" />
     <ClInclude Include="..\..\..\scribus\util_debug.h" />
     <ClInclude Include="..\..\..\scribus\util_os.h" />
     <ClInclude Include="resource.h" />
@@ -1369,6 +1370,7 @@
     <ClCompile Include="..\..\..\scribus\scribuscore.cpp" />
     <ClCompile Include="..\..\..\scribus\scribusdoc.cpp" />
     <ClCompile Include="..\..\..\scribus\ui\viewtoolbar.cpp" />
+    <ClCompile Include="..\..\..\scribus\undotransaction.cpp" />
     <ClCompile Include="..\..\..\scribus\upgradechecker.cpp" />
     <ClCompile Include="..\..\..\scribus\util_debug.cpp" />
     <ClCompile Include="..\..\..\scribus\util_os.cpp" />

Modified: trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj.filters
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=19416&path=/trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj.filters
==============================================================================
--- trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj.filters (original)
+++ trunk/Scribus/win32/vc11/scribus-main/Scribus.vcxproj.filters Mon Aug 11 04:59:24 2014
@@ -1005,6 +1005,9 @@
     <ClInclude Include="..\..\..\scribus\util_os.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\scribus\undotransaction.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\scribus\desaxe\digester.cpp">
@@ -3459,6 +3462,9 @@
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClCompile Include="..\..\..\scribus\util_os.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\scribus\undotransaction.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
   </ItemGroup>




More information about the scribus-commit mailing list