Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonzqt/functionsheet.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzQt includes
Toshihiro Shimizu 890ddd
#include "toonzqt/gutil.h"
Toshihiro Shimizu 890ddd
#include "toonzqt/functionviewer.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzLib includes
Toshihiro Shimizu 890ddd
#include "toonz/tframehandle.h"
Toshihiro Shimizu 890ddd
#include "toonz/doubleparamcmd.h"
Toshihiro Shimizu 890ddd
#include "toonz/preferences.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TnzBase includes
Toshihiro Shimizu 890ddd
#include "tunit.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "../toonz/menubarcommandids.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// Qt includes
Toshihiro Shimizu 890ddd
#include <qpainter></qpainter>
Toshihiro Shimizu 890ddd
#include <qgridlayout></qgridlayout>
Toshihiro Shimizu 890ddd
#include <qpaintevent></qpaintevent>
Toshihiro Shimizu 890ddd
#include <qmenu></qmenu>
Toshihiro Shimizu 890ddd
#include <qapplication> //for drag&drop</qapplication>
Toshihiro Shimizu 890ddd
#include <qdrag></qdrag>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Local namespace stuff
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
namespace
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int cColumnDragHandleWidth = 8;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const int cGroupShortNameY = 0; //!< Column header's y pos for channel groups' short name tabs
Toshihiro Shimizu 890ddd
const int cGroupLongNameY = 27; //!< Same for its long name tabs
Toshihiro Shimizu 890ddd
const int cChannelNameY = 50;   //!< Column header's y pos of channel name tabs, up to the widget's height
Toshihiro Shimizu 890ddd
const int cColHeadersEndY = 87; //!< End of column headers y pos
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
} // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    Function Sheet Tools
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*--- NumericalColumnsのセグメントの左側のバーをクリックしたとき ---*/
Toshihiro Shimizu 890ddd
class MoveChannelsDragTool : public Spreadsheet::DragTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FunctionSheet *m_sheet;
Toshihiro Shimizu 890ddd
	std::vector<keyframesetter *=""> m_setters;</keyframesetter>
Toshihiro Shimizu 890ddd
	int m_oldRow;
Toshihiro Shimizu 890ddd
	QRect m_selectedCells;
