Esempio n. 1
0
void CollapsedTablePainterEx::paintCellFill(const TableCell& cell, ScPainterExBase* p) const
{
	QString colorName = cell.fillColor();

	if (colorName == CommonStrings::None)
		return;

	p->save();

	ScribusDoc* doc = m_table->doc();
	ScColorShade colorShade(doc->PageColors[colorName], (int) cell.fillShade());
	p->setBrush(colorShade);
	p->setFillMode(ScPainterExBase::Solid);
	p->setStrokeMode(ScPainterExBase::None);

	int row = cell.row();
	int col = cell.column();
	int lastRow = row + cell.rowSpan() - 1;
	int lastCol = col + cell.columnSpan() - 1;

	double x = m_table->columnPosition(col);
	double y = m_table->rowPosition(row);
	double width = m_table->columnPosition(lastCol) + m_table->columnWidth(lastCol) - x;
	double height = m_table->rowPosition(lastRow) + m_table->rowHeight(lastRow) - y;
	p->drawRect(x, y, width, height);

	p->restore();
}
void CollapsedTablePainter::paintCellFill(const TableCell& cell, ScPainter* p) const
{
	QString colorName = cell.fillColor();

	if (colorName == CommonStrings::None)
		return;

	p->save();

	QColor color;
	table()->SetQColor(&color, colorName, 100.0); // TODO: Support shade.
	p->setBrush(color);
	p->setFillMode(ScPainter::Solid);
	p->setStrokeMode(ScPainter::None);

	int row = cell.row();
	int col = cell.column();
	int lastRow = row + cell.rowSpan() - 1;
	int lastCol = col + cell.columnSpan() - 1;

	qreal x = table()->columnPosition(col);
	qreal y = table()->rowPosition(row);
	qreal width = table()->columnPosition(lastCol) + table()->columnWidth(lastCol) - x;
	qreal height = table()->rowPosition(lastRow) + table()->rowHeight(lastRow) - y;
	p->drawRect(x, y, width, height);

	p->restore();
}
Esempio n. 3
0
void PageItem_Table::assertValid() const
{
	// Check list sizes.
	Q_ASSERT(rows() == m_rowPositions.size());
	Q_ASSERT(rows() == m_rowHeights.size());
	Q_ASSERT(columns() == m_columnPositions.size());
	Q_ASSERT(columns() == m_columnWidths.size());
	Q_ASSERT(rows() == m_cellRows.size());
	foreach (QList<TableCell> cellRow, m_cellRows)
		Q_ASSERT(columns() == cellRow.size());

	for (int row = 0; row < rows(); ++row)
	{
		for (int col = 0; col < columns(); ++col)
		{
			TableCell cell = m_cellRows[row][col];

			// Check that the cell reports correct row and column.
			Q_ASSERT(cell.row() == row);
			Q_ASSERT(cell.column() == col);

			// Check that the row and column span is sane.
			Q_ASSERT(cell.rowSpan() >= 1 && cell.columnSpan() >= 1);

			if (cell.rowSpan() > 1 || cell.columnSpan() > 1)
			{
				// Check that there's exactly one matching cell area.
				CellArea expectedArea(cell.row(), cell.column(), cell.columnSpan(), cell.rowSpan());
				Q_ASSERT(m_cellAreas.count(expectedArea) == 1);
			}
		}
	}

	// Check that the active position is in this table.
	Q_ASSERT(validCell(m_activeRow, m_activeColumn));

	// Check that the active cell is valid.
	Q_ASSERT(m_activeCell.isValid());
	Q_ASSERT(validCell(m_activeCell.row(), m_activeCell.column()));

	// Check that selected cells are valid.
	foreach (const TableCell& cell, m_selection)
	{
		Q_ASSERT(cell.isValid());
		Q_ASSERT(validCell(cell.row(), cell.column()));
	}
Esempio n. 4
0
double PageItem_Table::maxLeftBorderWidth() const
{
	double maxWidth = 0.0;
	TableCell cell;
	for (int row = 0; row < rows(); row += cell.rowSpan())
	{
		cell = cellAt(row, 0);
		maxWidth = qMax(maxWidth, TableUtils::collapseBorders(cell.leftBorder(), leftBorder()).width());
	}
	return maxWidth;
}
Esempio n. 5
0
void PageItem_Table::selectCells(int startRow, int startColumn, int endRow, int endColumn)
{
	if (!validCell(startRow, startColumn) || !validCell(endRow, endColumn))
		return;

	const TableCell startCell = cellAt(startRow, startColumn);
	const TableCell endCell = cellAt(endRow, endColumn);

	const int topRow = qMin(startCell.row(), endCell.row());
	const int bottomRow = qMax(startCell.row() + startCell.rowSpan() - 1,
		endCell.row() + endCell.rowSpan() - 1);

	const int leftCol = qMin(startCell.column(), endCell.column());
	const int rightCol = qMax(startCell.column() + startCell.columnSpan() - 1,
		endCell.column() + endCell.columnSpan() - 1);

	for (int row = topRow; row <= bottomRow; ++row)
		for (int col = leftCol; col <= rightCol; ++col)
			selectCell(row, col);
	emit selectionChanged();
}
Esempio n. 6
0
void CollapsedTablePainterEx::paintCellBottomBorders(const TableCell& cell, ScPainterExBase* p) const
{
	/*
	 * We are going to paint the border marked # in the following setup.
	 *
	 *  +--------------------------+--------------------------+--------------------------+
	 *  |                          |                          |                          |
	 *  |                          |                          |                          |
	 *  |        topLeftCell   topLeft         cell        topRight   topRightCell       |
	 *  |                          |                          |                          |
	 *  |                          |                          |                          |
	 *  +----------left------------+######### border-#########+----------right-----------+
	 *  |                          |                          |                          |
	 *  |                          |                          |                          |
	 *  |     bottomLeftCell   bottomLeft   bottomCell   bottomRight  bottomRightCell    |
	 *  |                          |                          |                          |
	 *  |                          |                          |                          |
	 *  +--------------------------+--------------------------+--------------------------+
	 */
	// The cell ends in this row.
	const int lastRow = cell.row() + cell.rowSpan() - 1;
	// The cell ends in this column.
	const int lastCol = cell.column() + cell.columnSpan() - 1;
	// The Y position of the border segments to paint.
	const double borderY = m_table->rowPosition(lastRow) + m_table->rowHeight(lastRow);

	// The start point of the border segment currently being painted.
	QPointF start(0.0, borderY);
	// The end point of the border segment currently being painted.
	QPointF end(0.0, borderY);
	// The start and end offset factors for the border segment currently being painted.
	QPointF startOffsetFactors, endOffsetFactors;
	// Start and end column of border segment currently being painted.
	int startCol, endCol;

	for (int col = cell.column(); col <= lastCol; col += endCol - startCol + 1)
	{
		// Get the neighboring cell below and determine border segment column interval.
		TableCell bottomCell = m_table->cellAt(lastRow + 1, col);
		startCol = qMax(cell.column(), bottomCell.column());
		endCol = qMin(lastCol, bottomCell.isValid() ? bottomCell.column() + bottomCell.columnSpan() - 1 : lastCol);

		// Get the remaining neighboring cells.
		TableCell topLeftCell = m_table->cellAt(lastRow, startCol - 1);
		TableCell topRightCell = m_table->cellAt(lastRow, endCol + 1);
		TableCell bottomRightCell = m_table->cellAt(lastRow + 1, endCol + 1);
		TableCell bottomLeftCell = m_table->cellAt(lastRow + 1, startCol - 1);

		// Resolve borders between neighboring cells.
		TableBorder topLeft, left, bottomLeft, border, topRight, right, bottomRight;
		resolveBordersHorizontal(topLeftCell, cell, topRightCell, bottomLeftCell, bottomCell, bottomRightCell, &topLeft, &left, &bottomLeft, &border, &topRight, &right, &bottomRight, m_table);

		if (border.isNull())
			continue; // Quit early if the border is null.

		// Set initial coordinates.
		start.setX(m_table->columnPosition(startCol));
		end.setX(m_table->columnPosition(endCol) + m_table->columnWidth(endCol));

		// Adjust coordinates for joining.
		joinHorizontal(border, topLeft, left, bottomLeft, topRight, right, bottomRight,
			 &start, &end, &startOffsetFactors, &endOffsetFactors);

		// Paint the border segment.
		paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, p);
	}
}
Esempio n. 7
0
void CollapsedTablePainterEx::paintCellRightBorders(const TableCell& cell, ScPainterExBase* p) const
{
	/*
	 * We are going to paint the border marked # in the following setup.
	 *
	 *       +----------------------+----------------------+
	 *       |                      |                      |
	 *       |                      |                      |
	 *       |    topLeftCell      top     topRightCell    |
	 *       |                      |                      |
	 *       |                      |                      |
	 *       +--------topLeft-------+-------topRight-------+
	 *       |                      #                      |
	 *       |                      #                      |
	 *       |         cell      border      rightCell     |
	 *       |                      #                      |
	 *       |                      #                      |
	 *       +-------bottomLeft-----+------bottomRight-----+
	 *       |                      |                      |
	 *       |                      |                      |
	 *       |  bottomLeftCell   bottom   bottomRightCell  |
	 *       |                      |                      |
	 *       |                      |                      |
	 *       +----------------------+----------------------+
	 */

	// The cell ends in this row.
	const int lastRow = cell.row() + cell.rowSpan() - 1;
	// The cell ends in this column.
	const int lastCol = cell.column() + cell.columnSpan() - 1;
	// The X position of the border segments to paint.
	const double borderX = m_table->columnPosition(lastCol) + m_table->columnWidth(lastCol);

	// The start point of the border segment currently being painted.
	QPointF start(borderX, 0.0);
	// The end point of the border segment currently being painted.
	QPointF end(borderX, 0.0);
	// The start and end offset factors for the border segment currently being painted.
	QPointF startOffsetFactors, endOffsetFactors;
	// The start and end row of border segment currently being painted.
	int startRow, endRow;

	for (int row = cell.row(); row <= lastRow; row += endRow - startRow + 1)
	{
		// Get the neighboring cell to the right and determine border segment row interval.
		TableCell rightCell = m_table->cellAt(row, lastCol + 1);
		startRow = qMax(cell.row(), rightCell.row());
		endRow = qMin(lastRow, rightCell.isValid() ? rightCell.row() + rightCell.rowSpan() - 1 : lastRow);

		// Get the remaining neighboring cells surrounding the segment.
		TableCell topLeftCell = m_table->cellAt(startRow - 1, lastCol);
		TableCell topRightCell = m_table->cellAt(startRow - 1, lastCol + 1);
		TableCell bottomRightCell = m_table->cellAt(endRow + 1, lastCol + 1);
		TableCell bottomLeftCell = m_table->cellAt(endRow + 1, lastCol);

		// Resolve borders between neighboring cells.
		TableBorder topLeft, top, topRight, border, bottomLeft, bottom, bottomRight;
		resolveBordersVertical(topLeftCell, topRightCell, cell, rightCell, bottomLeftCell, bottomRightCell, &topLeft, &top, &topRight, &border, &bottomLeft, &bottom, &bottomRight, m_table);

		if (border.isNull())
			continue; // Quit early if the border to paint is null.

		// Set initial coordinates.
		start.setY(m_table->rowPosition(startRow));
		end.setY(m_table->rowPosition(endRow) + m_table->rowHeight(endRow));

		// Adjust coordinates for joining.
		joinVertical(border, topLeft, top, topRight, bottomLeft, bottom, bottomRight,
			 &start, &end, &startOffsetFactors, &endOffsetFactors);

		// Paint the border.
		paintBorder(border, start, end, startOffsetFactors, endOffsetFactors, p);
	}
}
Esempio n. 8
0
TableHandle PageItem_Table::hitTest(const QPointF& point, double threshold) const
{
	const QPointF framePoint = getTransform().inverted().map(point);
	const QPointF gridPoint = framePoint - gridOffset();
	const QRectF gridRect = QRectF(0.0, 0.0, tableWidth(), tableHeight());

	// Test if hit is outside frame.
	if (!QRectF(0.0, 0.0, width(), height()).contains(framePoint))
		return TableHandle(TableHandle::None);

	// Test if hit is outside table.
	if (!gridRect.adjusted(-threshold, -threshold, threshold, threshold).contains(gridPoint))
		return TableHandle(TableHandle::None);

	const double tableHeight = this->tableHeight();
	const double tableWidth = this->tableWidth();
	const double x = gridPoint.x();
	const double y = gridPoint.y();

	// Test if hit is on left edge of table.
	if (x <= threshold)
		return TableHandle(TableHandle::RowSelect);

	// Test if hit is on top edge of table.
	if (y <= threshold)
		return TableHandle(TableHandle::ColumnSelect);

	// Test if hit is on bottom right corner of table.
	if (x >= tableWidth - threshold && y >= tableHeight - threshold)
		return TableHandle(TableHandle::TableResize);

	// Test if hit is on right edge of table.
	if (y >= tableHeight - threshold && y <= tableHeight + threshold)
		return TableHandle(TableHandle::RowResize, rows() - 1);

	// Test if hit is on bottom edge of table.
	if (x >= tableWidth - threshold && x <= tableWidth + threshold)
		return TableHandle(TableHandle::ColumnResize, columns() - 1);

	const TableCell hitCell = cellAt(point);
	const QRectF hitRect = hitCell.boundingRect();

	// Test if hit is on cell interior.
	if (hitRect.adjusted(threshold, threshold, -threshold, -threshold).contains(gridPoint))
		return TableHandle(TableHandle::CellSelect); // Hit interior of cell.

	const double toLeft = x - hitRect.left();
	const double toRight = hitRect.right() - x;
	const double toTop = y - hitRect.top();
	const double toBottom = hitRect.bottom() - y;
	TableHandle handle(TableHandle::None);

	// Test which side of the cell was hit.
	if (qMin(toLeft, toRight) < qMin(toTop, toBottom))
	{
		handle.setType(TableHandle::ColumnResize);
		handle.setIndex((toLeft < toRight ? hitCell.column() : hitCell.column() + hitCell.columnSpan()) - 1);
	}
	else
	{
		handle.setType(TableHandle::RowResize);
		handle.setIndex((toTop < toBottom ? hitCell.row() : hitCell.row() + hitCell.rowSpan()) - 1);
	}
	return handle;
}
void TableGesture::paintTableOutline(
	const QList<qreal>& rowHeights, const QList<qreal>& rowPositions,
	const QList<qreal>& columnWidths, const QList<qreal>& columnPositions, QPainter* p)
{
	if (!m_table || !m_canvas || !p)
		return;

	p->save();
	p->scale(m_canvas->scale(), m_canvas->scale());
	p->translate(-m_doc->minCanvasCoordinate.x(), -m_doc->minCanvasCoordinate.y());
	p->setTransform(m_table->getTransform(), true);
	p->setRenderHint(QPainter::Antialiasing);
	p->setPen(QPen(QColor(100, 200, 255), 3.0 / m_canvas->scale(), Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));

	QPointF offset = m_table->gridOffset();

	// First draw a rect around the table.
	p->drawRect(QRectF(offset.x(), offset.y(), columnPositions.last() + columnWidths.last(),
		rowPositions.last() + rowHeights.last()));

	/**
	 * cellAt() and cellRect() are fast, stroking is not. So we paint the
	 * left and top edges of the cells in two passes as this allows us to
	 * greatly minimize the number of strokes.
	 */

	TableCell cell;

	// Paint left edge(s) in each of the columns.
	for (int col = 1; col < m_table->columns(); ++col)
	{
		QPointF startPoint(columnPositions[col], 0.0);
		QPointF endPoint(startPoint);
		for (int row = 0; row < m_table->rows(); row += cell.rowSpan())
		{
			cell = m_table->cellAt(row, col);
			int endRow = cell.row() + cell.rowSpan() - 1;
			qreal bottom = rowPositions[endRow] + rowHeights[endRow];

			if (cell.column() == col)
				endPoint.setY(bottom);
			else
			{
				p->drawLine(startPoint + offset, endPoint + offset);
				startPoint.setY(bottom);
				endPoint.setY(bottom);
			}
		}
		if (endPoint.y() > startPoint.y())
			p->drawLine(startPoint + offset, endPoint + offset);
	}

	// Paint top edge(s) in each of the rows.
	for (int row = 1; row < m_table->rows(); ++row)
	{
		QPointF startPoint(0.0, rowPositions[row]);
		QPointF endPoint(startPoint);
		for (int col = 0; col < m_table->columns(); col += cell.columnSpan())
		{
			cell = m_table->cellAt(row, col);
			int endCol = cell.column() + cell.columnSpan() - 1;
			qreal right = columnPositions[endCol] + columnWidths[endCol];

			if (cell.row() == row)
				endPoint.setX(right);
			else
			{
				p->drawLine(startPoint + offset, endPoint + offset);
				startPoint.setX(right);
				endPoint.setX(right);
			}
		}
		if (endPoint.x() > startPoint.x())
			p->drawLine(startPoint + offset, endPoint + offset);
	}

	p->restore();
}
void CollapsedTablePainter::paintTable(ScPainter* p)
{
	p->save();
	p->translate(table()->gridOffset());

	// Paint table fill.
	paintTableFill(p);

	/*
	 * We paint the table in five passes:
	 *
	 * 1) Cell fills.
	 * 2) Vertical borders.
	 * 3) Horizontal borders
	 * 4) Decorative grid lines.
	 * 5) Cell content.
	 */

	// Pass 1: Paint cell fills.
	for (int row = 0; row < table()->rows(); ++row)
	{
		int colSpan = 0;
		for (int col = 0; col < table()->columns(); col += colSpan)
		{
			TableCell cell = table()->cellAt(row, col);
			if (row == cell.row())
				paintCellFill(cell, p);
			colSpan = cell.columnSpan();
		}
	}

	// Pass 2: Paint vertical borders.
	for (int row = 0; row < table()->rows(); ++row)
	{
		int colSpan = 0;
		for (int col = 0; col < table()->columns(); col += colSpan)
		{
			TableCell cell = table()->cellAt(row, col);
			if (row == cell.row())
			{
				paintCellRightBorders(cell, p);
				if (col == 0)
					paintCellLeftBorders(cell, p);
			}
			colSpan = cell.columnSpan();
		}
	}

	// Pass 3: Paint horizontal borders.
	for (int row = 0; row < table()->rows(); ++row)
	{
		int colSpan = 0;
		for (int col = 0; col < table()->columns(); col += colSpan)
		{
			TableCell cell = table()->cellAt(row, col);
			if (row == cell.row())
			{
				paintCellBottomBorders(cell, p);
				if (row == 0)
					paintCellTopBorders(cell, p);
			}
			colSpan = cell.columnSpan();
		}
	}

	// Pass 4: Paint grid lines.
	if (table()->m_Doc->guidesPrefs().framesShown)
	{
		for (int row = 0; row < table()->rows(); ++row)
		{
			int colSpan = 0;
			for (int col = 0; col < table()->columns(); col += colSpan)
			{
				TableCell cell = table()->cellAt(row, col);
				if (row == cell.row())
				{
					int endCol = col + cell.columnSpan() - 1;
					int endRow = row + cell.rowSpan() - 1;
					qreal left = table()->columnPosition(col);
					qreal right = table()->columnPosition(endCol) + table()->columnWidth(endCol);
					qreal top = table()->rowPosition(row);
					qreal bottom = table()->rowPosition(endRow) + table()->rowHeight(endRow);
					// Paint right and bottom grid line.
					paintGridLine(QPointF(right, top), QPointF(right, bottom), p);
					paintGridLine(QPointF(left, bottom), QPointF(right, bottom), p);
					// Paint left and top grid line.
					if (col == 0)
						paintGridLine(QPointF(left, top), QPointF(left, bottom), p);
					if (row == 0)
						paintGridLine(QPointF(left, top), QPointF(right, top), p);
				}
				colSpan = cell.columnSpan();
			}
		}
	}

	// Pass 5: Paint cell content.
	for (int row = 0; row < table()->rows(); ++row)
	{
		for (int col = 0; col < table()->columns(); col ++)
		{
			TableCell cell = table()->cellAt(row, col);
			if (cell.row() == row && cell.column() == col)
			{
				PageItem* textFrame = cell.textFrame();
				textFrame->DrawObj(p, QRectF());
				textFrame->DrawObj_Decoration(p);
			}
		}
	}

	p->restore();
}