Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzTools includes
Toshihiro Shimizu 890ddd
#include "tools/imagegrouping.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/imageutils.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/strokesdata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/rasterimagedata.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/dvdialog.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tpalettehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/palettecontroller.h"
Toshihiro Shimizu 890ddd
#include "toonz/tobjecthandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/tcenterlinevectorizer.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobject.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tstroke.h"
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tcolorstyles.h"
Toshihiro Shimizu 890ddd
#include "tpalette.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
#include <qclipboard></qclipboard>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void vectorizeToonzImageData(const TVectorImageP &image, const ToonzImageData *tiData,
Toshihiro Shimizu 890ddd
							 std::set<int> &indexes, TPalette *palette,</int>
Toshihiro Shimizu 890ddd
							 const VectorizerConfiguration &config)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!tiData)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QApplication::setOverrideCursor(Qt::WaitCursor);
Toshihiro Shimizu 890ddd
	TRasterP ras;
Toshihiro Shimizu 890ddd
	std::vector<trectd> rects;</trectd>
Toshihiro Shimizu 890ddd
	std::vector<tstroke> strokes;</tstroke>
Toshihiro Shimizu 890ddd
	std::vector<tstroke> originalStrokes;</tstroke>
Toshihiro Shimizu 890ddd
	TAffine affine;
Toshihiro Shimizu 890ddd
	double dpiX, dpiY;
Toshihiro Shimizu 890ddd
	tiData->getData(ras, dpiX, dpiY, rects, strokes, originalStrokes, affine, image->getPalette());
Toshihiro Shimizu 890ddd
	TRasterCM32P rasCM = ras;
Toshihiro Shimizu 890ddd
	TToonzImageP ti(rasCM, rasCM->getBounds());
Toshihiro Shimizu 890ddd
	VectorizerCore vc;
Toshihiro Shimizu 890ddd
	TVectorImageP vi = vc.vectorize(ti, config, palette);
Toshihiro Shimizu 890ddd
	assert(vi);
Toshihiro Shimizu 890ddd
	vi->setPalette(palette);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TScale sc(dpiX / Stage::inch, dpiY / Stage::inch);
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	TRectD selectionBounds;
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)rects.size(); i++)
Toshihiro Shimizu 890ddd
		selectionBounds += rects[i];
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)strokes.size(); i++)
Toshihiro Shimizu 890ddd
		selectionBounds += strokes[i].getBBox();
