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