Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tfx.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/txshcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshlevelcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshpalettecolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshzeraryfxcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundtextcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshmeshcolumn.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshcell.h"
Toshihiro Shimizu 890ddd
#include "toonz/txsheet.h"
Toshihiro Shimizu 890ddd
#include "toonz/fxdag.h"
Toshihiro Shimizu 890ddd
#include "toonz/tcolumnfxset.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
shun_iwasawa 2c0f50
#include <qmap></qmap>
shun-iwasawa f84c65
#include "tstream.h"
shun_iwasawa 2c0f50
shun_iwasawa 2c0f50
namespace {
shun_iwasawa 2c0f50
QMap<int, qpair<qstring,="" tpixel32="">> filterColors;</int,>
shun_iwasawa 2c0f50
};
shun_iwasawa 2c0f50
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
// TXshCellColumn
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshCellColumn::TXshCellColumn() : m_first(0) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshCellColumn::~TXshCellColumn() { m_cells.clear(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXshCellColumn::getRange(int &r0, int &r1) const {
Shinya Kitaoka 120a6e
  int cellCount = m_cells.size();
Shinya Kitaoka 120a6e
  r0            = m_first;
Shinya Kitaoka 120a6e
  r1            = r0 + cellCount - 1;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < cellCount && m_cells[i].isEmpty(); i++) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i >= cellCount) {
Shinya Kitaoka 120a6e
    r0 = 0;
Shinya Kitaoka 120a6e
    r1 = -1;
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  r0 = m_first + i;
Shinya Kitaoka 120a6e
  for (i = cellCount - 1; i >= 0 && m_cells[i].isEmpty(); i--) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  r1 = m_first + i;
Shinya Kitaoka 120a6e
  return r1 - r0 + 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXshCellColumn::getRowCount() const {
Shinya Kitaoka 120a6e
  int i = m_cells.size();
Shinya Kitaoka 120a6e
  for (; i > 0 && m_cells[i - 1].isEmpty(); i--) {
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (i == 0)
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    return m_first + i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXshCellColumn::getMaxFrame() const {
Shinya Kitaoka 120a6e
  int r0, r1;
Shinya Kitaoka 120a6e
  getRange(r0, r1);
Shinya Kitaoka 120a6e
  return r1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXshCellColumn::getFirstRow() const { return m_first; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
const TXshCell &TXshCellColumn::getCell(int row) const {
Shinya Kitaoka 120a6e
  static TXshCell emptyCell;
Shinya Kitaoka 120a6e
  if (row < 0 || row < m_first || row >= m_first + (int)m_cells.size())
Shinya Kitaoka 120a6e
    return emptyCell;
Shinya Kitaoka 120a6e
  return m_cells[row - m_first];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshCellColumn::isCellEmpty(int row) const {
Shinya Kitaoka 120a6e
  return getCell(row).isEmpty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--- debug only
Shinya Kitaoka 120a6e
void TXshCellColumn::checkColumn() const {
Shinya Kitaoka 120a6e
  assert(m_first >= 0);
Shinya Kitaoka 120a6e
  int r0, r1;
Shinya Kitaoka 120a6e
  int range = getRange(r0, r1);
Shinya Kitaoka 120a6e
  assert(range >= 0);
Shinya Kitaoka 120a6e
  assert(range == (int)m_cells.size());
Shinya Kitaoka 120a6e
  assert(getRowCount() >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TXshCell firstCell = getCell(m_first);
Shinya Kitaoka 120a6e
  TXshCell lastCell  = getCell(r1);
Shinya Kitaoka 120a6e
  if (range == 0)
Shinya Kitaoka 120a6e
    assert(firstCell.isEmpty() && lastCell.isEmpty());
Shinya Kitaoka 120a6e
  else {
Shinya Kitaoka 120a6e
    assert(firstCell.isEmpty() == 0);
Shinya Kitaoka 120a6e
    assert(lastCell.isEmpty() == 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    int maxFrame = getMaxFrame();
Shinya Kitaoka 120a6e
    assert(maxFrame == r1);
Shinya Kitaoka 120a6e
    assert(getCell(maxFrame).isEmpty() == 0);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshCellColumn::getCells(int row, int rowCount, TXshCell cells[]) {
Shinya Kitaoka 120a6e
  const TXshCell emptyCell;
Shinya Kitaoka 120a6e
  int first = m_first;
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  int cellCount = m_cells.size();
Shinya Kitaoka 120a6e
  if (row < 0 || row + rowCount - 1 < first || row >= first + cellCount) {
Shinya Kitaoka 120a6e
    for (i = 0; i < rowCount; i++) cells[i] = emptyCell;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int dst, src, n, delta;
Shinya Kitaoka 120a6e
  n     = rowCount;
Shinya Kitaoka 120a6e
  delta = m_first - row;
Shinya Kitaoka 120a6e
  if (delta < 0) {  // le celle cominciano PRIMA della zona da leggere
Shinya Kitaoka 120a6e
    dst = 0;
Shinya Kitaoka 120a6e
    src = -delta;
Shinya Kitaoka 120a6e
  } else {  // le celle cominciano DOPO della zona da leggere
Shinya Kitaoka 120a6e
    dst = delta;
Shinya Kitaoka 120a6e
    src = 0;
Shinya Kitaoka 120a6e
    n -= delta;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (n + src > cellCount) n = cellCount - src;
Shinya Kitaoka 120a6e
shun-iwasawa f84c65
  TXshCell *dstCell    = cells;
shun-iwasawa f84c65
  TXshCell *endDstCell = dstCell + dst;
Shinya Kitaoka 120a6e
  while (dstCell < endDstCell) *dstCell++ = emptyCell;
Shinya Kitaoka 120a6e
  endDstCell += n;
Shinya Kitaoka 120a6e
  while (dstCell < endDstCell) *dstCell++ = m_cells[src++];
shun-iwasawa f84c65
  endDstCell = cells + rowCount;
Shinya Kitaoka 120a6e
  while (dstCell < endDstCell) *dstCell++ = emptyCell;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshCellColumn::setCell(int row, const TXshCell &cell) {
Shinya Kitaoka 120a6e
  if (!canSetCell(cell)) return false;
Shinya Kitaoka 120a6e
  assert(row >= 0);
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Shinya Kitaoka 120a6e
  checkColumn();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
  if (m_cells.empty())  // se la colonna e' vuota
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (!cell.isEmpty()) {
Shinya Kitaoka 120a6e
      m_cells.push_back(cell);
Shinya Kitaoka 120a6e
      m_first = row;
Shinya Kitaoka 120a6e
      // updateIcon();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int oldCellCount = m_cells.size();
Shinya Kitaoka 120a6e
  assert(oldCellCount > 0);
Shinya Kitaoka 120a6e
  int lastRow = m_first + oldCellCount - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row < m_first)  // prima
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (cell.isEmpty()) return false;  // non faccio nulla
Shinya Kitaoka 120a6e
    int delta = m_first - row;
Shinya Kitaoka 120a6e
    assert(delta > 0);
Shinya Kitaoka 120a6e
    m_cells.insert(m_cells.begin(), delta - 1, TXshCell());  // celle vuote
Shinya Kitaoka 120a6e
    m_cells.insert(m_cells.begin(),
Shinya Kitaoka 120a6e
                   cell);  // devo settare la prima comp. del vettore
Shinya Kitaoka 120a6e
    m_first = row;         // row 'e la nuova firstrow
Shinya Kitaoka 120a6e
// updateIcon();
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Shinya Kitaoka 120a6e
    checkColumn();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  } else if (row > lastRow)  // dopo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (cell.isEmpty()) return false;  // non faccio nulla
Shinya Kitaoka 120a6e
    int count = row - lastRow - 1;
Shinya Kitaoka 120a6e
    // se necessario, inserisco celle vuote
Shinya Kitaoka 120a6e
    for (int i = 0; i < count; ++i) m_cells.push_back(TXshCell());
Shinya Kitaoka 120a6e
    m_cells.push_back(cell);
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Shinya Kitaoka 120a6e
    checkColumn();
Toshihiro Shimizu 890ddd
#endif
Shinya Kitaoka 120a6e
    return true;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //"[r0,r1]"
Shinya Kitaoka 120a6e
  int index = row - m_first;
Shinya Kitaoka 120a6e
  assert(0 <= index && index < (int)m_cells.size());
Shinya Kitaoka 120a6e
  m_cells[index] = cell;
Shinya Kitaoka 120a6e
  // if(index == 0) updateIcon();
Shinya Kitaoka 120a6e
  if (cell.isEmpty()) {
Shinya Kitaoka 120a6e
    if (row == lastRow) {
Shinya Kitaoka 120a6e
      // verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
      while (!m_cells.empty() && m_cells.back().isEmpty()) m_cells.pop_back();
Shinya Kitaoka 120a6e
    } else if (row == m_first) {
Shinya Kitaoka 120a6e
      // verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
      while (!m_cells.empty() && m_cells.front().isEmpty()) {
Shinya Kitaoka 120a6e
        m_cells.erase(m_cells.begin());
Shinya Kitaoka 120a6e
        m_first++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    if (m_cells.empty()) m_first = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  checkColumn();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshCellColumn::setCells(int row, int rowCount, const TXshCell cells[]) {
Shinya Kitaoka 120a6e
  assert(row >= 0);
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < rowCount; i++)
Shinya Kitaoka 120a6e
    if (!canSetCell(cells[i])) return false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int oldCellCount = m_cells.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // le celle da settare sono [ra, rb]
Shinya Kitaoka 120a6e
  int ra = row;
Shinya Kitaoka 120a6e
  int rb = row + rowCount - 1;
Shinya Kitaoka 120a6e
  assert(ra <= rb);
Shinya Kitaoka 120a6e
  // le celle non vuote sono [c_ra, c_rb]
Shinya Kitaoka 120a6e
  int c_rb = m_first + oldCellCount - 1;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row > c_rb)  // sono oltre l'ultima riga
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    if (oldCellCount == 0) m_first = row;  // row 'e la nuova firstrow
shun-iwasawa f84c65
    int newCellCount = row - m_first + rowCount;
Shinya Kitaoka 120a6e
    m_cells.resize(newCellCount);
Shinya Kitaoka 120a6e
  } else if (row < m_first) {
Shinya Kitaoka 120a6e
    int delta = m_first - row;
Shinya Kitaoka 120a6e
    m_cells.insert(m_cells.begin(), delta, TXshCell());
Shinya Kitaoka 120a6e
    m_first = row;  // row e' la nuova firstrow
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (rb > c_rb) {
Shinya Kitaoka 120a6e
    for (int i = 0; i < rb - c_rb; ++i) m_cells.push_back(TXshCell());
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int index = row - m_first;
Shinya Kitaoka 120a6e
  assert(0 <= index && index < (int)m_cells.size());
Shinya Kitaoka 120a6e
  for (int i = 0; i < rowCount; i++) m_cells[index + i] = cells[i];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
  while (!m_cells.empty() && m_cells.back().isEmpty()) {
Shinya Kitaoka 120a6e
    m_cells.pop_back();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
  while (!m_cells.empty() && m_cells.front().isEmpty()) {
Shinya Kitaoka 120a6e
    m_cells.erase(m_cells.begin());
Shinya Kitaoka 120a6e
    m_first++;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  if (m_cells.empty()) {
Shinya Kitaoka 120a6e
    m_first = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // updateIcon();
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshCellColumn::insertEmptyCells(int row, int rowCount) {
shun-iwasawa f84c65
  if (m_cells.empty())
shun-iwasawa f84c65
    return;  // se la colonna e' vuota non devo inserire
shun-iwasawa f84c65
             // celle
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row >= m_first + (int)m_cells.size()) return;  // dopo:non inserisco nulla
Shinya Kitaoka 120a6e
  if (row <= m_first)                                // prima
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    m_first += rowCount;
Shinya Kitaoka 120a6e
  } else  // in mezzo
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    int delta                          = row - m_first;
Shinya Kitaoka 120a6e
    std::vector<txshcell>::iterator it = m_cells.begin();</txshcell>
Shinya Kitaoka 120a6e
    std::advance(it, delta);
Shinya Kitaoka 120a6e
    m_cells.insert(it, rowCount, TXshCell());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// sbianca le celle [row, row+rowCount-1] (senza shiftare)
Shinya Kitaoka 120a6e
void TXshCellColumn::clearCells(int row, int rowCount) {
Shinya Kitaoka 120a6e
  if (rowCount <= 0) return;
Shinya Kitaoka 120a6e
  if (m_cells.empty()) return;  // se la colonna e' vuota
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // le celle da cancellare sono [ra, rb]
Shinya Kitaoka 120a6e
  int ra = row;
Shinya Kitaoka 120a6e
  int rb = row + rowCount - 1;
Shinya Kitaoka 120a6e
  assert(ra <= rb);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int cellCount = m_cells.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // le celle non vuote sono [c_ra, c_rb]
Shinya Kitaoka 120a6e
  int c_ra = m_first;
Shinya Kitaoka 120a6e
  int c_rb = m_first + cellCount - 1;
Shinya Kitaoka 120a6e
  assert(c_ra <= c_rb);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // se e' sotto o sopra le celle occupate non devo far nulla
Shinya Kitaoka 120a6e
  if (rb < c_ra || ra > c_rb) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // restringo l'area da cancellare in modo che comprenda solo celle non vuote
Shinya Kitaoka 120a6e
  if (ra < c_ra) ra = c_ra;
Shinya Kitaoka 120a6e
  if (rb > c_rb) rb = c_rb;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // devo "sbiancare" n celle
Shinya Kitaoka 120a6e
  int n = rb - ra + 1;
Shinya Kitaoka 120a6e
  assert(n >= 0);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (n == cellCount)  // ho cancellato tutto
Shinya Kitaoka 120a6e
  {
Shinya Kitaoka 120a6e
    m_cells.clear();
Shinya Kitaoka 120a6e
    m_first = 0;
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    assert(ra - c_ra < (int)m_cells.size());
Shinya Kitaoka 120a6e
    assert(ra - c_ra + n <= (int)m_cells.size());
Shinya Kitaoka 120a6e
    // std::fill_n(&m_cells[ra-c_ra],n, TXshCell());
Shinya Kitaoka 120a6e
    int i;
Shinya Kitaoka 120a6e
    for (i = 0; i < n; i++) m_cells[ra - c_ra + i] = TXshCell();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
    while (!m_cells.empty() && m_cells.back().isEmpty()) {
Shinya Kitaoka 120a6e
      m_cells.pop_back();
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (m_cells.empty()) {
Shinya Kitaoka 120a6e
      m_first = 0;
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      // verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
      while (!m_cells.empty() && m_cells.front().isEmpty()) {
Shinya Kitaoka 120a6e
        m_cells.erase(m_cells.begin());
Shinya Kitaoka 120a6e
        m_first++;
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // updateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// rimuove le celle [row, row+rowCount-1] (shiftando)
Shinya Kitaoka 120a6e
void TXshCellColumn::removeCells(int row, int rowCount) {
Shinya Kitaoka 120a6e
  if (rowCount <= 0) return;
Shinya Kitaoka 120a6e
  if (m_cells.empty()) return;  // se la colonna e' vuota
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int cellCount = m_cells.size();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row >= m_first + cellCount) return;  // sono "sotto" l'ultima cella
Shinya Kitaoka 120a6e
  if (row < m_first) {
Shinya Kitaoka 120a6e
    if (row + rowCount <= m_first)  //"sono sopra la prima cella"
Shinya Kitaoka 120a6e
    {                               // aggiorno solo m_first
Shinya Kitaoka 120a6e
      m_first -= rowCount;
Shinya Kitaoka 120a6e
      return;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
    rowCount += row - m_first;
Shinya Kitaoka 120a6e
    m_first = row;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(row >= m_first);
Shinya Kitaoka 120a6e
  // le celle sotto m_first+cellCount sono gia' vuote
Shinya Kitaoka 120a6e
  if (rowCount > m_first + cellCount - row)
Shinya Kitaoka 120a6e
    rowCount = m_first + cellCount - row;
Shinya Kitaoka 120a6e
  if (rowCount <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (row == m_first) {
Shinya Kitaoka 120a6e
    // cancello all'inizio
Shinya Kitaoka 120a6e
    assert(rowCount <= cellCount);
Shinya Kitaoka 120a6e
    std::vector<txshcell>::iterator it  = m_cells.begin();</txshcell>
Shinya Kitaoka 120a6e
    std::vector<txshcell>::iterator it2 = m_cells.begin();</txshcell>
Shinya Kitaoka 120a6e
    std::advance(it2, rowCount);
Shinya Kitaoka 120a6e
    m_cells.erase(it, it2);
Shinya Kitaoka 120a6e
    // verifico la presenza di celle bianche all'inizio
Shinya Kitaoka 120a6e
    while (!m_cells.empty() && m_cells.front().isEmpty()) {
Shinya Kitaoka 120a6e
      m_cells.erase(m_cells.begin());
Shinya Kitaoka 120a6e
      m_first++;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    // cancello dopo l'inizio
Shinya Kitaoka 120a6e
    int d                               = row - m_first;
Shinya Kitaoka 120a6e
    std::vector<txshcell>::iterator it  = m_cells.begin();</txshcell>
Shinya Kitaoka 120a6e
    std::vector<txshcell>::iterator it2 = m_cells.begin();</txshcell>
Shinya Kitaoka 120a6e
    std::advance(it, d);
Shinya Kitaoka 120a6e
    std::advance(it2, d + rowCount);
Shinya Kitaoka 120a6e
    m_cells.erase(it, it2);
Shinya Kitaoka 120a6e
    if (row + rowCount == m_first + cellCount) {
Shinya Kitaoka 120a6e
      // verifico la presenza di celle bianche alla fine
Shinya Kitaoka 120a6e
      while (!m_cells.empty() && m_cells.back().isEmpty()) {
Shinya Kitaoka 120a6e
        m_cells.pop_back();
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (m_cells.empty()) {
Shinya Kitaoka 120a6e
    m_first = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  // updateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshCellColumn::getLevelRange(int row, int &r0, int &r1) const {
Shinya Kitaoka 120a6e
  r0 = r1       = row;
Shinya Kitaoka 120a6e
  TXshCell cell = getCell(row);
Shinya Kitaoka 120a6e
  if (cell.isEmpty()) return false;
Shinya Kitaoka 120a6e
  while (r0 > 0 &&
Shinya Kitaoka 120a6e
         getCell(r0 - 1).m_level.getPointer() == cell.m_level.getPointer())
Shinya Kitaoka 120a6e
    r0--;
Shinya Kitaoka 120a6e
  while (getCell(r1 + 1).m_level.getPointer() == cell.m_level.getPointer())
Shinya Kitaoka 120a6e
    r1++;
Shinya Kitaoka 120a6e
  return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
shun-iwasawa f84c65
//-----------------------------------------------------------------------------
shun-iwasawa f84c65
shun-iwasawa f84c65
void TXshCellColumn::saveCellMarks(TOStream &os) {
shun-iwasawa f84c65
  if (m_cellMarkIds.isEmpty()) return;
shun-iwasawa f84c65
  // gather frame numbers with the same id
shun-iwasawa f84c65
  QMap<int, qstring=""> idStrMap;</int,>
shun-iwasawa f84c65
  QMap<int, int="">::const_iterator i = m_cellMarkIds.constBegin();</int,>
shun-iwasawa f84c65
  while (i != m_cellMarkIds.constEnd()) {
shun-iwasawa f84c65
    if (!idStrMap.contains(i.value()))
shun-iwasawa f84c65
      idStrMap.insert(i.value(), QString::number(i.key()));
shun-iwasawa f84c65
    else
shun-iwasawa f84c65
      idStrMap[i.value()] += " " + QString::number(i.key());
shun-iwasawa f84c65
    ++i;
shun-iwasawa f84c65
  }
shun-iwasawa f84c65
  os.openChild("cellMarks");
shun-iwasawa f84c65
  QMap<int, qstring="">::const_iterator j = idStrMap.constBegin();</int,>
shun-iwasawa f84c65
  while (j != idStrMap.constEnd()) {
shun-iwasawa f84c65
    std::map<std::string, std::string=""> attr;</std::string,>
shun-iwasawa f84c65
    attr["id"] = std::to_string(j.key());
shun-iwasawa f84c65
    os.openChild("cellMark", attr);
shun-iwasawa f84c65
    os << j.value();
shun-iwasawa f84c65
    os.closeChild();
shun-iwasawa f84c65
    ++j;
shun-iwasawa f84c65
  }
shun-iwasawa f84c65
  os.closeChild();
shun-iwasawa f84c65
}
shun-iwasawa f84c65
shun-iwasawa f84c65
bool TXshCellColumn::loadCellMarks(std::string tagName, TIStream &is) {
shun-iwasawa f84c65
  if (tagName != "cellMarks") return false;
shun-iwasawa f84c65
  m_cellMarkIds.clear();
shun-iwasawa f84c65
  while (is.openChild(tagName)) {
shun-iwasawa f84c65
    if (tagName == "cellMark") {
shun-iwasawa f84c65
      int id;
shun-iwasawa f84c65
      QString frameStr;
shun-iwasawa f84c65
      if (is.getTagParam("id", id)) {
shun-iwasawa f84c65
        is >> frameStr;
shun-iwasawa f84c65
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
shun-iwasawa f84c65
        QStringList frameStrList = frameStr.split(" ", Qt::SkipEmptyParts);
shun-iwasawa f84c65
#else
shun-iwasawa f84c65
        QStringList frameStrList = frameStr.split(" ", QString::SkipEmptyParts);
shun-iwasawa f84c65
#endif
shun-iwasawa f84c65
        for (auto fStr : frameStrList) m_cellMarkIds.insert(fStr.toInt(), id);
shun-iwasawa f84c65
      }
shun-iwasawa f84c65
    }
shun-iwasawa f84c65
    is.closeChild();
shun-iwasawa f84c65
  }
shun-iwasawa f84c65
  return true;
shun-iwasawa f84c65
}
shun-iwasawa f84c65
shun-iwasawa f84c65
void TXshCellColumn::setCellMark(int frame, int id) {
shun-iwasawa f84c65
  if (id < 0)
shun-iwasawa f84c65
    m_cellMarkIds.remove(frame);
shun-iwasawa f84c65
  else
shun-iwasawa f84c65
    m_cellMarkIds.insert(frame, id);
shun-iwasawa f84c65
}
shun-iwasawa f84c65
shun-iwasawa f84c65
int TXshCellColumn::getCellMark(int frame) const {
shun-iwasawa f84c65
  return m_cellMarkIds.value(frame, -1);
shun-iwasawa f84c65
}
shun-iwasawa f84c65
shun-iwasawa f84c65
QMap<int, int=""> TXshCellColumn::getCellMarks() const { return m_cellMarkIds; }</int,>
shun-iwasawa f84c65
shun-iwasawa f84c65
void TXshCellColumn::clearCellMarks() { m_cellMarkIds.clear(); }
shun-iwasawa f84c65
Toshihiro Shimizu 890ddd
//=============================================================================
Shinya Kitaoka 120a6e
// TXshColumn
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshColumn::setStatusWord(int status) { m_status = status; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshColumn *TXshColumn::createEmpty(int type) {
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case eSoundType:
Shinya Kitaoka 120a6e
    return new TXshSoundColumn;
Shinya Kitaoka 120a6e
  case eZeraryFxType:
Shinya Kitaoka 120a6e
    return new TXshZeraryFxColumn(0);
Shinya Kitaoka 120a6e
  case ePaletteType:
Shinya Kitaoka 120a6e
    return new TXshPaletteColumn;
Shinya Kitaoka 120a6e
  case eSoundTextType:
Shinya Kitaoka 120a6e
    return new TXshSoundTextColumn;
Shinya Kitaoka 120a6e
  case eMeshType:
Shinya Kitaoka 120a6e
    return new TXshMeshColumn;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  assert(type == eLevelType);
Shinya Kitaoka 120a6e
  return new TXshLevelColumn;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshColumn::ColumnType TXshColumn::toColumnType(int levelType) {
Shinya Kitaoka 120a6e
  ColumnType colType = TXshColumn::eLevelType;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (levelType & LEVELCOLUMN_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::eLevelType;
Shinya Kitaoka 120a6e
  else if (levelType == ZERARYFX_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::eZeraryFxType;
Shinya Kitaoka 120a6e
  else if (levelType == PLT_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::ePaletteType;
Shinya Kitaoka 120a6e
  else if (levelType == SND_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::eSoundType;
Shinya Kitaoka 120a6e
  else if (levelType == SND_TXT_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::eSoundTextType;
Shinya Kitaoka 120a6e
  else if (levelType == MESH_XSHLEVEL)
Shinya Kitaoka 120a6e
    colType = TXshColumn::eMeshType;
Shinya Kitaoka 120a6e
  else
luzpaz 27707d
    assert(!"Unknown level type!");
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return colType;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
justburner 64e039
justburner 64e039
bool TXshColumn::canBeParent() const {
justburner 64e039
  switch (getColumnType()) {
justburner 64e039
  case eLevelType:
justburner 64e039
  case eZeraryFxType:
justburner 64e039
  case ePaletteType:
justburner 64e039
  case eMeshType:
justburner 64e039
    return true;
justburner 64e039
  case eSoundType:
justburner 64e039
  case eSoundTextType:
justburner 64e039
    return false;
justburner 64e039
  default:
justburner 64e039
    assert(!"Unknown level type!");
shun-iwasawa 443318
    return false;
justburner 64e039
  }
justburner 64e039
}
justburner 64e039
justburner 64e039
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TXshColumn::isRendered() const {
manongjohn 09549b
  //  if (!getXsheet() || !getFx()) return false;
manongjohn 09549b
  //  if (!isPreviewVisible()) return false;
manongjohn 25e6cf
  if (!getXsheet() || !isPreviewVisible()) return false;
manongjohn 25e6cf
  if (getColumnType() == eSoundType) return true;
manongjohn 25e6cf
  if (!getFx()) return false;
Shinya Kitaoka 120a6e
  return getXsheet()->getFxDag()->isRendered(getFx());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TXshColumn::isReference() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  if(!getXsheet() || !getFx()) return true;
Shinya Kitaoka 120a6e
  if(getXsheet()->getFxDag()->getTerminalFxs()->containsFx(getFx())) return
Shinya Kitaoka 120a6e
false;
Toshihiro Shimizu 890ddd
  return getFx()->getOutputConnectionCount()==0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshColumn::isControl() const {
Shinya Kitaoka 120a6e
  if (!getXsheet() || !getFx()) return false;
Shinya Kitaoka 120a6e
  return getXsheet()->getFxDag()->isControl(getFx());
Shinya Kitaoka 120a6e
  /*
Shinya Kitaoka 120a6e
TFx *fx = getFx();
Shinya Kitaoka 120a6e
if(!fx) return false;
Shinya Kitaoka 120a6e
if(!getXsheet()) return false;
Shinya Kitaoka 120a6e
if(getXsheet()->getFxDag()->getTerminalFxs()->containsFx(getFx())) return false;
Shinya Kitaoka 120a6e
for(int i=0;i<fx->getOutputConnectionCount();i++)</fx->
Shinya Kitaoka 120a6e
{
Shinya Kitaoka 120a6e
TFxPort *port = fx->getOutputConnection(i);
Shinya Kitaoka 120a6e
if(port->getOwnerFx()->getInputPort(0) != port)
Shinya Kitaoka 120a6e
return true;
Shinya Kitaoka 120a6e
}
Shinya Kitaoka 120a6e
return false;
Shinya Kitaoka 120a6e
*/
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef LEVO
Shinya Kitaoka 120a6e
void TXshColumn::setCamstandNextState() {
Shinya Kitaoka 120a6e
  setCamstandVisible(!isCamstandVisible());
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (Preferences::instance()->isCamStandOpacityEnabled()) {
Shinya Kitaoka 120a6e
    // camera stand, 3-state-toggle: notvisible -> visible+nottransparent ->
Shinya Kitaoka 120a6e
    // visible+transparent
Shinya Kitaoka 120a6e
    if (isCamstandVisible()) {
Shinya Kitaoka 120a6e
      if (isCamstandTransparent())
Shinya Kitaoka 120a6e
        setCamstandVisible(false);
Shinya Kitaoka 120a6e
      else
Shinya Kitaoka 120a6e
        setCamstandTransparent(true);
Shinya Kitaoka 120a6e
    } else {
Shinya Kitaoka 120a6e
      setCamstandVisible(true);
Shinya Kitaoka 120a6e
      setCamstandTransparent(false);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    setCamstandTransparent(false);
Shinya Kitaoka 120a6e
    setCamstandVisible(!isCamstandVisible());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshColumn::isCamstandVisible() const {
Shinya Kitaoka 120a6e
  return (m_status & eCamstandVisible) == 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*
Toshihiro Shimizu 890ddd
bool TXshColumn::isCamstandTransparent() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  return (m_status&eCamstandTransparent)!=0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::setCamstandTransparent(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
  const int mask = eCamstandTransparent;
Shinya Kitaoka 120a6e
  if(!on) m_status&=~mask; else m_status|=mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshColumn::setCamstandVisible(bool on) {
Shinya Kitaoka 120a6e
  const int mask = eCamstandVisible;
Shinya Kitaoka 120a6e
  if (on)
Shinya Kitaoka 120a6e
    m_status &= ~mask;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_status |= mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshColumn::isPreviewVisible() const {
Shinya Kitaoka 120a6e
  return (m_status & ePreviewVisible) == 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshColumn::setPreviewVisible(bool on) {
Shinya Kitaoka 120a6e
  const int mask = ePreviewVisible;
Shinya Kitaoka 120a6e
  if (on)
Shinya Kitaoka 120a6e
    m_status &= ~mask;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_status |= mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshColumn::isLocked() const { return (m_status & eLocked) != 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshColumn::lock(bool on) {
Shinya Kitaoka 120a6e
  const int mask = eLocked;
Shinya Kitaoka 120a6e
  if (on)
Shinya Kitaoka 120a6e
    m_status |= mask;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_status &= ~mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TXshColumn::isMask() const { return (m_status & eMasked) != 0; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshColumn::setIsMask(bool on) {
Shinya Kitaoka 120a6e
  const int mask = eMasked;
Shinya Kitaoka 120a6e
  if (on)
Shinya Kitaoka 120a6e
    m_status |= mask;
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    m_status &= ~mask;
Toshihiro Shimizu 890ddd
}
shun_iwasawa 2c0f50
shun_iwasawa 2c0f50
//-----------------------------------------------------------------------------
shun_iwasawa 2c0f50
manongjohn 09549b
void TXshColumn::resetColumnProperties() {
manongjohn 09549b
  setStatusWord(0);
manongjohn 09549b
  setOpacity(255);
manongjohn 09549b
  setColorTag(0);
shun-iwasawa a266be
  setColorFilterId(0);  // None
manongjohn 09549b
}