Toshihiro Shimizu 890ddd
	TTranslation tr(selectionBounds.getP00());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)vi->getStrokeCount(); i++) {
Toshihiro Shimizu 890ddd
		TStroke *stroke = vi->getStroke(i);
Toshihiro Shimizu 890ddd
		stroke->transform(sc.inv() * affine * tr, true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UINT oldImageSize = image->getStrokeCount();
Toshihiro Shimizu 890ddd
	image->mergeImage(vi, TAffine());
Toshihiro Shimizu 890ddd
	UINT newImageSize = image->getStrokeCount();
Toshihiro Shimizu 890ddd
	indexes.clear();
Toshihiro Shimizu 890ddd
	for (UINT sI = oldImageSize; sI < newImageSize; sI++)
Toshihiro Shimizu 890ddd
		indexes.insert(sI);
Toshihiro Shimizu 890ddd
	QApplication::restoreOverrideCursor();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void copyStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
	StrokesData *data = new StrokesData();
Toshihiro Shimizu 890ddd
	data->setImage(image, indexes);
Toshihiro Shimizu 890ddd
	clipboard->setMimeData(data, QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool pasteStrokesWithoutUndo(TVectorImageP image, std::set<int> &outIndexes,</int>
Toshihiro Shimizu 890ddd
							 TSceneHandle *sceneHandle, bool insert = true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
	QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
	const StrokesData *stData = dynamic_cast<const *="" strokesdata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
	const ToonzImageData *tiData = dynamic_cast<const *="" toonzimagedata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
	const FullColorImageData *fciData = dynamic_cast<const *="" fullcolorimagedata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
	std::set<int> indexes = outIndexes;</int>
Toshihiro Shimizu 890ddd
	if (stData)
Toshihiro Shimizu 890ddd
		stData->getImage(image, indexes, insert);
Toshihiro Shimizu 890ddd
	else if (tiData) {
Toshihiro Shimizu 890ddd
		ToonzScene *scene = sceneHandle->getScene();
Toshihiro Shimizu 890ddd
		assert(scene);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const VectorizerParameters *vParams = scene->getProperties()->getVectorizerParameters();
Toshihiro Shimizu 890ddd
		assert(vParams);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		std::auto_ptr<vectorizerconfiguration> config(vParams->getCurrentConfiguration(0.0));</vectorizerconfiguration>
Toshihiro Shimizu 890ddd
		vectorizeToonzImageData(image, tiData, indexes, image->getPalette(), *config);
Toshihiro Shimizu 890ddd
	} else if (fciData) {
Toshihiro Shimizu 890ddd
		DVGui::error(QObject::tr("The copied selection cannot be pasted in the current drawing."));
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->notifyView();
Toshihiro Shimizu 890ddd
	outIndexes = indexes; //outIndexes is a reference  to current  selection, so the notifyImageChanged could reset it!
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void deleteStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMutexLocker lock(image->getMutex());
Shinya Kitaoka 3bfa54
	std::vector<int> indexesV(indexes.begin(), indexes.end());</int>
Toshihiro Shimizu 890ddd
	TRectD bbox;
Toshihiro Shimizu 890ddd
	UINT i = 0;
Toshihiro Shimizu 890ddd
	for (; i < indexesV.size(); i++)
Toshihiro Shimizu 890ddd
		bbox += image->getStroke(indexesV[i])->getBBox();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::vector<tfilledregioninf> regions;</tfilledregioninf>
Toshihiro Shimizu 890ddd
	ImageUtils::getFillingInformationOverlappingArea(image, regions, bbox);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP other = image->splitImage(indexesV, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	indexes.clear();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
	StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->notifyView();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void cutStrokesWithoutUndo(TVectorImageP image, std::set<int> &indexes)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	copyStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
	deleteStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// CopyStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CopyStrokesUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMimeData *m_oldData;
Toshihiro Shimizu 890ddd
	QMimeData *m_newData;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CopyStrokesUndo(QMimeData *oldData,
Toshihiro Shimizu 890ddd
					QMimeData *newData)
Toshihiro Shimizu 890ddd
		: m_oldData(oldData), m_newData(newData)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(cloneData(m_oldData), QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(cloneData(m_newData), QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// PasteStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class PasteStrokesUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXshSimpleLevelP m_level;
Toshihiro Shimizu 890ddd
	TFrameId m_frameId;
Toshihiro Shimizu 890ddd
	std::set<int> m_indexes;</int>
Toshihiro Shimizu 890ddd
	TPaletteP m_oldPalette;
Toshihiro Shimizu 890ddd
	QMimeData *m_oldData;
Toshihiro Shimizu 890ddd
	TSceneHandle *m_sceneHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	PasteStrokesUndo(TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
					 const TFrameId &frameId,
Toshihiro Shimizu 890ddd
					 std::set<int> &indexes,</int>
Toshihiro Shimizu 890ddd
					 TPaletteP oldPalette,
Toshihiro Shimizu 890ddd
					 TSceneHandle *sceneHandle)
Toshihiro Shimizu 890ddd
		: m_level(level), m_frameId(frameId), m_indexes(indexes), m_oldPalette(oldPalette), m_sceneHandle(sceneHandle)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
		m_oldData = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~PasteStrokesUndo()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		delete m_oldData;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Se la selezione corrente e' la stroke selection devo svuotarla,
Toshihiro Shimizu 890ddd
		// altrimenti puo' rimanere selezionato uno stroke che non esiste piu'.
Toshihiro Shimizu 890ddd
		StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
		if (selection)
Toshihiro Shimizu 890ddd
			selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		std::set<int> indexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
		deleteStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		std::set<int> indexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
		QMimeData *data = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(cloneData(m_oldData), QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		pasteStrokesWithoutUndo(image, indexes, m_sceneHandle);
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(data, QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class RemoveEndpointsUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXshSimpleLevelP m_level;
Toshihiro Shimizu 890ddd
	TFrameId m_frameId;
Shinya Kitaoka 3bfa54
	std::vector<std::pair<int, *="" tstroke="">> m_strokes;</std::pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	RemoveEndpointsUndo(TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
						const TFrameId &frameId,
Shinya Kitaoka 3bfa54
						std::vector<std::pair<int, *="" tstroke="">> strokes)</std::pair<int,>
Toshihiro Shimizu 890ddd
		: m_level(level), m_frameId(frameId), m_strokes(strokes)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~RemoveEndpointsUndo()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 0; i < (int)m_strokes.size(); i++)
Toshihiro Shimizu 890ddd
			delete m_strokes[i].second;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TVectorImageP vi = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 0; i < (int)m_strokes.size(); i++) {
Toshihiro Shimizu 890ddd
			TStroke *newS = new TStroke(*(m_strokes[i].second));
Toshihiro Shimizu 890ddd
			newS->setId(m_strokes[i].second->getId());
Toshihiro Shimizu 890ddd
			vi->restoreEndpoints(m_strokes[i].first, newS);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
		if (selection)
Toshihiro Shimizu 890ddd
			selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		TVectorImageP vi = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		for (i = 0; i < (int)m_strokes.size(); i++) {
Toshihiro Shimizu 890ddd
			TStroke *s = vi->removeEndpoints(m_strokes[i].first);
Toshihiro Shimizu 890ddd
			delete s;
Toshihiro Shimizu 890ddd
			//assert(s==m_strokes[i].second);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// DeleteFramesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DeleteStrokesUndo : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
protected:
Toshihiro Shimizu 890ddd
	TXshSimpleLevelP m_level;
Toshihiro Shimizu 890ddd
	TFrameId m_frameId;
Toshihiro Shimizu 890ddd
	std::set<int> m_indexes;</int>
Toshihiro Shimizu 890ddd
	QMimeData *m_data;
Toshihiro Shimizu 890ddd
	TSceneHandle *m_sceneHandle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	DeleteStrokesUndo(TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
					  const TFrameId &frameId,
Toshihiro Shimizu 890ddd
					  std::set<int> indexes, QMimeData *data,</int>
Toshihiro Shimizu 890ddd
					  TSceneHandle *sceneHandle)
Toshihiro Shimizu 890ddd
		: m_level(level), m_frameId(frameId), m_indexes(indexes), m_data(data), m_sceneHandle(sceneHandle)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~DeleteStrokesUndo()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		delete m_data;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
		QMimeData *oldData = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(cloneData(m_data), QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
		std::set<int> indexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		pasteStrokesWithoutUndo(image, indexes, m_sceneHandle, false);
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		clipboard->setMimeData(oldData, QClipboard::Clipboard);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		std::set<int> indexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
		deleteStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// CutStrokesUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class CutStrokesUndo : public DeleteStrokesUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	CutStrokesUndo(TXshSimpleLevel *level,
Toshihiro Shimizu 890ddd
				   const TFrameId &frameId,
Toshihiro Shimizu 890ddd
				   std::set<int> indexes, QMimeData *data,</int>
Toshihiro Shimizu 890ddd
				   TSceneHandle *sceneHandle)
Toshihiro Shimizu 890ddd
		: DeleteStrokesUndo(level, frameId, indexes, data, sceneHandle)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~CutStrokesUndo()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		std::set<int> indexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
		cutStrokesWithoutUndo(image, indexes);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection ctor/dtor
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection::StrokeSelection()
Toshihiro Shimizu 890ddd
	: m_groupCommand(new TGroupCommand()), m_sceneHandle(), m_updateSelectionBBox(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_groupCommand->setSelection(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection::~StrokeSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection::StrokeSelection(const StrokeSelection &other)
Toshihiro Shimizu 890ddd
	: m_vi(other.m_vi), m_indexes(other.m_indexes), m_groupCommand(new TGroupCommand()), m_sceneHandle(other.m_sceneHandle), m_updateSelectionBBox(other.m_updateSelectionBBox)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_groupCommand->setSelection(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
StrokeSelection &StrokeSelection::operator=(const StrokeSelection &other)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_vi = other.m_vi;
Toshihiro Shimizu 890ddd
	m_indexes = other.m_indexes;
Toshihiro Shimizu 890ddd
	m_sceneHandle = other.m_sceneHandle;
Toshihiro Shimizu 890ddd
	m_updateSelectionBBox = other.m_updateSelectionBBox;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::select(int index, bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (on)
Toshihiro Shimizu 890ddd
		m_indexes.insert(index);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_indexes.erase(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::toggle(int index)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::set<int>::iterator it = m_indexes.find(index);</int>
Toshihiro Shimizu 890ddd
	if (it == m_indexes.end())
Toshihiro Shimizu 890ddd
		m_indexes.insert(index);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_indexes.erase(it);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// removeEndpoints
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::removeEndpoints()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_vi)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_indexes.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
	std::vector<std::pair<int, *="" tstroke="">> undoData;</std::pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_vi->findRegions();
Toshihiro Shimizu 890ddd
	set<int>::iterator it = m_indexes.begin();</int>
Toshihiro Shimizu 890ddd
	for (; it != m_indexes.end(); ++it) {
Toshihiro Shimizu 890ddd
		TStroke *s = m_vi->removeEndpoints(*it);
Toshihiro Shimizu 890ddd
		if (s)
Shinya Kitaoka 3bfa54
			undoData.push_back(std::pair<int, *="" tstroke="">(*it, s));</int,>
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	if (!undoData.empty())
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new RemoveEndpointsUndo(level, tool->getCurrentFid(), undoData));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_updateSelectionBBox = true;
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
	m_updateSelectionBBox = false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// deleteStrokes
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::deleteStrokes()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!m_vi)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_indexes.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isSpline = tool->getApplication()->getCurrentObject()->isSpline();
Toshihiro Shimizu 890ddd
	TUndo *undo;
Toshihiro Shimizu 890ddd
	if (isSpline)
Toshihiro Shimizu 890ddd
		undo = new ToolUtils::UndoPath(tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StrokesData *data = new StrokesData();
Toshihiro Shimizu 890ddd
	data->setImage(m_vi, m_indexes);
Toshihiro Shimizu 890ddd
	std::set<int> oldIndexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
	deleteStrokesWithoutUndo(m_vi, m_indexes);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isSpline) {
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new DeleteStrokesUndo(level, tool->getCurrentFid(), oldIndexes, data, m_sceneHandle));
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		assert(undo);
Toshihiro Shimizu 890ddd
		if (undo)
Toshihiro Shimizu 890ddd
			TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::copy()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::copy()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_indexes.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QClipboard *clipboard = QApplication::clipboard();
Toshihiro Shimizu 890ddd
	QMimeData *oldData = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
	copyStrokesWithoutUndo(m_vi, m_indexes);
Toshihiro Shimizu 890ddd
	QMimeData *newData = cloneData(clipboard->mimeData());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//TUndoManager::manager()->add(new CopyStrokesUndo(oldData, newData));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::paste()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::paste()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (TTool::getApplication()->getCurrentObject()->isSpline()) {
Toshihiro Shimizu 890ddd
		const StrokesData *stData = dynamic_cast<const *="" strokesdata="">(QApplication::clipboard()->mimeData());</const>
Toshihiro Shimizu 890ddd
		if (!stData)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TVectorImageP splineImg = tool->getImage(true);
Toshihiro Shimizu 890ddd
		TVectorImageP img = stData->m_image;
Toshihiro Shimizu 890ddd
		if (!splineImg || !img)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QMutexLocker lock(splineImg->getMutex());
Toshihiro Shimizu 890ddd
		TUndo *undo = new ToolUtils::UndoPath(tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Toshihiro Shimizu 890ddd
		while (splineImg->getStrokeCount() > 0)
Toshihiro Shimizu 890ddd
			splineImg->deleteStroke(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TStroke *stroke = img->getStroke(0);
Toshihiro Shimizu 890ddd
		splineImg->addStroke(new TStroke(*stroke), false);
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
		tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
		tool->invalidate();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImageP tarImg = tool->touchImage();
Toshihiro Shimizu 890ddd
	if (!tarImg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TPaletteP palette = tarImg->getPalette();
Toshihiro Shimizu 890ddd
	TPaletteP oldPalette = new TPalette();
Toshihiro Shimizu 890ddd
	if (palette)
Toshihiro Shimizu 890ddd
		oldPalette = palette->clone();
Toshihiro Shimizu 890ddd
	bool isPaste = pasteStrokesWithoutUndo(tarImg, m_indexes, m_sceneHandle);
Toshihiro Shimizu 890ddd
	if (isPaste) {
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new PasteStrokesUndo(level, tool->getCurrentFid(), m_indexes, oldPalette, m_sceneHandle));
Toshihiro Shimizu 890ddd
		m_updateSelectionBBox = isPaste;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
	tool->getApplication()->getPaletteController()->getCurrentLevelPalette()->notifyPaletteChanged();
Toshihiro Shimizu 890ddd
	m_updateSelectionBBox = false;
Toshihiro Shimizu 890ddd
	tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// StrokeSelection::cut()
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::cut()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_indexes.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isSpline = tool->getApplication()->getCurrentObject()->isSpline();
Toshihiro Shimizu 890ddd
	TUndo *undo;
Toshihiro Shimizu 890ddd
	if (isSpline)
Toshihiro Shimizu 890ddd
		undo = new ToolUtils::UndoPath(tool->getXsheet()->getStageObject(tool->getObjectId())->getSpline());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	StrokesData *data = new StrokesData();
Toshihiro Shimizu 890ddd
	data->setImage(m_vi, m_indexes);
Toshihiro Shimizu 890ddd
	std::set<int> oldIndexes = m_indexes;</int>
Toshihiro Shimizu 890ddd
	cutStrokesWithoutUndo(m_vi, m_indexes);
Toshihiro Shimizu 890ddd
	if (!isSpline) {
Toshihiro Shimizu 890ddd
		TXshSimpleLevel *level = tool->getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
		TUndoManager::manager()->add(new CutStrokesUndo(level, tool->getCurrentFid(), oldIndexes, data, m_sceneHandle));
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		assert(undo);
Toshihiro Shimizu 890ddd
		if (undo)
Toshihiro Shimizu 890ddd
			TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// enableCommands
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::enableCommands()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Clear, &StrokeSelection::deleteStrokes);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Cut, &StrokeSelection::cut);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Copy, &StrokeSelection::copy);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Paste, &StrokeSelection::paste);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_Group, &TGroupCommand::group);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_Ungroup, &TGroupCommand::ungroup);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_BringToFront, &TGroupCommand::front);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_BringForward, &TGroupCommand::forward);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_SendBack, &TGroupCommand::back);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_SendBackward, &TGroupCommand::backward);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_EnterGroup, &TGroupCommand::enterGroup);
Toshihiro Shimizu 890ddd
	enableCommand(m_groupCommand.get(), MI_ExitGroup, &TGroupCommand::exitGroup);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_RemoveEndpoints, &StrokeSelection::removeEndpoints);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//===================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class UndoSetStrokeStyle : public TUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TVectorImageP m_image;
Shinya Kitaoka 3bfa54
	std::vector<int> m_strokeIndexes;</int>
Shinya Kitaoka 3bfa54
	std::vector<int> m_oldStyles;</int>
Toshihiro Shimizu 890ddd
	int m_newStyle;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	UndoSetStrokeStyle(TVectorImageP image, int newStyle)
Toshihiro Shimizu 890ddd
		: m_image(image), m_newStyle(newStyle)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void addStroke(TStroke *stroke)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_strokeIndexes.push_back(m_image->getStrokeIndex(stroke));
Toshihiro Shimizu 890ddd
		m_oldStyles.push_back(stroke->getStyle());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		UINT size = m_strokeIndexes.size();
Toshihiro Shimizu 890ddd
		assert(size == m_oldStyles.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (UINT i = 0; i != size; i++) {
Toshihiro Shimizu 890ddd
			int index = m_strokeIndexes[i];
Toshihiro Shimizu 890ddd
			if (index != -1 && index < (int)m_image->getStrokeCount())
Toshihiro Shimizu 890ddd
				m_image->getStroke(index)->setStyle(m_oldStyles[i]);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void redo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		UINT size = m_strokeIndexes.size();
Toshihiro Shimizu 890ddd
		assert(size == m_oldStyles.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (UINT i = 0; i != size; i++) {
Toshihiro Shimizu 890ddd
			int index = m_strokeIndexes[i];
Toshihiro Shimizu 890ddd
			if (index != -1 && index < (int)m_image->getStrokeCount())
Toshihiro Shimizu 890ddd
				m_image->getStroke(index)->setStyle(m_newStyle);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getSize() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return sizeof(*this) +
Toshihiro Shimizu 890ddd
			   m_strokeIndexes.capacity() * sizeof(m_strokeIndexes[0]) +
Toshihiro Shimizu 890ddd
			   m_oldStyles.capacity() * sizeof(m_oldStyles[0]);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// changeColorStyle
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void StrokeSelection::changeColorStyle(int styleIndex)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TVectorImageP img(tool->getImage(true));
Toshihiro Shimizu 890ddd
	if (!img)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TPalette *palette = img->getPalette();
Toshihiro Shimizu 890ddd
	TColorStyle *cs = palette->getStyle(styleIndex);
Toshihiro Shimizu 890ddd
	if (!cs->isStrokeStyle())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_indexes.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UndoSetStrokeStyle *undo = new UndoSetStrokeStyle(img, styleIndex);
Toshihiro Shimizu 890ddd
	std::set<int>::iterator it;</int>
Toshihiro Shimizu 890ddd
	for (it = m_indexes.begin(); it != m_indexes.end(); ++it) {
Toshihiro Shimizu 890ddd
		int index = *it;
Toshihiro Shimizu 890ddd
		assert(0 <= index && index < (int)img->getStrokeCount());
Toshihiro Shimizu 890ddd
		TStroke *stroke = img->getStroke(index);
Toshihiro Shimizu 890ddd
		undo->addStroke(stroke);
Toshihiro Shimizu 890ddd
		stroke->setStyle(styleIndex);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
}