Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tconst.h"
Toshihiro Shimizu 890ddd
#include "tundo.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxcommand.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/tfxhandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfxset.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheethandle.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/fxschematicscene.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/schematicnode.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/fxschematicnode.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/selectioncommandids.h"
Toshihiro Shimizu 890ddd
#include "fxdata.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
#include "toonzqt/fxselection.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
bool canGroup(TFx *fx) {
Shinya Kitaoka 120a6e
  TXsheetFx *xfx = dynamic_cast<txsheetfx *="">(fx);</txsheetfx>
Shinya Kitaoka 120a6e
  TOutputFx *ofx = dynamic_cast<toutputfx *="">(fx);</toutputfx>
Shinya Kitaoka 120a6e
  return (!xfx && !ofx);
Toshihiro Shimizu 890ddd
}
shun-iwasawa 4a3868
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
// FxSelection
Toshihiro Shimizu 890ddd
//
Toshihiro Shimizu 890ddd
//=========================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FxSelection::FxSelection()
Shinya Kitaoka 120a6e
    : m_xshHandle(0)
Shinya Kitaoka 120a6e
    , m_fxHandle(0)
Shinya Kitaoka 120a6e
    , m_pastePosition(TConst::nowhere)
Shinya Kitaoka 120a6e
    , m_schematicScene(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FxSelection::FxSelection(const FxSelection &src)
Shinya Kitaoka 120a6e
    : m_selectedFxs(src.m_selectedFxs)
Shinya Kitaoka 120a6e
    , m_selectedLinks(src.m_selectedLinks)
Shinya Kitaoka 120a6e
    , m_xshHandle(src.m_xshHandle)
Shinya Kitaoka 120a6e
    , m_fxHandle(src.m_fxHandle)
Shinya Kitaoka 120a6e
    , m_selectedColIndexes(src.m_selectedColIndexes)
Shinya Kitaoka 120a6e
    , m_pastePosition(TConst::nowhere)
Shinya Kitaoka 120a6e
    , m_schematicScene(src.m_schematicScene) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FxSelection::~FxSelection() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::enableCommands() {
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Clear, &FxSelection::deleteSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Cut, &FxSelection::cutSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Copy, &FxSelection::copySelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Paste, &FxSelection::pasteSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Group, &FxSelection::groupSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Ungroup, &FxSelection::ungroupSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_Collapse, &FxSelection::collapseSelection);
Shinya Kitaoka 120a6e
  enableCommand(this, MI_ExplodeChild, &FxSelection::explodeChild);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSelection *FxSelection::clone() const {
Shinya Kitaoka 120a6e
  assert(0);
Shinya Kitaoka 120a6e
  return new FxSelection(*this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::select(TFxP fx) { m_selectedFxs.append(fx); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::select(int colIndex) {
Shinya Kitaoka 120a6e
  m_selectedColIndexes.append(colIndex);
Tact Yoshida b8554a
  std::sort(m_selectedColIndexes.begin(), m_selectedColIndexes.end());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::unselect(int colIndex) {
Shinya Kitaoka 120a6e
  m_selectedColIndexes.removeOne(colIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::unselect(TFxP fx) {
Shinya Kitaoka 120a6e
  int index = m_selectedFxs.indexOf(fx);
Shinya Kitaoka 120a6e
  if (index >= 0) m_selectedFxs.removeAt(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::select(SchematicLink *link) {
Shinya Kitaoka 120a6e
  if (link->isLineShaped()) return;
Shinya Kitaoka 120a6e
  Link boundingFxs = getBoundingFxs(link);
Shinya Kitaoka 120a6e
  if (boundingFxs == Link()) return;
Shinya Kitaoka 120a6e
  m_selectedLinks.append(boundingFxs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::unselect(SchematicLink *link) {
Shinya Kitaoka 120a6e
  Link boundingFxs = getBoundingFxs(link);
Shinya Kitaoka 120a6e
  int index        = m_selectedLinks.indexOf(boundingFxs);
Shinya Kitaoka 120a6e
  if (index >= 0) m_selectedLinks.removeAt(index);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::isSelected(TFxP fx) const {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_selectedFxs.size(); i++) {
Shinya Kitaoka 120a6e
    TFx *selectedFx      = m_selectedFxs[i].getPointer();
Shinya Kitaoka 120a6e
    TZeraryColumnFx *zfx = dynamic_cast<tzerarycolumnfx *="">(selectedFx);</tzerarycolumnfx>
Shinya Kitaoka 120a6e
    if (zfx &&
Shinya Kitaoka 120a6e
        (fx.getPointer() == zfx || fx.getPointer() == zfx->getZeraryFx()))
Shinya Kitaoka 120a6e
      return true;
Shinya Kitaoka 120a6e
    if (fx.getPointer() == selectedFx) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::isSelected(int columnIndex) const {
Shinya Kitaoka 120a6e
  return m_selectedColIndexes.contains(columnIndex);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::isSelected(SchematicLink *link) {
Shinya Kitaoka 120a6e
  Link boundingFxs = getBoundingFxs(link);
Shinya Kitaoka 120a6e
  return m_selectedLinks.contains(boundingFxs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::deleteSelection() {
shun-iwasawa 4a3868
  emit doDelete();
shun-iwasawa 4a3868
  // std::list<tfxp, std::allocator<tfxp="">> fxList = m_selectedFxs.toStdList();</tfxp,>
shun-iwasawa 4a3868
  // TFxCommand::deleteSelection(fxList, m_selectedLinks.toStdList(),
shun-iwasawa 4a3868
  //                            m_selectedColIndexes.toStdList(), m_xshHandle,
shun-iwasawa 4a3868
  //                            m_fxHandle);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::copySelection() {
Shinya Kitaoka 120a6e
  QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
  FxsData *fxsData      = new FxsData();
Shinya Kitaoka 120a6e
  fxsData->setFxs(m_selectedFxs, m_selectedLinks, m_selectedColIndexes,
Shinya Kitaoka 120a6e
                  m_xshHandle->getXsheet());
Shinya Kitaoka 120a6e
  clipboard->setMimeData(fxsData);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::cutSelection() {
Shinya Kitaoka 120a6e
  copySelection();
Shinya Kitaoka 120a6e
  deleteSelection();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::pasteSelection() {
Shinya Kitaoka 120a6e
  /*--- Fxノードを1つだけ選択していた場合、Replace paste ---*/
Shinya Kitaoka 120a6e
  if (m_selectedFxs.size() >= 1 && m_selectedLinks.size() == 0 &&
Shinya Kitaoka 120a6e
      m_selectedColIndexes.isEmpty())
Shinya Kitaoka 120a6e
    replacePasteSelection();
Shinya Kitaoka 120a6e
  /*--- Linkを1つだけ選択していた場合、Insert paste ---*/
Shinya Kitaoka 120a6e
  else if (m_selectedFxs.size() == 0 && m_selectedLinks.size() >= 1 &&
Shinya Kitaoka 120a6e
           m_selectedColIndexes.isEmpty())
Shinya Kitaoka 120a6e
    insertPasteSelection();
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    QClipboard *clipboard = QApplication::clipboard();
Shinya Kitaoka 120a6e
    const FxsData *fxsData =
Shinya Kitaoka 120a6e
        dynamic_cast<const *="" fxsdata="">(clipboard->mimeData());</const>
Shinya Kitaoka 120a6e
    if (!fxsData) return;
Shinya Kitaoka 120a6e
    QList<tfxp> fxs;</tfxp>
Shinya Kitaoka 120a6e
    QMap<tfx *,="" int=""> zeraryFxColumnSize;</tfx>
Shinya Kitaoka 120a6e
    QList<txshcolumnp> columns;</txshcolumnp>
Shinya Kitaoka 120a6e
    fxsData->getFxs(fxs, zeraryFxColumnSize, columns);
Shinya Kitaoka 120a6e
    if (fxs.isEmpty() && columns.isEmpty()) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // in case of the paste command triggered from short cut key
Shinya Kitaoka 120a6e
    if (m_pastePosition == TConst::nowhere && m_schematicScene) {
Shinya Kitaoka 120a6e
      SchematicSceneViewer *ssv =
Shinya Kitaoka 120a6e
          dynamic_cast<schematicsceneviewer *="">(m_schematicScene->views().at(0));</schematicsceneviewer>
Shinya Kitaoka 120a6e
      if (ssv)
Shinya Kitaoka 120a6e
        m_pastePosition =
Shinya Kitaoka 120a6e
            TPointD(ssv->getOldScenePos().x(), ssv->getOldScenePos().y());
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
shun-iwasawa 60079f
    if (!columns.isEmpty()) {
shun-iwasawa 60079f
      // make sure that the levels contained in the pasted column nodes are
shun-iwasawa 60079f
      // registered in the scene cast it may rename the level if there is
shun-iwasawa 60079f
      // another level with the same name
shun-iwasawa 60079f
      TUndoManager::manager()->beginBlock();
shun-iwasawa 60079f
      emit columnPasted(columns);
shun-iwasawa 60079f
    }
shun-iwasawa 60079f
shun-iwasawa 443318
    TFxCommand::pasteFxs(std::list<tfxp>(fxs.begin(), fxs.end()),</tfxp>
shun-iwasawa 443318
                         zeraryFxColumnSize.toStdMap(),
shun-iwasawa 443318
                         std::list<txshcolumnp>(columns.begin(), columns.end()),</txshcolumnp>
shun-iwasawa 443318
                         m_pastePosition, m_xshHandle, m_fxHandle);
Shinya Kitaoka 120a6e
shun-iwasawa 60079f
    if (!columns.isEmpty()) {
shun-iwasawa 60079f
      TUndoManager::manager()->endBlock();
shun-iwasawa 60079f
    }
shun-iwasawa 60079f
Shinya Kitaoka 120a6e
    if (m_schematicScene) {
Shinya Kitaoka 120a6e
      selectNone();
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)fxs.size(); i++) select(fxs[i]);
Shinya Kitaoka 120a6e
      m_schematicScene->selectNodes(fxs);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_pastePosition = TConst::nowhere;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::insertPasteSelection() {
Shinya Kitaoka 120a6e
  QClipboard *clipboard  = QApplication::clipboard();
Shinya Kitaoka 120a6e
  const FxsData *fxsData = dynamic_cast<const *="" fxsdata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pastePosition = TConst::nowhere;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!fxsData || !fxsData->isConnected()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_selectedLinks.isEmpty()) return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Start an undo block and ensure it is appropriately destroyed
Shinya Kitaoka 120a6e
  struct Auto {
Shinya Kitaoka 120a6e
    bool m_destruct;
Shinya Kitaoka 120a6e
    ~Auto() {
Shinya Kitaoka 120a6e
      if (m_destruct) TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } auto_ = {false};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // Need to make a temporary copy of selected links. It's necessary since the
Shinya Kitaoka 120a6e
  // selection will
Shinya Kitaoka 120a6e
  // be updated (cleared) after each insertion.
Shinya Kitaoka 120a6e
  QList<tfxcommand::link> selectedLinks(m_selectedLinks);</tfxcommand::link>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, size = selectedLinks.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) {
Shinya Kitaoka 120a6e
    // Clone the fxs to be inserted
Shinya Kitaoka 120a6e
    QList<tfxp> fxs;</tfxp>
Shinya Kitaoka 120a6e
    QMap<tfx *,="" int=""> zeraryFxColumnSize;</tfx>
Shinya Kitaoka 120a6e
    QList<txshcolumnp> columns;</txshcolumnp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    fxsData->getFxs(fxs, zeraryFxColumnSize, columns);
Shinya Kitaoka 120a6e
    if (fxs.empty() && columns.empty()) return true;
Toshihiro Shimizu 890ddd
Jeremy Bullock 089f72
    // auto ends the undo block in the destructor.
Jeremy Bullock 089f72
    if (!auto_.m_destruct) {
shun-iwasawa 8f7598
      auto_.m_destruct = true;
shun-iwasawa 8f7598
      TUndoManager::manager()->beginBlock();
shun-iwasawa 60079f
      // make sure that the levels contained in the pasted column nodes are
shun-iwasawa 60079f
      // registered in the scene cast it may rename the level if there is
shun-iwasawa 60079f
      // another level with the same name
shun-iwasawa 60079f
      emit columnPasted(columns);
Jeremy Bullock 089f72
    }
Toshihiro Shimizu 890ddd
shun-iwasawa 443318
    TFxCommand::insertPasteFxs(
shun-iwasawa 443318
        selectedLinks[i], std::list<tfxp>(fxs.begin(), fxs.end()),</tfxp>
shun-iwasawa 443318
        zeraryFxColumnSize.toStdMap(),
shun-iwasawa 443318
        std::list<txshcolumnp>(columns.begin(), columns.end()), m_xshHandle,</txshcolumnp>
shun-iwasawa 443318
        m_fxHandle);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::addPasteSelection() {
Shinya Kitaoka 120a6e
  QClipboard *clipboard  = QApplication::clipboard();
Shinya Kitaoka 120a6e
  const FxsData *fxsData = dynamic_cast<const *="" fxsdata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pastePosition = TConst::nowhere;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!fxsData || !fxsData->isConnected()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_selectedFxs.isEmpty()) return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  struct Auto {
Shinya Kitaoka 120a6e
    bool m_destruct;
Shinya Kitaoka 120a6e
    ~Auto() {
Shinya Kitaoka 120a6e
      if (m_destruct) TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } auto_ = {false};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QList<tfxp> selectedFxs(m_selectedFxs);</tfxp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, size = selectedFxs.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) {
Shinya Kitaoka 120a6e
    // Clone the fxs to be inserted
Shinya Kitaoka 120a6e
    QList<tfxp> fxs;</tfxp>
Shinya Kitaoka 120a6e
    QMap<tfx *,="" int=""> zeraryFxColumnSize;</tfx>
Shinya Kitaoka 120a6e
    QList<txshcolumnp> columns;</txshcolumnp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    fxsData->getFxs(fxs, zeraryFxColumnSize, columns);
Shinya Kitaoka 120a6e
    if (fxs.empty() && columns.empty()) return true;
Toshihiro Shimizu 890ddd
Jeremy Bullock 089f72
    // auto ends the undo block in its destructor
Shinya Kitaoka 120a6e
    if (!auto_.m_destruct)
Shinya Kitaoka 120a6e
      auto_.m_destruct = true, TUndoManager::manager()->beginBlock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TFx *inFx = selectedFxs[i].getPointer();
shun-iwasawa 443318
    TFxCommand::addPasteFxs(
shun-iwasawa 443318
        inFx, std::list<tfxp>(fxs.begin(), fxs.end()),</tfxp>
shun-iwasawa 443318
        zeraryFxColumnSize.toStdMap(),
shun-iwasawa 443318
        std::list<txshcolumnp>(columns.begin(), columns.end()), m_xshHandle,</txshcolumnp>
shun-iwasawa 443318
        m_fxHandle);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::replacePasteSelection() {
Shinya Kitaoka 120a6e
  QClipboard *clipboard  = QApplication::clipboard();
Shinya Kitaoka 120a6e
  const FxsData *fxsData = dynamic_cast<const *="" fxsdata="">(clipboard->mimeData());</const>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_pastePosition = TConst::nowhere;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!fxsData || !fxsData->isConnected()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_selectedFxs.isEmpty()) return true;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  struct Auto {
Shinya Kitaoka 120a6e
    bool m_destruct;
Shinya Kitaoka 120a6e
    ~Auto() {
Shinya Kitaoka 120a6e
      if (m_destruct) TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } auto_ = {false};
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  QList<tfxp> selectedFxs(m_selectedFxs);</tfxp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int i, size = selectedFxs.size();
Shinya Kitaoka 120a6e
  for (i = 0; i < size; ++i) {
Shinya Kitaoka 120a6e
    // Clone the fxs to be inserted
Shinya Kitaoka 120a6e
    QList<tfxp> fxs;</tfxp>
Shinya Kitaoka 120a6e
    QMap<tfx *,="" int=""> zeraryFxColumnSize;</tfx>
Shinya Kitaoka 120a6e
    QList<txshcolumnp> columns;</txshcolumnp>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    fxsData->getFxs(fxs, zeraryFxColumnSize, columns);
Shinya Kitaoka 120a6e
    if (fxs.empty() && columns.empty()) return true;
Toshihiro Shimizu 890ddd
Jeremy Bullock 089f72
    // auto ends the undo block in its destructor
shun-iwasawa 60079f
    if (!auto_.m_destruct) {
Shinya Kitaoka 120a6e
      auto_.m_destruct = true, TUndoManager::manager()->beginBlock();
shun-iwasawa 60079f
      // make sure that the levels contained in the pasted column nodes are
shun-iwasawa 60079f
      // registered in the scene cast it may rename the level if there is
shun-iwasawa 60079f
      // another level with the same name
shun-iwasawa 60079f
      emit columnPasted(columns);
shun-iwasawa 60079f
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    TFx *inFx = m_selectedFxs[i].getPointer();
shun-iwasawa 443318
    TFxCommand::replacePasteFxs(
shun-iwasawa 443318
        inFx, std::list<tfxp>(fxs.begin(), fxs.end()),</tfxp>
shun-iwasawa 443318
        zeraryFxColumnSize.toStdMap(),
shun-iwasawa 443318
        std::list<txshcolumnp>(columns.begin(), columns.end()), m_xshHandle,</txshcolumnp>
shun-iwasawa 443318
        m_fxHandle);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::groupSelection() {
Shinya Kitaoka 120a6e
  if (m_selectedFxs.size() <= 1) return;
shun-iwasawa 443318
  TFxCommand::groupFxs(
shun-iwasawa 443318
      std::list<tfxp>(m_selectedFxs.begin(), m_selectedFxs.end()), m_xshHandle);</tfxp>
Shinya Kitaoka 120a6e
  selectNone();
Shinya Kitaoka 120a6e
  m_xshHandle->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::ungroupSelection() {
Shinya Kitaoka 120a6e
  if (isEmpty()) return;
Shinya Kitaoka 120a6e
  QSet<int> idSet;</int>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < m_selectedFxs.size(); i++) {
Shinya Kitaoka 120a6e
    int groupId = m_selectedFxs[i]->getAttributes()->getGroupId();
Shinya Kitaoka 120a6e
    if (groupId > 0) idSet.insert(groupId);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TUndoManager::manager()->beginBlock();
Shinya Kitaoka 120a6e
  QSet<int>::iterator it;</int>
Jeremy Bullock 089f72
  for (it = idSet.begin(); it != idSet.end(); it++) {
shun-iwasawa 8f7598
    TFxCommand::ungroupFxs(*it, m_xshHandle);
Jeremy Bullock 089f72
  }
Shinya Kitaoka 120a6e
  TUndoManager::manager()->endBlock();
Shinya Kitaoka 120a6e
  selectNone();
Shinya Kitaoka 120a6e
  m_xshHandle->notifyXsheetChanged();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::collapseSelection() {
Shinya Kitaoka 120a6e
  if (!m_selectedFxs.isEmpty()) emit doCollapse(m_selectedFxs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::explodeChild() {
Shinya Kitaoka 120a6e
  if (!m_selectedFxs.isEmpty()) emit doExplodeChild(m_selectedFxs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Link FxSelection::getBoundingFxs(SchematicLink *link) {
Shinya Kitaoka 120a6e
  Link boundingFxs;
Shinya Kitaoka 120a6e
  if (link) {
Shinya Kitaoka 120a6e
    SchematicPort *port = link->getStartPort();
Shinya Kitaoka 120a6e
    if (!port) return boundingFxs;
Shinya Kitaoka 120a6e
    if (port->getType() == 201 || port->getType() == 202 ||
Shinya Kitaoka 120a6e
        port->getType() == 203)
Shinya Kitaoka 120a6e
      boundingFxs = getBoundingFxs(port, link->getOtherPort(port));
Shinya Kitaoka 120a6e
    else if (port->getType() == 200 || port->getType() == 204)
Shinya Kitaoka 120a6e
      boundingFxs = getBoundingFxs(link->getOtherPort(port), port);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return boundingFxs;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
Link FxSelection::getBoundingFxs(SchematicPort *inputPort,
Shinya Kitaoka 120a6e
                                 SchematicPort *outputPort) {
Shinya Kitaoka 120a6e
  Link boundingFxs;
manongjohn cd6e9e
  if (!inputPort || !outputPort) return boundingFxs;
Shinya Kitaoka 120a6e
  FxSchematicNode *inputNode =
Shinya Kitaoka 120a6e
      dynamic_cast<fxschematicnode *="">(outputPort->getNode());</fxschematicnode>
Shinya Kitaoka 120a6e
  FxSchematicNode *outputNode =
Shinya Kitaoka 120a6e
      dynamic_cast<fxschematicnode *="">(inputPort->getNode());</fxschematicnode>
Shinya Kitaoka 120a6e
  FxGroupNode *groupNode = dynamic_cast<fxgroupnode *="">(inputNode);</fxgroupnode>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!inputNode || !outputNode ||
Shinya Kitaoka 120a6e
      (groupNode && groupNode->getOutputConnectionsCount() != 1))
Shinya Kitaoka 120a6e
    return boundingFxs;
Shinya Kitaoka 120a6e
  if (dynamic_cast<txsheetfx *="">(outputNode->getFx())) {</txsheetfx>
Shinya Kitaoka 120a6e
    if (!groupNode)
Shinya Kitaoka 120a6e
      boundingFxs.m_inputFx = inputNode->getFx();
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      TFxSet *terminals =
Shinya Kitaoka 120a6e
          m_xshHandle->getXsheet()->getFxDag()->getTerminalFxs();
Shinya Kitaoka 120a6e
      QList<tfxp> roots = groupNode->getRootFxs();</tfxp>
Shinya Kitaoka 120a6e
      int i;
Shinya Kitaoka 120a6e
      for (i = 0; i < roots.size(); i++)
Shinya Kitaoka 120a6e
        if (terminals->containsFx(roots[i].getPointer())) {
Shinya Kitaoka 120a6e
          boundingFxs.m_inputFx = roots[i];
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    boundingFxs.m_outputFx = outputNode->getFx();
Shinya Kitaoka 120a6e
    return boundingFxs;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (outputNode->isA(eGroupedFx)) {
Shinya Kitaoka 120a6e
    // devo prima trovare l'effetto interno al gruppo al quale inputNode e'
Shinya Kitaoka 120a6e
    // linkato.
Shinya Kitaoka 120a6e
    FxGroupNode *groupNode = dynamic_cast<fxgroupnode *="">(outputNode);</fxgroupnode>
Shinya Kitaoka 120a6e
    assert(groupNode);
Shinya Kitaoka 120a6e
    QList<tfx *=""> fxs;</tfx>
Shinya Kitaoka 120a6e
    TFx *inputFx = inputNode->getFx();
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < inputFx->getOutputConnectionCount(); i++) {
Shinya Kitaoka 120a6e
      TFx *outputFx = inputFx->getOutputConnection(i)->getOwnerFx();
Shinya Kitaoka 120a6e
      if (!outputFx) continue;
Shinya Kitaoka 120a6e
      if (groupNode->contains(outputFx)) fxs.push_back(outputFx);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (fxs.size() != 1)  // un nodo esterno al gruppo puo' essere linkato a
Shinya Kitaoka 120a6e
                          // piu' nodi interni al gruppo
Shinya Kitaoka 120a6e
      return boundingFxs;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    TFx *outputFx = fxs[0];
Shinya Kitaoka 120a6e
    // ho tovato l'effetto, ora devo trovare l'indice della porta a cui e'
Shinya Kitaoka 120a6e
    // linkato l'effetto in input
Shinya Kitaoka 120a6e
    for (i = 0; i < outputFx->getInputPortCount(); i++) {
Shinya Kitaoka 120a6e
      TFxPort *inputPort = outputFx->getInputPort(i);
Shinya Kitaoka 120a6e
      TFx *fx            = inputPort->getFx();
Shinya Kitaoka 120a6e
      if (fx == inputFx) break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (i >= outputFx->getInputPortCount()) return boundingFxs;
Shinya Kitaoka 120a6e
    boundingFxs.m_inputFx  = inputFx;
Shinya Kitaoka 120a6e
    boundingFxs.m_outputFx = outputFx;
Shinya Kitaoka 120a6e
    boundingFxs.m_index    = i;
Shinya Kitaoka 120a6e
    return boundingFxs;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    bool found = false;
Shinya Kitaoka 120a6e
    int i, index = -1;
Shinya Kitaoka 120a6e
    for (i = 0; i < outputNode->getInputPortCount() && !found; i++) {
Shinya Kitaoka 120a6e
      FxSchematicPort *inputAppPort = outputNode->getInputPort(i);
Shinya Kitaoka 120a6e
      int j;
Shinya Kitaoka 120a6e
      for (j = 0; j < inputAppPort->getLinkCount(); j++) {
Shinya Kitaoka 120a6e
        FxSchematicNode *outputAppNode =
Shinya Kitaoka 120a6e
            dynamic_cast<fxschematicnode *="">(inputAppPort->getLinkedNode(j));</fxschematicnode>
Shinya Kitaoka 120a6e
        if (!outputAppNode) continue;
Shinya Kitaoka 120a6e
        FxSchematicPort *outputAppPort = outputAppNode->getOutputPort();
Shinya Kitaoka 120a6e
        if (inputAppPort == inputPort && outputPort == outputAppPort) {
Shinya Kitaoka 120a6e
          found = true;
Shinya Kitaoka 120a6e
          index = i;
Shinya Kitaoka 120a6e
          break;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (index == -1) return boundingFxs;
Shinya Kitaoka 120a6e
    TFx *inputFx           = inputNode->getFx();
Shinya Kitaoka 120a6e
    TFx *outputFx          = outputNode->getFx();
Shinya Kitaoka 120a6e
    boundingFxs.m_inputFx  = inputFx;
Shinya Kitaoka 120a6e
    boundingFxs.m_outputFx = outputFx;
Shinya Kitaoka 120a6e
    boundingFxs.m_index    = index;
Shinya Kitaoka 120a6e
    return boundingFxs;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::isConnected() {
Shinya Kitaoka 120a6e
  if (m_selectedFxs.isEmpty()) return false;
Shinya Kitaoka 120a6e
  QList<tfx *=""> visitedFxs;</tfx>
Shinya Kitaoka 120a6e
  visitFx(m_selectedFxs.at(0).getPointer(), visitedFxs);
Shinya Kitaoka 120a6e
  bool connected = true;
Shinya Kitaoka 120a6e
  QList<tfxp>::const_iterator it;</tfxp>
Shinya Kitaoka 120a6e
  TXsheet *xsh        = m_xshHandle->getXsheet();
Shinya Kitaoka 120a6e
  TFxSet *internalFxs = xsh->getFxDag()->getInternalFxs();
Shinya Kitaoka 120a6e
  for (it = m_selectedFxs.begin(); it != m_selectedFxs.end(); it++) {
Shinya Kitaoka 120a6e
    TFx *selectedFx = it->getPointer();
Shinya Kitaoka 120a6e
    TColumnFx *cfx  = dynamic_cast<tcolumnfx *="">(selectedFx);</tcolumnfx>
Shinya Kitaoka 120a6e
    if (!cfx && !internalFxs->containsFx(selectedFx)) return false;
Shinya Kitaoka 120a6e
    TZeraryColumnFx *zfx = dynamic_cast<tzerarycolumnfx *="">(selectedFx);</tzerarycolumnfx>
shun-iwasawa 4a3868
    if (zfx) selectedFx = zfx->getZeraryFx();
shun-iwasawa 4a3868
    connected = connected && visitedFxs.contains(selectedFx);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return connected;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void FxSelection::visitFx(TFx *fx, QList<tfx *=""> &visitedFxs) {</tfx>
Shinya Kitaoka 120a6e
  if (visitedFxs.contains(fx)) return;
Shinya Kitaoka 120a6e
  TZeraryColumnFx *zfx = dynamic_cast<tzerarycolumnfx *="">(fx);</tzerarycolumnfx>
shun-iwasawa 4a3868
  if (zfx) fx = zfx->getZeraryFx();
Shinya Kitaoka 120a6e
  if (!canGroup(fx)) return;
Shinya Kitaoka 120a6e
  visitedFxs.append(fx);
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < fx->getInputPortCount(); i++) {
Shinya Kitaoka 120a6e
    TFx *inputFx              = fx->getInputPort(i)->getFx();
Shinya Kitaoka 120a6e
    TZeraryColumnFx *onputZFx = dynamic_cast<tzerarycolumnfx *="">(inputFx);</tzerarycolumnfx>
shun-iwasawa 4a3868
    if (onputZFx) inputFx = onputZFx->getZeraryFx();
Shinya Kitaoka 120a6e
    if (!inputFx) continue;
Shinya Kitaoka 120a6e
    bool canBeGrouped = !inputFx->getAttributes()->isGrouped() ||
Shinya Kitaoka 120a6e
                        (inputFx->getAttributes()->getEditingGroupId() ==
Shinya Kitaoka 120a6e
                         fx->getAttributes()->getEditingGroupId());
Shinya Kitaoka 120a6e
    if (!visitedFxs.contains(inputFx) && isSelected(inputFx) && canBeGrouped)
Shinya Kitaoka 120a6e
      visitFx(inputFx, visitedFxs);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (zfx) fx = zfx;
Shinya Kitaoka 120a6e
  if (fx->isZerary() && !zfx) {
Shinya Kitaoka 120a6e
    TXsheet *xsh    = m_xshHandle->getXsheet();
Shinya Kitaoka 120a6e
    int columnCount = xsh->getColumnCount();
Shinya Kitaoka 120a6e
    int j;
Shinya Kitaoka 120a6e
    for (j = 0; j < columnCount; j++) {
Shinya Kitaoka 120a6e
      TZeraryColumnFx *zerary =
Shinya Kitaoka 120a6e
          dynamic_cast<tzerarycolumnfx *="">(xsh->getColumn(j)->getFx());</tzerarycolumnfx>
Shinya Kitaoka 120a6e
      if (zerary && zerary->getZeraryFx() == fx) {
Shinya Kitaoka 120a6e
        fx = zerary;
Shinya Kitaoka 120a6e
        break;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  for (i = 0; i < fx->getOutputConnectionCount(); i++) {
Shinya Kitaoka 120a6e
    TFx *outputFx = fx->getOutputConnection(i)->getOwnerFx();
Shinya Kitaoka 120a6e
    if (!outputFx) continue;
Shinya Kitaoka 120a6e
    bool canBeGrouped = !outputFx->getAttributes()->isGrouped() ||
Shinya Kitaoka 120a6e
                        (outputFx->getAttributes()->getEditingGroupId() ==
Shinya Kitaoka 120a6e
                         fx->getAttributes()->getEditingGroupId());
Shinya Kitaoka 120a6e
    if (!visitedFxs.contains(outputFx) && isSelected(outputFx) && canBeGrouped)
Shinya Kitaoka 120a6e
      visitFx(outputFx, visitedFxs);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool FxSelection::areLinked(TFx *outFx, TFx *inFx) {
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < outFx->getInputPortCount(); i++) {
Shinya Kitaoka 120a6e
    TFx *inputFx = outFx->getInputPort(i)->getFx();
Shinya Kitaoka 120a6e
    if (inFx == inputFx) return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}