void TestTableLayout::testTableWidth()
{
    KoTableStyle *tableStyle = new KoTableStyle();
    QVERIFY(tableStyle);
    initTestSimple(2, 2, tableStyle);

    /*
     * Fixed width.
     *
     * Rules:
     *  - Table should have 1 rect.
     *  - Width of this rect should be 60 pt (fixed).
     */
    tableStyle->setWidth(QTextLength(QTextLength::FixedLength, 60.0));
    QTextTableFormat tableFormat = m_table->format();
    tableStyle->applyStyle(tableFormat);
    m_table->setFormat(tableFormat);
    m_layout->layout();
    QCOMPARE(m_textLayout->m_tableLayout.m_tableLayoutData->m_tableRects.size(), 1);
    QCOMPARE(m_textLayout->m_tableLayout.m_tableLayoutData->m_tableRects.at(0).rect.width(), 60.0);

    /*
     * Relative width:
     *
     * Rules:
     *  - Table should have 1 rect.
     *  - Width of this rect should be 80 pt (40% of shape which is 200).
     */
    tableStyle->setWidth(QTextLength(QTextLength::PercentageLength, 40.0));
    tableStyle->applyStyle(tableFormat);
    m_table->setFormat(tableFormat);
    m_layout->layout();
    QCOMPARE(m_textLayout->m_tableLayout.m_tableLayoutData->m_tableRects.size(), 1);
    QCOMPARE(m_textLayout->m_tableLayout.m_tableLayoutData->m_tableRects.at(0).rect.width(), 80.0);
}
void TestTableLayout::testColumnWidthFixed()
{
    KoTableStyle *tableStyle = new KoTableStyle;
    tableStyle->setWidth(QTextLength(QTextLength::FixedLength, 150.0));

    setupTest("merged text", "top right text", "mid right text", "bottom left text", "bottom mid text", "bottom right text", tableStyle);
    KoTableColumnAndRowStyleManager styleManager = KoTableColumnAndRowStyleManager::getManager(m_table);

    KoTableColumnStyle column1style;
    column1style.setColumnWidth(2.3);
    styleManager.setColumnStyle(0, column1style);

    KoTableColumnStyle column2style;
    column2style.setColumnWidth(122.5);
    styleManager.setColumnStyle(1, column2style);

    KoTableColumnStyle column3style;
    column3style.setColumnWidth(362.9);
    styleManager.setColumnStyle(2, column3style);

    m_layout->layout();

    QVERIFY(qAbs(QTextCursor(m_table->parentFrame()).block().layout()->lineAt(0).width() - 200.0) < ROUNDING); // table should grow to 200
    QVERIFY(qAbs(mergedCellBlock().layout()->lineAt(0).width() - 124.8) < ROUNDING);
    QVERIFY(qAbs(topRightCellBlock().layout()->lineAt(0).width() - 362.9) < ROUNDING);
    QVERIFY(qAbs(bottomLeftCellBlock().layout()->lineAt(0).width() - 2.3) < ROUNDING);
    QVERIFY(qAbs(bottomMidCellBlock().layout()->lineAt(0).width() - 122.5) < ROUNDING);
    QVERIFY(qAbs(bottomRightCellBlock().layout()->lineAt(0).width() - 362.9) < ROUNDING);
}
void TestTableLayout::testCellRowAndColumnSpanning()
{
    KoTableStyle *tableStyle = new KoTableStyle();
    QVERIFY(tableStyle);
    tableStyle->setWidth(QTextLength(QTextLength::FixedLength, 300));

    initTestSimple(3, 3, tableStyle);

    QTextTableCell cell1 = m_table->cellAt(0, 0);
    m_table->mergeCells(0, 0, 2, 2);
    m_layout->layout();
    cell1 = m_table->cellAt(0, 0); // We get it again, just in case.

    /*
     * Cell 0,0 rules:
     *   x = 0 (no borders/margins/paddings)
     *   y = 0 (no borders/margins/paddings)
     *   width = 100*2 = 200 (column span 2)
     *   height = 2 * 14.4 = 28.8 (row span 2)
     */
    QCOMPARE(m_textLayout->m_tableLayout.cellBoundingRect(cell1), QRectF(0, 0, 200, 28.8));

    cleanupTest();
}
void TestTableLayout::testFeatureCombination()
{
    /* Let's create a larger 3x3 table with interrelated features
     *  - different borders
     *  - different column widths
     *  - merged cells
     */
    KoTableStyle *tableStyle = new KoTableStyle();
    QVERIFY(tableStyle);
    tableStyle->setWidth(QTextLength(QTextLength::FixedLength, 300.0));
    QList<KoTableRowStyle *> rowStyles;
    QMap<QPair<int, int>, KoTableCellStyle *> cellStyles;
    QMap<QPair<int, int>, QString> cellTexts;


    KoTableCellStyle *cellStyle1 = new KoTableCellStyle();
    QVERIFY(cellStyle1);
    cellStyle1->setPadding(8.0);
    cellStyle1->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 5.0, Qt::black);
    cellStyle1->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 6.0, Qt::black);
    cellStyle1->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 4.0, Qt::black);
    cellStyle1->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 8.0, Qt::black);
    cellStyles.insert(qMakePair(0, 0), cellStyle1);

    KoTableCellStyle *cellStyle2 = new KoTableCellStyle();
    QVERIFY(cellStyle2);
    cellStyle2->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 5.0, Qt::black);
    cellStyle2->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 6.0, Qt::black);
    cellStyle2->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 8.0, Qt::black);
    cellStyle2->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 4.0, Qt::black);
    cellStyles.insert(qMakePair(0, 1), cellStyle2);

    KoTableCellStyle *cellStyle3 = new KoTableCellStyle();
    QVERIFY(cellStyle3);
    cellStyle3->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle3->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle3->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle3->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyles.insert(qMakePair(0, 2), cellStyle3);

    KoTableCellStyle *cellStyle4 = new KoTableCellStyle();
    QVERIFY(cellStyle4);
    cellStyle4->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle4->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle4->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle4->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyles.insert(qMakePair(1, 0), cellStyle4);

    KoTableCellStyle *cellStyle5 = new KoTableCellStyle();
    QVERIFY(cellStyle5);
    cellStyle5->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle5->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle5->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle5->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyles.insert(qMakePair(1, 2), cellStyle5);

    KoTableCellStyle *cellStyle6 = new KoTableCellStyle();
    QVERIFY(cellStyle6);
    cellStyle6->setEdge(KoTableCellStyle::Left, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle6->setEdge(KoTableCellStyle::Right, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle6->setEdge(KoTableCellStyle::Top, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyle6->setEdge(KoTableCellStyle::Bottom, KoTableCellStyle::BorderSolid, 2.0, Qt::black);
    cellStyles.insert(qMakePair(2, 2), cellStyle6);

    QList<KoTableColumnStyle *> columnStyles;
    // Give column 0 50 pt width.
    KoTableColumnStyle *columnStyle1 = new KoTableColumnStyle();
    QVERIFY(columnStyle1);
    columnStyle1->setColumnWidth(50.0);
    columnStyles.append(columnStyle1);
    // And column 1 100 pt width.
    KoTableColumnStyle *columnStyle2 = new KoTableColumnStyle();
    columnStyle2->setColumnWidth(100.0);
    QVERIFY(columnStyle2);
    columnStyles.append(columnStyle2);
    // And column 2 150 pt width.
    KoTableColumnStyle *columnStyle3 = new KoTableColumnStyle();
    columnStyle3->setColumnWidth(150.0);
    QVERIFY(columnStyle3);
    columnStyles.append(columnStyle3);

    initTest(3, 3, tableStyle, columnStyles, rowStyles, cellStyles, cellTexts);
    m_layout->layout();
    m_table->mergeCells(1, 0, 2, 2);

    /* Top row should be as high as the max required cell height
     * 1st cell requires row to be 12+8+8+14.4=42.4
     * 2nd cell requires row to be 12+14.4=26.4
     * 3rd cell requires row to be 4+14.4=16.4
     *
     * Next row hight depends only on last column 4+14.4
     *
     * Last row hight depends only on last column 4+14.4
     *
     * Thus the merged cell (bottom 2 rows) have a combined height of 36.6 at it's disposal
     *
     * When testing we need to subtract the margins and paddings to get the cellContentRect
     */
    QTextTableCell cell = m_table->cellAt(0, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(13, 12, 23, 14.4));

    cell = m_table->cellAt(0, 1);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(55, 8, 89, 30.4));

    cell = m_table->cellAt(0, 2);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(152, 2, 146, 38.4));

    cell = m_table->cellAt(1, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(2, 28+14.4+2, 146, 4+2*14.4));

    cell = m_table->cellAt(1, 2);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(152, 28+14.4+2, 146, 14.4));

    cell = m_table->cellAt(2, 2);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell), QRectF(152, 32+2*14.4+2, 146, 14.4));

    cleanupTest();
}
void TestTableLayout::testTableAlignment()
{
    KoTableStyle *tableStyle = new KoTableStyle();
    QVERIFY(tableStyle);
    tableStyle->setWidth(QTextLength(QTextLength::FixedLength, 50.0));
    tableStyle->setAlignment(Qt::AlignRight);
    initTestSimple(1, 2, tableStyle);
    m_layout->layout();

    // Right aligned.

    /*
     * Cell 0,0 rules:
     *   x = 150 = 200 - 50 (shape width - table width)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    QTextTableCell cell1 = m_table->cellAt(0, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell1), QRectF(150, 0, 25, 14.4));

    /*
     * Cell 0,1 rules:
     *   x = 175 = (200 - 50) + 25 ((shape width - table width) + column width)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    QTextTableCell cell2 = m_table->cellAt(0, 1);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell2), QRectF(175, 0, 25, 14.4));

    // Centered.

    tableStyle->setAlignment(Qt::AlignHCenter);
    QTextTableFormat tableFormat = m_table->format();
    tableStyle->applyStyle(tableFormat);
    m_table->setFormat(tableFormat);
    m_layout->layout();

    /*
     * Cell 0,0 rules:
     *   x = 75 = (200 - 50) / 2 ((shape width - table width) / 2)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell1 = m_table->cellAt(0, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell1), QRectF(75, 0, 25, 14.4));

    /*
     * Cell 0,1 rules:
     *   x = 100 = ((200 - 50) / 2) + 25 (((shape width - table width) / 2) + column width)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell2 = m_table->cellAt(0, 1);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell2), QRectF(100, 0, 25, 14.4));

    // Left aligned.

    tableStyle->setAlignment(Qt::AlignLeft);
    tableFormat = m_table->format();
    tableStyle->applyStyle(tableFormat);
    m_table->setFormat(tableFormat);
    m_layout->layout();

    /*
     * Cell 0,0 rules:
     *   x = 0 (no borders/margins/paddings)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell1 = m_table->cellAt(0, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell1), QRectF(0, 0, 25, 14.4));

    /*
     * Cell 0,1 rules:
     *   x = 50 / 2 = 25 (table width / number of columns)
     *   y = 0 (no borders/margins/paddings)
     *   width = 50 / 2 = 25 (table width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell2 = m_table->cellAt(0, 1);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell2), QRectF(25, 0, 25, 14.4));

    // Justify aligned.

    tableStyle->setAlignment(Qt::AlignJustify); // Will overrule the explicitly set table width.
    tableFormat = m_table->format();
    tableStyle->applyStyle(tableFormat);
    m_table->setFormat(tableFormat);
    m_layout->layout();

    /*
     * Cell 0,0 rules:
     *   x = 0 (no borders/margins/paddings)
     *   y = 0 (no borders/margins/paddings)
     *   width = 200 / 2 = 100 (shape width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell1 = m_table->cellAt(0, 0);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell1), QRectF(0, 0, 100, 14.4));

    /*
     * Cell 0,1 rules:
     *   x = 200 / 2 = 100 (shape width / number of columns)
     *   y = 0 (no borders/margins/paddings)
     *   width = 200 / 2 = 100 (shape width / number of columns)
     *   height = 1 * 14.4 = 14.4 (number of lines * line height)
     */
    cell2 = m_table->cellAt(0, 1);
    QCOMPARE(m_textLayout->m_tableLayout.cellContentRect(cell2), QRectF(100, 0, 100, 14.4));

    cleanupTest();
}