Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCOLUMNSET_INCLUDED
Toshihiro Shimizu 890ddd
#define TCOLUMNSET_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tsmartpointer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#undef DVAPI
Toshihiro Shimizu 890ddd
#undef DVVAR
Toshihiro Shimizu 890ddd
#ifdef TXSHEET_EXPORTS
Toshihiro Shimizu 890ddd
#define DVAPI DV_EXPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_EXPORT_VAR
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
#define DVAPI DV_IMPORT_API
Toshihiro Shimizu 890ddd
#define DVVAR DV_IMPORT_VAR
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class DVAPI TColumnHeader : public TSmartObject
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	DECLARE_CLASS_CODE
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int m_index; //!< The header's index in a columns set
Toshihiro Shimizu 890ddd
	int m_pos;   //!< The header's screen X pos in a columns viewer
Toshihiro Shimizu 890ddd
	int m_width; //!< The header's width in a columns viewer
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool m_inColumnsSet; //!< (TO BE REMOVED ASAP) Whether the header
Toshihiro Shimizu 890ddd
						 //!< belongs to a columns set. Should be
Toshihiro Shimizu 890ddd
						 //!< redirected to a negative m_index.
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TColumnHeader();
Toshihiro Shimizu 890ddd
	virtual ~TColumnHeader() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getIndex() const { return m_index; }
Toshihiro Shimizu 890ddd
	int getPos() const { return m_pos; }
Toshihiro Shimizu 890ddd
	int getX0() const { return m_pos; }
