QQuickItem * DataSetView::createRowNumber(int row)
{
	//std::cout << "createRowNumber("<<row<<") called!\n" << std::flush;


	if(_rowNumberDelegate == NULL)
	{
		_rowNumberDelegate = new QQmlComponent(qmlEngine(this));
		_rowNumberDelegate->setData("import QtQuick 2.10\nItem {\n"
			"property alias text: tekst.text\n"
			"Rectangle	{ color: \"lightGrey\";	anchors.fill: parent }\n"
			"Text		{ id: tekst; anchors.centerIn: parent }\n"
		"}", QUrl());
	}

	QQuickItem * rowNumber = NULL;

	if(_rowNumberItems.count(row) == 0  || _rowNumberItems[row] == NULL)
	{

		if(_rowNumberStorage.size() > 0)
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createRowNumber("<<row<<") from storage!\n" << std::flush;
#endif
			rowNumber = _rowNumberStorage.top();
			_rowNumberStorage.pop();
		}
		else
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createRowNumber("<<row<<") ex nihilo!\n" << std::flush;
#endif
			rowNumber = qobject_cast<QQuickItem*>(_rowNumberDelegate->create());
			rowNumber->setParent(this);
			rowNumber->setParentItem(this);
		}

		rowNumber->setProperty("z", 10);
		rowNumber->setProperty("text", QString::fromStdString(std::to_string(row + 1))); //Nobody wants zero-based rows...

		rowNumber->setY(_dataRowsMaxHeight * (1 + row));
		rowNumber->setZ(-3);
		rowNumber->setHeight(_dataRowsMaxHeight);
		rowNumber->setWidth(_rowNumberMaxWidth);

		rowNumber->setVisible(true);

		_rowNumberItems[row] = rowNumber;
	}
	else
		rowNumber = _rowNumberItems[row];

	rowNumber->setX(_viewportX);

	return _rowNumberItems[row];
}
QQuickItem * DataSetView::createColumnHeader(int col)
{
	//std::cout << "createColumnHeader("<<col<<") called!\n" << std::flush;


	if(_columnHeaderDelegate == NULL)
	{
		_columnHeaderDelegate = new QQmlComponent(qmlEngine(this));
		_columnHeaderDelegate->setData("import QtQuick 2.10\nItem {\n"
			"property alias text: tekst.text\n"
		   "Rectangle	{ color: \"lightGrey\";	anchors.fill: parent }\n"
		   "Text		{ id: tekst; anchors.centerIn: parent }\n"
		"}", QUrl());
	}

	QQuickItem * columnHeader = NULL;

	if(_columnHeaderItems.count(col) == 0  || _columnHeaderItems[col] == NULL)
	{

		if(_columnHeaderStorage.size() > 0)
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createColumnHeader("<<col<<") from storage!\n" << std::flush;
#endif
			columnHeader = _columnHeaderStorage.top();
			_columnHeaderStorage.pop();
		}
		else
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createColumnHeader("<<col<<") ex nihilo!\n" << std::flush;
#endif
			columnHeader = qobject_cast<QQuickItem*>(_columnHeaderDelegate->create());
			columnHeader->setParent(this);
			columnHeader->setParentItem(this);
		}

		columnHeader->setProperty("z", 10);
		columnHeader->setProperty("text", _model->headerData(col, Qt::Orientation::Horizontal).toString());

		columnHeader->setZ(-3);
		columnHeader->setHeight(_dataRowsMaxHeight);
		columnHeader->setWidth(_dataColsMaxWidth[col]);

		columnHeader->setVisible(true);

		_columnHeaderItems[col] = columnHeader;
	}
	else
		columnHeader = _columnHeaderItems[col];

	columnHeader->setX(_colXPositions[col]);
	columnHeader->setY(_viewportY);

	return columnHeader;
}
QQuickItem * DataSetView::createTextItem(int row, int col)
{
	//std::cout << "createTextItem("<<row<<", "<<col<<") called!\n" << std::flush;

	if((_cellTextItems.count(col) == 0 && _cellTextItems[col].count(row) == 0) || _cellTextItems[col][row] == NULL)
	{

		if(_itemDelegate == NULL)
		{
			_itemDelegate = new QQmlComponent(qmlEngine(this));
			_itemDelegate->setData("import QtQuick 2.10\nText { property bool active: true; text: \"???\"; color: active ? 'black' : 'grey' }", QUrl());
		}

		QQuickItem * textItem = NULL;

		if(_textItemStorage.size() > 0)
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createTextItem("<<row<<", "<<col<<") from storage!\n" << std::flush;
#endif
			textItem = _textItemStorage.top();
			_textItemStorage.pop();
		}
		else
		{
#ifdef DEBUG_VIEWPORT
			std::cout << "createTextItem("<<row<<", "<<col<<") ex nihilo!\n" << std::flush;
#endif
			textItem = qobject_cast<QQuickItem*>(_itemDelegate->create());
			textItem->setParent(this);
			textItem->setParentItem(this);
		}

		QModelIndex ind(_model->index(row, col));
		bool active = _model->data(ind, _roleNameToRole["active"]).toBool();
		textItem->setProperty("color", active ? "black" : "grey");
		textItem->setProperty("text", _model->data(ind));
		textItem->setX(_colXPositions[col] + _itemHorizontalPadding);
		textItem->setY(-2 + _dataRowsMaxHeight + _itemVerticalPadding + row * _dataRowsMaxHeight);
		textItem->setZ(-4);
		textItem->setVisible(true);

		_cellTextItems[col][row] = textItem;
	}

	return _cellTextItems[col][row];
}