Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "hookselection.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tstageobjecttree.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tools/tool.h"
Toshihiro Shimizu 890ddd
#include "tools/toolhandle.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include <qapplication></qapplication>
Toshihiro Shimizu 890ddd
#include <qclipboard></qclipboard>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// HookUndo
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HookUndo::HookUndo(const TXshLevelP &level)
Toshihiro Shimizu 890ddd
	: m_level(level)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	HookSet *hookSet = m_level->getHookSet();
Toshihiro Shimizu 890ddd
	assert(hookSet);
Toshihiro Shimizu 890ddd
	if (hookSet)
Toshihiro Shimizu 890ddd
		m_oldHooks = *hookSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HookUndo::~HookUndo()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookUndo::onAdd()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	HookSet *hookSet = m_level->getHookSet();
Toshihiro Shimizu 890ddd
	assert(hookSet);
Toshihiro Shimizu 890ddd
	if (hookSet)
Toshihiro Shimizu 890ddd
		m_newHooks = *hookSet;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookUndo::assignHookSet(const HookSet &src) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	HookSet *hookSet = m_level->getHookSet();
Toshihiro Shimizu 890ddd
	assert(hookSet);
Toshihiro Shimizu 890ddd
	if (hookSet)
Toshihiro Shimizu 890ddd
		*hookSet = src;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentXsheet()->getXsheet()->getStageObjectTree()->invalidateAll();
