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(); }
void PropertiesPalette_Table::updateBorders() { if (!m_doc || !m_item || !m_item->isTable()) return; PageItem_Table* table = m_item->asTable(); TableSideSelector::Sides selectedSides = sideSelector->selection(); m_doc->dontResize = true; if (m_doc->appMode != modeEditTable) { if (selectedSides & TableSideSelector::Left) table->setLeftBorder(m_currentBorder); if (selectedSides & TableSideSelector::Right) table->setRightBorder(m_currentBorder); if (selectedSides & TableSideSelector::Top) table->setTopBorder(m_currentBorder); if (selectedSides & TableSideSelector::Bottom) table->setBottomBorder(m_currentBorder); } else { TableCell cell = table->activeCell(); if (selectedSides & TableSideSelector::Left) cell.setLeftBorder(m_currentBorder); if (selectedSides & TableSideSelector::Right) cell.setRightBorder(m_currentBorder); if (selectedSides & TableSideSelector::Top) cell.setTopBorder(m_currentBorder); if (selectedSides & TableSideSelector::Bottom) cell.setBottomBorder(m_currentBorder); } table->adjustTable(); table->update(); }
double PageItem_Table::maxBottomBorderWidth() const { double maxWidth = 0.0; TableCell cell; for (int col = 0; col < columns(); col += cell.columnSpan()) { cell = cellAt(rows() - 1, col); maxWidth = qMax(maxWidth, TableUtils::collapseBorders(bottomBorder(), cell.bottomBorder()).width()); } return maxWidth; }
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; }
void Hashtable::addElement(char *string){ TableCell<char*>* neededList = &Table[hash(string)]; if(neededList->listIsEmpty()) occupiedCells++; else if(neededList->sizeOfCell == 1) numberOfConflicts++; neededList->sizeOfCell++; neededList->addList(string); }
bool Hashtable::findElement(char *string){ TableCell<char*>* neededList = &Table[hash(string)]; if (!neededList->listIsEmpty()){ int i = 0; ElementList<char*>* scanningElement = neededList->headList(); while(scanningElement != NULL){ i = 0; while((scanningElement->data[i] == string[i])&&(string[i] != '\0')) //compare current string with pattern i++; if (string[i] == '\0') return true; scanningElement = scanningElement->next; } } return false; }
void PageItem_Table::activateCell(const TableCell& cell) { ASSERT_VALID(); TableCell newActiveCell = validCell(cell.row(), cell.column()) ? cell : cellAt(0, 0); // Deselect previous active cell and its text. m_activeCell.textFrame()->setSelected(false); m_activeCell.textFrame()->itemText.deselectAll(); // Set the new active cell and select it. m_activeCell = newActiveCell; m_activeCell.textFrame()->setSelected(true); m_Doc->currentStyle = m_activeCell.textFrame()->currentStyle(); m_activeRow = m_activeCell.row(); m_activeColumn = m_activeCell.column(); emit selectionChanged(); ASSERT_VALID(); }
bool Hashtable::removeElement(char *string){ TableCell<char*>* neededList = &Table[hash(string)]; if (!neededList->listIsEmpty()){ neededList->sizeOfCell--; if(neededList->sizeOfCell == 1) numberOfConflicts--; int i = 0; ElementList<char*>* previousElement = NULL; ElementList<char*>* scanningElement = neededList->headList(); while(scanningElement != NULL){ i = 0; while((scanningElement->data[i] == string[i])&&(string[i] != '\0')) i++; if (string[i] == '\0'){ //delete scanningElement from neededList if (previousElement == NULL){ neededList->removeFromList(1); if(neededList->listIsEmpty()) occupiedCells--; } else{ ElementList<char*>* tmp = scanningElement; previousElement->next = scanningElement->next; delete tmp; } return false; } previousElement = scanningElement; scanningElement = scanningElement->next; } } return false; }
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 PropertiesPalette_Table::on_fillColor_activated(const QString& colorName) { if (!m_item || !m_item->isTable()) return; QString color = colorName; if (colorName == CommonStrings::tr_NoneColor) color = CommonStrings::None; PageItem_Table* table = m_item->asTable(); if (m_doc->appMode != modeEditTable) { table->setFillColor(color); table->setFillShade(fillShade->value()); } else { TableCell cell = table->activeCell(); cell.setFillColor(color); cell.setFillShade(fillShade->value()); } table->update(); }
void PropertiesPalette_Table::on_fillShade_valueChanged(int shade) { if (!m_item || !m_item->isTable()) return; QString color = fillColor->currentColor(); if (color == CommonStrings::tr_NoneColor) color = CommonStrings::None; PageItem_Table* table = m_item->asTable(); if (m_doc->appMode != modeEditTable) { table->setFillColor(color); table->setFillShade(shade); } else { TableCell cell = table->activeCell(); cell.setFillColor(color); cell.setFillShade(shade); } table->update(); }
void PageItem_Table::updateSpans(int index, int number, ChangeType changeType) { // Loop through areas of merged cells. QMutableListIterator<CellArea> areaIt(m_cellAreas); while (areaIt.hasNext()) { CellArea oldArea = areaIt.next(); // Get a copy of the area adjusted to the change. CellArea newArea; switch (changeType) { case RowsInserted: newArea = oldArea.adjustedForRowInsertion(index, number); break; case RowsRemoved: newArea = oldArea.adjustedForRowRemoval(index, number); break; case ColumnsInserted: newArea = oldArea.adjustedForColumnInsertion(index, number); break; case ColumnsRemoved: newArea = oldArea.adjustedForColumnRemoval(index, number); break; default: break; } // Check if the area was affected by the change. if (newArea != oldArea) { if (newArea.height() < 1 || newArea.width() < 1) { // Adjusted area was annihilated, so remove it. areaIt.remove(); } else if (newArea.height() == 1 && newArea.width() == 1) { // Adjusted area is 1x1, so remove it. areaIt.remove(); // And reset row/column span of spanning cell to 1. TableCell oldSpanningCell = cellAt(oldArea.row(), oldArea.column()); oldSpanningCell.setRowSpan(1); oldSpanningCell.setColumnSpan(1); } else { // Replace the area with the adjusted copy. areaIt.setValue(newArea); // And set row/column spanning of spanning cell. TableCell newSpanningCell = cellAt(newArea.row(), newArea.column()); newSpanningCell.setRowSpan(newArea.height()); newSpanningCell.setColumnSpan(newArea.width()); } } } }
void PropertiesPalette_Table::updateFillControls() { if (m_item && m_item->isTable()) { PageItem_Table* table = m_item->asTable(); // Enable fill editing controls. fillColor->setEnabled(true); fillColorLabel->setEnabled(true); fillShade->setEnabled(true); fillShadeLabel->setEnabled(true); // Fill in values. if (m_doc->appMode != modeEditTable) { QString color = table->fillColor(); if (color == CommonStrings::None) color = CommonStrings::tr_NoneColor; setCurrentComboItem(fillColor, color); fillShade->setValue(table->fillShade()); } else { TableCell cell = table->activeCell(); QString color = cell.fillColor(); if (color == CommonStrings::None) color = CommonStrings::tr_NoneColor; setCurrentComboItem(fillColor, color); fillShade->setValue(cell.fillShade()); } } else { // Disable fill editing controls. fillColor->setEnabled(false); fillColorLabel->setEnabled(false); fillShade->setEnabled(false); fillShadeLabel->setEnabled(false); } }
void CollapsedTablePainterEx::paintTable(ScPainterExBase* p) { p->save(); p->translate(m_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 < m_table->rows(); ++row) { int colSpan = 0; for (int col = 0; col < m_table->columns(); col += colSpan) { TableCell cell = m_table->cellAt(row, col); if (row == cell.row()) paintCellFill(cell, p); colSpan = cell.columnSpan(); } } // Pass 2: Paint vertical borders. for (int row = 0; row < m_table->rows(); ++row) { int colSpan = 0; for (int col = 0; col < m_table->columns(); col += colSpan) { TableCell cell = m_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 < m_table->rows(); ++row) { int colSpan = 0; for (int col = 0; col < m_table->columns(); col += colSpan) { TableCell cell = m_table->cellAt(row, col); if (row == cell.row()) { paintCellBottomBorders(cell, p); if (row == 0) paintCellTopBorders(cell, p); } colSpan = cell.columnSpan(); } } // Pass 5: Paint cell content. for (int row = 0; row < m_table->rows(); ++row) { for (int col = 0; col < m_table->columns(); col ++) { TableCell cell = m_table->cellAt(row, col); if (cell.row() == row && cell.column() == col) { PageItem_TextFrame* textFrame = cell.textFrame(); m_pageOutput->drawItem(textFrame, p, QRect()); } } } p->restore(); }
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); } }
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 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(); }
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(); }
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())); }
void CollapsedTablePainter::resolveBordersVertical(const TableCell& topLeftCell, const TableCell& topRightCell, const TableCell& leftCell, const TableCell& rightCell, const TableCell& bottomLeftCell, const TableCell& bottomRightCell, TableBorder* topLeft, TableBorder* top, TableBorder* topRight, TableBorder* center, TableBorder* bottomLeft, TableBorder* bottom, TableBorder* bottomRight) const { Q_ASSERT(topLeft); Q_ASSERT(top); Q_ASSERT(topRight); Q_ASSERT(center); Q_ASSERT(bottomLeft); Q_ASSERT(bottom); Q_ASSERT(bottomRight); if (!leftCell.isValid() && !rightCell.isValid()) { qWarning("leftCell and rightCell invalid!"); return; } // Resolve top left. if (topLeftCell.row() == leftCell.row()) *topLeft = TableBorder(); else if (topLeftCell.isValid() && leftCell.isValid()) *topLeft = collapseBorders(leftCell.topBorder(), topLeftCell.bottomBorder()); else if (topLeftCell.isValid()) *topLeft = collapseBorders(table()->bottomBorder(), topLeftCell.bottomBorder()); else if (leftCell.isValid()) *topLeft = collapseBorders(leftCell.topBorder(), table()->topBorder()); else *topLeft = TableBorder(); // Resolve top. if (topLeftCell.column() == topRightCell.column()) *top = TableBorder(); else if (topLeftCell.isValid() && topRightCell.isValid()) *top = collapseBorders(topRightCell.leftBorder(), topLeftCell.rightBorder()); else if (topLeftCell.isValid()) *top = collapseBorders(table()->rightBorder(), topLeftCell.rightBorder()); else if (topRightCell.isValid()) *top = collapseBorders(topRightCell.leftBorder(), table()->leftBorder()); else *top = TableBorder(); // Resolve top right. if (topRightCell.row() == rightCell.row()) *topRight = TableBorder(); else if (topRightCell.isValid() && rightCell.isValid()) *topRight = collapseBorders(rightCell.topBorder(), topRightCell.bottomBorder()); else if (topRightCell.isValid()) *topRight = collapseBorders(table()->bottomBorder(), topRightCell.bottomBorder()); else if (rightCell.isValid()) *topRight = collapseBorders(rightCell.topBorder(), table()->topBorder()); else *topRight = TableBorder(); // Resolve center. if (leftCell.column() == rightCell.column()) *center = TableBorder(); else if (leftCell.isValid() && rightCell.isValid()) *center = collapseBorders(rightCell.leftBorder(), leftCell.rightBorder()); else if (leftCell.isValid()) *center = collapseBorders(table()->rightBorder(), leftCell.rightBorder()); else if (rightCell.isValid()) *center = collapseBorders(rightCell.leftBorder(), table()->leftBorder()); else *center = TableBorder(); // Resolve bottom left. if (bottomLeftCell.row() == leftCell.row()) *bottomLeft = TableBorder(); else if (bottomLeftCell.isValid() && leftCell.isValid()) *bottomLeft = collapseBorders(bottomLeftCell.topBorder(), leftCell.bottomBorder()); else if (bottomLeftCell.isValid()) *bottomLeft = collapseBorders(bottomLeftCell.topBorder(), table()->topBorder()); else if (leftCell.isValid()) *bottomLeft = collapseBorders(table()->bottomBorder(), leftCell.bottomBorder()); else *bottomLeft = TableBorder(); // Resolve bottom. if (bottomLeftCell.column() == bottomRightCell.column()) *bottom = TableBorder(); else if (bottomLeftCell.isValid() && bottomRightCell.isValid()) *bottom = collapseBorders(bottomRightCell.leftBorder(), bottomLeftCell.rightBorder()); else if (bottomLeftCell.isValid()) *bottom = collapseBorders(table()->rightBorder(), bottomLeftCell.rightBorder()); else if (bottomRightCell.isValid()) *bottom = collapseBorders(bottomRightCell.leftBorder(), table()->leftBorder()); else *bottom = TableBorder(); // Resolve bottom right. if (bottomRightCell.row() == rightCell.row()) *bottomRight = TableBorder(); else if (bottomRightCell.isValid() && rightCell.isValid()) *bottomRight = collapseBorders(bottomRightCell.topBorder(), rightCell.bottomBorder()); else if (bottomRightCell.isValid()) *bottomRight = collapseBorders(bottomRightCell.topBorder(), table()->topBorder()); else if (rightCell.isValid()) *bottomRight = collapseBorders(table()->bottomBorder(), rightCell.bottomBorder()); else *bottomRight = TableBorder(); }
CellPos(int pos, TableData const *data) { TableCell cel = data->cellAt(pos); r = cel.row(); c = cel.column(); off = pos - cel.firstPosition(); }
void PageItem_Table::getNamedResources(ResourceCollection& lists) const { TableBorder lborder = leftBorder(); foreach (const TableBorderLine& line, lborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } TableBorder rborder = rightBorder(); foreach (const TableBorderLine& line, rborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } TableBorder bborder = bottomBorder(); foreach (const TableBorderLine& line, bborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } TableBorder tborder = topBorder(); foreach (const TableBorderLine& line, tborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } QString tableStyleName = this->styleName(); if (!tableStyleName.isEmpty()) lists.collectTableStyle(tableStyleName); for (int row = 0; row < rows(); ++row) { int colSpan = 0; for (int col = 0; col < columns(); col += colSpan) { TableCell cell = cellAt(row, col); PageItem_TextFrame* textFrame = cell.textFrame(); textFrame->getNamedResources(lists); QString cellStyle = cell.styleName(); if (!cellStyle.isEmpty()) lists.collectCellStyle(cellStyle); QString cellFill = cell.fillColor(); if (cellFill != CommonStrings::None) lists.collectColor(cellFill); lborder = cell.leftBorder(); foreach (const TableBorderLine& line, lborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } rborder = cell.rightBorder(); foreach (const TableBorderLine& line, rborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } bborder = cell.bottomBorder(); foreach (const TableBorderLine& line, bborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } tborder = cell.topBorder(); foreach (const TableBorderLine& line, tborder.borderLines()) { if (line.color() == CommonStrings::None) continue; lists.collectColor(line.color()); } colSpan = cell.columnSpan(); } } PageItem::getNamedResources(lists); }
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); } }
void PageItem_Table::mergeCells(int row, int column, int numRows, int numCols) { ASSERT_VALID(); if (!validCell(row, column) || !validCell(row + numRows - 1, column + numCols - 1)) return; CellArea newArea(row, column, numCols, numRows); // Unite intersecting areas. QMutableListIterator<CellArea> areaIt(m_cellAreas); while (areaIt.hasNext()) { CellArea oldArea = areaIt.next(); if (newArea.intersects(oldArea)) { // The two areas intersect, so unite them. newArea = newArea.united(oldArea); // Reset row/column span of old spanning cell, then remove old area. TableCell oldSpanningCell = cellAt(oldArea.row(), oldArea.column()); oldSpanningCell.setRowSpan(1); oldSpanningCell.setColumnSpan(1); areaIt.remove(); } } // Set row/column span of new spanning cell, and add new area. TableCell newSpanningCell = cellAt(newArea.row(), newArea.column()); newSpanningCell.setRowSpan(newArea.height()); newSpanningCell.setColumnSpan(newArea.width()); m_cellAreas.append(newArea); // Update cells. TODO: Not for entire table. updateCells(); // If merged area covers active position, move to the spanning cell. if (newArea.contains(m_activeRow, m_activeColumn)) moveTo(newSpanningCell); // Remove all cells covered by the merged area from the selection. QMutableSetIterator<TableCell> cellIt(m_selection); while (cellIt.hasNext()) { TableCell cell = cellIt.next(); if (newArea.contains(cell.row(), cell.column()) && !(cell.row() == newArea.row() && cell.column() == newArea.column())) cellIt.remove(); } emit changed(); ASSERT_VALID(); }
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::resolveBordersHorizontal(const TableCell& topLeftCell, const TableCell& topCell, const TableCell& topRightCell, const TableCell& bottomLeftCell, const TableCell& bottomCell, const TableCell& bottomRightCell, TableBorder* topLeft, TableBorder* left, TableBorder* bottomLeft, TableBorder* center, TableBorder* topRight, TableBorder* right, TableBorder* bottomRight) const { Q_ASSERT(topLeft); Q_ASSERT(left); Q_ASSERT(bottomLeft); Q_ASSERT(center); Q_ASSERT(topRight); Q_ASSERT(right); Q_ASSERT(bottomRight); if (!topCell.isValid() && !bottomCell.isValid()) { qWarning("topCell and bottomCell invalid!"); return; } // Resolve top left. if (topLeftCell.column() == topCell.column()) *topLeft = TableBorder(); else if (topLeftCell.isValid() && topCell.isValid()) *topLeft = collapseBorders(topCell.leftBorder(), topLeftCell.rightBorder()); else if (topLeftCell.isValid()) *topLeft = collapseBorders(table()->rightBorder(), topLeftCell.rightBorder()); else if (topCell.isValid()) *topLeft = collapseBorders(topCell.leftBorder(), table()->leftBorder()); else *topLeft = TableBorder(); // Resolve left. if (topLeftCell.row() == bottomLeftCell.row()) *left = TableBorder(); else if (topLeftCell.isValid() && bottomLeftCell.isValid()) *left = collapseBorders(bottomLeftCell.topBorder(), topLeftCell.bottomBorder()); else if (topLeftCell.isValid()) *left = collapseBorders(table()->bottomBorder(), topLeftCell.bottomBorder()); else if (bottomLeftCell.isValid()) *left = collapseBorders(bottomLeftCell.topBorder(), table()->topBorder()); else *left = TableBorder(); // Resolve bottom left. if (bottomLeftCell.column() == bottomCell.column()) *bottomLeft = TableBorder(); else if (bottomLeftCell.isValid() && bottomCell.isValid()) *bottomLeft = collapseBorders(bottomCell.leftBorder(), bottomLeftCell.rightBorder()); else if (bottomLeftCell.isValid()) *bottomLeft = collapseBorders(table()->rightBorder(), bottomLeftCell.rightBorder()); else if (bottomCell.isValid()) *bottomLeft = collapseBorders(bottomCell.leftBorder(), table()->leftBorder()); else *bottomLeft = TableBorder(); // Resolve center. if (topCell.row() == bottomCell.row()) *center = TableBorder(); else if (topCell.isValid() && bottomCell.isValid()) *center = collapseBorders(topCell.bottomBorder(), bottomCell.topBorder()); else if (topCell.isValid()) *center = collapseBorders(table()->bottomBorder(), topCell.bottomBorder()); else if (bottomCell.isValid()) *center = collapseBorders(bottomCell.topBorder(), table()->topBorder()); else *center = TableBorder(); // Resolve top right. if (topRightCell.column() == topCell.column()) *topRight = TableBorder(); else if (topRightCell.isValid() && topCell.isValid()) *topRight = collapseBorders(topRightCell.leftBorder(), topCell.rightBorder()); else if (topRightCell.isValid()) *topRight = collapseBorders(topRightCell.leftBorder(), table()->leftBorder()); else if (topCell.isValid()) *topRight = collapseBorders(table()->rightBorder(), topCell.rightBorder()); else *topRight = TableBorder(); // Resolve right. if (topRightCell.row() == bottomRightCell.row()) *right = TableBorder(); else if (topRightCell.isValid() && bottomRightCell.isValid()) *right = collapseBorders(bottomRightCell.topBorder(), topRightCell.bottomBorder()); else if (topRightCell.isValid()) *right = collapseBorders(table()->bottomBorder(), topRightCell.bottomBorder()); else if (bottomRightCell.isValid()) *right = collapseBorders(bottomRightCell.topBorder(), table()->topBorder()); else *right = TableBorder(); // Resolve bottom right. if (bottomRightCell.column() == bottomCell.column()) *bottomRight = TableBorder(); else if (bottomRightCell.isValid() && bottomCell.isValid()) *bottomRight = collapseBorders(bottomRightCell.leftBorder(), bottomCell.rightBorder()); else if (bottomRightCell.isValid()) *bottomRight = collapseBorders(bottomRightCell.leftBorder(), table()->leftBorder()); else if (bottomCell.isValid()) *bottomRight = collapseBorders(table()->rightBorder(), bottomCell.rightBorder()); else *bottomRight = TableBorder(); }