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