Toshihiro Shimizu 890ddd
	int m_firstKeyframeRow;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	MoveChannelsDragTool(FunctionSheet *sheet) : m_sheet(sheet), m_firstKeyframeRow(-1) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void click(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		m_firstKeyframeRow = -1;
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = m_sheet->getChannel(col);
Toshihiro Shimizu 890ddd
		if (!channel)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = channel->getParam();
Toshihiro Shimizu 890ddd
		int k0 = -1, k1 = -1;
Toshihiro Shimizu 890ddd
		if (curve->isKeyframe(row))
Toshihiro Shimizu 890ddd
			k0 = k1 = curve->getClosestKeyframe(row);
Toshihiro Shimizu 890ddd
		else {
Toshihiro Shimizu 890ddd
			k0 = curve->getPrevKeyframe(row);
Toshihiro Shimizu 890ddd
			k1 = curve->getNextKeyframe(row);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		//return if clicking outside of the segments
Toshihiro Shimizu 890ddd
		if (k0 < 0 || k1 < 0)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		int r0 = tround(curve->keyframeIndexToFrame(k0));
Toshihiro Shimizu 890ddd
		int r1 = tround(curve->keyframeIndexToFrame(k1));
Toshihiro Shimizu 890ddd
		if (m_sheet->isSelectedCell(row, col)) {
Toshihiro Shimizu 890ddd
			m_selectedCells = m_sheet->getSelectedCells();
Toshihiro Shimizu 890ddd
			m_selectedCells.setTop(r0);
Toshihiro Shimizu 890ddd
			m_selectedCells.setBottom(r1);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			m_selectedCells = QRect(col, r0, 1, r1 - r0 + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_sheet->selectCells(m_selectedCells);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*---
Toshihiro Shimizu 890ddd
	 シンプルに左のバーをクリックした場合はcolは1つだけ。
Toshihiro Shimizu 890ddd
	 すでに複数Columnが選択されている上でその選択範囲内のセルの左バーをクリックした場合は
Toshihiro Shimizu 890ddd
	 横(Column)幅は選択範囲に順ずるようになる。高さ(row)はクリックしたセグメントと同じになる。
Toshihiro Shimizu 890ddd
	---*/
Toshihiro Shimizu 890ddd
		/*--- セグメントごとドラッグに備えてKeyFrameを格納する ---*/
Toshihiro Shimizu 890ddd
		for (int col = m_selectedCells.left(); col <= m_selectedCells.right(); ++col) {
Toshihiro Shimizu 890ddd
			TDoubleParam *curve = m_sheet->getCurve(col);
Toshihiro Shimizu 890ddd
			if (!curve)
Toshihiro Shimizu 890ddd
				continue;
Toshihiro Shimizu 890ddd
			KeyframeSetter *setter = new KeyframeSetter(curve);
Toshihiro Shimizu 890ddd
			for (int k = 0; k < curve->getKeyframeCount(); k++) {
Toshihiro Shimizu 890ddd
				int row = (int)curve->keyframeIndexToFrame(k);
Toshihiro Shimizu 890ddd
				if (r0 <= row && row <= r1) {
Toshihiro Shimizu 890ddd
					if (m_firstKeyframeRow < 0 || row < m_firstKeyframeRow)
Toshihiro Shimizu 890ddd
						m_firstKeyframeRow = row;
Toshihiro Shimizu 890ddd
					setter->selectKeyframe(k);
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			m_setters.push_back(setter);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		m_oldRow = row;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void drag(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		int d = row - m_oldRow;
Toshihiro Shimizu 890ddd
		m_oldRow = row;
Toshihiro Shimizu 890ddd
		if (d + m_firstKeyframeRow < 0)
Toshihiro Shimizu 890ddd
			d = -m_firstKeyframeRow;
Toshihiro Shimizu 890ddd
		m_firstKeyframeRow += d;
Toshihiro Shimizu 890ddd
		for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
			m_setters[i]->moveKeyframes(d, 0.0);
Toshihiro Shimizu 890ddd
		m_selectedCells.translate(0, d);
Toshihiro Shimizu 890ddd
		m_sheet->selectCells(m_selectedCells);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void release(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		for (int i = 0; i < (int)m_setters.size(); i++)
Toshihiro Shimizu 890ddd
			delete m_setters[i];
Toshihiro Shimizu 890ddd
		m_setters.clear();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*--- NumericalColumnsのセル部分をクリックしたとき ---*/
Toshihiro Shimizu 890ddd
class FunctionSheetSelectionTool : public Spreadsheet::DragTool
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int m_firstRow, m_firstCol;
Toshihiro Shimizu 890ddd
	FunctionSheet *m_sheet;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	FunctionSheetSelectionTool(FunctionSheet *sheet)
Toshihiro Shimizu 890ddd
		: m_sheet(sheet), m_firstRow(-1), m_firstCol(-1) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void click(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (0 != (e->modifiers() & Qt::ShiftModifier) && !m_sheet->getSelectedCells().isEmpty()) {
Toshihiro Shimizu 890ddd
			QRect selectedCells = m_sheet->getSelectedCells();
Toshihiro Shimizu 890ddd
			if (col < selectedCells.center().x()) {
Toshihiro Shimizu 890ddd
				m_firstCol = selectedCells.right();
Toshihiro Shimizu 890ddd
				selectedCells.setLeft(col);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				m_firstCol = selectedCells.left();
Toshihiro Shimizu 890ddd
				selectedCells.setRight(col);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			if (row < selectedCells.center().y()) {
Toshihiro Shimizu 890ddd
				m_firstRow = selectedCells.bottom();
Toshihiro Shimizu 890ddd
				selectedCells.setTop(row);
Toshihiro Shimizu 890ddd
			} else {
Toshihiro Shimizu 890ddd
				m_firstRow = selectedCells.top();
Toshihiro Shimizu 890ddd
				selectedCells.setBottom(row);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			m_sheet->selectCells(selectedCells);
Toshihiro Shimizu 890ddd
		} else {
Toshihiro Shimizu 890ddd
			// regular click, no shift
Toshihiro Shimizu 890ddd
			m_firstCol = col;
Toshihiro Shimizu 890ddd
			m_firstRow = row;
Toshihiro Shimizu 890ddd
			QRect selectedCells(col, row, 1, 1);
Toshihiro Shimizu 890ddd
			m_sheet->selectCells(selectedCells);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void drag(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (row < 0)
Toshihiro Shimizu 890ddd
			row = 0;
Toshihiro Shimizu 890ddd
		if (col < 0)
Toshihiro Shimizu 890ddd
			col = 0;
Toshihiro Shimizu 890ddd
		int r0 = qMin(row, m_firstRow);
Toshihiro Shimizu 890ddd
		int r1 = qMax(row, m_firstRow);
Toshihiro Shimizu 890ddd
		int c0 = qMin(col, m_firstCol);
Toshihiro Shimizu 890ddd
		int c1 = qMax(col, m_firstCol);
Toshihiro Shimizu 890ddd
		QRect selectedCells(c0, r0, c1 - c0 + 1, r1 - r0 + 1);
Toshihiro Shimizu 890ddd
		m_sheet->selectCells(selectedCells);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	void release(int row, int col, QMouseEvent *e)
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		if (row == m_firstRow && col == m_firstCol) {
Toshihiro Shimizu 890ddd
			if (Preferences::instance()->isMoveCurrentEnabled())
Toshihiro Shimizu 890ddd
				m_sheet->setCurrentFrame(row);
Toshihiro Shimizu 890ddd
			FunctionTreeModel::Channel *channel = m_sheet->getChannel(col);
Toshihiro Shimizu 890ddd
			if (channel)
Toshihiro Shimizu 890ddd
				channel->setIsCurrent(true);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    FunctionSheetRowViewer  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSheetRowViewer::FunctionSheetRowViewer(FunctionSheet *parent)
Toshihiro Shimizu 890ddd
	: Spreadsheet::RowPanel(parent), m_sheet(parent)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setMinimumSize(QSize(100, 100));
Toshihiro Shimizu 890ddd
	setMouseTracking(true);
Toshihiro Shimizu 890ddd
	setFocusPolicy(Qt::NoFocus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetRowViewer::paintEvent(QPaintEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//calls GenericPanel's event
Toshihiro Shimizu 890ddd
	Spreadsheet::RowPanel::paintEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetRowViewer::mousePressEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//calls GenericPanel's event
Toshihiro Shimizu 890ddd
	Spreadsheet::RowPanel::mousePressEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetRowViewer::mouseMoveEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//calls GenericPanel's event
Toshihiro Shimizu 890ddd
	Spreadsheet::RowPanel::mouseMoveEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetRowViewer::mouseReleaseEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Spreadsheet::RowPanel::mouseReleaseEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetRowViewer::contextMenuEvent(QContextMenuEvent *event)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QMenu *menu = new QMenu(this);
Toshihiro Shimizu 890ddd
	CommandManager *cmdManager = CommandManager::instance();
Toshihiro Shimizu 890ddd
	menu->addAction(cmdManager->getAction(MI_InsertSceneFrame));
Toshihiro Shimizu 890ddd
	menu->addAction(cmdManager->getAction(MI_RemoveSceneFrame));
Toshihiro Shimizu 890ddd
	menu->addAction(cmdManager->getAction(MI_InsertGlobalKeyframe));
Toshihiro Shimizu 890ddd
	menu->addAction(cmdManager->getAction(MI_RemoveGlobalKeyframe));
Toshihiro Shimizu 890ddd
	menu->exec(event->globalPos());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    FunctionSheetColumnHeadViewer  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSheetColumnHeadViewer::FunctionSheetColumnHeadViewer(FunctionSheet *parent)
Toshihiro Shimizu 890ddd
	: Spreadsheet::ColumnPanel(parent), m_sheet(parent), m_draggingChannel(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setMouseTracking(true); // for updating the tooltip
Toshihiro Shimizu 890ddd
	setFocusPolicy(Qt::NoFocus);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetColumnHeadViewer::paintEvent(QPaintEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QPainter painter(this);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QRect toBeUpdated = e->rect();
Toshihiro Shimizu 890ddd
	painter.setClipRect(toBeUpdated);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int x0 = toBeUpdated.left();
Toshihiro Shimizu 890ddd
	int x1 = toBeUpdated.right();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// visible columns range
Toshihiro Shimizu 890ddd
	int c0 = getViewer()->xToColumn(x0);
Toshihiro Shimizu 890ddd
	int c1 = getViewer()->xToColumn(x1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (c0 > c1)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int n = c1 - c0 + 1 + 2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FunctionTreeModel::ChannelGroup *currentGroup = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--- 表示範囲+左右1カラムの範囲で、ChannelGroupを格納。無ければ0を入れる ---*/
Toshihiro Shimizu 890ddd
	std::vector<functiontreemodel::channelgroup *=""> channelGroups(n);</functiontreemodel::channelgroup>
Toshihiro Shimizu 890ddd
	for (int i = 0; i < n; ++i) {
Toshihiro Shimizu 890ddd
		channelGroups[i] = 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		int c = c0 - 1 + i;
Toshihiro Shimizu 890ddd
		if (c < 0)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = m_sheet->getChannel(c);
Toshihiro Shimizu 890ddd
		if (!channel)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		channelGroups[i] = channel->getChannelGroup();
Toshihiro Shimizu 890ddd
		if (!currentGroup && channel->isCurrent())
Toshihiro Shimizu 890ddd
			currentGroup = channelGroups[i];
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int y0 = 0;
Toshihiro Shimizu 890ddd
	int y1 = 17;
Toshihiro Shimizu 890ddd
	int y2 = 34;
Toshihiro Shimizu 890ddd
	int y3 = 53;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	/*--- Channelの有る範囲内を明るめのグレーで塗る ---*/
Toshihiro Shimizu 890ddd
	for (int c = c0; c <= c1; c++) {
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = m_sheet->getChannel(c);
Toshihiro Shimizu 890ddd
		if (!channel)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		int x0 = getViewer()->columnToX(c);
Toshihiro Shimizu 890ddd
		int x1 = getViewer()->columnToX(c + 1) - 1;
Toshihiro Shimizu 890ddd
		//Column Width
Toshihiro Shimizu 890ddd
		int width = x1 - x0 + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		painter.fillRect(x0, y0, width, y3 - y0, getViewer()->getBGColor());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (int c = c0; c <= c1; ++c) {
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = m_sheet->getChannel(c);
Toshihiro Shimizu 890ddd
		if (!channel)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		int i = c - c0 + 1;
Toshihiro Shimizu 890ddd
		/*---- 現在のColumnと前後のColumnのChannelGroup ---*/
Toshihiro Shimizu 890ddd
		FunctionTreeModel::ChannelGroup
Toshihiro Shimizu 890ddd
			*prevGroup = channelGroups[c - c0],
Toshihiro Shimizu 890ddd
			*group = channelGroups[c - c0 + 1],
Toshihiro Shimizu 890ddd
			*nextGroup = channelGroups[c - c0 + 2];
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*---- 前後とグループが違ってた場合、それぞれフラグを立てる ---*/
Toshihiro Shimizu 890ddd
		bool firstGroupColumn = prevGroup != group;
Toshihiro Shimizu 890ddd
		bool lastGroupColumn = nextGroup != group;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*--- 現在のカラムの左右座標 ---*/
Toshihiro Shimizu 890ddd
		int x0 = getViewer()->columnToX(c);
Toshihiro Shimizu 890ddd
		int x1 = getViewer()->columnToX(c + 1) - 1;
Toshihiro Shimizu 890ddd
		//Column width
Toshihiro Shimizu 890ddd
		int width = x1 - x0 + 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QRect selectedRect = m_sheet->getSelectedCells();
Toshihiro Shimizu 890ddd
		bool isSelected = (selectedRect.left() <= c && c <= selectedRect.right()) ? true : false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//paint with light color if selected
Toshihiro Shimizu 890ddd
		if (isSelected)
Toshihiro Shimizu 890ddd
			painter.fillRect(x0, y1, width, y3 - y1, getViewer()->getCurrentRowBgColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//draw horizonntal lines
Toshihiro Shimizu 890ddd
		painter.setPen(QPen(getViewer()->getColumnHeaderBorderColor(), 3));
Toshihiro Shimizu 890ddd
		painter.drawLine(x0, y0, x1, y0);
Toshihiro Shimizu 890ddd
		painter.setPen(getViewer()->getColumnHeaderBorderColor());
Toshihiro Shimizu 890ddd
		painter.drawLine(x0, y1, x1, y1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//draw vertical bar
Toshihiro Shimizu 890ddd
		painter.fillRect(x0, y1, 6, y3 - y1, getViewer()->getColumnHeaderBorderColor());
Toshihiro Shimizu 890ddd
		if (firstGroupColumn)
Toshihiro Shimizu 890ddd
			painter.fillRect(x0, y0, 6, y1 - y0, getViewer()->getColumnHeaderBorderColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//channel name
Toshihiro Shimizu 890ddd
		painter.setPen(getViewer()->getTextColor());
Toshihiro Shimizu 890ddd
		if (channel->isCurrent())
Toshihiro Shimizu 890ddd
			painter.setPen(getViewer()->getSelectedColumnTextColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QString text = channel->getShortName();
Toshihiro Shimizu 890ddd
		int d = 8;
Toshihiro Shimizu 890ddd
		painter.drawText(x0 + d, y1, width - d, y3 - y1 + 1, Qt::TextWrapAnywhere | Qt::AlignLeft | Qt::AlignVCenter, text);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//group name
Toshihiro Shimizu 890ddd
		if (firstGroupColumn) {
Toshihiro Shimizu 890ddd
			int tmpwidth = (lastGroupColumn) ? width : width * 2;
Toshihiro Shimizu 890ddd
			painter.setPen(getViewer()->getTextColor());
Toshihiro Shimizu 890ddd
			if (group == currentGroup)
Toshihiro Shimizu 890ddd
				painter.setPen(getViewer()->getSelectedColumnTextColor());
Toshihiro Shimizu 890ddd
			text = group->getShortName();
Toshihiro Shimizu 890ddd
			painter.drawText(x0 + d, y0, tmpwidth - d, y1 - y0 + 1, Qt::AlignLeft | Qt::AlignVCenter, text);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! update tooltips
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
void FunctionSheetColumnHeadViewer::mouseMoveEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if ((e->buttons() & Qt::MidButton) &&
Toshihiro Shimizu 890ddd
		m_draggingChannel &&
Toshihiro Shimizu 890ddd
		(e->pos() - m_dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
Toshihiro Shimizu 890ddd
		QDrag *drag = new QDrag(this);
Toshihiro Shimizu 890ddd
		QMimeData *mimeData = new QMimeData;
Toshihiro Shimizu 890ddd
		mimeData->setText(m_draggingChannel->getExprRefName());
Toshihiro Shimizu 890ddd
		drag->setMimeData(mimeData);
Toshihiro Shimizu 890ddd
		static const QPixmap cursorPixmap(":Resources/dragcursor_exp_text.png");
Toshihiro Shimizu 890ddd
		drag->setDragCursor(cursorPixmap, Qt::MoveAction);
Toshihiro Shimizu 890ddd
		Qt::DropAction dropAction = drag->exec();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// get the column under the cursor
Toshihiro Shimizu 890ddd
	int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
	FunctionTreeModel::Channel *channel = m_sheet->getChannel(col);
Toshihiro Shimizu 890ddd
	if (!channel) {
Toshihiro Shimizu 890ddd
		setToolTip(QString(""));
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		setToolTip(channel->getExprRefName());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetColumnHeadViewer::mousePressEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QPoint pos = e->pos();
Toshihiro Shimizu 890ddd
	int currentC = getViewer()->xToColumn(pos.x());
Toshihiro Shimizu 890ddd
	FunctionTreeModel::Channel *channel;
Toshihiro Shimizu 890ddd
	for (int c = 0; c <= m_sheet->getChannelCount(); c++) {
Toshihiro Shimizu 890ddd
		channel = m_sheet->getChannel(c);
Toshihiro Shimizu 890ddd
		if (!channel || c != currentC)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	if (channel && e->button() == Qt::MidButton) {
Toshihiro Shimizu 890ddd
		m_draggingChannel = channel;
Toshihiro Shimizu 890ddd
		m_dragStartPosition = e->pos();
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	} else if (channel)
Toshihiro Shimizu 890ddd
		channel->setIsCurrent(true);
Toshihiro Shimizu 890ddd
	m_draggingChannel = 0;
Toshihiro Shimizu 890ddd
	if (!channel)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Open folder
Toshihiro Shimizu 890ddd
	FunctionTreeModel::ChannelGroup *channelGroup = channel->getChannelGroup();
Toshihiro Shimizu 890ddd
	if (!channelGroup->isOpen())
Toshihiro Shimizu 890ddd
		channelGroup->getModel()->setExpandedItem(channelGroup->createIndex(), true);
Toshihiro Shimizu 890ddd
	//Select all segment
Toshihiro Shimizu 890ddd
	std::set<double> frames;</double>
Toshihiro Shimizu 890ddd
	channel->getParam()->getKeyframes(frames);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QRect rect(0, 0, 0, 0);
Toshihiro Shimizu 890ddd
	if (!frames.empty())
Toshihiro Shimizu 890ddd
		rect = QRect(currentC, 0, 1, (*frames.rbegin()) + 1);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	getViewer()->selectCells(rect);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetColumnHeadViewer::contextMenuEvent(QContextMenuEvent *ce)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	// First, select column under cursor
Toshihiro Shimizu 890ddd
	const QPoint &pos = ce->pos();
Toshihiro Shimizu 890ddd
	int cursorCol = getViewer()->xToColumn(pos.x());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (cursorCol < 0 || cursorCol >= m_sheet->getChannelCount())
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FunctionTreeModel::Channel *channel = m_sheet->getChannel(cursorCol);
Toshihiro Shimizu 890ddd
	if (!channel)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Ok, now let's summon a context menu with appropriate options
Toshihiro Shimizu 890ddd
	FunctionViewer *fv = m_sheet->getViewer();
Toshihiro Shimizu 890ddd
	if (!fv) {
Toshihiro Shimizu 890ddd
		assert(fv);
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const QPoint &globalPos = mapToGlobal(pos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (pos.y() >= cChannelNameY)
Toshihiro Shimizu 890ddd
		fv->openContextMenu(channel, globalPos);
Toshihiro Shimizu 890ddd
	else {
Toshihiro Shimizu 890ddd
		FunctionTreeModel::ChannelGroup *group = channel->getChannelGroup();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// In this case, commands are different from the tree view. Rather than showing in the tree,
Toshihiro Shimizu 890ddd
		// channels get ACTIVATED
Toshihiro Shimizu 890ddd
		QMenu menu;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		QAction showAnimatedOnly(FunctionTreeView::tr("Show Animated Only"), 0);
Toshihiro Shimizu 890ddd
		QAction showAll(FunctionTreeView::tr("Show All"), 0);
Toshihiro Shimizu 890ddd
		menu.addAction(&showAnimatedOnly);
Toshihiro Shimizu 890ddd
		menu.addAction(&showAll);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// execute menu
Toshihiro Shimizu 890ddd
		QAction *action = menu.exec(globalPos);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (action != &showAll && action != &showAnimatedOnly)
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// Process action
Toshihiro Shimizu 890ddd
		if (action == &showAll) {
Toshihiro Shimizu 890ddd
			int c, cCount = group->getChildCount();
Toshihiro Shimizu 890ddd
			for (c = 0; c != cCount; ++c) {
Toshihiro Shimizu 890ddd
				FunctionTreeModel::Channel *channel = dynamic_cast<functiontreemodel::channel *="">(group->getChild(c));</functiontreemodel::channel>
Toshihiro Shimizu 890ddd
				if (channel && !channel->isHidden())
Toshihiro Shimizu 890ddd
					channel->setIsActive(true);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		} else if (action == &showAnimatedOnly) {
Toshihiro Shimizu 890ddd
			int c, cCount = group->getChildCount();
Toshihiro Shimizu 890ddd
			for (c = 0; c != cCount; ++c) {
Toshihiro Shimizu 890ddd
				FunctionTreeModel::Channel *channel = dynamic_cast<functiontreemodel::channel *="">(group->getChild(c));</functiontreemodel::channel>
Toshihiro Shimizu 890ddd
				if (channel && !channel->isHidden())
Toshihiro Shimizu 890ddd
					channel->setIsActive(channel->isAnimated());
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		fv->update();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    FunctionSheetCellViewer  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSheetCellViewer::FunctionSheetCellViewer(FunctionSheet *parent)
Toshihiro Shimizu 890ddd
	: Spreadsheet::CellPanel(parent), m_sheet(parent), m_editRow(0), m_editCol(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_lineEdit = new DVGui::LineEdit(this);
Toshihiro Shimizu 890ddd
	// lineEdit->setGeometry(10,10,100,30);
Toshihiro Shimizu 890ddd
	m_lineEdit->hide();
Toshihiro Shimizu 890ddd
	bool ret = connect(m_lineEdit, SIGNAL(editingFinished()), this, SLOT(onCellEditorEditingFinished()));
Toshihiro Shimizu 890ddd
	assert(ret);
Toshihiro Shimizu 890ddd
	setMouseTracking(true);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	setFocusProxy(m_lineEdit);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Called when the cell panel is left/right-clicked
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Spreadsheet::DragTool *FunctionSheetCellViewer::createDragTool(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int row = getViewer()->yToRow(e->pos().y());
Toshihiro Shimizu 890ddd
	int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
	bool isEmpty = true;
Toshihiro Shimizu 890ddd
	TDoubleParam *curve = m_sheet->getCurve(col);
Toshihiro Shimizu 890ddd
	if (curve) {
Toshihiro Shimizu 890ddd
		int kCount = curve->getKeyframeCount();
Toshihiro Shimizu 890ddd
		if (kCount > 0) {
Toshihiro Shimizu 890ddd
			int row0 = (int)curve->keyframeIndexToFrame(0);
Toshihiro Shimizu 890ddd
			int row1 = (int)curve->keyframeIndexToFrame(kCount - 1);
Toshihiro Shimizu 890ddd
			isEmpty = row < row0 || row > row1;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isEmpty) {
Toshihiro Shimizu 890ddd
		int x = e->pos().x() - getViewer()->columnToX(col);
Toshihiro Shimizu 890ddd
		if (0 <= x && x < cColumnDragHandleWidth + 9)
Toshihiro Shimizu 890ddd
			return new MoveChannelsDragTool(m_sheet);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return new FunctionSheetSelectionTool(m_sheet);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// return Spreadsheet::CellPanel::createDragTool(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::drawCells(QPainter &painter, int r0, int c0, int r1, int c1)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//key frames
Toshihiro Shimizu 890ddd
	QColor KeyFrameColor = getViewer()->getKeyFrameColor();
Toshihiro Shimizu 890ddd
	QColor KeyFrameBorderColor = getViewer()->getKeyFrameBorderColor();
Toshihiro Shimizu 890ddd
	QColor SelectedKeyFrameColor = getViewer()->getSelectedKeyFrameColor();
Toshihiro Shimizu 890ddd
	//inbetween
Toshihiro Shimizu 890ddd
	QColor InBetweenColor = getViewer()->getInBetweenColor();
Toshihiro Shimizu 890ddd
	QColor InBetweenBorderColor = getViewer()->getInBetweenBorderColor();
Toshihiro Shimizu 890ddd
	QColor SelectedInBetweenColor = getViewer()->getSelectedInBetweenColor();
Toshihiro Shimizu 890ddd
	//empty cells
Toshihiro Shimizu 890ddd
	QColor SelectedEmptyColor = getViewer()->getSelectedEmptyColor();
Toshihiro Shimizu 890ddd
	//empty cells in scene frame range
Toshihiro Shimizu 890ddd
	QColor SelectedSceneRangeEmptyColor = getViewer()->getSelectedSceneRangeEmptyColor();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//top and bottom pos
Toshihiro Shimizu 890ddd
	int y0 = getViewer()->rowToY(r0);
Toshihiro Shimizu 890ddd
	int y1 = getViewer()->rowToY(r1 + 1) - 1;
Toshihiro Shimizu 890ddd
	for (int c = c0; c <= c1; c++) {
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = m_sheet->getCurve(c);
Toshihiro Shimizu 890ddd
		/*--- もしカラムcにパラメータが無ければcurveには0が返る ---*/
Toshihiro Shimizu 890ddd
		if (!curve)
Toshihiro Shimizu 890ddd
			continue;
Toshihiro Shimizu 890ddd
		//left and right pos
Toshihiro Shimizu 890ddd
		int x0 = getViewer()->columnToX(c);
Toshihiro Shimizu 890ddd
		int x1 = getViewer()->columnToX(c + 1) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		// find the curve keyframe range
Toshihiro Shimizu 890ddd
		int kr0 = 0, kr1 = -1;
Toshihiro Shimizu 890ddd
		int kCount = curve->getKeyframeCount();
Toshihiro Shimizu 890ddd
		if (kCount > 0) {
Toshihiro Shimizu 890ddd
			kr0 = curve->keyframeIndexToFrame(0);
Toshihiro Shimizu 890ddd
			kr1 = curve->keyframeIndexToFrame(kCount - 1);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//get the unit
Toshihiro Shimizu 890ddd
		TMeasure *measure = curve->getMeasure();
Toshihiro Shimizu 890ddd
		const TUnit *unit = measure ? measure->getCurrentUnit() : 0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//draw each cell
Toshihiro Shimizu 890ddd
		for (int row = r0; row <= r1; row++) {
Toshihiro Shimizu 890ddd
			int ya = m_sheet->rowToY(row);
Toshihiro Shimizu 890ddd
			int yb = m_sheet->rowToY(row + 1) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			bool isSelected = getViewer()->isSelectedCell(row, c);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			double value = curve->getValue(row);
Toshihiro Shimizu 890ddd
			if (unit)
Toshihiro Shimizu 890ddd
				value = unit->convertTo(value);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			QRect cellRect(x0, ya, x1 - x0 + 1, yb - ya + 1);
Toshihiro Shimizu 890ddd
			QRect borderRect(x0, ya, 7, yb - ya + 1);
Toshihiro Shimizu 890ddd
			QColor cellColor, borderColor;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			/*--- キーフレーム間の範囲だけ色をつける ---*/
Toshihiro Shimizu 890ddd
			if (kr0 <= row && row <= kr1) {
Toshihiro Shimizu 890ddd
				if (curve->isKeyframe(row)) {
Toshihiro Shimizu 890ddd
					cellColor = (isSelected) ? SelectedKeyFrameColor : KeyFrameColor;
Toshihiro Shimizu 890ddd
					borderColor = KeyFrameBorderColor;
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					cellColor = (isSelected) ? SelectedInBetweenColor : InBetweenColor;
Toshihiro Shimizu 890ddd
					borderColor = InBetweenBorderColor;
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
				painter.setPen(Qt::NoPen);
Toshihiro Shimizu 890ddd
				painter.fillRect(cellRect, cellColor);
Toshihiro Shimizu 890ddd
				painter.fillRect(borderRect, borderColor);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//display whether segment are Linked
Toshihiro Shimizu 890ddd
				if (curve->isKeyframe(row)) {
Toshihiro Shimizu 890ddd
					TDoubleKeyframe kf = curve->getKeyframeAt(row);
Toshihiro Shimizu 890ddd
					//if the segments are NOT linked, then cut off the side bar
Toshihiro Shimizu 890ddd
					if (!kf.m_linkedHandles) {
Toshihiro Shimizu 890ddd
						int rowCenterPos = (ya + yb) / 2;
Toshihiro Shimizu 890ddd
						QPoint points[4] = {
Toshihiro Shimizu 890ddd
							QPoint(x0, rowCenterPos),
Toshihiro Shimizu 890ddd
							QPoint(x0 + 7, rowCenterPos + 3),
Toshihiro Shimizu 890ddd
							QPoint(x0 + 7, rowCenterPos - 3),
Toshihiro Shimizu 890ddd
							QPoint(x0, rowCenterPos)};
Toshihiro Shimizu 890ddd
						QBrush oldBrush = painter.brush();
Toshihiro Shimizu 890ddd
						painter.setBrush(QBrush(cellColor));
Toshihiro Shimizu 890ddd
						painter.drawPolygon(points, 4);
Toshihiro Shimizu 890ddd
						painter.setBrush(oldBrush);
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				//draw cell value
Toshihiro Shimizu 890ddd
				painter.setPen(getViewer()->getTextColor());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				/*--- 整数から小数点以下3桁以内の場合はそれ以降の0000を描かない ---*/
Toshihiro Shimizu 890ddd
				QString text;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
				double thousandValue = value * 1000.0;
Toshihiro Shimizu 890ddd
				if (areAlmostEqual(thousandValue, (double)tround(thousandValue), 0.0001)) {
Toshihiro Shimizu 890ddd
					text = QString::number(value, 'f', 3);
Toshihiro Shimizu 890ddd
					while (text.endsWith("0")) {
Toshihiro Shimizu 890ddd
						text.chop(1);
Toshihiro Shimizu 890ddd
						if (text.endsWith(".")) {
Toshihiro Shimizu 890ddd
							text.chop(1);
Toshihiro Shimizu 890ddd
							break;
Toshihiro Shimizu 890ddd
						}
Toshihiro Shimizu 890ddd
					}
Toshihiro Shimizu 890ddd
				} else {
Toshihiro Shimizu 890ddd
					text = QString::number(value, 'f', 4);
Toshihiro Shimizu 890ddd
					text.truncate(5);
Toshihiro Shimizu 890ddd
					text.append("~");
Toshihiro Shimizu 890ddd
				}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
				static QFont font("Arial", 9, QFont::Normal);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
				static QFont font("Helvetica", 9, QFont::Normal);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
				painter.setFont(font);
Toshihiro Shimizu 890ddd
				painter.drawText(cellRect.adjusted(10, 0, 0, 0), Qt::AlignVCenter | Qt::AlignLeft, text);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
			//empty and selected cell
Toshihiro Shimizu 890ddd
			else if (isSelected) {
Toshihiro Shimizu 890ddd
				int rowCount = getViewer()->getRowCount();
Toshihiro Shimizu 890ddd
				cellColor = (row >= rowCount) ? SelectedEmptyColor : SelectedSceneRangeEmptyColor;
Toshihiro Shimizu 890ddd
				painter.setPen(Qt::NoPen);
Toshihiro Shimizu 890ddd
				painter.fillRect(cellRect, cellColor);
Toshihiro Shimizu 890ddd
			}
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::mouseDoubleClickEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int row = getViewer()->yToRow(e->pos().y());
Toshihiro Shimizu 890ddd
	int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
	int x0, y0, x1, y1;
Toshihiro Shimizu 890ddd
	x0 = getViewer()->columnToX(col);
Toshihiro Shimizu 890ddd
	x1 = getViewer()->columnToX(col + 1) - 1;
Toshihiro Shimizu 890ddd
	y0 = getViewer()->rowToY(row);
Toshihiro Shimizu 890ddd
	y1 = getViewer()->rowToY(row + 1) - 1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_editRow = row;
Toshihiro Shimizu 890ddd
	m_editCol = col;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TDoubleParam *curve = m_sheet->getCurve(col);
Toshihiro Shimizu 890ddd
	if (curve) {
Toshihiro Shimizu 890ddd
		double v = curve->getValue(row);
Toshihiro Shimizu 890ddd
		TMeasure *measure = curve->getMeasure();
Toshihiro Shimizu 890ddd
		const TUnit *unit = measure ? measure->getCurrentUnit() : 0;
Toshihiro Shimizu 890ddd
		if (unit)
Toshihiro Shimizu 890ddd
			v = unit->convertTo(v);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		m_lineEdit->setText(QString::number(v, 'f', 4));
Toshihiro Shimizu 890ddd
		//in order to put the cursor to the left end
Toshihiro Shimizu 890ddd
		m_lineEdit->setSelection(m_lineEdit->text().length(), -m_lineEdit->text().length());
Toshihiro Shimizu 890ddd
	} else
Toshihiro Shimizu 890ddd
		m_lineEdit->setText("");
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef WIN32
Toshihiro Shimizu 890ddd
	static QFont font("Arial", 9, QFont::Normal);
Toshihiro Shimizu 890ddd
#else
Toshihiro Shimizu 890ddd
	static QFont font("Helvetica", 9, QFont::Normal);
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
	m_lineEdit->setFont(font);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_lineEdit->setGeometry(x0 - 2, y0 - 2, x1 - x0 + 1 + 4, y1 - y0 + 1 + 4); // x0,y0,x1-x0+1,y0-y1+1);
Toshihiro Shimizu 890ddd
	m_lineEdit->show();
Toshihiro Shimizu 890ddd
	m_lineEdit->raise();
Toshihiro Shimizu 890ddd
	m_lineEdit->setFocus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::onCellEditorEditingFinished()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	QString text = m_lineEdit->text();
Toshihiro Shimizu 890ddd
	if (!text.isEmpty() && m_lineEdit->isReturnPressed()) {
Toshihiro Shimizu 890ddd
		double value = text.toDouble();
Toshihiro Shimizu 890ddd
		TDoubleParam *curve = m_sheet->getCurve(m_editCol);
Toshihiro Shimizu 890ddd
		if (curve) {
Toshihiro Shimizu 890ddd
			TMeasure *measure = curve->getMeasure();
Toshihiro Shimizu 890ddd
			const TUnit *unit = measure ? measure->getCurrentUnit() : 0;
Toshihiro Shimizu 890ddd
			if (unit)
Toshihiro Shimizu 890ddd
				value = unit->convertFrom(value);
Toshihiro Shimizu 890ddd
			KeyframeSetter::setValue(curve, m_editRow, value);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	m_lineEdit->hide();
Toshihiro Shimizu 890ddd
	m_lineEdit->clearFocus();
Toshihiro Shimizu 890ddd
	m_sheet->setFocus();
Toshihiro Shimizu 890ddd
	update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::mousePressEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//escape from the line edit by clicking outside
Toshihiro Shimizu 890ddd
	if (m_lineEdit->isVisible()) {
Toshihiro Shimizu 890ddd
		m_lineEdit->hide();
Toshihiro Shimizu 890ddd
		m_lineEdit->clearFocus();
Toshihiro Shimizu 890ddd
		m_sheet->setFocus();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (e->button() == Qt::LeftButton || e->button() == Qt::MidButton)
Toshihiro Shimizu 890ddd
		Spreadsheet::CellPanel::mousePressEvent(e);
Toshihiro Shimizu 890ddd
	else if (e->button() == Qt::RightButton) {
Toshihiro Shimizu 890ddd
		int row = getViewer()->yToRow(e->pos().y());
Toshihiro Shimizu 890ddd
		int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
		update();
Toshihiro Shimizu 890ddd
		openContextMenu(e);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::mouseReleaseEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Spreadsheet::CellPanel::mouseReleaseEvent(e);
Toshihiro Shimizu 890ddd
	/*
Toshihiro Shimizu 890ddd
  int row = getViewer()->yToRow(e->pos().y());
Toshihiro Shimizu 890ddd
  int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
  FunctionSheet::DragTool *dragTool = m_sheet->getDragTool();
Toshihiro Shimizu 890ddd
  if(dragTool) dragTool->release(row,col);
Toshihiro Shimizu 890ddd
  m_sheet->setDragTool(0);
Toshihiro Shimizu 890ddd
  */
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::mouseMoveEvent(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	Spreadsheet::CellPanel::mouseMoveEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// TODO: refactor: cfr functionpanel.cpp
Toshihiro Shimizu 890ddd
void FunctionSheetCellViewer::openContextMenu(QMouseEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	struct locals {
Toshihiro Shimizu 890ddd
		static void sheet__setSegmentType(
Toshihiro Shimizu 890ddd
			FunctionSelection *selection,
Toshihiro Shimizu 890ddd
			TDoubleParam *curve,
Toshihiro Shimizu 890ddd
			int segmentIndex,
Toshihiro Shimizu 890ddd
			TDoubleKeyframe::Type type)
Toshihiro Shimizu 890ddd
		{
Toshihiro Shimizu 890ddd
			selection->selectSegment(curve, segmentIndex);
Toshihiro Shimizu 890ddd
			KeyframeSetter setter(curve, segmentIndex);
Toshihiro Shimizu 890ddd
			setter.setType(type);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}; // locals
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	QAction deleteKeyframeAction(tr("Delete Key"), 0);
Toshihiro Shimizu 890ddd
	QAction insertKeyframeAction(tr("Set Key"), 0);
Toshihiro Shimizu 890ddd
	QAction setLinearAction(tr("Linear Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setSpeedInOutAction(tr("Speed In / Speed Out Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setEaseInOutAction(tr("Ease In / Ease Out Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setEaseInOut2Action(tr("Ease In / Ease Out (%) Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setExponentialAction(tr("Exponential Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setExpressionAction(tr("Expression Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setFileAction(tr("File Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setConstantAction(tr("Constant Interpolation"), 0);
Toshihiro Shimizu 890ddd
	QAction setStep1Action(tr("Step 1"), 0);
Toshihiro Shimizu 890ddd
	QAction setStep2Action(tr("Step 2"), 0);
Toshihiro Shimizu 890ddd
	QAction setStep3Action(tr("Step 3"), 0);
Toshihiro Shimizu 890ddd
	QAction setStep4Action(tr("Step 4"), 0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int row = getViewer()->yToRow(e->pos().y());
Toshihiro Shimizu 890ddd
	int col = getViewer()->xToColumn(e->pos().x());
Toshihiro Shimizu 890ddd
	TDoubleParam *curve = m_sheet->getCurve(col);
Toshihiro Shimizu 890ddd
	if (!curve)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	bool isEmpty = true;
Toshihiro Shimizu 890ddd
	bool isKeyframe = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// find the curve keyframe range
Toshihiro Shimizu 890ddd
	int kCount = curve->getKeyframeCount();
Toshihiro Shimizu 890ddd
	if (kCount > 0) {
Toshihiro Shimizu 890ddd
		if (curve->keyframeIndexToFrame(0) <= row &&
Toshihiro Shimizu 890ddd
			row <= curve->keyframeIndexToFrame(kCount - 1)) {
Toshihiro Shimizu 890ddd
			isEmpty = false;
Toshihiro Shimizu 890ddd
			isKeyframe = curve->isKeyframe(row);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	int kIndex = curve->getPrevKeyframe(row);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// build menu
Toshihiro Shimizu 890ddd
	QMenu menu(0);
Toshihiro Shimizu 890ddd
	if (!isKeyframe) //menu.addAction(&deleteKeyframeAction); else
Toshihiro Shimizu 890ddd
		menu.addAction(&insertKeyframeAction);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!isEmpty && !isKeyframe && kIndex >= 0) {
Toshihiro Shimizu 890ddd
		menu.addSeparator();
Toshihiro Shimizu 890ddd
		TDoubleKeyframe kf = curve->getKeyframe(kIndex);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::Linear)
Toshihiro Shimizu 890ddd
			menu.addAction(&setLinearAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::SpeedInOut)
Toshihiro Shimizu 890ddd
			menu.addAction(&setSpeedInOutAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::EaseInOut)
Toshihiro Shimizu 890ddd
			menu.addAction(&setEaseInOutAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::EaseInOutPercentage)
Toshihiro Shimizu 890ddd
			menu.addAction(&setEaseInOut2Action);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::Exponential)
Toshihiro Shimizu 890ddd
			menu.addAction(&setExponentialAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::Expression)
Toshihiro Shimizu 890ddd
			menu.addAction(&setExpressionAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::File)
Toshihiro Shimizu 890ddd
			menu.addAction(&setFileAction);
Toshihiro Shimizu 890ddd
		if (kf.m_type != TDoubleKeyframe::Constant)
Toshihiro Shimizu 890ddd
			menu.addAction(&setConstantAction);
Toshihiro Shimizu 890ddd
		menu.addSeparator();
Toshihiro Shimizu 890ddd
		if (kf.m_step != 1)
Toshihiro Shimizu 890ddd
			menu.addAction(&setStep1Action);
Toshihiro Shimizu 890ddd
		if (kf.m_step != 2)
Toshihiro Shimizu 890ddd
			menu.addAction(&setStep2Action);
Toshihiro Shimizu 890ddd
		if (kf.m_step != 3)
Toshihiro Shimizu 890ddd
			menu.addAction(&setStep3Action);
Toshihiro Shimizu 890ddd
		if (kf.m_step != 4)
Toshihiro Shimizu 890ddd
			menu.addAction(&setStep4Action);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	menu.addSeparator();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	CommandManager *cmdManager = CommandManager::instance();
Toshihiro Shimizu 890ddd
	menu.addAction(cmdManager->getAction("MI_Cut"));
Toshihiro Shimizu 890ddd
	menu.addAction(cmdManager->getAction("MI_Copy"));
Toshihiro Shimizu 890ddd
	menu.addAction(cmdManager->getAction("MI_Paste"));
Toshihiro Shimizu 890ddd
	menu.addAction(cmdManager->getAction("MI_Clear"));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	menu.addAction(cmdManager->getAction("MI_Insert"));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	FunctionSelection *selection = m_sheet->getSelection();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// execute menu
Toshihiro Shimizu 890ddd
	QAction *action = menu.exec(e->globalPos()); // QCursor::pos());
Toshihiro Shimizu 890ddd
	if (action == &deleteKeyframeAction) {
Toshihiro Shimizu 890ddd
		KeyframeSetter::removeKeyframeAt(curve, row);
Toshihiro Shimizu 890ddd
	} else if (action == &insertKeyframeAction) {
Toshihiro Shimizu 890ddd
		KeyframeSetter(curve).createKeyframe(row);
Toshihiro Shimizu 890ddd
	} else if (action == &setLinearAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::Linear);
Toshihiro Shimizu 890ddd
	else if (action == &setSpeedInOutAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::SpeedInOut);
Toshihiro Shimizu 890ddd
	else if (action == &setEaseInOutAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::EaseInOut);
Toshihiro Shimizu 890ddd
	else if (action == &setEaseInOut2Action)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::EaseInOutPercentage);
Toshihiro Shimizu 890ddd
	else if (action == &setExponentialAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::Exponential);
Toshihiro Shimizu 890ddd
	else if (action == &setExpressionAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::Expression);
Toshihiro Shimizu 890ddd
	else if (action == &setFileAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::File);
Toshihiro Shimizu 890ddd
	else if (action == &setConstantAction)
Toshihiro Shimizu 890ddd
		locals::sheet__setSegmentType(selection, curve, kIndex, TDoubleKeyframe::Constant);
Toshihiro Shimizu 890ddd
	else if (action == &setStep1Action)
Toshihiro Shimizu 890ddd
		KeyframeSetter(curve, kIndex).setStep(1);
Toshihiro Shimizu 890ddd
	else if (action == &setStep2Action)
Toshihiro Shimizu 890ddd
		KeyframeSetter(curve, kIndex).setStep(2);
Toshihiro Shimizu 890ddd
	else if (action == &setStep3Action)
Toshihiro Shimizu 890ddd
		KeyframeSetter(curve, kIndex).setStep(3);
Toshihiro Shimizu 890ddd
	else if (action == &setStep4Action)
Toshihiro Shimizu 890ddd
		KeyframeSetter(curve, kIndex).setStep(4);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    FunctionSheetColumnToCurveMapper  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
class FunctionSheetColumnToCurveMapper : public ColumnToCurveMapper
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FunctionSheet *m_sheet;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Toshihiro Shimizu 890ddd
	FunctionSheetColumnToCurveMapper(FunctionSheet *sheet) : m_sheet(sheet) {}
Toshihiro Shimizu 890ddd
	TDoubleParam *getCurve(int columnIndex) const
Toshihiro Shimizu 890ddd
	{
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *channel = m_sheet->getChannel(columnIndex);
Toshihiro Shimizu 890ddd
		if (channel)
Toshihiro Shimizu 890ddd
			return channel->getParam();
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
//    FunctionSheet  implementation
Toshihiro Shimizu 890ddd
//********************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSheet::FunctionSheet(QWidget *parent)
Toshihiro Shimizu 890ddd
	: SpreadsheetViewer(parent), m_selectedCells(), m_selection(0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setColumnsPanel(m_columnHeadViewer = new FunctionSheetColumnHeadViewer(this));
Toshihiro Shimizu 890ddd
	setRowsPanel(m_rowViewer = new FunctionSheetRowViewer(this));
Toshihiro Shimizu 890ddd
	setCellsPanel(m_cellViewer = new FunctionSheetCellViewer(this));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	setColumnCount(20);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionSheet::~FunctionSheet()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool FunctionSheet::anyWidgetHasFocus()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return hasFocus() ||
Toshihiro Shimizu 890ddd
		   m_rowViewer->hasFocus() ||
Toshihiro Shimizu 890ddd
		   m_columnHeadViewer->hasFocus() ||
Toshihiro Shimizu 890ddd
		   m_cellViewer->hasFocus();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::setSelection(FunctionSelection *selection)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_selection = selection;
Toshihiro Shimizu 890ddd
	m_selection->setColumnToCurveMapper(new FunctionSheetColumnToCurveMapper(this));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::showEvent(QShowEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	registerFrameScroller();
Toshihiro Shimizu 890ddd
	SpreadsheetViewer::showEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::hideEvent(QHideEvent *e)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	unregisterFrameScroller();
Toshihiro Shimizu 890ddd
	SpreadsheetViewer::hideEvent(e);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::onFrameSwitched()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	setCurrentRow(getCurrentFrame());
Toshihiro Shimizu 890ddd
	m_rowViewer->update();
Toshihiro Shimizu 890ddd
	m_cellViewer->update();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::setCurrentFrame(int frame)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (getFrameHandle())
Toshihiro Shimizu 890ddd
		getFrameHandle()->setFrame(frame);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int FunctionSheet::getCurrentFrame() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getFrameHandle() ? getFrameHandle()->getFrame() : 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int FunctionSheet::getChannelCount()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_functionTreeModel == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return m_functionTreeModel->getActiveChannelCount();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
FunctionTreeModel::Channel *FunctionSheet::getChannel(int column)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_functionTreeModel == 0)
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return m_functionTreeModel->getActiveChannel(column);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TDoubleParam *FunctionSheet::getCurve(int column)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	FunctionTreeModel::Channel *channel = getChannel(column);
Toshihiro Shimizu 890ddd
	return channel ? channel->getParam() : 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::setModel(FunctionTreeModel *model)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_functionTreeModel = model;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::setViewer(FunctionViewer *viewer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_functionViewer = viewer;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
QRect FunctionSheet::getSelectedCells() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (getSelection())
Toshihiro Shimizu 890ddd
		return getSelection()->getSelectedCells();
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return QRect();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::selectCells(const QRect &selectedCells)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_selectedCells = selectedCells;
Toshihiro Shimizu 890ddd
	if (getSelection()) {
Toshihiro Shimizu 890ddd
		QList<tdoubleparam *=""> curves;</tdoubleparam>
Toshihiro Shimizu 890ddd
		for (int c = selectedCells.left(); c <= selectedCells.right(); c++) {
Toshihiro Shimizu 890ddd
			TDoubleParam *param = 0;
Toshihiro Shimizu 890ddd
			if (c < getChannelCount())
Toshihiro Shimizu 890ddd
				param = getChannel(c)->getParam();
Toshihiro Shimizu 890ddd
			curves.push_back(param);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
		getSelection()->selectCells(selectedCells, curves);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (selectedCells.width() == 1 && curves[0] && !getChannel(selectedCells.x())->isCurrent())
Toshihiro Shimizu 890ddd
			getChannel(selectedCells.x())->setIsCurrent(true);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	updateAll();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void FunctionSheet::updateAll()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_rowViewer->update();
Toshihiro Shimizu 890ddd
	m_columnHeadViewer->update();
Toshihiro Shimizu 890ddd
	m_cellViewer->update();
Toshihiro Shimizu 890ddd
	setColumnCount(getChannelCount());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! Display expression name of the current segment
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
QString FunctionSheet::getSelectedParamName()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_functionTreeModel->getCurrentChannel())
Toshihiro Shimizu 890ddd
		return m_functionTreeModel->getCurrentChannel()->getExprRefName();
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		return QString();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int FunctionSheet::getColumnIndexByCurve(TDoubleParam *param) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return m_functionTreeModel->getColumnIndexByCurve(param);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*! scroll column to show the current one 
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
void FunctionSheet::onCurrentChannelChanged(FunctionTreeModel::Channel *channel)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (!channel)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	for (int c = 0; c < getChannelCount(); c++) {
Toshihiro Shimizu 890ddd
		FunctionTreeModel::Channel *tmpChan = getChannel(c);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (tmpChan == channel) {
Toshihiro Shimizu 890ddd
			ensureVisibleCol(c);
Toshihiro Shimizu 890ddd
			return;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}