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
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//TXshCellColumn
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshCellColumn::TXshCellColumn()
Toshihiro Shimizu 890ddd
	: m_first(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshCellColumn::~TXshCellColumn()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_cells.clear();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TXshCellColumn::getRange(int &r0, int &r1) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int cellCount = m_cells.size();
Toshihiro Shimizu 890ddd
	r0 = m_first;
Toshihiro Shimizu 890ddd
	r1 = r0 + cellCount - 1;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < cellCount && m_cells[i].isEmpty(); i++) {
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (i >= cellCount) {
Toshihiro Shimizu 890ddd
		r0 = 0;
Toshihiro Shimizu 890ddd
		r1 = -1;
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	r0 = m_first + i;
Toshihiro Shimizu 890ddd
	for (i = cellCount - 1; i >= 0 && m_cells[i].isEmpty(); i--) {
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	r1 = m_first + i;
Toshihiro Shimizu 890ddd
	return r1 - r0 + 1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TXshCellColumn::getRowCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i = m_cells.size();
Toshihiro Shimizu 890ddd
	for (; i > 0 && m_cells[i - 1].isEmpty(); i--) {
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (i == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return m_first + i;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TXshCellColumn::getMaxFrame() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int r0, r1;
Toshihiro Shimizu 890ddd
	getRange(r0, r1);
Toshihiro Shimizu 890ddd
	return r1;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TXshCellColumn::getFirstRow() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_first;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TXshCell &TXshCellColumn::getCell(int row) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	static TXshCell emptyCell;
Toshihiro Shimizu 890ddd
	if (row < 0 || row < m_first ||
Toshihiro Shimizu 890ddd
		row >= m_first + (int)m_cells.size())
Toshihiro Shimizu 890ddd
		return emptyCell;
Toshihiro Shimizu 890ddd
	return m_cells[row - m_first];
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshCellColumn::isCellEmpty(int row) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getCell(row).isEmpty();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--- debug only
Toshihiro Shimizu 890ddd
void TXshCellColumn::checkColumn() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(m_first >= 0);
Toshihiro Shimizu 890ddd
	int r0, r1;
Toshihiro Shimizu 890ddd
	int range = getRange(r0, r1);
Toshihiro Shimizu 890ddd
	assert(range >= 0);
Toshihiro Shimizu 890ddd
	assert(range == (int)m_cells.size());
Toshihiro Shimizu 890ddd
	assert(getRowCount() >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell firstCell = getCell(m_first);
Toshihiro Shimizu 890ddd
	TXshCell lastCell = getCell(r1);
Toshihiro Shimizu 890ddd
	if (range == 0)
Toshihiro Shimizu 890ddd
		assert(firstCell.isEmpty() && lastCell.isEmpty());
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		assert(firstCell.isEmpty() == 0);
Toshihiro Shimizu 890ddd
		assert(lastCell.isEmpty() == 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int maxFrame = getMaxFrame();
Toshihiro Shimizu 890ddd
		assert(maxFrame == r1);
Toshihiro Shimizu 890ddd
		assert(getCell(maxFrame).isEmpty() == 0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshCellColumn::getCells(int row, int rowCount, TXshCell cells[])
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const TXshCell emptyCell;
Toshihiro Shimizu 890ddd
	int first = m_first;
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	int cellCount = m_cells.size();
Toshihiro Shimizu 890ddd
	if (row < 0 || row + rowCount - 1 < first ||
Toshihiro Shimizu 890ddd
		row >= first + cellCount) {
Toshihiro Shimizu 890ddd
		for (i = 0; i < rowCount; i++)
Toshihiro Shimizu 890ddd
			cells[i] = emptyCell;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int dst, src, n, delta;
Toshihiro Shimizu 890ddd
	n = rowCount;
Toshihiro Shimizu 890ddd
	delta = m_first - row;
Toshihiro Shimizu 890ddd
	if (delta < 0) { // le celle cominciano PRIMA della zona da leggere
Toshihiro Shimizu 890ddd
		dst = 0;
Toshihiro Shimizu 890ddd
		src = -delta;
Toshihiro Shimizu 890ddd
	} else { //le celle cominciano DOPO della zona da leggere
Toshihiro Shimizu 890ddd
		dst = delta;
Toshihiro Shimizu 890ddd
		src = 0;
Toshihiro Shimizu 890ddd
		n -= delta;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (n + src > cellCount)
Toshihiro Shimizu 890ddd
		n = cellCount - src;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TXshCell *dstCell = cells;
Toshihiro Shimizu 890ddd
	TXshCell *endDstCell = dstCell + dst;
Toshihiro Shimizu 890ddd
	while (dstCell < endDstCell)
Toshihiro Shimizu 890ddd
		*dstCell++ = emptyCell;
Toshihiro Shimizu 890ddd
	endDstCell += n;
Toshihiro Shimizu 890ddd
	while (dstCell < endDstCell)
Toshihiro Shimizu 890ddd
		*dstCell++ = m_cells[src++];
Toshihiro Shimizu 890ddd
	endDstCell = cells + rowCount;
Toshihiro Shimizu 890ddd
	while (dstCell < endDstCell)
Toshihiro Shimizu 890ddd
		*dstCell++ = emptyCell;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshCellColumn::setCell(int row, const TXshCell &cell)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!canSetCell(cell))
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	assert(row >= 0);
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Toshihiro Shimizu 890ddd
	checkColumn();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	if (m_cells.empty()) //se la colonna e' vuota
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (!cell.isEmpty()) {
Toshihiro Shimizu 890ddd
			m_cells.push_back(cell);
Toshihiro Shimizu 890ddd
			m_first = row;
Toshihiro Shimizu 890ddd
			//updateIcon();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int oldCellCount = m_cells.size();
Toshihiro Shimizu 890ddd
	assert(oldCellCount > 0);
Toshihiro Shimizu 890ddd
	int lastRow = m_first + oldCellCount - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (row < m_first) //prima
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (cell.isEmpty())
Toshihiro Shimizu 890ddd
			return false; //non faccio nulla
Toshihiro Shimizu 890ddd
		int delta = m_first - row;
Toshihiro Shimizu 890ddd
		assert(delta > 0);
Toshihiro Shimizu 890ddd
		m_cells.insert(m_cells.begin(), delta - 1, TXshCell()); //celle vuote
Toshihiro Shimizu 890ddd
		m_cells.insert(m_cells.begin(), cell);					//devo settare la prima comp. del vettore
Toshihiro Shimizu 890ddd
		m_first = row;											//row 'e la nuova firstrow
Toshihiro Shimizu 890ddd
//updateIcon();
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Toshihiro Shimizu 890ddd
		checkColumn();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	} else if (row > lastRow) //dopo
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (cell.isEmpty())
Toshihiro Shimizu 890ddd
			return false; //non faccio nulla
Toshihiro Shimizu 890ddd
		int count = row - lastRow - 1;
Toshihiro Shimizu 890ddd
		//se necessario, inserisco celle vuote
Toshihiro Shimizu 890ddd
		for (int i = 0; i < count; ++i)
Toshihiro Shimizu 890ddd
			m_cells.push_back(TXshCell());
Toshihiro Shimizu 890ddd
		m_cells.push_back(cell);
Toshihiro Shimizu 890ddd
#ifndef NDEBUG
Toshihiro Shimizu 890ddd
		checkColumn();
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
		return true;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//"[r0,r1]"
Toshihiro Shimizu 890ddd
	int index = row - m_first;
Toshihiro Shimizu 890ddd
	assert(0 <= index && index < (int)m_cells.size());
Toshihiro Shimizu 890ddd
	m_cells[index] = cell;
Toshihiro Shimizu 890ddd
	//if(index == 0) updateIcon();
Toshihiro Shimizu 890ddd
	if (cell.isEmpty()) {
Toshihiro Shimizu 890ddd
		if (row == lastRow) {
Toshihiro Shimizu 890ddd
			// verifico la presenza di celle bianche alla fine
Toshihiro Shimizu 890ddd
			while (!m_cells.empty() && m_cells.back().isEmpty())
Toshihiro Shimizu 890ddd
				m_cells.pop_back();
Toshihiro Shimizu 890ddd
		} else if (row == m_first) {
Toshihiro Shimizu 890ddd
			// verifico la presenza di celle bianche all'inizio
Toshihiro Shimizu 890ddd
			while (!m_cells.empty() && m_cells.front().isEmpty()) {
Toshihiro Shimizu 890ddd
				m_cells.erase(m_cells.begin());
Toshihiro Shimizu 890ddd
				m_first++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		if (m_cells.empty())
Toshihiro Shimizu 890ddd
			m_first = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	checkColumn();
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshCellColumn::setCells(int row, int rowCount, const TXshCell cells[])
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(row >= 0);
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < rowCount; i++)
Toshihiro Shimizu 890ddd
		if (!canSetCell(cells[i]))
Toshihiro Shimizu 890ddd
			return false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int oldCellCount = m_cells.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// le celle da settare sono [ra, rb]
Toshihiro Shimizu 890ddd
	int ra = row;
Toshihiro Shimizu 890ddd
	int rb = row + rowCount - 1;
Toshihiro Shimizu 890ddd
	assert(ra <= rb);
Toshihiro Shimizu 890ddd
	// le celle non vuote sono [c_ra, c_rb]
Toshihiro Shimizu 890ddd
	int c_rb = m_first + oldCellCount - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (row > c_rb) //sono oltre l'ultima riga
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (oldCellCount == 0)
Toshihiro Shimizu 890ddd
			m_first = row; //row 'e la nuova firstrow
Toshihiro Shimizu 890ddd
		int newCellCount = row - m_first + rowCount;
Toshihiro Shimizu 890ddd
		m_cells.resize(newCellCount);
Toshihiro Shimizu 890ddd
	} else if (row < m_first) {
Toshihiro Shimizu 890ddd
		int delta = m_first - row;
Toshihiro Shimizu 890ddd
		m_cells.insert(m_cells.begin(), delta, TXshCell());
Toshihiro Shimizu 890ddd
		m_first = row; //row e' la nuova firstrow
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (rb > c_rb) {
Toshihiro Shimizu 890ddd
		for (int i = 0; i < rb - c_rb; ++i)
Toshihiro Shimizu 890ddd
			m_cells.push_back(TXshCell());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int index = row - m_first;
Toshihiro Shimizu 890ddd
	assert(0 <= index && index < (int)m_cells.size());
Toshihiro Shimizu 890ddd
	for (int i = 0; i < rowCount; i++)
Toshihiro Shimizu 890ddd
		m_cells[index + i] = cells[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// verifico la presenza di celle bianche alla fine
Toshihiro Shimizu 890ddd
	while (!m_cells.empty() && m_cells.back().isEmpty()) {
Toshihiro Shimizu 890ddd
		m_cells.pop_back();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// verifico la presenza di celle bianche all'inizio
Toshihiro Shimizu 890ddd
	while (!m_cells.empty() && m_cells.front().isEmpty()) {
Toshihiro Shimizu 890ddd
		m_cells.erase(m_cells.begin());
Toshihiro Shimizu 890ddd
		m_first++;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (m_cells.empty()) {
Toshihiro Shimizu 890ddd
		m_first = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//updateIcon();
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshCellColumn::insertEmptyCells(int row, int rowCount)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_cells.empty())
Toshihiro Shimizu 890ddd
		return; //se la colonna e' vuota non devo inserire celle
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (row >= m_first + (int)m_cells.size())
Toshihiro Shimizu 890ddd
		return;			//dopo:non inserisco nulla
Toshihiro Shimizu 890ddd
	if (row <= m_first) //prima
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_first += rowCount;
Toshihiro Shimizu 890ddd
	} else //in mezzo
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int delta = row - m_first;
Toshihiro Shimizu 890ddd
		std::vector<txshcell>::iterator it = m_cells.begin();</txshcell>
Toshihiro Shimizu 890ddd
		std::advance(it, delta);
Toshihiro Shimizu 890ddd
		m_cells.insert(it, rowCount, TXshCell());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
// sbianca le celle [row, row+rowCount-1] (senza shiftare)
Toshihiro Shimizu 890ddd
void TXshCellColumn::clearCells(int row, int rowCount)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (rowCount <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_cells.empty())
Toshihiro Shimizu 890ddd
		return; //se la colonna e' vuota
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// le celle da cancellare sono [ra, rb]
Toshihiro Shimizu 890ddd
	int ra = row;
Toshihiro Shimizu 890ddd
	int rb = row + rowCount - 1;
Toshihiro Shimizu 890ddd
	assert(ra <= rb);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int cellCount = m_cells.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// le celle non vuote sono [c_ra, c_rb]
Toshihiro Shimizu 890ddd
	int c_ra = m_first;
Toshihiro Shimizu 890ddd
	int c_rb = m_first + cellCount - 1;
Toshihiro Shimizu 890ddd
	assert(c_ra <= c_rb);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// se e' sotto o sopra le celle occupate non devo far nulla
Toshihiro Shimizu 890ddd
	if (rb < c_ra || ra > c_rb)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// restringo l'area da cancellare in modo che comprenda solo celle non vuote
Toshihiro Shimizu 890ddd
	if (ra < c_ra)
Toshihiro Shimizu 890ddd
		ra = c_ra;
Toshihiro Shimizu 890ddd
	if (rb > c_rb)
Toshihiro Shimizu 890ddd
		rb = c_rb;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// devo "sbiancare" n celle
Toshihiro Shimizu 890ddd
	int n = rb - ra + 1;
Toshihiro Shimizu 890ddd
	assert(n >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (n == cellCount) // ho cancellato tutto
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_cells.clear();
Toshihiro Shimizu 890ddd
		m_first = 0;
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		assert(ra - c_ra < (int)m_cells.size());
Toshihiro Shimizu 890ddd
		assert(ra - c_ra + n <= (int)m_cells.size());
Toshihiro Shimizu 890ddd
		//std::fill_n(&m_cells[ra-c_ra],n, TXshCell());
Toshihiro Shimizu 890ddd
		int i;
Toshihiro Shimizu 890ddd
		for (i = 0; i < n; i++)
Toshihiro Shimizu 890ddd
			m_cells[ra - c_ra + i] = TXshCell();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// verifico la presenza di celle bianche alla fine
Toshihiro Shimizu 890ddd
		while (!m_cells.empty() && m_cells.back().isEmpty()) {
Toshihiro Shimizu 890ddd
			m_cells.pop_back();
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (m_cells.empty()) {
Toshihiro Shimizu 890ddd
			m_first = 0;
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			// verifico la presenza di celle bianche all'inizio
Toshihiro Shimizu 890ddd
			while (!m_cells.empty() && m_cells.front().isEmpty()) {
Toshihiro Shimizu 890ddd
				m_cells.erase(m_cells.begin());
Toshihiro Shimizu 890ddd
				m_first++;
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//updateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// rimuove le celle [row, row+rowCount-1] (shiftando)
Toshihiro Shimizu 890ddd
void TXshCellColumn::removeCells(int row, int rowCount)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (rowCount <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	if (m_cells.empty())
Toshihiro Shimizu 890ddd
		return; //se la colonna e' vuota
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int cellCount = m_cells.size();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (row >= m_first + cellCount)
Toshihiro Shimizu 890ddd
		return; //sono "sotto" l'ultima cella
Toshihiro Shimizu 890ddd
	if (row < m_first) {
Toshihiro Shimizu 890ddd
		if (row + rowCount <= m_first) //"sono sopra la prima cella"
Toshihiro Shimizu 890ddd
		{							   // aggiorno solo m_first
Toshihiro Shimizu 890ddd
			m_first -= rowCount;
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		rowCount += row - m_first;
Toshihiro Shimizu 890ddd
		m_first = row;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(row >= m_first);
Toshihiro Shimizu 890ddd
	// le celle sotto m_first+cellCount sono gia' vuote
Toshihiro Shimizu 890ddd
	if (rowCount > m_first + cellCount - row)
Toshihiro Shimizu 890ddd
		rowCount = m_first + cellCount - row;
Toshihiro Shimizu 890ddd
	if (rowCount <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (row == m_first) {
Toshihiro Shimizu 890ddd
		//cancello all'inizio
Toshihiro Shimizu 890ddd
		assert(rowCount <= cellCount);
Toshihiro Shimizu 890ddd
		std::vector<txshcell>::iterator it = m_cells.begin();</txshcell>
Toshihiro Shimizu 890ddd
		std::vector<txshcell>::iterator it2 = m_cells.begin();</txshcell>
Toshihiro Shimizu 890ddd
		std::advance(it2, rowCount);
Toshihiro Shimizu 890ddd
		m_cells.erase(it, it2);
Toshihiro Shimizu 890ddd
		// verifico la presenza di celle bianche all'inizio
Toshihiro Shimizu 890ddd
		while (!m_cells.empty() && m_cells.front().isEmpty()) {
Toshihiro Shimizu 890ddd
			m_cells.erase(m_cells.begin());
Toshihiro Shimizu 890ddd
			m_first++;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		// cancello dopo l'inizio
Toshihiro Shimizu 890ddd
		int d = row - m_first;
Toshihiro Shimizu 890ddd
		std::vector<txshcell>::iterator it = m_cells.begin();</txshcell>
Toshihiro Shimizu 890ddd
		std::vector<txshcell>::iterator it2 = m_cells.begin();</txshcell>
Toshihiro Shimizu 890ddd
		std::advance(it, d);
Toshihiro Shimizu 890ddd
		std::advance(it2, d + rowCount);
Toshihiro Shimizu 890ddd
		m_cells.erase(it, it2);
Toshihiro Shimizu 890ddd
		if (row + rowCount == m_first + cellCount) {
Toshihiro Shimizu 890ddd
			// verifico la presenza di celle bianche alla fine
Toshihiro Shimizu 890ddd
			while (!m_cells.empty() && m_cells.back().isEmpty()) {
Toshihiro Shimizu 890ddd
				m_cells.pop_back();
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (m_cells.empty()) {
Toshihiro Shimizu 890ddd
		m_first = 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	//updateIcon();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshCellColumn::getLevelRange(int row, int &r0, int &r1) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	r0 = r1 = row;
Toshihiro Shimizu 890ddd
	TXshCell cell = getCell(row);
Toshihiro Shimizu 890ddd
	if (cell.isEmpty())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	while (r0 > 0 && getCell(r0 - 1).m_level.getPointer() == cell.m_level.getPointer())
Toshihiro Shimizu 890ddd
		r0--;
Toshihiro Shimizu 890ddd
	while (getCell(r1 + 1).m_level.getPointer() == cell.m_level.getPointer())
Toshihiro Shimizu 890ddd
		r1++;
Toshihiro Shimizu 890ddd
	return true;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
//TXshColumn
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::setStatusWord(int status)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_status = status;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshColumn *TXshColumn::createEmpty(int type)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	switch (type) {
Toshihiro Shimizu 890ddd
	case eSoundType:
Toshihiro Shimizu 890ddd
		return new TXshSoundColumn;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE eZeraryFxType : return new TXshZeraryFxColumn(0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE ePaletteType : return new TXshPaletteColumn;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE eSoundTextType : return new TXshSoundTextColumn;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		CASE eMeshType : return new TXshMeshColumn;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	assert(type == eLevelType);
Toshihiro Shimizu 890ddd
	return new TXshLevelColumn;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshColumn::ColumnType TXshColumn::toColumnType(int levelType)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	ColumnType colType = TXshColumn::eLevelType;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (levelType & LEVELCOLUMN_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::eLevelType;
Toshihiro Shimizu 890ddd
	else if (levelType == ZERARYFX_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::eZeraryFxType;
Toshihiro Shimizu 890ddd
	else if (levelType == PLT_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::ePaletteType;
Toshihiro Shimizu 890ddd
	else if (levelType == SND_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::eSoundType;
Toshihiro Shimizu 890ddd
	else if (levelType == SND_TXT_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::eSoundTextType;
Toshihiro Shimizu 890ddd
	else if (levelType == MESH_XSHLEVEL)
Toshihiro Shimizu 890ddd
		colType = TXshColumn::eMeshType;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		assert(!"Unkown level type!");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return colType;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isRendered() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!getXsheet() || !getFx())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	if (!isPreviewVisible())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	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;
Toshihiro Shimizu 890ddd
  if(getXsheet()->getFxDag()->getTerminalFxs()->containsFx(getFx())) return false;
Toshihiro Shimizu 890ddd
  return getFx()->getOutputConnectionCount()==0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isControl() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!getXsheet() || !getFx())
Toshihiro Shimizu 890ddd
		return false;
Toshihiro Shimizu 890ddd
	return getXsheet()->getFxDag()->isControl(getFx());
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  TFx *fx = getFx();
Toshihiro Shimizu 890ddd
  if(!fx) return false;
Toshihiro Shimizu 890ddd
  if(!getXsheet()) return false;
Toshihiro Shimizu 890ddd
  if(getXsheet()->getFxDag()->getTerminalFxs()->containsFx(getFx())) return false;
Toshihiro Shimizu 890ddd
  for(int i=0;i<fx->getOutputConnectionCount();i++)</fx->
Toshihiro Shimizu 890ddd
  {
Toshihiro Shimizu 890ddd
    TFxPort *port = fx->getOutputConnection(i);
Toshihiro Shimizu 890ddd
    if(port->getOwnerFx()->getInputPort(0) != port)
Toshihiro Shimizu 890ddd
      return true;
Toshihiro Shimizu 890ddd
  }
Toshihiro Shimizu 890ddd
  return false;
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
#ifdef LEVO
Toshihiro Shimizu 890ddd
void TXshColumn::setCamstandNextState()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setCamstandVisible(!isCamstandVisible());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (Preferences::instance()->isCamStandOpacityEnabled()) {
Toshihiro Shimizu 890ddd
		// camera stand, 3-state-toggle: notvisible -> visible+nottransparent -> visible+transparent
Toshihiro Shimizu 890ddd
		if (isCamstandVisible()) {
Toshihiro Shimizu 890ddd
			if (isCamstandTransparent())
Toshihiro Shimizu 890ddd
				setCamstandVisible(false);
Toshihiro Shimizu 890ddd
			else
Toshihiro Shimizu 890ddd
				setCamstandTransparent(true);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			setCamstandVisible(true);
Toshihiro Shimizu 890ddd
			setCamstandTransparent(false);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} else {
Toshihiro Shimizu 890ddd
		setCamstandTransparent(false);
Toshihiro Shimizu 890ddd
		setCamstandVisible(!isCamstandVisible());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isCamstandVisible() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	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;
Toshihiro Shimizu 890ddd
  if(!on) m_status&=~mask; else m_status|=mask; 
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::setCamstandVisible(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int mask = eCamstandVisible;
Toshihiro Shimizu 890ddd
	if (on)
Toshihiro Shimizu 890ddd
		m_status &= ~mask;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_status |= mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isPreviewVisible() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_status & ePreviewVisible) == 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::setPreviewVisible(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int mask = ePreviewVisible;
Toshihiro Shimizu 890ddd
	if (on)
Toshihiro Shimizu 890ddd
		m_status &= ~mask;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_status |= mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isLocked() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_status & eLocked) != 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::lock(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int mask = eLocked;
Toshihiro Shimizu 890ddd
	if (on)
Toshihiro Shimizu 890ddd
		m_status |= mask;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_status &= ~mask;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TXshColumn::isMask() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_status & eMasked) != 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshColumn::setIsMask(bool on)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	const int mask = eMasked;
Toshihiro Shimizu 890ddd
	if (on)
Toshihiro Shimizu 890ddd
		m_status |= mask;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		m_status &= ~mask;
Toshihiro Shimizu 890ddd
}