Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzCore includes
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "toutputproperties.h"
Toshihiro Shimizu 890ddd
#include "tfx.h"
Toshihiro Shimizu 890ddd
#include "tparamcontainer.h"
Toshihiro Shimizu 890ddd
#include "tparamset.h"
Toshihiro Shimizu 890ddd
#include "tfxattributes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshchildlevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/observer.h"
Toshihiro Shimizu 890ddd
#include "toonz/controlpointobserver.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfx.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfxset.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshpalettecolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshzeraryfxcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/columnfan.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshnoteset.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsimplelevel.h"
Toshihiro Shimizu 890ddd
#include "toonz/stage.h"
Toshihiro Shimizu 890ddd
#include "toonz/textureutils.h"
Toshihiro Shimizu 890ddd
#include "xshhandlemanager.h"
Jaroslav 203cc8
#include "orientation.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TXsheet, 18)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
namespace {
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
string getColumnDefaultName(TXsheet *xsh, int col, QString oldName) {
Shinya Kitaoka 120a6e
  TXshColumn *column = xsh->getColumn(col);
Shinya Kitaoka 120a6e
  if (column) {
Shinya Kitaoka 120a6e
    TXshLevelColumn *lc = column->getLevelColumn();
Shinya Kitaoka 120a6e
    if (lc) {
Shinya Kitaoka 120a6e
      int r0, r1;
Shinya Kitaoka 120a6e
      if (lc->getRange(r0, r1)) {
Shinya Kitaoka 120a6e
        TXshCell cell = lc->getCell(r0);
Shinya Kitaoka 120a6e
        assert(!cell.isEmpty());
Shinya Kitaoka 120a6e
        TXshLevel *level = cell.m_level.getPointer();
Shinya Kitaoka 120a6e
        if (level) {
Shinya Kitaoka 120a6e
          bool isNumber = true;
Shinya Kitaoka 120a6e
          oldName.right(oldName.size() - 3).toInt(&isNumber);
Shinya Kitaoka 120a6e
          if (oldName.left(3) == "Col" && isNumber)
Shinya Kitaoka 120a6e
            return ::to_string(level->getName());
Shinya Kitaoka 120a6e
          else
Shinya Kitaoka 120a6e
            return "";
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return "Col" + std::to_string(col + 1);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void setColumnName(TXsheet *xsh, int col) {
Shinya Kitaoka 120a6e
  TStageObject *obj = xsh->getStageObject(TStageObjectId::ColumnId(col));
Shinya Kitaoka 120a6e
  QString oldName   = QString::fromStdString(obj->getName());
Shinya Kitaoka 120a6e
  string name       = getColumnDefaultName(xsh, col, oldName);
Shinya Kitaoka 120a6e
  if (!name.empty()) obj->setName(name);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// TXsheetImp
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
struct TXsheet::TXsheetImp {
Shinya Kitaoka 120a6e
  unsigned long m_id;  //!< The xsheet instance's unique identifier
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TColumnSetT<txshcolumn> m_columnSet;</txshcolumn>
Shinya Kitaoka 120a6e
  TStageObjectTree *m_pegTree;
Shinya Kitaoka 120a6e
  FxDag *m_fxDag;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int m_frameCount;
Shinya Kitaoka 120a6e
  int m_soloColumn;
Shinya Kitaoka 120a6e
  int m_viewColumn;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSoundTrackP m_mixedSound;
Jaroslav 203cc8
  ColumnFan m_columnFans[Orientations::COUNT];
Shinya Kitaoka 120a6e
  XshHandleManager *m_handleManager;
Shinya Kitaoka 120a6e
  ToonzScene *m_scene;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TXsheetImp();
Shinya Kitaoka 120a6e
  ~TXsheetImp();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  static inline unsigned long newIdentifier() {
Shinya Kitaoka 120a6e
    static unsigned long currentId = 0;
Shinya Kitaoka 120a6e
    return ++currentId;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
  void copyFoldedState();
Jaroslav 203cc8
Toshihiro Shimizu 890ddd
private:
Jaroslav 203cc8
  void initColumnFans();
Jaroslav 203cc8
Shinya Kitaoka 120a6e
  // not implemented
Shinya Kitaoka 120a6e
  TXsheetImp(const TXsheetImp &);
Shinya Kitaoka 120a6e
  TXsheetImp &operator=(const TXsheetImp &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXsheet::SoundProperties::SoundProperties()
Shinya Kitaoka 120a6e
    : m_fromFrame(-1), m_toFrame(-1), m_frameRate(-1), m_isPreview(false) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXsheet::SoundProperties::~SoundProperties() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool TXsheet::SoundProperties::operator==(
Shinya Kitaoka 120a6e
    const SoundProperties &c) const {
Shinya Kitaoka 120a6e
  return m_fromFrame == c.m_fromFrame && m_toFrame == c.m_toFrame &&
Shinya Kitaoka 120a6e
         m_frameRate == c.m_frameRate && m_isPreview == c.m_isPreview;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool TXsheet::SoundProperties::operator!=(
Shinya Kitaoka 120a6e
    const SoundProperties &c) const {
Shinya Kitaoka 120a6e
  return !(*this == c);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXsheet::TXsheetImp::TXsheetImp()
Shinya Kitaoka 120a6e
    : m_id(newIdentifier())
Shinya Kitaoka 120a6e
    , m_pegTree(new TStageObjectTree)
Shinya Kitaoka 120a6e
    , m_handleManager(0)
Shinya Kitaoka 120a6e
    , m_fxDag(new FxDag())
Shinya Kitaoka 120a6e
    , m_frameCount(0)
Shinya Kitaoka 120a6e
    , m_soloColumn(-1)
Shinya Kitaoka 120a6e
    , m_viewColumn(-1)
Shinya Kitaoka 120a6e
    , m_mixedSound(0)
Jaroslav 203cc8
    , m_scene(0) {
Jaroslav 203cc8
  initColumnFans();
Jaroslav 203cc8
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXsheet::TXsheetImp::~TXsheetImp() {
Shinya Kitaoka 120a6e
  assert(m_pegTree);
Shinya Kitaoka 120a6e
  assert(m_fxDag);
Shinya Kitaoka 120a6e
  assert(m_handleManager);
Shinya Kitaoka 120a6e
  delete m_pegTree;
Shinya Kitaoka 120a6e
  delete m_fxDag;
Shinya Kitaoka 120a6e
  delete m_handleManager;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
//-----------------------------------------------------------------------------
Jaroslav 203cc8
Jaroslav 203cc8
void TXsheet::TXsheetImp::initColumnFans() {
Jaroslav 203cc8
  for (auto o : Orientations::all()) {
Jaroslav 203cc8
    int index = o->dimension(PredefinedDimension::INDEX);
Jaroslav 203cc8
    m_columnFans[index].setDimension(o->dimension(PredefinedDimension::LAYER));
Jaroslav 203cc8
  }
Jaroslav 203cc8
}
Jaroslav 203cc8
Jaroslav 203cc8
void TXsheet::TXsheetImp::copyFoldedState() {
Jaroslav 203cc8
  for (int i = 1; i < Orientations::COUNT; i++)
Jaroslav 203cc8
    m_columnFans[i].copyFoldedStateFrom(m_columnFans[0]);
Jaroslav 203cc8
}
Jaroslav 203cc8
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// TXsheet
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXsheet::TXsheet()
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_player(0)
Shinya Kitaoka 120a6e
    , m_imp(new TXsheet::TXsheetImp)
Shinya Kitaoka 120a6e
    , m_notes(new TXshNoteSet()) {
Shinya Kitaoka 120a6e
  // extern TSyntax::Grammar *createXsheetGrammar(TXsheet*);
Shinya Kitaoka 120a6e
  m_soundProperties      = new TXsheet::SoundProperties();
Shinya Kitaoka 120a6e
  m_imp->m_handleManager = new XshHandleManager(this);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->setHandleManager(m_imp->m_handleManager);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->createGrammar(this);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXsheet::~TXsheet() {
Shinya Kitaoka 120a6e
  texture_utils::invalidateTextures(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  assert(m_imp);
Shinya Kitaoka 120a6e
  if (m_notes) delete m_notes;
Shinya Kitaoka 120a6e
  if (m_soundProperties) delete m_soundProperties;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
unsigned long TXsheet::id() const { return m_imp->m_id; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXsheet::getFrameCount() const { return m_imp->m_frameCount; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TXshCell &TXsheet::getCell(int row, int col) const {
Jaroslav 203cc8
  return getCell(CellPosition(row, col));
Jaroslav 203cc8
}
Jaroslav 203cc8
Jaroslav 203cc8
const TXshCell &TXsheet::getCell(const CellPosition &pos) const {
Shinya Kitaoka 120a6e
  static const TXshCell emptyCell;
Jaroslav 203cc8
Jaroslav 203cc8
  TXshColumnP column = m_imp->m_columnSet.getColumn(pos.layer());
Shinya Kitaoka 120a6e
  if (!column) return emptyCell;
Shinya Kitaoka 120a6e
  TXshCellColumn *xshColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!xshColumn) return emptyCell;
Jaroslav 203cc8
  return xshColumn->getCell(pos.frame());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::setCell(int row, int col, const TXshCell &cell) {
Shinya Kitaoka 120a6e
  if (row < 0 || col < 0) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  bool wasColumnEmpty = isColumnEmpty(col);
Shinya Kitaoka 120a6e
  TXshCellColumn *cellColumn;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!cell.isEmpty()) {
Shinya Kitaoka 120a6e
    TXshLevel *level = cell.m_level.getPointer();
Shinya Kitaoka 120a6e
    assert(level);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int levelType               = level->getType();
Shinya Kitaoka 120a6e
    TXshColumn::ColumnType type = TXshColumn::eLevelType;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (levelType == SND_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eSoundType;
Shinya Kitaoka 120a6e
    else if (levelType == SND_TXT_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eSoundTextType;
Shinya Kitaoka 120a6e
    else if (levelType == PLT_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::ePaletteType;
Shinya Kitaoka 120a6e
    else if (levelType == ZERARYFX_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eZeraryFxType;
Shinya Kitaoka 120a6e
    else if (levelType == MESH_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eMeshType;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    cellColumn = touchColumn(col, type)->getCellColumn();
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    TXshColumn *column = getColumn(col);
Shinya Kitaoka 120a6e
    cellColumn         = column ? column->getCellColumn() : 0;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!cellColumn || cellColumn->isLocked()) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  cellColumn->setXsheet(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!cellColumn->setCell(row, cell)) {
Shinya Kitaoka 120a6e
    if (wasColumnEmpty) {
Shinya Kitaoka 120a6e
      removeColumn(col);
Shinya Kitaoka 120a6e
      insertColumn(col);
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFx *fx = cellColumn->getFx();
Shinya Kitaoka 120a6e
  if (wasColumnEmpty && fx && fx->getOutputConnectionCount() == 0 &&
Shinya Kitaoka 120a6e
      cellColumn->getPaletteColumn() == 0)
Shinya Kitaoka 120a6e
    getFxDag()->addToXsheet(fx);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (cell.isEmpty())
Shinya Kitaoka 120a6e
    updateFrameCount();
Shinya Kitaoka 120a6e
  else if (row >= m_imp->m_frameCount)
Shinya Kitaoka 120a6e
    m_imp->m_frameCount = row + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TNotifier::instance()->notify(TXsheetChange());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::getCells(int row, int col, int rowCount, TXshCell cells[]) const {
Shinya Kitaoka 120a6e
  static const TXshCell emptyCell;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column) {
Shinya Kitaoka 120a6e
    for (i = 0; i < rowCount; i++) cells[i] = emptyCell;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TXshCellColumn *xshColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!xshColumn) {
Shinya Kitaoka 120a6e
    for (i = 0; i < rowCount; i++) cells[i] = emptyCell;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  xshColumn->getCells(row, rowCount, cells);
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::setCells(int row, int col, int rowCount, const TXshCell cells[]) {
Shinya Kitaoka 120a6e
  static const TXshCell emptyCell;
Shinya Kitaoka 120a6e
  int i = 0;
Shinya Kitaoka 120a6e
  while (i < rowCount && cells[i].isEmpty()) i++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // inserito da Elisa verso novembre 2009.
Shinya Kitaoka 120a6e
  // cosi' ha il difetto che se assegno celle vuote non fa nulla
Shinya Kitaoka 120a6e
  // per ora lo commento. bisogna indagare se questo rompe qualcosa
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // ho modificato il seguito per gestire il caso in cui i>=rowCount
Shinya Kitaoka 120a6e
  // => niente livelli dentro cells
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // if(i>=rowCount)
Shinya Kitaoka 120a6e
  //  return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshColumn::ColumnType type = TXshColumn::eLevelType;
Shinya Kitaoka 120a6e
  if (i < rowCount) {
Shinya Kitaoka 120a6e
    TXshLevel *level = cells[i].m_level.getPointer();
Shinya Kitaoka 120a6e
    int levelType    = level->getType();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    if (levelType == SND_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eSoundType;
Shinya Kitaoka 120a6e
    else if (levelType == SND_TXT_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eSoundTextType;
Shinya Kitaoka 120a6e
    else if (levelType == PLT_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::ePaletteType;
Shinya Kitaoka 120a6e
    else if (levelType == ZERARYFX_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eZeraryFxType;
Shinya Kitaoka 120a6e
    else if (levelType == MESH_XSHLEVEL)
Shinya Kitaoka 120a6e
      type = TXshColumn::eMeshType;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bool wasColumnEmpty    = isColumnEmpty(col);
Shinya Kitaoka 120a6e
  TXshCellColumn *column = touchColumn(col, type)->getCellColumn();
Shinya Kitaoka 120a6e
  if (!column) return false;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int oldColRowCount = column->getMaxFrame() + 1;
Shinya Kitaoka 120a6e
  bool ret           = column->setCells(row, rowCount, cells);
Shinya Kitaoka 120a6e
  if (!ret || column->isLocked()) {
Shinya Kitaoka 120a6e
    if (wasColumnEmpty) {
Shinya Kitaoka 120a6e
      removeColumn(col);
Shinya Kitaoka 120a6e
      insertColumn(col);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  int newColRowCount = column->getMaxFrame() + 1;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TFx *fx = column->getFx();
Shinya Kitaoka 120a6e
  if (wasColumnEmpty && fx && fx->getOutputConnectionCount() == 0)
Shinya Kitaoka 120a6e
    getFxDag()->addToXsheet(fx);
Shinya Kitaoka 120a6e
  column->setXsheet(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (newColRowCount > m_imp->m_frameCount)
Shinya Kitaoka 120a6e
    m_imp->m_frameCount = newColRowCount;
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    if (oldColRowCount == m_imp->m_frameCount &&
Shinya Kitaoka 120a6e
        newColRowCount < m_imp->m_frameCount)
Shinya Kitaoka 120a6e
      updateFrameCount();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::insertCells(int row, int col, int rowCount) {
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column || column->isLocked()) return;
Shinya Kitaoka 120a6e
  TXshCellColumn *xshColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!xshColumn) return;
Shinya Kitaoka 120a6e
  xshColumn->insertEmptyCells(row, rowCount);
Shinya Kitaoka 120a6e
  // aggiorno il frame count
Shinya Kitaoka 120a6e
  int fc = xshColumn->getMaxFrame() + 1;
Shinya Kitaoka 120a6e
  if (fc > m_imp->m_frameCount) m_imp->m_frameCount = fc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::removeCells(int row, int col, int rowCount) {
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column || column->isLocked()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshCellColumn *xshCellColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!xshCellColumn) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int oldColRowCount = xshCellColumn->getMaxFrame() + 1;
Shinya Kitaoka 120a6e
  xshCellColumn->removeCells(row, rowCount);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // aggiornamento framecount
Shinya Kitaoka 120a6e
  if (oldColRowCount == m_imp->m_frameCount) updateFrameCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TNotifier::instance()->notify(TXsheetChange());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::clearCells(int row, int col, int rowCount) {
Shinya Kitaoka 120a6e
  const TXshColumnP &column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column || column->isLocked()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXshCellColumn *xshCellColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!xshCellColumn) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int oldColRowCount = xshCellColumn->getMaxFrame() + 1;
Shinya Kitaoka 120a6e
  xshCellColumn->clearCells(row, rowCount);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // aggiornamento framecount
Shinya Kitaoka 120a6e
  if (oldColRowCount == m_imp->m_frameCount) updateFrameCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::clearAll() {
Shinya Kitaoka 120a6e
  int c0 = 0, c1 = m_imp->m_columnSet.getColumnCount() - 1;
Shinya Kitaoka 120a6e
  int r0 = 0, r1 = getFrameCount() - 1;
Shinya Kitaoka 120a6e
  m_imp->m_columnSet.clear();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_pegTree) {
Shinya Kitaoka 120a6e
    delete m_imp->m_pegTree;
Shinya Kitaoka 120a6e
    m_imp->m_pegTree = new TStageObjectTree();
Shinya Kitaoka 120a6e
    m_imp->m_pegTree->setHandleManager(m_imp->m_handleManager);
Shinya Kitaoka 120a6e
    m_imp->m_pegTree->createGrammar(this);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_imp->m_fxDag) {
Shinya Kitaoka 120a6e
    delete m_imp->m_fxDag;
Shinya Kitaoka 120a6e
    m_imp->m_fxDag = new FxDag();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  m_imp->m_frameCount = 0;
Shinya Kitaoka 120a6e
  m_imp->m_mixedSound = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXsheet::getCellRange(int col, int &r0, int &r1) const {
Shinya Kitaoka 120a6e
  r0                 = 0;
Shinya Kitaoka 120a6e
  r1                 = -1;
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column) return 0;
Shinya Kitaoka 120a6e
  TXshCellColumn *cellColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
  if (!cellColumn) return 0;
Shinya Kitaoka 120a6e
  return cellColumn->getRange(r0, r1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXsheet::getMaxFrame(int col) const {
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  if (!column) return 0;
Shinya Kitaoka 120a6e
  return column->getMaxFrame();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::isColumnEmpty(int col) const {
Shinya Kitaoka 120a6e
  TXshColumnP column = m_imp->m_columnSet.getColumn(col);
Shinya Kitaoka 120a6e
  return column ? column->isEmpty() : true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::getUsedLevels(set<txshlevel *=""> &levels) const {</txshlevel>
Shinya Kitaoka 120a6e
  set<const *="" txsheet=""> visitedXshs;</const>
Shinya Kitaoka 120a6e
  vector<const *="" txsheet=""> todoXshs;</const>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  visitedXshs.insert(this);
Shinya Kitaoka 120a6e
  todoXshs.push_back(this);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  while (!todoXshs.empty()) {
Shinya Kitaoka 120a6e
    const TXsheet *xsh = todoXshs.back();
Shinya Kitaoka 120a6e
    todoXshs.pop_back();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    int c0 = 0, c1 = xsh->getColumnCount() - 1;
Shinya Kitaoka 120a6e
    for (int c = c0; c <= c1; ++c) {
Shinya Kitaoka 120a6e
      TXshColumnP column = const_cast<txsheet *="">(xsh)->getColumn(c);</txsheet>
Shinya Kitaoka 120a6e
      if (!column) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TXshCellColumn *cellColumn = column->getCellColumn();
Shinya Kitaoka 120a6e
      if (!cellColumn) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      int r0, r1;
Shinya Kitaoka 120a6e
      if (!cellColumn->getRange(r0, r1)) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      TXshLevel *level = 0;
Shinya Kitaoka 120a6e
      for (int r = r0; r <= r1; r++) {
Shinya Kitaoka 120a6e
        TXshCell cell = cellColumn->getCell(r);
Shinya Kitaoka 120a6e
        if (cell.isEmpty() || !cell.m_level) continue;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
        if (level != cell.m_level.getPointer()) {
Shinya Kitaoka 120a6e
          level = cell.m_level.getPointer();
Shinya Kitaoka 120a6e
          levels.insert(level);
Shinya Kitaoka 120a6e
          if (level->getChildLevel()) {
Shinya Kitaoka 120a6e
            TXsheet *childXsh = level->getChildLevel()->getXsheet();
Shinya Kitaoka 120a6e
            if (visitedXshs.count(childXsh) == 0) {
Shinya Kitaoka 120a6e
              visitedXshs.insert(childXsh);
Shinya Kitaoka 120a6e
              todoXshs.push_back(childXsh);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::isLevelUsed(TXshLevel *level) const {
Shinya Kitaoka 120a6e
  set<txshlevel *=""> levels;</txshlevel>
Shinya Kitaoka 120a6e
  getUsedLevels(levels);
Shinya Kitaoka 120a6e
  return levels.count(level) > 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObject *TXsheet::getStageObject(const TStageObjectId &id) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectTree *TXsheet::getStageObjectTree() const {
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TXsheet::getPlacement(const TStageObjectId &id, int frame) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getPlacement(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TXsheet::getZ(const TStageObjectId &id, int frame) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getZ(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TXsheet::getNoScaleZ(const TStageObjectId &id) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getNoScaleZ();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TXsheet::getParentPlacement(const TStageObjectId &id, int frame) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getParentPlacement(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TPointD TXsheet::getCenter(const TStageObjectId &id, int frame) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getCenter(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::setCenter(const TStageObjectId &id, int frame,
Shinya Kitaoka 120a6e
                        const TPointD ¢er) {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->getStageObject(id)->setCenter(frame, center);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TStageObjectId TXsheet::getStageObjectParent(const TStageObjectId &id) {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->getParent();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::setStageObjectParent(const TStageObjectId &id,
Shinya Kitaoka 120a6e
                                   const TStageObjectId &parentId) {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->getStageObject(id)->setParent(parentId);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::hasChildren(const TStageObjectId &id) const {
Shinya Kitaoka 120a6e
  assert(id != TStageObjectId::NoneId);
Shinya Kitaoka 120a6e
  return m_imp->m_pegTree->getStageObject(id)->hasChildren();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TXsheet::getCameraAff(int frame) const {
Shinya Kitaoka 120a6e
  TStageObjectId cameraId = getStageObjectTree()->getCurrentCameraId();
Shinya Kitaoka 120a6e
  TAffine cameraAff       = getPlacement(cameraId, frame);
Shinya Kitaoka 120a6e
  double cameraZ          = getZ(cameraId, frame);
Shinya Kitaoka 120a6e
  TAffine aff             = cameraAff * TScale((1000 + cameraZ) / 1000);
Shinya Kitaoka 120a6e
  return aff;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::reverseCells(int r0, int c0, int r1, int c1) {
Shinya Kitaoka 120a6e
  int rowCount = r1 - r0;
Shinya Kitaoka 120a6e
  if (rowCount < 0 || c1 - c0 < 0) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
    int i1, i2;
Shinya Kitaoka 120a6e
    for (i1 = r0, i2 = r1; i1 < i2; i1++, i2--) {
Jaroslav 203cc8
      TXshCell app1 = getCell(CellPosition(i1, j));
Jaroslav 203cc8
      TXshCell app2 = getCell(CellPosition(i2, j));
Shinya Kitaoka 120a6e
      setCell(i1, j, app2);
Shinya Kitaoka 120a6e
      setCell(i2, j, app1);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::swingCells(int r0, int c0, int r1, int c1) {
Shinya Kitaoka 120a6e
  int rowCount = r1 - r0;
Shinya Kitaoka 120a6e
  if (rowCount < 0 || c1 - c0 < 0) return;
Shinya Kitaoka 120a6e
  int r0Mod = r1 + 1;
Shinya Kitaoka 120a6e
  for (int c = c0; c <= c1; ++c) insertCells(r0Mod, c, rowCount);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (int j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
    for (int i1 = r0Mod, i2 = r1 - 1; i2 >= r0; i1++, i2--) {
Jaroslav 203cc8
      TXshCell cell = getCell(CellPosition(i2, j));
Shinya Kitaoka 120a6e
      setCell(i1, j, cell);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::incrementCells(int r0, int c0, int r1, int c1,
Shinya Kitaoka 120a6e
                             vector<std::pair<trect, txshcell="">> &forUndo) {</std::pair<trect,>
Shinya Kitaoka 120a6e
  for (int j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
    int i = r0;
Jaroslav 203cc8
    while (getCell(CellPosition(i, j)).isEmpty() && i <= r1 - 1) i++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    for (; i <= r1 - 1; i++) {
Jaroslav 203cc8
      if (getCell(CellPosition(i + 1, j)).isEmpty()) break;
Jaroslav 203cc8
      const TXshCell &ce1 = getCell(CellPosition(i, j)),
Jaroslav 203cc8
                     &ce2 = getCell(CellPosition(i + 1, j));
Shinya Kitaoka 120a6e
      if (ce2.getSimpleLevel() != ce1.getSimpleLevel() ||
Shinya Kitaoka 120a6e
          ce2.getFrameId().getNumber() < ce1.getFrameId().getNumber())
Shinya Kitaoka 120a6e
        return false;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    i = r0;
Jaroslav 203cc8
    while (getCell(CellPosition(i, j)).isEmpty() && i <= r1 - 1) i++;
Shinya Kitaoka 120a6e
    int count;
Shinya Kitaoka 120a6e
    for (; i <= r1 - 1; i++) {
Shinya Kitaoka 120a6e
      count = 1;
Jaroslav 203cc8
      if (getCell(CellPosition(i + 1, j)).isEmpty()) continue;
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
      int frame1 = getCell(CellPosition(i, j)).getFrameId().getNumber();
Shinya Kitaoka 120a6e
      if (frame1 == -1) break;
Jaroslav 203cc8
      while (!getCell(CellPosition(i + 1, j)).isEmpty() &&
Jaroslav 203cc8
             getCell(CellPosition(i + 1, j)).getFrameId().getNumber() ==
Jaroslav 203cc8
                 getCell(CellPosition(i, j)).getFrameId().getNumber())
Shinya Kitaoka 120a6e
        i++, count++;
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
      int frame2 = getCell(CellPosition(i + 1, j)).getFrameId().getNumber();
Shinya Kitaoka 120a6e
      if (frame2 == -1) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (frame1 + count == frame2)
Shinya Kitaoka 120a6e
        continue;
Jaroslav 203cc8
      else if (frame1 + count < frame2)  // add
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        int numCells = frame2 - frame1 - count;
Shinya Kitaoka 120a6e
        insertCells(i + 1, j, numCells);
Shinya Kitaoka 120a6e
        forUndo.push_back(std::pair<trect, txshcell="">(</trect,>
Shinya Kitaoka 120a6e
            TRect(i + 1, j, i + 1 + numCells - 1, j), TXshCell()));
Jaroslav 203cc8
        for (int k = 1; k <= numCells; k++)
Jaroslav 203cc8
          setCell(i + k, j, getCell(CellPosition(i, j)));
Shinya Kitaoka 120a6e
        i += numCells;
Shinya Kitaoka 120a6e
        r1 += numCells;
Jaroslav 203cc8
      } else  // remove
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        int numCells = count - frame2 + frame1;
Shinya Kitaoka 120a6e
        i            = i - numCells;
Jaroslav 203cc8
        forUndo.push_back(
Jaroslav 203cc8
            std::pair<trect, txshcell="">(TRect(i + 1, j, i + 1 + numCells - 1, j),</trect,>
Jaroslav 203cc8
                                       getCell(CellPosition(i + 1, j))));
Shinya Kitaoka 120a6e
        removeCells(i + 1, j, numCells);
Shinya Kitaoka 120a6e
        r1 -= numCells;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return true;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::duplicateCells(int r0, int c0, int r1, int c1, int upTo) {
Shinya Kitaoka 120a6e
  assert(upTo >= r1 + 1);
Shinya Kitaoka 120a6e
  int chunk = r1 - r0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
    insertCells(r1 + 1, j, upTo - (r1 + 1) + 1);
Shinya Kitaoka 120a6e
    for (int i = r1 + 1; i <= upTo; i++)
Jaroslav 203cc8
      setCell(i, j, getCell(CellPosition(r0 + ((i - (r1 + 1)) % chunk), j)));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::stepCells(int r0, int c0, int r1, int c1, int type) {
Shinya Kitaoka 120a6e
  int nr = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  int nc = c1 - c0 + 1;
Shinya Kitaoka 120a6e
  if (nr < 1 || nc <= 0) return;
Shinya Kitaoka 120a6e
  int size = nr * nc;
Shinya Kitaoka 120a6e
  std::unique_ptr<txshcell[]> cells(new TXshCell[size]);</txshcell[]>
Shinya Kitaoka 120a6e
  if (!cells) return;
Shinya Kitaoka 120a6e
  // salvo il contenuto delle celle in cells
Shinya Kitaoka 120a6e
  int k = 0;
Shinya Kitaoka 120a6e
  for (int r = r0; r <= r1; r++)
Shinya Kitaoka 120a6e
    for (int c = c0; c <= c1; c++) {
Jaroslav 203cc8
      cells[k++] = getCell(CellPosition(r, c));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int nrows = nr * (type - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int c = c0; c <= c1; ++c) insertCells(r1 + 1, c, nrows);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
    int i, k;
Shinya Kitaoka 120a6e
    for (i = r0, k = j - c0; k < size; k += nc) {
Shinya Kitaoka 120a6e
      for (int i1 = 0; i1 < type; i1++) {
Shinya Kitaoka 120a6e
        if (cells[k].isEmpty())
Shinya Kitaoka 120a6e
          clearCells(i + i1, j);
Shinya Kitaoka 120a6e
        else
Shinya Kitaoka 120a6e
          setCell(i + i1, j, cells[k]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      i += type;  // dipende dal tipo di step (2 o 3 per ora)
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::increaseStepCells(int r0, int c0, int &r1, int c1) {
Shinya Kitaoka 120a6e
  int c, size = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  QList<int> ends;</int>
Shinya Kitaoka 120a6e
  for (c = c0; c <= c1; c++) {
Shinya Kitaoka 120a6e
    int r = r0, i = 0, rEnd = r1;
Shinya Kitaoka 120a6e
    while (r <= rEnd) {
Jaroslav 203cc8
      TXshCell cell = getCell(CellPosition(r, c));
Shinya Kitaoka 120a6e
      if (!cell.isEmpty()) {
Shinya Kitaoka 120a6e
        insertCells(r, c);
Shinya Kitaoka 120a6e
        setCell(r, c, cell);
Shinya Kitaoka 120a6e
        rEnd++;
Shinya Kitaoka 120a6e
        r++;
Jaroslav 203cc8
        while (cell == getCell(CellPosition(r, c)) && r <= rEnd) r++;
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        r++;
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ends.append(rEnd);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (ends.isEmpty()) return;
Shinya Kitaoka 120a6e
  // controllo se devo cambiare la selezione
Shinya Kitaoka 120a6e
  bool allIncreaseIsEqual = true;
Shinya Kitaoka 120a6e
  for (c = 0; c < ends.size() - 1 && allIncreaseIsEqual; c++)
Shinya Kitaoka 120a6e
    allIncreaseIsEqual       = allIncreaseIsEqual && ends[c] == ends[c + 1];
Shinya Kitaoka 120a6e
  if (allIncreaseIsEqual) r1 = ends[0];
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::decreaseStepCells(int r0, int c0, int &r1, int c1) {
Shinya Kitaoka 120a6e
  int c, size = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  QList<int> ends;</int>
Shinya Kitaoka 120a6e
  for (c = c0; c <= c1; c++) {
Shinya Kitaoka 120a6e
    int r = r0, i = 0, rEnd = r1;
Shinya Kitaoka 120a6e
    while (r <= rEnd) {
Jaroslav 203cc8
      TXshCell cell = getCell(CellPosition(r, c));
Shinya Kitaoka 120a6e
      if (!cell.isEmpty()) {
Shinya Kitaoka 120a6e
        r++;
Shinya Kitaoka 120a6e
        bool removed = false;
Jaroslav 203cc8
        while (cell == getCell(CellPosition(r, c)) && r <= rEnd) {
Shinya Kitaoka 120a6e
          if (!removed) {
Shinya Kitaoka 120a6e
            removed = true;
Shinya Kitaoka 120a6e
            removeCells(r, c);
Shinya Kitaoka 120a6e
            rEnd--;
Shinya Kitaoka 120a6e
          } else
Shinya Kitaoka 120a6e
            r++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        r++;
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    ends.append(rEnd);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (ends.isEmpty()) return;
Shinya Kitaoka 120a6e
  // controllo se devo cambiare la selezione
Shinya Kitaoka 120a6e
  bool allDecreaseIsEqual = true;
Shinya Kitaoka 120a6e
  for (c = 0; c < ends.size() - 1 && allDecreaseIsEqual; c++)
Shinya Kitaoka 120a6e
    allDecreaseIsEqual       = allDecreaseIsEqual && ends[c] == ends[c + 1];
Shinya Kitaoka 120a6e
  if (allDecreaseIsEqual) r1 = ends[0];
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::eachCells(int r0, int c0, int r1, int c1, int type) {
Shinya Kitaoka 120a6e
  int nr = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  int nc = c1 - c0 + 1;
Shinya Kitaoka 120a6e
  if (nr < type || nc <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int newRows = nr % type ? nr / type + 1 : nr / type;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int size = newRows * nc;
Shinya Kitaoka 120a6e
  assert(size > 0);
Shinya Kitaoka 120a6e
  std::unique_ptr<txshcell[]> cells(new TXshCell[size]);</txshcell[]>
Shinya Kitaoka 120a6e
  assert(cells);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int i, j, k;
Shinya Kitaoka 120a6e
  for (j = r0, i = 0; i < size;
Shinya Kitaoka 120a6e
       j += type)  // in cells copio il contenuto delle celle che mi interessano
Shinya Kitaoka 120a6e
  {
Jaroslav 203cc8
    for (k = c0; k <= c1; k++, i++) cells[i] = getCell(CellPosition(j, k));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int c;
Shinya Kitaoka 120a6e
  for (c = c0; c <= c1; ++c) removeCells(r0 + newRows, c, nr - newRows);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (i = r0, k = 0; i < r0 + newRows && k < size; i++)
Shinya Kitaoka 120a6e
    for (j = c0; j <= c1; j++) {
Shinya Kitaoka 120a6e
      //----110523 iwasawa
Shinya Kitaoka 38fd86
      // Eachでできた空きセルに、操作前のセルの中身が残ってしまう不具合を修正
Shinya Kitaoka 120a6e
      if (cells[k].isEmpty())
Shinya Kitaoka 120a6e
        clearCells(i, j);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        setCell(i, j, cells[k]);
Shinya Kitaoka 120a6e
      k++;
Shinya Kitaoka 120a6e
    }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! force cells order in n-steps. returns the row amount after process
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka 120a6e
int TXsheet::reframeCells(int r0, int r1, int col, int type) {
Shinya Kitaoka 120a6e
  // Row amount in the selection
Shinya Kitaoka 120a6e
  int nr = r1 - r0 + 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (nr < 1) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  QVector<txshcell> cells;</txshcell>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  cells.clear();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int r = r0; r <= r1; r++) {
Jaroslav 203cc8
    if (cells.size() == 0 || cells.last() != getCell(CellPosition(r, col)))
Jaroslav 203cc8
      cells.push_back(getCell(CellPosition(r, col)));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (cells.empty()) return 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // row amount after n-step
Shinya Kitaoka 120a6e
  int nrows = cells.size() * type;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // if needed, insert cells
Shinya Kitaoka 120a6e
  if (nr < nrows) {
Shinya Kitaoka 120a6e
    insertCells(r1 + 1, col, nrows - nr);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // if needed, remove cells
Shinya Kitaoka 120a6e
  else if (nr > nrows) {
Shinya Kitaoka 120a6e
    removeCells(r0 + nrows, col, nr - nrows);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (int i = r0, k = 0; i < r0 + nrows; k++) {
Shinya Kitaoka 120a6e
    for (int i1 = 0; i1 < type; i1++) {
Shinya Kitaoka 120a6e
      if (cells[k].isEmpty())
Shinya Kitaoka 120a6e
        clearCells(i + i1, col);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        setCell(i + i1, col, cells[k]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    i += type;  // dipende dal tipo di step (2 o 3 per ora)
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return nrows;  // return row amount after process
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::resetStepCells(int r0, int c0, int r1, int c1) {
Shinya Kitaoka 120a6e
  int c, size = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  for (c = c0; c <= c1; c++) {
Shinya Kitaoka 120a6e
    int r = r0, i = 0;
Shinya Kitaoka 120a6e
    TXshCell *cells = new TXshCell[size];
Shinya Kitaoka 120a6e
    while (r <= r1) {
Shinya Kitaoka 120a6e
      // mi prendo le celle che mi servono
Jaroslav 203cc8
      cells[i] = getCell(CellPosition(r, c));
Shinya Kitaoka 120a6e
      r++;
Jaroslav 203cc8
      while (cells[i] == getCell(CellPosition(r, c)) && r <= r1) r++;
Shinya Kitaoka 120a6e
      i++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    size = i;
Shinya Kitaoka 120a6e
    removeCells(r0, c, r1 - r0 + 1);
Shinya Kitaoka 120a6e
    insertCells(r0, c, i);
Shinya Kitaoka 120a6e
    i = 0;
Shinya Kitaoka 120a6e
    r = r0;
Shinya Kitaoka 120a6e
    for (i = 0; i < size; i++, r++) setCell(r, c, cells[i]);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*! Roll first cells of rect r0,c0,r1,c1. Move cells contained in first row to
Shinya Kitaoka 120a6e
 * last row.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void TXsheet::rollupCells(int r0, int c0, int r1, int c1) {
Shinya Kitaoka 120a6e
  int nc   = c1 - c0 + 1;
Shinya Kitaoka 120a6e
  int size = 1 * nc;
Shinya Kitaoka 120a6e
  assert(size > 0);
Shinya Kitaoka 120a6e
  std::unique_ptr<txshcell[]> cells(new TXshCell[size]);</txshcell[]>
Shinya Kitaoka 120a6e
  assert(cells);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // in cells copio il contenuto delle celle che mi interessano
Shinya Kitaoka 120a6e
  int k;
Jaroslav 203cc8
  for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r0, k));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (k = c0; k <= c1; k++) removeCells(r0, k, 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (k = c0; k <= c1; k++) {
Shinya Kitaoka 120a6e
    insertCells(r1, k, 1);
Shinya Kitaoka 120a6e
    setCell(r1, k, cells[k - c0]);  // setto le celle
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
/*! Roll last cells of rect r0,c0,r1,c1. Move cells contained in last row to
Shinya Kitaoka 120a6e
 * first row.
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
void TXsheet::rolldownCells(int r0, int c0, int r1, int c1) {
Shinya Kitaoka 120a6e
  int nc   = c1 - c0 + 1;
Shinya Kitaoka 120a6e
  int size = 1 * nc;
Shinya Kitaoka 120a6e
  assert(size > 0);
Shinya Kitaoka 120a6e
  std::unique_ptr<txshcell[]> cells(new TXshCell[size]);</txshcell[]>
Shinya Kitaoka 120a6e
  assert(cells);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // in cells copio il contenuto delle celle che mi interessano
Shinya Kitaoka 120a6e
  int k;
Jaroslav 203cc8
  for (k = c0; k <= c1; k++) cells[k - c0] = getCell(CellPosition(r1, k));
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (k = c0; k <= c1; k++) removeCells(r1, k, 1);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (k = c0; k <= c1; k++) {
Shinya Kitaoka 120a6e
    insertCells(r0, k, 1);
Shinya Kitaoka 120a6e
    setCell(r0, k, cells[k - c0]);  // setto le celle
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Stretch cells contained in rect r0,c0,r1,c1, from r1-r0+1 to nr.
Shinya Kitaoka 120a6e
                If nr>r1-r0+1 add cells, overwise remove cells. */
Shinya Kitaoka 120a6e
void TXsheet::timeStretch(int r0, int c0, int r1, int c1, int nr) {
Shinya Kitaoka 120a6e
  int oldNr = r1 - r0 + 1;
Shinya Kitaoka 120a6e
  if (nr > oldNr) /* ingrandisce */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int c;
Shinya Kitaoka 120a6e
    for (c = c0; c <= c1; c++) {
Shinya Kitaoka 120a6e
      int dn = nr - oldNr;
Shinya Kitaoka 120a6e
      assert(oldNr > 0);
Shinya Kitaoka 120a6e
      std::unique_ptr<txshcell[]> cells(new TXshCell[oldNr]);</txshcell[]>
Shinya Kitaoka 120a6e
      assert(cells);
Shinya Kitaoka 120a6e
      getCells(r0, c, oldNr, cells.get());
Shinya Kitaoka 120a6e
      insertCells(r0 + 1, c, dn);
Shinya Kitaoka 120a6e
      int i;
Shinya Kitaoka 120a6e
      for (i = nr - 1; i >= 0; i--) {
Shinya Kitaoka 120a6e
        int j = i * double(oldNr) / double(nr);
Shinya Kitaoka 120a6e
        if (j < i) setCell(i + r0, c, cells[j]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else /* rimpicciolisce */
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int c;
Shinya Kitaoka 120a6e
    for (c = c0; c <= c1; c++) {
Shinya Kitaoka 120a6e
      int dn = oldNr - nr;
Shinya Kitaoka 120a6e
      std::unique_ptr<txshcell[]> cells(new TXshCell[oldNr]);</txshcell[]>
Shinya Kitaoka 120a6e
      assert(cells);
Shinya Kitaoka 120a6e
      getCells(r0, c, oldNr, cells.get());
Shinya Kitaoka 120a6e
      int i;
Shinya Kitaoka 120a6e
      for (i = 0; i < nr; i++) {
Shinya Kitaoka 120a6e
        int j = i * double(oldNr) / double(nr);
Shinya Kitaoka 120a6e
        if (j > i) setCell(i + r0, c, cells[j]);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
      removeCells(r1 - dn + 1, c, dn);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
int TXsheet::exposeLevel(int row, int col, TXshLevel *xl, bool overwrite) {
Shinya Kitaoka 120a6e
  if (!xl) return 0;
Shinya Kitaoka 120a6e
  std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
  xl->getFids(fids);
Shinya Kitaoka 120a6e
  int frameCount = 1;
Shinya Kitaoka 120a6e
  if (fids.empty()) {
Shinya Kitaoka 120a6e
    setCell(row, col, TXshCell(xl, TFrameId(1)));
Shinya Kitaoka 120a6e
    updateFrameCount();
Shinya Kitaoka 120a6e
    return frameCount;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  exposeLevel(row, col, xl, fids, overwrite);
Shinya Kitaoka 120a6e
  return (int)fids.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// customized version for load level popup
Shinya Kitaoka 120a6e
int TXsheet::exposeLevel(int row, int col, TXshLevel *xl,
Shinya Kitaoka 120a6e
                         std::vector<tframeid> &fIds_, int xFrom, int xTo,</tframeid>
Shinya Kitaoka 120a6e
                         int step, int inc, int frameCount,
Shinya Kitaoka 120a6e
                         bool doesFileActuallyExist) {
Shinya Kitaoka 120a6e
  if (!xl) return 0;
Shinya Kitaoka 120a6e
  std::vector<tframeid> fids;</tframeid>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (doesFileActuallyExist)
Shinya Kitaoka 120a6e
    xl->getFids(fids);
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    for (int i = 0; i < (int)fIds_.size(); i++) {
Shinya Kitaoka 120a6e
      fids.push_back(fIds_[i]);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // multiple exposing
Shinya Kitaoka 120a6e
  if (frameCount < 0 || xFrom < 0 || xTo < 0 || step < 0 || inc < 0) {
Shinya Kitaoka 120a6e
    insertCells(row, col, xl->getFrameCount());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    frameCount = 1;
Shinya Kitaoka 120a6e
    if (fids.empty())
Shinya Kitaoka 120a6e
      setCell(row, col, TXshCell(xl, TFrameId(1)));
Shinya Kitaoka 120a6e
    else {
Shinya Kitaoka 120a6e
      frameCount = (int)fids.size();
Shinya Kitaoka 120a6e
      insertCells(row, col, frameCount);
Shinya Kitaoka 120a6e
      std::vector<tframeid>::iterator it;</tframeid>
Shinya Kitaoka 120a6e
      for (it = fids.begin(); it != fids.end(); ++it)
Shinya Kitaoka 120a6e
        setCell(row++, col, TXshCell(xl, *it));
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    updateFrameCount();
Shinya Kitaoka 120a6e
    return frameCount;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // single exposing
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  insertCells(row, col, frameCount);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (fids.empty()) {
Shinya Kitaoka 120a6e
    setCell(row, col, TXshCell(xl, TFrameId(1)));
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    if (inc == 0)  // inc = Auto
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      std::vector<tframeid>::iterator it;</tframeid>
Shinya Kitaoka 120a6e
      it = fids.begin();
Shinya Kitaoka 120a6e
      while (it->getNumber() < xFrom) it++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (step == 0)  // Step = Auto
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        std::vector<tframeid>::iterator next_it;</tframeid>
Shinya Kitaoka 120a6e
        next_it = it;
Shinya Kitaoka 120a6e
        next_it++;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        int startFrame = it->getNumber();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        for (int f = startFrame; f < startFrame + frameCount; f++) {
Shinya Kitaoka 120a6e
          if (next_it != fids.end() && f >= next_it->getNumber()) {
Shinya Kitaoka 120a6e
            it++;
Shinya Kitaoka 120a6e
            next_it++;
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          setCell(row++, col, TXshCell(xl, *it));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      else  // Step != Auto
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        int loopCount = frameCount / step;
Shinya Kitaoka 120a6e
        for (int loop = 0; loop < loopCount; loop++) {
Shinya Kitaoka 120a6e
          for (int s = 0; s < step; s++) {
Shinya Kitaoka 120a6e
            setCell(row++, col, TXshCell(xl, *it));
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
          it++;
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    } else  // inc != Auto
Shinya Kitaoka 120a6e
    {
Shinya Kitaoka 120a6e
      int loopCount;
Shinya Kitaoka 120a6e
      if (step == 0)  // Step = Auto
Shinya Kitaoka 120a6e
        step = inc;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      loopCount = frameCount / step;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      for (int loop = 0; loop < loopCount; loop++) {
Shinya Kitaoka 120a6e
        TFrameId id(xFrom + loop * inc, fids.begin()->getLetter());
Shinya Kitaoka 120a6e
        for (int s = 0; s < step; s++) {
Shinya Kitaoka 120a6e
          setCell(row++, col, TXshCell(xl, id));
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  updateFrameCount();
Shinya Kitaoka 120a6e
  return frameCount;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::exposeLevel(int row, int col, TXshLevel *xl,
Shinya Kitaoka 120a6e
                          std::vector<tframeid> fids, bool overwrite) {</tframeid>
Shinya Kitaoka 120a6e
  int frameCount = (int)fids.size();
Shinya Kitaoka 120a6e
  if (!overwrite) insertCells(row, col, frameCount);
Shinya Kitaoka 120a6e
  std::vector<tframeid>::iterator it;</tframeid>
Shinya Kitaoka 120a6e
  for (it = fids.begin(); it != fids.end(); ++it)
Shinya Kitaoka 120a6e
    setCell(row++, col, TXshCell(xl, *it));
Shinya Kitaoka 120a6e
  updateFrameCount();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::updateFrameCount() {
Shinya Kitaoka 120a6e
  m_imp->m_frameCount = 0;
Shinya Kitaoka 120a6e
  for (int i = 0; i < m_imp->m_columnSet.getColumnCount(); ++i) {
Shinya Kitaoka 120a6e
    TXshColumnP cc = m_imp->m_columnSet.getColumn(i);
Shinya Kitaoka 120a6e
    if (cc && !cc->isEmpty())
Shinya Kitaoka 120a6e
      m_imp->m_frameCount =
Shinya Kitaoka 120a6e
          std::max(m_imp->m_frameCount, cc->getMaxFrame() + 1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  clearAll();
Shinya Kitaoka 120a6e
  TStageObjectId cameraId   = TStageObjectId::CameraId(0);
Shinya Kitaoka 120a6e
  TStageObject *firstCamera = getStageObject(cameraId);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->removeStageObject(cameraId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int col = 0;
Shinya Kitaoka 120a6e
  string tagName;
Shinya Kitaoka 120a6e
  while (is.openChild(tagName)) {
Shinya Kitaoka 120a6e
    if (tagName == "columns") {
Shinya Kitaoka 120a6e
      while (!is.eos()) {
Shinya Kitaoka 120a6e
        TPersist *p = 0;
Shinya Kitaoka 120a6e
        is >> p;
Shinya Kitaoka 120a6e
        TXshColumn *column = dynamic_cast<txshcolumn *="">(p);</txshcolumn>
Shinya Kitaoka 120a6e
        if (!column) throw TException("expected xsheet column");
Shinya Kitaoka 120a6e
        m_imp->m_columnSet.insertColumn(col++, column);
Shinya Kitaoka 120a6e
        column->setXsheet(this);
Shinya Kitaoka 120a6e
        if (TXshZeraryFxColumn *zc =
Shinya Kitaoka 120a6e
                dynamic_cast<txshzeraryfxcolumn *="">(column)) {</txshzeraryfxcolumn>
Shinya Kitaoka 120a6e
          TFx *fx         = zc->getZeraryColumnFx()->getZeraryFx();
Shinya Kitaoka 120a6e
          int fxTypeCount = m_imp->m_fxDag->getFxTypeCount(fx);
Shinya Kitaoka 120a6e
          int maxFxTypeId = std::max(fxTypeCount, fx->getAttributes()->getId());
Shinya Kitaoka 120a6e
          m_imp->m_fxDag->updateFxTypeTable(fx, maxFxTypeId);
Shinya Kitaoka 120a6e
          m_imp->m_fxDag->updateFxIdTable(fx);
Shinya Kitaoka 120a6e
          for (int j = 0; j < fx->getParams()->getParamCount(); j++) {
Shinya Kitaoka 120a6e
            TParam *param = fx->getParams()->getParam(j);
Shinya Kitaoka 120a6e
            if (TDoubleParam *dp = dynamic_cast<tdoubleparam *="">(param))</tdoubleparam>
Shinya Kitaoka 120a6e
              getStageObjectTree()->setGrammar(dp);
Shinya Kitaoka 120a6e
            else if (dynamic_cast<tpointparam *="">(param) ||</tpointparam>
Shinya Kitaoka 120a6e
                     dynamic_cast<trangeparam *="">(param) ||</trangeparam>
Shinya Kitaoka 120a6e
                     dynamic_cast<tpixelparam *="">(param)) {</tpixelparam>
Shinya Kitaoka 120a6e
              TParamSet *paramSet = dynamic_cast<tparamset *="">(param);</tparamset>
Shinya Kitaoka 120a6e
              assert(paramSet);
Shinya Kitaoka 120a6e
              int f;
Shinya Kitaoka 120a6e
              for (f = 0; f < paramSet->getParamCount(); f++) {
Shinya Kitaoka 120a6e
                TDoubleParam *dp = dynamic_cast<tdoubleparam *="">(</tdoubleparam>
Shinya Kitaoka 120a6e
                    paramSet->getParam(f).getPointer());
Shinya Kitaoka 120a6e
                if (!dp) continue;
Shinya Kitaoka 120a6e
                getStageObjectTree()->setGrammar(dp);
Shinya Kitaoka 120a6e
              }
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    } else if (tagName == "pegbars") {
Shinya Kitaoka 120a6e
      TPersist *p = m_imp->m_pegTree;
Shinya Kitaoka 120a6e
      is >> *p;
Shinya Kitaoka 120a6e
    } else if (tagName == "fxnodes") {
Shinya Kitaoka 120a6e
      m_imp->m_fxDag->loadData(is);
Shinya Kitaoka 120a6e
      std::vector<tfx *=""> fxs;</tfx>
Shinya Kitaoka 120a6e
      m_imp->m_fxDag->getFxs(fxs);
Shinya Kitaoka 120a6e
      for (int i = 0; i < (int)fxs.size(); i++) {
Shinya Kitaoka 120a6e
        TFx *fx = fxs[i];
Shinya Kitaoka 120a6e
        for (int j = 0; j < fx->getParams()->getParamCount(); j++) {
Shinya Kitaoka 120a6e
          TParam *param = fx->getParams()->getParam(j);
Shinya Kitaoka 120a6e
          if (TDoubleParam *dp = dynamic_cast<tdoubleparam *="">(param))</tdoubleparam>
Shinya Kitaoka 120a6e
            getStageObjectTree()->setGrammar(dp);
Shinya Kitaoka 120a6e
          else if (dynamic_cast<tpointparam *="">(param) ||</tpointparam>
Shinya Kitaoka 120a6e
                   dynamic_cast<trangeparam *="">(param) ||</trangeparam>
Shinya Kitaoka 120a6e
                   dynamic_cast<tpixelparam *="">(param)) {</tpixelparam>
Shinya Kitaoka 120a6e
            TParamSet *paramSet = dynamic_cast<tparamset *="">(param);</tparamset>
Shinya Kitaoka 120a6e
            assert(paramSet);
Shinya Kitaoka 120a6e
            int f;
Shinya Kitaoka 120a6e
            for (f = 0; f < paramSet->getParamCount(); f++) {
Shinya Kitaoka 120a6e
              TDoubleParam *dp = dynamic_cast<tdoubleparam *="">(</tdoubleparam>
Shinya Kitaoka 120a6e
                  paramSet->getParam(f).getPointer());
Shinya Kitaoka 120a6e
              if (!dp) continue;
Shinya Kitaoka 120a6e
              getStageObjectTree()->setGrammar(dp);
Shinya Kitaoka 120a6e
            }
Shinya Kitaoka 120a6e
          }
Shinya Kitaoka 120a6e
        }
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (is.matchEndTag()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // was ist dass?
Shinya Kitaoka 120a6e
      TFxSet fxSet;
Shinya Kitaoka 120a6e
      fxSet.loadData(is);
Shinya Kitaoka 120a6e
    } else if (tagName == "columnFan") {
Jaroslav 203cc8
      m_imp->m_columnFans[0].loadData(is);
Jaroslav 203cc8
      m_imp->copyFoldedState();
Shinya Kitaoka 120a6e
    } else if (tagName == "noteSet") {
Shinya Kitaoka 120a6e
      m_notes->loadData(is);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      throw TException("xsheet, unknown tag: " + tagName);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    is.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  updateFrameCount();
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void TXsheet::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  os.openChild("columns");
Shinya Kitaoka 120a6e
  for (int c = 0; c < m_imp->m_columnSet.getColumnCount(); ++c) {
Shinya Kitaoka 120a6e
    TXshColumnP column = m_imp->m_columnSet.getColumn(c);
Shinya Kitaoka 120a6e
    if (column && c < getFirstFreeColumnIndex()) os << column.getPointer();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
  os.openChild("pegbars");
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->saveData(os, getFirstFreeColumnIndex());
Shinya Kitaoka 120a6e
  // os << *(m_imp->m_pegTree);
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  FxDag *fxDag = getFxDag();
Shinya Kitaoka 120a6e
  os.openChild("fxnodes");
Shinya Kitaoka 120a6e
  fxDag->saveData(os, getFirstFreeColumnIndex());
Shinya Kitaoka 120a6e
  os.closeChild();
Shinya Kitaoka 120a6e
Jaroslav 203cc8
  // does not matter which Orientation to take, as all fans share folded data
Jaroslav 203cc8
  ColumnFan *columnFan = getColumnFan(Orientations::topToBottom());
Shinya Kitaoka 120a6e
  if (!columnFan->isEmpty()) {
Shinya Kitaoka 120a6e
    os.openChild("columnFan");
Shinya Kitaoka 120a6e
    columnFan->saveData(os);
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshNoteSet *notes = getNotes();
Shinya Kitaoka 120a6e
  if (notes->getCount() > 0) {
Shinya Kitaoka 120a6e
    os.openChild("noteSet");
Shinya Kitaoka 120a6e
    notes->saveData(os);
Shinya Kitaoka 120a6e
    os.closeChild();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(TXsheet, "xsheet")
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::insertColumn(int col, TXshColumn::ColumnType type) {
Shinya Kitaoka 120a6e
  insertColumn(col, TXshColumn::createEmpty(type));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::insertColumn(int col, TXshColumn *column) {
Shinya Kitaoka 120a6e
  column->setXsheet(this);
Shinya Kitaoka 120a6e
  m_imp->m_columnSet.insertColumn(col, column);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->insertColumn(col);
Shinya Kitaoka 120a6e
  if (column->getPaletteColumn() ==
Shinya Kitaoka 120a6e
      0)  // palette column are not connected to the xsheet fx node
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    TFx *fx = column->getFx();
Shinya Kitaoka 120a6e
    if (fx) getFxDag()->addToXsheet(fx);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::removeColumn(int col) {
Shinya Kitaoka 120a6e
  TXshColumn *column = getColumn(col);
Shinya Kitaoka 120a6e
  if (column) {
Shinya Kitaoka 120a6e
    TFx *fx = column->getFx();
Shinya Kitaoka 120a6e
    if (fx) {
Shinya Kitaoka 120a6e
      getFxDag()->removeFromXsheet(fx);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
      // disconnetto dal columnFx tutti gli effetti connessi in uscita
Shinya Kitaoka 120a6e
      TFxPort *outPort = 0;
Shinya Kitaoka 120a6e
      while ((outPort = fx->getOutputConnection(0))) outPort->setFx(0);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_imp->m_columnSet.removeColumn(col);
Shinya Kitaoka 120a6e
  m_imp->m_pegTree->removeColumn(col);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::moveColumn(int srcIndex, int dstIndex) {
Shinya Kitaoka 120a6e
  if (srcIndex == dstIndex) return;
Shinya Kitaoka 120a6e
  assert(srcIndex >= 0);
Shinya Kitaoka 120a6e
  assert(dstIndex >= 0);
Shinya Kitaoka 120a6e
  int col = std::max(srcIndex, dstIndex);
Shinya Kitaoka 120a6e
  if (col >= m_imp->m_columnSet.getColumnCount()) {
Shinya Kitaoka 120a6e
    int n = m_imp->m_columnSet.getColumnCount();
Shinya Kitaoka 120a6e
    touchColumn(col, TXshColumn::eLevelType);
Shinya Kitaoka 120a6e
    while (n <= col) {
Shinya Kitaoka 120a6e
      TXshColumn *column = getColumn(n);
Shinya Kitaoka 120a6e
      assert(column);
Shinya Kitaoka 120a6e
      column->setXsheet(this);
Shinya Kitaoka 120a6e
      n++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  assert(m_imp->m_columnSet.getColumnCount() > srcIndex);
Shinya Kitaoka 120a6e
  assert(m_imp->m_columnSet.getColumnCount() > dstIndex);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (srcIndex < dstIndex) {
Shinya Kitaoka 120a6e
    int c0 = srcIndex;
Shinya Kitaoka 120a6e
    int c1 = dstIndex;
Shinya Kitaoka 120a6e
    assert(c0 < c1);
Shinya Kitaoka 120a6e
    m_imp->m_columnSet.rollLeft(c0, c1 - c0 + 1);
Shinya Kitaoka 120a6e
    for (int c = c0; c < c1; ++c) m_imp->m_pegTree->swapColumns(c, c + 1);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    int c0 = dstIndex;
Shinya Kitaoka 120a6e
    int c1 = srcIndex;
Shinya Kitaoka 120a6e
    assert(c0 < c1);
Shinya Kitaoka 120a6e
    m_imp->m_columnSet.rollRight(c0, c1 - c0 + 1);
Shinya Kitaoka 120a6e
    for (int c = c1 - 1; c >= c0; --c) m_imp->m_pegTree->swapColumns(c, c + 1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshColumn *TXsheet::getColumn(int col) const {
Shinya Kitaoka 120a6e
  return m_imp->m_columnSet.getColumn(col).getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXsheet::getColumnCount() const {
Shinya Kitaoka 120a6e
  return m_imp->m_columnSet.getColumnCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXsheet::getFirstFreeColumnIndex() const {
Shinya Kitaoka 120a6e
  int i = getColumnCount();
Shinya Kitaoka 120a6e
  while (i > 0 && isColumnEmpty(i - 1)) --i;
Shinya Kitaoka 120a6e
  return i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshColumn *TXsheet::touchColumn(int index, TXshColumn::ColumnType type) {
Shinya Kitaoka 120a6e
  TXshColumn *column = m_imp->m_columnSet.touchColumn(index, type).getPointer();
Shinya Kitaoka 120a6e
  if (!column) return 0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  // NOTE (Daniele): The following && should be a bug... but I fear I'd break
Shinya Kitaoka 120a6e
  // something changing it.
Shinya Kitaoka 120a6e
  // Observe that the implied behavior is that of REPLACING AN EXISTING
Shinya Kitaoka 120a6e
  // LEGITIMATE COLUMN!
Shinya Kitaoka 120a6e
  // Please, Inquire further if you're not upon release!
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (column->isEmpty() && column->getColumnType() != type) {
Shinya Kitaoka 120a6e
    removeColumn(index);
Shinya Kitaoka 120a6e
    insertColumn(index, type);
Shinya Kitaoka 120a6e
    column = getColumn(index);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return column;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
namespace {  // Utility function
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void searchAudioColumn(TXsheet *xsh, std::vector<txshsoundcolumn *=""> &sounds,</txshsoundcolumn>
Shinya Kitaoka 120a6e
                       bool isPreview = true) {
Shinya Kitaoka 120a6e
  int i       = 0;
Shinya Kitaoka 120a6e
  int columns = xsh->getColumnCount();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (; i < columns; ++i) {
Shinya Kitaoka 120a6e
    TXshColumn *column = xsh->getColumn(i);
Shinya Kitaoka 120a6e
    if (column) {
Shinya Kitaoka 120a6e
      TXshSoundColumn *soundCol = column->getSoundColumn();
Shinya Kitaoka 120a6e
      if (soundCol && ((isPreview && soundCol->isPreviewVisible()) ||
Shinya Kitaoka 120a6e
                       (!isPreview && soundCol->isCamstandVisible()))) {
Shinya Kitaoka 120a6e
        sounds.push_back(soundCol);
Shinya Kitaoka 120a6e
        continue;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrack *TXsheet::makeSound(SoundProperties *properties) {
Shinya Kitaoka 120a6e
  std::vector<txshsoundcolumn *=""> sounds;</txshsoundcolumn>
Shinya Kitaoka 120a6e
  searchAudioColumn(this, sounds, properties->m_isPreview);
Shinya Kitaoka 120a6e
  if (!m_imp->m_mixedSound || *properties != *m_soundProperties) {
Shinya Kitaoka 120a6e
    if (!sounds.empty() && properties->m_fromFrame <= properties->m_toFrame)
Shinya Kitaoka 120a6e
      m_imp->m_mixedSound = sounds[0]->mixingTogether(
Shinya Kitaoka 120a6e
          sounds, properties->m_fromFrame, properties->m_toFrame,
Shinya Kitaoka 120a6e
          properties->m_frameRate);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      m_imp->m_mixedSound = 0;
Shinya Kitaoka 120a6e
    delete m_soundProperties;
Shinya Kitaoka 120a6e
    m_soundProperties = properties;
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    delete properties;
Shinya Kitaoka 120a6e
  return m_imp->m_mixedSound.getPointer();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::scrub(int frame, bool isPreview) {
Shinya Kitaoka 120a6e
  double fps =
Shinya Kitaoka 120a6e
      getScene()->getProperties()->getOutputProperties()->getFrameRate();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TXsheet::SoundProperties *prop = new TXsheet::SoundProperties();
Shinya Kitaoka 120a6e
  prop->m_isPreview              = isPreview;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSoundTrack *st = makeSound(prop);  // Absorbs prop's ownership
Shinya Kitaoka 120a6e
  if (!st) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double samplePerFrame = st->getSampleRate() / fps;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double s0 = frame * samplePerFrame, s1 = s0 + samplePerFrame;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  play(st, s0, s1, false);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::stopScrub() {
Shinya Kitaoka 120a6e
  if (m_player) m_player->stop();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::play(TSoundTrackP soundtrack, int s0, int s1, bool loop) {
Shinya Kitaoka 120a6e
  if (!TSoundOutputDevice::installed()) return;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (!m_player) m_player = new TSoundOutputDevice();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (m_player) {
Shinya Kitaoka 120a6e
    try {
Shinya Kitaoka 120a6e
      m_player->play(soundtrack, s0, s1, loop);
Shinya Kitaoka 120a6e
    } catch (TSoundDeviceException &) {
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
FxDag *TXsheet::getFxDag() const { return m_imp->m_fxDag; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
ColumnFan *TXsheet::getColumnFan(const Orientation *o) const {
Jaroslav 203cc8
  int index = o->dimension(PredefinedDimension::INDEX);
Jaroslav 203cc8
  return &m_imp->m_columnFans[index];
Jaroslav 203cc8
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
ToonzScene *TXsheet::getScene() const { return m_imp->m_scene; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::setScene(ToonzScene *scene) { m_imp->m_scene = scene; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::checkCircularReferences(const TXshCell &cellCandidate) {
Shinya Kitaoka 120a6e
  if (cellCandidate.isEmpty() || !cellCandidate.m_level->getChildLevel())
Shinya Kitaoka 120a6e
    return false;
Shinya Kitaoka 120a6e
  TXsheet *childCandidate = cellCandidate.m_level->getChildLevel()->getXsheet();
Shinya Kitaoka 120a6e
  return checkCircularReferences(childCandidate);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::checkCircularReferences(TXshColumn *columnCandidate) {
Shinya Kitaoka 120a6e
  if (!columnCandidate || !columnCandidate->getLevelColumn()) return false;
Shinya Kitaoka 120a6e
  TXshLevelColumn *lc = columnCandidate->getLevelColumn();
Shinya Kitaoka 120a6e
  int r0 = 0, r1 = -1;
Shinya Kitaoka 120a6e
  if (lc->getRange(r0, r1) <= 0) return false;
Shinya Kitaoka 120a6e
  int r;
Shinya Kitaoka 120a6e
  TXshCell oldCell;
Shinya Kitaoka 120a6e
  for (r = r0; r <= r1; r++) {
Shinya Kitaoka 120a6e
    TXshCell cell = lc->getCell(r);
Shinya Kitaoka 120a6e
    // to speed up:
Shinya Kitaoka 120a6e
    if (cell.m_level.getPointer() == oldCell.m_level.getPointer()) continue;
Shinya Kitaoka 120a6e
    if (checkCircularReferences(cell)) return true;
Shinya Kitaoka 120a6e
    oldCell = cell;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXsheet::invalidateSound() { m_imp->m_mixedSound = TSoundTrackP(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXsheet::checkCircularReferences(TXsheet *childCandidate) {
Shinya Kitaoka 120a6e
  if (this == childCandidate) return true;
Shinya Kitaoka 120a6e
  if (childCandidate == 0) return false;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < childCandidate->getColumnCount(); i++)
Shinya Kitaoka 120a6e
    if (checkCircularReferences(childCandidate->getColumn(i))) return true;
Shinya Kitaoka 120a6e
  return false;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Builds the camstand bbox associated to the specified xsheet
Shinya Kitaoka 120a6e
TRectD TXsheet::getBBox(int r) const {
Shinya Kitaoka 120a6e
  static const double maxDouble = (std::numeric_limits<double>::max)();</double>
Shinya Kitaoka 120a6e
  static const TRectD voidRect(maxDouble, maxDouble, -maxDouble, -maxDouble);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  struct locals {
Shinya Kitaoka 120a6e
    static TRectD getBBox(const TXsheet *xsh, int r, int c) {
Shinya Kitaoka 120a6e
      // Discriminate cell content
Jaroslav 203cc8
      const TXshCell &cell = xsh->getCell(CellPosition(r, c));
Shinya Kitaoka 120a6e
      if (cell.isEmpty()) return voidRect;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (TXshChildLevel *cl = cell.getChildLevel())
Shinya Kitaoka 120a6e
        return cl->getXsheet()->getBBox(cell.getFrameId().getNumber() - 1);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      TXshSimpleLevel *sl = cell.getSimpleLevel();
Shinya Kitaoka 120a6e
      if (!sl ||
Shinya Kitaoka 120a6e
          !(sl->getType() &
Shinya Kitaoka 120a6e
            LEVELCOLUMN_XSHLEVEL))  // Avoid other mesh levels - which could
Shinya Kitaoka 120a6e
        return voidRect;            // be deformed too...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      // Retrieve column affine
Shinya Kitaoka 120a6e
      TAffine columnZaff;
Shinya Kitaoka 120a6e
      {
Shinya Kitaoka 120a6e
        TStageObject *colObj = xsh->getStageObject(TStageObjectId::ColumnId(c));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        const TAffine &columnAff = colObj->getPlacement(r);  // ...
Shinya Kitaoka 120a6e
        double columnZ           = colObj->getZ(r);          // ...
Shinya Kitaoka 120a6e
        double columnNoScaleZ    = colObj->getGlobalNoScaleZ();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        TStageObjectId cameraId =
Shinya Kitaoka 120a6e
            xsh->getStageObjectTree()->getCurrentCameraId();
Shinya Kitaoka 120a6e
        TStageObject *camera = xsh->getStageObject(cameraId);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        const TAffine &cameraAff = camera->getPlacement(r);  // ...
Shinya Kitaoka 120a6e
        double cameraZ           = camera->getZ(r);          // ...
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
        if (!TStageObject::perspective(columnZaff, cameraAff, cameraZ,
Shinya Kitaoka 120a6e
                                       columnAff, columnZ, columnNoScaleZ))
Shinya Kitaoka 120a6e
          return voidRect;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      const TRectD &bbox = sl->getBBox(cell.getFrameId());
Shinya Kitaoka 120a6e
      if (bbox.getLx() <= 0.0 || bbox.getLy() <= 0.0) return voidRect;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      return columnZaff * TScale(Stage::inch, Stage::inch) * bbox;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //-----------------------------------------------------------------------
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Initialize a union-neutral rect
Shinya Kitaoka 120a6e
  TRectD bbox(voidRect);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Traverse the xsheet's columns, adding the bbox of each
Shinya Kitaoka 120a6e
  int c, cCount = getColumnCount();
Shinya Kitaoka 120a6e
  for (c = 0; c != cCount; ++c) {
Shinya Kitaoka 120a6e
    // Skip empty or invisible columns
Shinya Kitaoka 120a6e
    TXshColumn *column = getColumn(c);
Shinya Kitaoka 120a6e
    if (column->isEmpty() || !column->isCamstandVisible()) continue;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    const TRectD &colBBox = locals::getBBox(this, r, c);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Make the union
Shinya Kitaoka 120a6e
    bbox.x0 = std::min(bbox.x0, colBBox.x0);
Shinya Kitaoka 120a6e
    bbox.y0 = std::min(bbox.y0, colBBox.y0);
Shinya Kitaoka 120a6e
    bbox.x1 = std::max(bbox.x1, colBBox.x1);
Shinya Kitaoka 120a6e
    bbox.y1 = std::max(bbox.y1, colBBox.y1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return bbox;
Toshihiro Shimizu 890ddd
}
shun-iwasawa 5e2a8f
shun-iwasawa 5e2a8f
//-----------------------------------------------------------------------
shun-iwasawa 5e2a8f
Jaroslav 203cc8
bool TXsheet::isRectEmpty(const CellPosition &pos0,
Jaroslav 203cc8
                          const CellPosition &pos1) const {
Jaroslav 203cc8
  for (int frame = pos0.frame(); frame <= pos1.frame(); frame++)
Jaroslav 203cc8
    for (int layer = pos0.layer(); layer <= pos1.layer(); layer++)
Jaroslav 203cc8
      if (!getCell(CellPosition(frame, layer)).isEmpty()) return false;
shun-iwasawa 5e2a8f
  return true;
shun-iwasawa 5e2a8f
}