Toshihiro Shimizu 890ddd
	TTool *tool = TTool::getApplication()->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (tool) {
Toshihiro Shimizu 890ddd
		tool->updateMatrix();
Toshihiro Shimizu 890ddd
		tool->invalidate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookUndo::undo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assignHookSet(m_oldHooks);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookUndo::redo() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assignHookSet(m_newHooks);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int HookUndo::getSize() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return sizeof(*this) + 2 * sizeof(HookSet);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// HooksData
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HooksData::HooksData(const TXshLevelP &level)
Toshihiro Shimizu 890ddd
	: m_level(level)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HooksData::~HooksData()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HooksData *HooksData::clone() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	HooksData *newData = new HooksData(m_level);
Toshihiro Shimizu 890ddd
	newData->m_hookPositions = m_hookPositions;
Toshihiro Shimizu 890ddd
	return newData;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
void HooksData::storeHookPositions(const std::vector<int> &ids)</int>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (ids.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TXshLevelP level = app->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	assert(level = m_level);
Toshihiro Shimizu 890ddd
	if (level != m_level || !m_level || m_level->getSimpleLevel()->isReadOnly())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	HookSet *hookSet = m_level->getHookSet();
Toshihiro Shimizu 890ddd
	if (!hookSet)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFrameId fid = app->getCurrentTool()->getTool()->getCurrentFid();
Toshihiro Shimizu 890ddd
	int i, idsSize = ids.size();
Toshihiro Shimizu 890ddd
	m_hookPositions.clear();
Toshihiro Shimizu 890ddd
	for (i = 0; i < idsSize; i++) {
Toshihiro Shimizu 890ddd
		Hook *hook = hookSet->getHook(ids[i]);
Toshihiro Shimizu 890ddd
		assert(hook);
Toshihiro Shimizu 890ddd
		if (!hook)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		TPointD aPos = hook->getAPos(fid);
Toshihiro Shimizu 890ddd
		TPointD bPos = hook->getBPos(fid);
Toshihiro Shimizu 890ddd
		m_hookPositions.push_back(HookPosition(ids[i], aPos, bPos));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HooksData::restoreHookPositions() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_hookPositions.empty())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TXshLevelP level = app->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	assert(level = m_level);
Toshihiro Shimizu 890ddd
	if (level != m_level || !m_level || m_level->getSimpleLevel()->isReadOnly())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	HookSet *hookSet = m_level->getHookSet();
Toshihiro Shimizu 890ddd
	if (!hookSet)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TFrameId fid = app->getCurrentTool()->getTool()->getCurrentFid();
Toshihiro Shimizu 890ddd
	int i, posSize = m_hookPositions.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (i = 0; i < posSize; i++) {
Toshihiro Shimizu 890ddd
		HookPosition hookPos = m_hookPositions[i];
Toshihiro Shimizu 890ddd
		Hook *hook = hookSet->getHook(hookPos.m_id);
Toshihiro Shimizu 890ddd
		assert(hook);
Toshihiro Shimizu 890ddd
		if (!hook)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		hook->setAPos(fid, hookPos.m_aPos);
Toshihiro Shimizu 890ddd
		hook->setBPos(fid, hookPos.m_bPos);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// HookSelection
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//===========================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HookSelection::HookSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HookSelection::~HookSelection()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSelection *HookSelection::clone() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return new HookSelection(*this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::select(int id, int side)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_hooks.insert(std::make_pair(id, side));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::unselect(int id, int side)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_hooks.erase(std::make_pair(id, side));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool HookSelection::isSelected(int id, int side) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_hooks.count(std::make_pair(id, side)) > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::invertSelection(int id, int side)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (isSelected(id, side))
Toshihiro Shimizu 890ddd
		unselect(id, side);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		select(id, side);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool HookSelection::isEmpty() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_hooks.empty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
HookSet *HookSelection::getHookSet() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	if (!xl)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	return xl->getHookSet();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool HookSelection::select(const TSelection *s)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (const HookSelection *hs = dynamic_cast<const *="" hookselection="">(s)) {</const>
Toshihiro Shimizu 890ddd
		m_level = hs->m_level;
Toshihiro Shimizu 890ddd
		m_hooks = hs->m_hooks;
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::enableCommands()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Clear, &HookSelection::deleteSelectedHooks);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Copy, &HookSelection::copySelectedHooks);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Cut, &HookSelection::cutSelectedHooks);
Toshihiro Shimizu 890ddd
	enableCommand(this, MI_Paste, &HookSelection::pasteSelectedHooks);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::deleteSelectedHooks()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TTool::Application *app = TTool::getApplication();
Toshihiro Shimizu 890ddd
	TTool *tool = app->getCurrentTool()->getTool();
Toshihiro Shimizu 890ddd
	if (!app)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TXshLevel *xl = app->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	HookSet *hookSet = xl->getHookSet();
Toshihiro Shimizu 890ddd
	if (!xl || !xl->getSimpleLevel() || !hookSet || xl->getSimpleLevel()->isReadOnly())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	HookUndo *undo = new HookUndo(xl->getSimpleLevel());
Toshihiro Shimizu 890ddd
	TFrameId fid = tool->getCurrentFid();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int i = 0; i < hookSet->getHookCount(); i++) {
Toshihiro Shimizu 890ddd
		Hook *hook = hookSet->getHook(i);
Toshihiro Shimizu 890ddd
		if (!hook || hook->isEmpty())
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		if (isSelected(i, 1) && isSelected(i, 2))
Toshihiro Shimizu 890ddd
			hookSet->clearHook(hook);
Toshihiro Shimizu 890ddd
		else if (isSelected(i, 2))
Toshihiro Shimizu 890ddd
			hook->setBPos(fid, hook->getAPos(fid));
Toshihiro Shimizu 890ddd
		else if (isSelected(i, 1))
Toshihiro Shimizu 890ddd
			hook->setAPos(fid, hook->getBPos(fid));
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
	app->getCurrentXsheet()->getXsheet()->getStageObjectTree()->invalidateAll();
Toshihiro Shimizu 890ddd
	tool->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::copySelectedHooks()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (isEmpty())
Toshihiro Shimizu 890ddd
		return;
Shinya Kitaoka 3bfa54
	std::vector<int> ids;</int>
Toshihiro Shimizu 890ddd
	std::set<std::pair<int, int="">>::iterator it;</std::pair<int,>
Toshihiro Shimizu 890ddd
	for (it = m_hooks.begin(); it != m_hooks.end(); it++) {
Toshihiro Shimizu 890ddd
		if (std::find(ids.begin(), ids.end(), it->first) == ids.end())
Toshihiro Shimizu 890ddd
			ids.push_back(it->first);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	HooksData *data = new HooksData(xl);
Toshihiro Shimizu 890ddd
	data->storeHookPositions(ids);
Toshihiro Shimizu 890ddd
	QApplication::clipboard()->setMimeData(data);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::cutSelectedHooks()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	copySelectedHooks();
Toshihiro Shimizu 890ddd
	TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	TUndo *undo = new HookUndo(xl);
Toshihiro Shimizu 890ddd
	HookSet *hookSet = xl->getHookSet();
Toshihiro Shimizu 890ddd
	std::set<std::pair<int, int="">>::iterator it;</std::pair<int,>
Toshihiro Shimizu 890ddd
	for (it = m_hooks.begin(); it != m_hooks.end(); it++) {
Toshihiro Shimizu 890ddd
		Hook *hook = hookSet->getHook(it->first);
Toshihiro Shimizu 890ddd
		assert(hook);
Toshihiro Shimizu 890ddd
		if (!hook)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TFrameId fid = TTool::getApplication()->getCurrentTool()->getTool()->getCurrentFid();
Toshihiro Shimizu 890ddd
		hook->eraseFrame(fid);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void HookSelection::pasteSelectedHooks()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const QMimeData *data = QApplication::clipboard()->mimeData();
Toshihiro Shimizu 890ddd
	const HooksData *hooksData = dynamic_cast<const *="" hooksdata="">(data);</const>
Toshihiro Shimizu 890ddd
	if (!hooksData)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	TXshLevel *xl = TTool::getApplication()->getCurrentLevel()->getLevel();
Toshihiro Shimizu 890ddd
	TUndo *undo = new HookUndo(xl);
Toshihiro Shimizu 890ddd
	hooksData->restoreHookPositions();
Toshihiro Shimizu 890ddd
	TUndoManager::manager()->add(undo);
Toshihiro Shimizu 890ddd
	TTool::getApplication()->getCurrentTool()->getTool()->invalidate();
Toshihiro Shimizu 890ddd
}