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