Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/imagegrouping.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzTools includes
Toshihiro Shimizu 890ddd
#include "tools/strokeselection.h"
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
#include "tools/toolutils.h"
Toshihiro Shimizu 890ddd
#include "vectorselectiontool.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/tselectionhandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tscenehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tvectorimage.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
#include "tthreadmessage.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qmenu></qmenu>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void groupWithoutUndo(TVectorImage *vimg, StrokeSelection *selection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int count = 0, fromStroke = -1, lastSelected = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
		if (selection->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (fromStroke == -1)
Toshihiro Shimizu 890ddd
				fromStroke = i;
Toshihiro Shimizu 890ddd
			else if (lastSelected != i - 1) //non sono contigui gli stroke selezionati: faccio affiorare quelli sotto
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				int j = 0;
Toshihiro Shimizu 890ddd
				for (j = 0; j < count; j++)
Toshihiro Shimizu 890ddd
					selection->select(fromStroke + j, false);
Toshihiro Shimizu 890ddd
				vimg->moveStrokes(fromStroke, count, i);
Toshihiro Shimizu 890ddd
				fromStroke = i - count;
Toshihiro Shimizu 890ddd
				for (j = 0; j < count; j++)
Toshihiro Shimizu 890ddd
					selection->select(fromStroke + j, true);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			lastSelected = i;
Toshihiro Shimizu 890ddd
			count++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(count > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vimg->group(fromStroke, count);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void ungroupWithoutUndo(TVectorImage *vimg, StrokeSelection *selection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)vimg->getStrokeCount();)
Toshihiro Shimizu 890ddd
		if (selection->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (!vimg->isStrokeGrouped(i)) {
Toshihiro Shimizu 890ddd
				i++;
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			i += vimg->ungroup(i);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			i++;
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// GroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class GroupUndo : public ToolUtils::TToolUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::auto_ptr<strokeselection> m_selection;</strokeselection>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	GroupUndo(TXshSimpleLevel *level, const TFrameId &frameId, StrokeSelection *selection)
Toshihiro Shimizu 890ddd
		: ToolUtils::TToolUndo(level, frameId), m_selection(selection) {}
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
		if (image)
Toshihiro Shimizu 890ddd
			ungroupWithoutUndo(image.getPointer(), m_selection.get());
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
		if (image)
Toshihiro Shimizu 890ddd
			groupWithoutUndo(image.getPointer(), m_selection.get());
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
	QString getToolName()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QObject::tr("Group");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// UngroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class UngroupUndo : public ToolUtils::TToolUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::auto_ptr<strokeselection> m_selection;</strokeselection>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	UngroupUndo(TXshSimpleLevel *level, const TFrameId &frameId, StrokeSelection *selection)
Toshihiro Shimizu 890ddd
		: ToolUtils::TToolUndo(level, frameId), m_selection(selection) {}
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
		if (image)
Toshihiro Shimizu 890ddd
			groupWithoutUndo(image.getPointer(), m_selection.get());
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
		if (image)
Toshihiro Shimizu 890ddd
			ungroupWithoutUndo(image.getPointer(), m_selection.get());
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
	QString getToolName()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QObject::tr("Ungroup");
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MoveGroupUndo
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class MoveGroupUndo : public ToolUtils::TToolUndo
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UCHAR m_moveType;
Toshihiro Shimizu 890ddd
	int m_refStroke, m_count, m_moveBefore;
Toshihiro Shimizu 890ddd
	vector<pair<tstroke *,="" int="">> m_selectedGroups;</pair<tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	MoveGroupUndo(TXshSimpleLevel *level, const TFrameId &frameId, UCHAR moveType,
Toshihiro Shimizu 890ddd
				  int refStroke, int count, int moveBefore, const vector<pair<tstroke *,="" int="">> &selectedGroups)</pair<tstroke>
Toshihiro Shimizu 890ddd
		: ToolUtils::TToolUndo(level, frameId), m_moveType(moveType), m_refStroke(refStroke), m_count(count), m_moveBefore(moveBefore), m_selectedGroups(selectedGroups)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	~MoveGroupUndo()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void undo() const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int refStroke;
Toshihiro Shimizu 890ddd
		int moveBefore;
Toshihiro Shimizu 890ddd
		switch (m_moveType) {
Toshihiro Shimizu 890ddd
		case TGroupCommand::FRONT: {
Toshihiro Shimizu 890ddd
			refStroke = m_moveBefore - m_count;
Toshihiro Shimizu 890ddd
			moveBefore = m_refStroke;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
			CASE TGroupCommand::FORWARD:
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				refStroke = m_moveBefore - m_count;
Toshihiro Shimizu 890ddd
				moveBefore = m_refStroke;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			CASE TGroupCommand::BACK:
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				refStroke = m_moveBefore;
Toshihiro Shimizu 890ddd
				moveBefore = m_refStroke + m_count;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			CASE TGroupCommand::BACKWARD:
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
				refStroke = m_moveBefore;
Toshihiro Shimizu 890ddd
				moveBefore = m_refStroke + m_count;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		DEFAULT:
Toshihiro Shimizu 890ddd
			assert(!"group move not defined!");
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		TVectorImageP image = m_level->getFrame(m_frameId, true);
Toshihiro Shimizu 890ddd
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
		image->moveStrokes(refStroke, m_count, moveBefore);
Toshihiro Shimizu 890ddd
		StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
		if (selection) { //Se la selezione corrente e' la StrokeSelection
Toshihiro Shimizu 890ddd
			// seleziono gli stroke che ho modificato con l'undo
Toshihiro Shimizu 890ddd
			selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (int i = 0; i < (int)m_selectedGroups.size(); i++) {
Toshihiro Shimizu 890ddd
				int index = image->getStrokeIndex(m_selectedGroups[i].first);
Toshihiro Shimizu 890ddd
				if (index == -1)
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				for (int j = index; j < index + m_selectedGroups[i].second; j++)
Toshihiro Shimizu 890ddd
					selection->select(j, true);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
		notifyImageChanged();
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
		if (!image)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		QMutexLocker lock(image->getMutex());
Toshihiro Shimizu 890ddd
		image->moveStrokes(m_refStroke, m_count, m_moveBefore);
Toshihiro Shimizu 890ddd
		StrokeSelection *selection = dynamic_cast<strokeselection *="">(TTool::getApplication()->getCurrentSelection()->getSelection());</strokeselection>
Toshihiro Shimizu 890ddd
		if (selection) { //Se la selezione corrente e' la StrokeSelection
Toshihiro Shimizu 890ddd
			// seleziono gli stroke che ho modificato con il redo
Toshihiro Shimizu 890ddd
			selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			for (int i = 0; i < (int)m_selectedGroups.size(); i++) {
Toshihiro Shimizu 890ddd
				int index = image->getStrokeIndex(m_selectedGroups[i].first);
Toshihiro Shimizu 890ddd
				if (index == -1)
Toshihiro Shimizu 890ddd
					continue;
Toshihiro Shimizu 890ddd
				for (int j = index; j < index + m_selectedGroups[i].second; j++)
Toshihiro Shimizu 890ddd
					selection->select(j, true);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
		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
	QString getToolName()
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return QObject::tr("Move Group");
Toshihiro Shimizu 890ddd
	}
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
// TGroupCommand
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
vector<pair<tstroke *,="" int="">> getSelectedGroups(TVectorImage *vimg, StrokeSelection *sel)</pair<tstroke>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UINT i, j;
Toshihiro Shimizu 890ddd
	vector<pair<tstroke *,="" int="">> ret;</pair<tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
		if (sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (vimg->isStrokeGrouped(i)) {
Toshihiro Shimizu 890ddd
				for (j = i + 1; j < vimg->getStrokeCount() && vimg->sameSubGroup(i, j); j++)
Toshihiro Shimizu 890ddd
					if (!sel->isSelected(j))
Toshihiro Shimizu 890ddd
						return vector<pair<tstroke *,="" int="">>();</pair<tstroke>
Toshihiro Shimizu 890ddd
				ret.push_back(pair<tstroke *,="" int="">(vimg->getStroke(i), j - i));</tstroke>
Toshihiro Shimizu 890ddd
				i = j - 1;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				ret.push_back(pair<tstroke *,="" int="">(vimg->getStroke(i), 1));</tstroke>
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} //namepsace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR TGroupCommand::getGroupingOptions()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = dynamic_cast<tvectorimage *="">(tool->getImage(false));</tvectorimage>
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	UCHAR mask = 0;
Toshihiro Shimizu 890ddd
	int count = 0;
Toshihiro Shimizu 890ddd
	UINT i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//spostamento: si possono  spostare solo gruppi interi  oppure  stroke   non gruppate
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<pair<tstroke *,="" int="">> strokeIndexes = getSelectedGroups(vimg, m_sel);</pair<tstroke>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
	//spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure una stroke singola  non gruppata
Toshihiro Shimizu 890ddd
for (i=0; i<vimg->getStrokeCount(); i++)</vimg->
Toshihiro Shimizu 890ddd
	if (m_sel->isSelected(i))
Toshihiro Shimizu 890ddd
  	{
Toshihiro Shimizu 890ddd
		if (strokeIndex != -1)
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
			if (!vimg->isStrokeGrouped(i) || !vimg->sameSubGroup(strokeIndex, i)) 
Toshihiro Shimizu 890ddd
				break;  
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		else 
Toshihiro Shimizu 890ddd
			{
Toshihiro Shimizu 890ddd
			strokeIndex = i;
Toshihiro Shimizu 890ddd
			if (vimg->isStrokeGrouped(i))
Toshihiro Shimizu 890ddd
				{
Toshihiro Shimizu 890ddd
				for (j=0; j<vimg->getStrokeCount(); j++)</vimg->
Toshihiro Shimizu 890ddd
					if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Toshihiro Shimizu 890ddd
						break;//non tutto il gruppo e' selezionato
Toshihiro Shimizu 890ddd
				if (j<vimg->getStrokeCount())</vimg->
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		count++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	 */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (strokeIndexes.empty())
Toshihiro Shimizu 890ddd
		return 0; //no stroke selected
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int strokeIndex = vimg->getStrokeIndex(strokeIndexes[0].first);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (strokeIndexes.size() > 1 || strokeIndex > 0) {
Toshihiro Shimizu 890ddd
		mask |= BACK;
Toshihiro Shimizu 890ddd
		mask |= BACKWARD;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (strokeIndexes.size() > 1 || strokeIndex + strokeIndexes[0].second - 1 < (int)vimg->getStrokeCount() - 1) {
Toshihiro Shimizu 890ddd
		mask |= FRONT;
Toshihiro Shimizu 890ddd
		mask |= FORWARD;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
if (i == vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
	if (strokeIndex+count<(int)vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
	  {
Toshihiro Shimizu 890ddd
		mask |= FRONT;
Toshihiro Shimizu 890ddd
		mask |= FORWARD;
Toshihiro Shimizu 890ddd
	  }
Toshihiro Shimizu 890ddd
	if (strokeIndex>0)
Toshihiro Shimizu 890ddd
	  {
Toshihiro Shimizu 890ddd
		mask |= BACK;
Toshihiro Shimizu 890ddd
		mask |= BACKWARD;
Toshihiro Shimizu 890ddd
	  }  
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel gruppo (anche piu' gruppi insieme)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount(); i++) {
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (!vimg->isStrokeGrouped(i))
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			for (j = 0; j < vimg->getStrokeCount(); j++)
Toshihiro Shimizu 890ddd
				if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
			if (j < vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (i == vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
		mask |= UNGROUP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//PER il GROUP: si raggruppa solo  se:
Toshihiro Shimizu 890ddd
	// //almeno una delle  stroke selezionate non fa parte di gruppi o e' di un gruppo diverso
Toshihiro Shimizu 890ddd
	// e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e' selezionato
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool groupingMakesSense = false;
Toshihiro Shimizu 890ddd
	int refStroke = -1;
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (vimg->isStrokeGrouped(i)) {
Toshihiro Shimizu 890ddd
				if (refStroke == -1)
Toshihiro Shimizu 890ddd
					refStroke = i;
Toshihiro Shimizu 890ddd
				else if (!vimg->sameSubGroup(refStroke, i))
Toshihiro Shimizu 890ddd
					groupingMakesSense = true; //gli storke selezionati non sono gia' tutti dello stesso gruppo
Toshihiro Shimizu 890ddd
				for (j = 0; j < vimg->getStrokeCount(); j++)
Toshihiro Shimizu 890ddd
					if (!m_sel->isSelected(j) && vimg->sameGroup(i, j))
Toshihiro Shimizu 890ddd
						return mask;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				groupingMakesSense = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (groupingMakesSense)
Toshihiro Shimizu 890ddd
		mask |= GROUP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef NUOVO
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
UCHAR TGroupCommand::getGroupingOptions()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = dynamic_cast<tvectorimage *="">(tool->getImage(false));</tvectorimage>
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int strokeIndex = -1;
Toshihiro Shimizu 890ddd
	UCHAR mask = 0;
Toshihiro Shimizu 890ddd
	int count = 0;
Toshihiro Shimizu 890ddd
	UINT i, j;
Toshihiro Shimizu 890ddd
	bool valid = true;
Toshihiro Shimizu 890ddd
	//spostamento: si puo' spostare solo un gruppo(e uno solo per volta) oppure una stroke singola  non gruppata
Toshihiro Shimizu 890ddd
	vector<pair<int, int="">> groups;</pair<int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount() && valid;)
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			strokeIndex = i;
Toshihiro Shimizu 890ddd
			count = 1;
Toshihiro Shimizu 890ddd
			if (vimg->isStrokeGrouped(i)) {
Toshihiro Shimizu 890ddd
				for (j = i + 1; j < vimg->getStrokeCount() && valid; j++)
Toshihiro Shimizu 890ddd
					if (m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Toshihiro Shimizu 890ddd
						count++;
Toshihiro Shimizu 890ddd
					else if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Toshihiro Shimizu 890ddd
						valid = false; //non tutto il gruppo e' selezionato
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			groups.push_back(pair<int, int="">(strokeIndex, count));</int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			i = i + count;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (groups.empty())
Toshihiro Shimizu 890ddd
		return 0; //no stroke selected
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!valid)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (strokeIndex + count < (int)vimg->getStrokeCount()) {
Toshihiro Shimizu 890ddd
		mask |= FRONT;
Toshihiro Shimizu 890ddd
		mask |= FORWARD;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (strokeIndex > 0) {
Toshihiro Shimizu 890ddd
		mask |= BACK;
Toshihiro Shimizu 890ddd
		mask |= BACKWARD;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//PER l'UNGROUP: si ungruppa solo se tutti gli stroke selezionati stanno nel gruppo (anche piu' gruppi insieme)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount(); i++) {
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (!vimg->isStrokeGrouped(i))
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
			for (j = 0; j < vimg->getStrokeCount(); j++)
Toshihiro Shimizu 890ddd
				if (!m_sel->isSelected(j) && vimg->sameSubGroup(i, j))
Toshihiro Shimizu 890ddd
					break;
Toshihiro Shimizu 890ddd
			if (j < vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (i == vimg->getStrokeCount())
Toshihiro Shimizu 890ddd
		mask |= UNGROUP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//PER il GROUP: si raggruppa solo  se:
Toshihiro Shimizu 890ddd
	// //almeno una delle  stroke selezionate non fa parte di gruppi o e' di un gruppo diverso
Toshihiro Shimizu 890ddd
	// e se c'e' una stroke di un gruppo, allora tutto il gruppo della stroke e' selezionato
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool groupingMakesSense = false;
Toshihiro Shimizu 890ddd
	int refStroke = -1;
Toshihiro Shimizu 890ddd
	for (i = 0; i < vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			if (vimg->isStrokeGrouped(i)) {
Toshihiro Shimizu 890ddd
				if (refStroke == -1)
Toshihiro Shimizu 890ddd
					refStroke = i;
Toshihiro Shimizu 890ddd
				else if (!vimg->sameSubGroup(refStroke, i))
Toshihiro Shimizu 890ddd
					groupingMakesSense = true; //gli storke selezionati non sono gia' tutti dello stesso gruppo
Toshihiro Shimizu 890ddd
				for (j = 0; j < vimg->getStrokeCount(); j++)
Toshihiro Shimizu 890ddd
					if (!m_sel->isSelected(j) && vimg->sameGroup(i, j))
Toshihiro Shimizu 890ddd
						return mask;
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				groupingMakesSense = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (groupingMakesSense)
Toshihiro Shimizu 890ddd
		mask |= GROUP;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::group()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!(getGroupingOptions() & GROUP))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(vimg->getMutex());
Toshihiro Shimizu 890ddd
	groupWithoutUndo(vimg, m_sel);
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(new GroupUndo(level, tool->getCurrentFid(), new StrokeSelection(*m_sel)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::enterGroup()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	int index = -1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < (int)vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
		if (m_sel->isSelected(i)) {
Toshihiro Shimizu 890ddd
			index = i;
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (index == -1)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!vimg->canEnterGroup(index))
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	vimg->enterGroup(index);
Toshihiro Shimizu 890ddd
	TSelection *selection = TSelection::getCurrent();
Toshihiro Shimizu 890ddd
	if (selection)
Toshihiro Shimizu 890ddd
		selection->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::exitGroup()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	vimg->exitGroup();
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentScene()->notifySceneChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::ungroup()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!(getGroupingOptions() & UNGROUP))
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
	TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	QMutexLocker lock(vimg->getMutex());
Toshihiro Shimizu 890ddd
	ungroupWithoutUndo(vimg, m_sel);
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(new UngroupUndo(level, tool->getCurrentFid(), new StrokeSelection(*m_sel)));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
void computeMovingBounds(TVectorImage*vimg, int fromIndex, int toIndex, int&lower, int& upper)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
lower = 0;
Toshihiro Shimizu 890ddd
upper = vimg->getStrokeCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int refDepth = vimg->getGroupDepth(fromIndex)-1;  
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
if (refDepth==0)
Toshihiro Shimizu 890ddd
  return;
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
int i;  
Toshihiro Shimizu 890ddd
for (i=fromIndex-1; i>=0; i--)
Toshihiro Shimizu 890ddd
  if (vimg->getCommonGroupDepth(fromIndex, i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    lower = i+1;
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
    }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
for (i=fromIndex+1; i<vimg->getStrokeCount(); i++)</vimg->
Toshihiro Shimizu 890ddd
  if (vimg->getCommonGroupDepth(fromIndex, i)
Toshihiro Shimizu 890ddd
    {
Toshihiro Shimizu 890ddd
    upper = i;
Toshihiro Shimizu 890ddd
    break;
Toshihiro Shimizu 890ddd
    }    
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int commonDepth(TVectorImage *vimg, int index1, int count, int index2)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i, ret = 1000;
Toshihiro Shimizu 890ddd
	for (i = index1; i < index1 + count; i++)
Toshihiro Shimizu 890ddd
		ret = tmin(ret, vimg->getCommonGroupDepth(i, index2));
Toshihiro Shimizu 890ddd
	return ret;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool cantMove1(TVectorImage* vimg, int refStroke, int count, int moveBefore, bool rev)
Toshihiro Shimizu 890ddd
  {   
Toshihiro Shimizu 890ddd
  if (moveBefore<(int)vimg->getStrokeCount() && moveBefore>0 &&
Toshihiro Shimizu 890ddd
             vimg->getCommonGroupDepth(moveBefore-1, moveBefore)>commonDepth(vimg, refStroke, count, moveBefore) && 
Toshihiro Shimizu 890ddd
             vimg->getCommonGroupDepth(moveBefore-1, moveBefore)>commonDepth(vimg, refStroke, count, moveBefore-1))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  int prev = (rev)?moveBefore:moveBefore-1;
Toshihiro Shimizu 890ddd
  
Toshihiro Shimizu 890ddd
  if (refStroke>0 && commonDepth(vimg, refStroke, count, refStroke-1)>commonDepth(vimg, refStroke, count, prev))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
  if (refStroke+count<(int)vimg->getStrokeCount() && commonDepth(vimg, refStroke, count, refStroke+count)>commonDepth(vimg, refStroke, count, prev))
Toshihiro Shimizu 890ddd
    return true;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  return false;
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
/*
Toshihiro Shimizu 890ddd
  int i, refStroke=-1, count=0;
Toshihiro Shimizu 890ddd
  for (i=0; i<(int)vimg->getStrokeCount(); i++)
Toshihiro Shimizu 890ddd
    if(m_sel->isSelected(i))
Toshihiro Shimizu 890ddd
      {
Toshihiro Shimizu 890ddd
      assert(refStroke==-1 || i==0  || m_sel->isSelected(i-1));
Toshihiro Shimizu 890ddd
      if (refStroke==-1)
Toshihiro Shimizu 890ddd
        refStroke = i;
Toshihiro Shimizu 890ddd
      count++;
Toshihiro Shimizu 890ddd
      }
Toshihiro Shimizu 890ddd
      
Toshihiro Shimizu 890ddd
  if(count==0) return;
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int doMoveGroup(UCHAR moveType, TVectorImage *vimg, const vector<pair<tstroke *,="" int="">> &selectedGroups, int index)</pair<tstroke>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int refStroke = vimg->getStrokeIndex(selectedGroups[index].first);
Toshihiro Shimizu 890ddd
	int count = selectedGroups[index].second;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int moveBefore;
Toshihiro Shimizu 890ddd
	switch (moveType) {
Toshihiro Shimizu 890ddd
	case TGroupCommand::FRONT:
Toshihiro Shimizu 890ddd
		moveBefore = vimg->getStrokeCount();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		while (moveBefore >= refStroke + count + 1 && !vimg->canMoveStrokes(refStroke, count, moveBefore))
Toshihiro Shimizu 890ddd
			moveBefore--;
Toshihiro Shimizu 890ddd
		if (moveBefore == refStroke + count)
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		CASE TGroupCommand::FORWARD : moveBefore = refStroke + count + 1;
Toshihiro Shimizu 890ddd
		while (moveBefore <= (int)vimg->getStrokeCount() && !vimg->canMoveStrokes(refStroke, count, moveBefore))
Toshihiro Shimizu 890ddd
			moveBefore++;
Toshihiro Shimizu 890ddd
		if (moveBefore == vimg->getStrokeCount() + 1)
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		CASE TGroupCommand::BACK : moveBefore = 0;
Toshihiro Shimizu 890ddd
		while (moveBefore <= refStroke - 1 && !vimg->canMoveStrokes(refStroke, count, moveBefore))
Toshihiro Shimizu 890ddd
			moveBefore++;
Toshihiro Shimizu 890ddd
		if (moveBefore == refStroke)
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
		CASE TGroupCommand::BACKWARD : moveBefore = refStroke - 1;
Toshihiro Shimizu 890ddd
		while (moveBefore >= 0 && !vimg->canMoveStrokes(refStroke, count, moveBefore))
Toshihiro Shimizu 890ddd
			moveBefore--;
Toshihiro Shimizu 890ddd
		if (moveBefore == -1)
Toshihiro Shimizu 890ddd
			return -1;
Toshihiro Shimizu 890ddd
	DEFAULT:
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vimg->moveStrokes(refStroke, count, moveBefore);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshSimpleLevel *level = TTool::getApplication()->getCurrentLevel()->getSimpleLevel();
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(new MoveGroupUndo(level, tool->getCurrentFid(), moveType,
Toshihiro Shimizu 890ddd
												   refStroke, count, moveBefore, selectedGroups));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return moveBefore;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::moveGroup(UCHAR moveType)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!tool)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TVectorImage *vimg = (TVectorImage *)tool->getImage(true);
Toshihiro Shimizu 890ddd
	if (!vimg)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	vector<pair<tstroke *,="" int="">> selectedGroups = getSelectedGroups(vimg, m_sel);</pair<tstroke>
Toshihiro Shimizu 890ddd
	if (selectedGroups.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int i, j;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->beginBlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	switch (moveType) {
Toshihiro Shimizu 890ddd
	case TGroupCommand::FRONT:
Toshihiro Shimizu 890ddd
		__OR TGroupCommand::BACKWARD : i = 0;
Toshihiro Shimizu 890ddd
		if (moveType == TGroupCommand::BACKWARD && vimg->getStrokeIndex(selectedGroups[i].first) == 0) //tutti i gruppi adiacenti gia in fondo non possono essere backwardati
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			i++;
Toshihiro Shimizu 890ddd
			while (i < (int)selectedGroups.size() &&
Toshihiro Shimizu 890ddd
				   vimg->getStrokeIndex(selectedGroups[i - 1].first) + selectedGroups[i - 1].second - 1 == vimg->getStrokeIndex(selectedGroups[i].first) - 1)
Toshihiro Shimizu 890ddd
				i++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (; i <= (int)selectedGroups.size() - 1; i++)
Toshihiro Shimizu 890ddd
			doMoveGroup(moveType, vimg, selectedGroups, i); //vimg->getStrokeIndex(selectedGroups[i].first), selectedGroups[i].second);
Toshihiro Shimizu 890ddd
		CASE TGroupCommand::BACK : __OR TGroupCommand::FORWARD : i = selectedGroups.size() - 1;
Toshihiro Shimizu 890ddd
		if (moveType == TGroupCommand::FORWARD && vimg->getStrokeIndex(selectedGroups[i].first) + selectedGroups[i].second - 1 == vimg->getStrokeCount() - 1) //tutti i gruppi adiacenti gia in cime non possono essere forwardati
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			i--;
Toshihiro Shimizu 890ddd
			while (i >= 0 &&
Toshihiro Shimizu 890ddd
				   vimg->getStrokeIndex(selectedGroups[i + 1].first) - 1 == vimg->getStrokeIndex(selectedGroups[i].first) + selectedGroups[i].second - 1)
Toshihiro Shimizu 890ddd
				i--;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		for (; i >= 0; i--)
Toshihiro Shimizu 890ddd
			doMoveGroup(moveType, vimg, selectedGroups, i);
Toshihiro Shimizu 890ddd
	DEFAULT:
Toshihiro Shimizu 890ddd
		assert(false);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->endBlock();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_sel->selectNone();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < (int)selectedGroups.size(); i++) {
Toshihiro Shimizu 890ddd
		int index = vimg->getStrokeIndex(selectedGroups[i].first);
Toshihiro Shimizu 890ddd
		for (j = index; j < index + selectedGroups[i].second; j++)
Toshihiro Shimizu 890ddd
			m_sel->select(j, true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	tool->notifyImageChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TGroupCommand::addMenuItems(QMenu *menu)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	UCHAR optionMask = getGroupingOptions();
Toshihiro Shimizu 890ddd
	if (optionMask == 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CommandManager *cm = CommandManager::instance();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (optionMask & TGroupCommand::GROUP)
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_Group));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (optionMask & TGroupCommand::UNGROUP)
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_Ungroup));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (optionMask & (TGroupCommand::GROUP | TGroupCommand::UNGROUP) &&
Toshihiro Shimizu 890ddd
		optionMask & (TGroupCommand::FORWARD | TGroupCommand::BACKWARD))
Toshihiro Shimizu 890ddd
		menu->addSeparator();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (optionMask & TGroupCommand::FORWARD) {
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_BringToFront));
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_BringForward));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (optionMask & TGroupCommand::BACKWARD) {
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_SendBack));
Toshihiro Shimizu 890ddd
		menu->addAction(cm->getAction(MI_SendBackward));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	menu->addSeparator();
Toshihiro Shimizu 890ddd
}