Toshihiro Shimizu 890ddd
	int getX1() const { return m_pos + m_width - 1; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void getCoords(int &x0, int &x1) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		x0 = m_pos;
Toshihiro Shimizu 890ddd
		x1 = m_pos + m_width - 1;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getWidth() const { return m_width; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool inColumnsSet() const { return m_inColumnsSet; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	template <class t=""></class>
Toshihiro Shimizu 890ddd
	friend class TColumnSetT;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TSmartPointerT<tcolumnheader>;</tcolumnheader>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TSmartPointerT<tcolumnheader> TColumnHeaderP;</tcolumnheader>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class t=""></class>
Toshihiro Shimizu 890ddd
class TColumnSetT
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	typedef TSmartPointerT<t> ColumnP;</t>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	std::vector<columnp> m_columns;</columnp>
Toshihiro Shimizu 890ddd
	int m_defaultWidth;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	static bool compareColumnPos(const int pos, const ColumnP &ch2)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		return pos <= ch2->getX1();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	TColumnSetT(int defaultWidth = 100) : m_defaultWidth(defaultWidth) {}
Toshihiro Shimizu 890ddd
	~TColumnSetT() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int getColumnCount() const { return m_columns.size(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void clear() { m_columns.clear(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void col2pos(int index, int &x0, int &x1) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0);
Toshihiro Shimizu 890ddd
		int columnCount = (int)m_columns.size();
Toshihiro Shimizu 890ddd
		if (index < columnCount)
Toshihiro Shimizu 890ddd
			m_columns[index]->getCoords(x0, x1);
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			x0 = (columnCount > 0 ? m_columns.back()->getX1() + 1 : 0) + (index - columnCount) * m_defaultWidth;
Toshihiro Shimizu 890ddd
			x1 = x0 + m_defaultWidth - 1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
	//versione con upper_bound
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int pos2col(int pos) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		// n.b. endPos e' la coordinata del primo pixel non occupato da colonne
Toshihiro Shimizu 890ddd
		int endPos = m_columns.empty() ? 0 : m_columns.back()->getX1() + 1;
Toshihiro Shimizu 890ddd
		if (pos >= endPos)
Toshihiro Shimizu 890ddd
			return m_columns.size() + (pos - endPos) / m_defaultWidth;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		typename std::vector<columnp>::const_iterator loc;</columnp>
Toshihiro Shimizu 890ddd
		loc = std::upper_bound(m_columns.begin(), m_columns.end(), pos, compareColumnPos);
Toshihiro Shimizu 890ddd
		return std::distance(m_columns.begin(), loc);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const ColumnP &getColumn(int index) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		static const ColumnP empty;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (index >= 0 && index < (int)m_columns.size())
Toshihiro Shimizu 890ddd
			return m_columns[index];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return empty;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const ColumnP &touchColumn(int index, int type = 0)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		const int count = m_columns.size();
Toshihiro Shimizu 890ddd
		if (index < count)
Toshihiro Shimizu 890ddd
			return m_columns[index];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int i = count; i <= index; ++i) {
Toshihiro Shimizu 890ddd
			int cType = (i != index) ? 0 : type;
Toshihiro Shimizu 890ddd
			ColumnP col = T::createEmpty(cType);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			m_columns.push_back(col);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		update(count);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(index == (int)m_columns.size() - 1);
Toshihiro Shimizu 890ddd
		return m_columns[index];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const ColumnP &insertColumn(int index, const ColumnP &column)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		//assert(column && column->m_index < 0);
Toshihiro Shimizu 890ddd
		assert(column && !column->m_inColumnsSet);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (index > 0)
Toshihiro Shimizu 890ddd
			touchColumn(index - 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_columns.insert(m_columns.begin() + index, column);
Toshihiro Shimizu 890ddd
		update(index);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return column;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const ColumnP removeColumn(int index)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int columnCount = m_columns.size();
Toshihiro Shimizu 890ddd
		if (index >= columnCount) // Shouldn't be asserted instead ?
Toshihiro Shimizu 890ddd
			return ColumnP();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		ColumnP column = m_columns[index];
Toshihiro Shimizu 890ddd
		//column->m_index = -1;                           // We should enforce this. Unfortunately, must be tested extensively.
Toshihiro Shimizu 890ddd
		column->m_inColumnsSet = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_columns.erase(m_columns.begin() + index);
Toshihiro Shimizu 890ddd
		update(index);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		return column;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void rollLeft(int index, int count)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0);
Toshihiro Shimizu 890ddd
		assert(count > 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int columnCount = m_columns.size();
Toshihiro Shimizu 890ddd
		if (index + count > columnCount)
Toshihiro Shimizu 890ddd
			count = columnCount - index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (count < 2)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(0 <= index && index + count - 1 < columnCount);
Toshihiro Shimizu 890ddd
		assert(count > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int i = index, j = index + count - 1;
Toshihiro Shimizu 890ddd
		ColumnP tmp = m_columns[i];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int k = i; k < j; ++k)
Toshihiro Shimizu 890ddd
			m_columns[k] = m_columns[k + 1];
Toshihiro Shimizu 890ddd
		m_columns[j] = tmp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		update(0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void rollRight(int index, int count)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		assert(index >= 0);
Toshihiro Shimizu 890ddd
		assert(count > 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int columnCount = m_columns.size();
Toshihiro Shimizu 890ddd
		if (index + count > columnCount)
Toshihiro Shimizu 890ddd
			count = columnCount - index;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (count < 2)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		assert(0 <= index && index + count - 1 < columnCount);
Toshihiro Shimizu 890ddd
		assert(count > 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int i = index, j = index + count - 1;
Toshihiro Shimizu 890ddd
		ColumnP tmp = m_columns[j];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		for (int k = j; k > i; --k)
Toshihiro Shimizu 890ddd
			m_columns[k] = m_columns[k - 1];
Toshihiro Shimizu 890ddd
		m_columns[i] = tmp;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		update(0);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//---------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void update(int fromIdx)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int pos = 0, index = 0;
Toshihiro Shimizu 890ddd
		if (fromIdx > 0) {
Toshihiro Shimizu 890ddd
			assert(fromIdx <= (int)m_columns.size());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			const ColumnP &left = m_columns[fromIdx - 1];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			pos = left->getX1() + 1;
Toshihiro Shimizu 890ddd
			index = left->m_index + 1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int c, cCount = m_columns.size();
Toshihiro Shimizu 890ddd
		for (c = fromIdx; c != cCount; ++c) {
Toshihiro Shimizu 890ddd
			const ColumnP &col = m_columns[c];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			col->m_pos = pos;
Toshihiro Shimizu 890ddd
			col->m_index = index++;
Toshihiro Shimizu 890ddd
			pos += col->m_width;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			col->m_inColumnsSet = true;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
private:
Toshihiro Shimizu 890ddd
	// Not copyable
Toshihiro Shimizu 890ddd
	TColumnSetT(const TColumnSetT &);
Toshihiro Shimizu 890ddd
	TColumnSetT &operator=(const TColumnSetT &);
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // TCOLUMNSET_INCLUDED