Changeset View
Changeset View
Standalone View
Standalone View
libs/textlayout/tests/TestTableLayout.cpp
Show All 27 Lines | |||||
28 | #include <KoTextBlockData.h> | 28 | #include <KoTextBlockData.h> | ||
29 | #include <KoTextBlockBorderData.h> | 29 | #include <KoTextBlockBorderData.h> | ||
30 | #include <KoTextDocument.h> | 30 | #include <KoTextDocument.h> | ||
31 | #include <KoInlineTextObjectManager.h> | 31 | #include <KoInlineTextObjectManager.h> | ||
32 | #include <KoTableColumnAndRowStyleManager.h> | 32 | #include <KoTableColumnAndRowStyleManager.h> | ||
33 | #include <KoTableColumnStyle.h> | 33 | #include <KoTableColumnStyle.h> | ||
34 | #include <KoTableRowStyle.h> | 34 | #include <KoTableRowStyle.h> | ||
35 | #include <KoTableStyle.h> | 35 | #include <KoTableStyle.h> | ||
36 | #include <KoTextPage.h> | ||||
36 | #include <KoTextDebug.h> | 37 | #include <KoTextDebug.h> | ||
38 | #include <FrameIterator.h> | ||||
39 | #include <KoPointedAt.h> | ||||
37 | 40 | | |||
38 | #include <QTextCursor> | 41 | #include <QTextCursor> | ||
39 | #include <QTextTable> | 42 | #include <QTextTable> | ||
40 | #include <QTest> | 43 | #include <QTest> | ||
41 | 44 | | |||
42 | #include <TextLayoutDebug.h> | 45 | #include <TextLayoutDebug.h> | ||
43 | 46 | | |||
44 | #define FRAME_SPACING 10.0 | 47 | #define FRAME_SPACING 10.0 | ||
45 | 48 | | |||
46 | 49 | | |||
47 | void TestTableLayout::initTestCase() | 50 | void TestTableLayout::initTestCase() | ||
48 | { | 51 | { | ||
49 | m_doc = 0; | 52 | m_doc = 0; | ||
50 | m_layout = 0; | 53 | m_layout = 0; | ||
51 | 54 | | |||
52 | m_loremIpsum = QString("Lorem ipsum dolor sit amet, XgXgectetuer adiXiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."); | 55 | m_loremIpsum = QString("Lorem ipsum dolor sit amet, XgXgectetuer adiXiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi."); | ||
53 | } | 56 | } | ||
54 | 57 | | |||
55 | void TestTableLayout::cleanupTestCase() | 58 | void TestTableLayout::cleanupTestCase() | ||
56 | { | 59 | { | ||
57 | delete m_doc; | 60 | delete m_doc; | ||
61 | m_doc = 0; | ||||
58 | } | 62 | } | ||
59 | 63 | | |||
60 | QTextCursor TestTableLayout::setupTest() | 64 | QTextCursor TestTableLayout::setupTest() | ||
61 | { | 65 | { | ||
62 | delete m_doc; | 66 | delete m_doc; | ||
63 | m_doc = new QTextDocument; | 67 | m_doc = new QTextDocument; | ||
64 | Q_ASSERT(m_doc); | 68 | Q_ASSERT(m_doc); | ||
65 | 69 | | |||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Line(s) | 195 | { | |||
196 | m_table->mergeCells(0,2,3,1); | 200 | m_table->mergeCells(0,2,3,1); | ||
197 | m_table->mergeCells(0,3,3,1); | 201 | m_table->mergeCells(0,3,3,1); | ||
198 | m_table->mergeCells(0,4,3,1); | 202 | m_table->mergeCells(0,4,3,1); | ||
199 | m_table->mergeCells(2,0,1,1); | 203 | m_table->mergeCells(2,0,1,1); | ||
200 | m_table->mergeCells(2,1,1,1); | 204 | m_table->mergeCells(2,1,1,1); | ||
201 | 205 | | |||
202 | m_layout->layout(); | 206 | m_layout->layout(); | ||
203 | 207 | | |||
204 | QVERIFY(!dynamic_cast<MockRootAreaProvider*>(m_layout->provider())->m_askedForMoreThenOneArea); | 208 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||
209 | QVERIFY(!provider->m_askedForMoreThenOneArea); | ||||
210 | // check if table is layed out | ||||
211 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
212 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
213 | } | ||||
214 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
215 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
216 | QVERIFY2(m_table == p.table, "m_table not found in area 0"); | ||||
205 | } | 217 | } | ||
206 | 218 | | |||
207 | void TestTableLayout::testColumnWidthUndefined() | 219 | void TestTableLayout::testColumnWidthUndefined() | ||
208 | { | 220 | { | ||
209 | setupTest("","","","","",""); | 221 | setupTest("","","","","",""); | ||
210 | m_layout->layout(); | 222 | m_layout->layout(); | ||
211 | 223 | | |||
212 | QCOMPARE(m_table->columns(), 3); | 224 | QCOMPARE(m_table->columns(), 3); | ||
▲ Show 20 Lines • Show All 151 Lines • ▼ Show 20 Line(s) | 369 | { | |||
364 | styleManager.setRowStyle(1, row1style); | 376 | styleManager.setRowStyle(1, row1style); | ||
365 | 377 | | |||
366 | m_layout->layout(); | 378 | m_layout->layout(); | ||
367 | 379 | | |||
368 | QVERIFY(!dynamic_cast<MockRootAreaProvider*>(m_layout->provider())->m_askedForMoreThenOneArea); | 380 | QVERIFY(!dynamic_cast<MockRootAreaProvider*>(m_layout->provider())->m_askedForMoreThenOneArea); | ||
369 | //QVERIFY(qAbs(mergedCellBlock().layout()->lineAt(0).height() - 14) < ROUNDING); | 381 | //QVERIFY(qAbs(mergedCellBlock().layout()->lineAt(0).height() - 14) < ROUNDING); | ||
370 | } | 382 | } | ||
371 | 383 | | |||
384 | QTextTable *TestTableLayout::addTable(QTextCursor cursor, int rows, int columns, KoTableStyle* tableStyle) | ||||
385 | { | ||||
386 | KoParagraphStyle style; | ||||
387 | style.setStyleId(101); // needed to do manually since we don't use the stylemanager | ||||
388 | style.applyStyle(m_block); | ||||
389 | QTextTableFormat tableFormat; | ||||
390 | if (tableStyle) { | ||||
391 | tableStyle->applyStyle(tableFormat); | ||||
392 | } | ||||
393 | QTextTable *table = cursor.insertTable(rows, columns, tableFormat); | ||||
394 | for (int r = 0; r < table->rows(); ++r) { | ||||
395 | for (int c = 0; c < table->columns(); ++c) { | ||||
396 | QString s = QString("Cell %1, %2").arg(r, c); | ||||
397 | table->cellAt(r,c).firstCursorPosition().insertText(s); | ||||
398 | QTextBlock b2 = table->cellAt(r,c).firstCursorPosition().block(); | ||||
399 | while (b2.isValid()) { | ||||
400 | style.applyStyle(b2); | ||||
401 | b2 = b2.next(); | ||||
402 | } | ||||
403 | } | ||||
404 | } | ||||
405 | return table; | ||||
406 | } | ||||
407 | | ||||
408 | void TestTableLayout::testOneTableNeedsTwoRootAreas() | ||||
409 | { | ||||
410 | QTextCursor c = setupTest(); | ||||
411 | QTextTable *table1 = addTable(c, 6, 3); | ||||
412 | | ||||
413 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
414 | QVERIFY(provider); | ||||
415 | provider->setSuggestedRect(QRect(100, 100, 200, 90)); | ||||
416 | provider->maxPosition = 10; // guard against loop | ||||
417 | | ||||
418 | m_layout->layout(); | ||||
419 | | ||||
420 | QCOMPARE(provider->m_areas.count(), 2); | ||||
421 | | ||||
422 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
423 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
424 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
425 | | ||||
426 | // table2 starts in first area and continues into second area | ||||
427 | point = provider->area(1)->referenceRect().topLeft() + QPointF(0., 10.); | ||||
428 | p = provider->area(1)->hitTest(point, Qt::FuzzyHit); | ||||
429 | QVERIFY2(table1 == p.table, "table1 not found in area 1"); | ||||
430 | } | ||||
431 | | ||||
432 | void TestTableLayout::testTwoTablesNeedsTwoRootAreas() | ||||
433 | { | ||||
434 | QTextCursor c = setupTest(); | ||||
435 | QTextTable *table1 = addTable(c, 2, 3); | ||||
436 | QTextTable *table2 = addTable(c, 3, 3); | ||||
437 | | ||||
438 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
439 | QVERIFY(provider); | ||||
440 | provider->setSuggestedRect(QRect(100, 100, 200, 90)); | ||||
441 | | ||||
442 | m_layout->layout(); | ||||
443 | | ||||
444 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
445 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
446 | } | ||||
447 | | ||||
448 | QCOMPARE(provider->m_areas.count(), 2); | ||||
449 | | ||||
450 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
451 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
452 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
453 | | ||||
454 | // table2 starts in first area and continues into second area | ||||
455 | point = provider->area(1)->referenceRect().topLeft() + QPointF(0., 10.); | ||||
456 | p = provider->area(1)->hitTest(point, Qt::FuzzyHit); | ||||
457 | QVERIFY2(table2 == p.table, "table2 not found in area 1"); | ||||
458 | } | ||||
459 | | ||||
460 | void TestTableLayout::testMergedRowsSpansAreas() | ||||
461 | { | ||||
462 | QTextCursor c = setupTest(); | ||||
463 | QTextTable *table1 = addTable(c, 6, 3); | ||||
464 | | ||||
465 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
466 | QVERIFY(provider); | ||||
467 | provider->setSuggestedRect(QRect(100, 100, 200, 90)); | ||||
468 | provider->maxPosition = 10; // guard against loop | ||||
469 | | ||||
470 | table1->mergeCells(0,0,2,1); | ||||
471 | table1->mergeCells(0,1,2,1); | ||||
472 | table1->mergeCells(0,2,2,1); | ||||
473 | | ||||
474 | table1->mergeCells(2,0,2,1); | ||||
475 | table1->mergeCells(2,1,2,1); | ||||
476 | table1->mergeCells(2,2,2,1); | ||||
477 | | ||||
478 | table1->mergeCells(4,0,2,1); | ||||
479 | table1->mergeCells(4,1,2,1); | ||||
480 | table1->mergeCells(4,2,2,1); | ||||
481 | | ||||
482 | m_layout->layout(); | ||||
483 | | ||||
484 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
485 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
486 | } | ||||
487 | // should be room in two areas (it is if cells are not merged) | ||||
488 | QCOMPARE(provider->m_areas.count(), 2); | ||||
489 | | ||||
490 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
491 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
492 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
493 | | ||||
494 | point = provider->area(1)->referenceRect().topLeft() + QPointF(0., 10.); | ||||
495 | p = provider->area(1)->hitTest(point, Qt::FuzzyHit); | ||||
496 | QVERIFY2(table1 == p.table, "table1 not found in area 1"); | ||||
497 | } | ||||
498 | | ||||
499 | void TestTableLayout::testMergedRowsSpansAreas2() | ||||
500 | { | ||||
501 | QTextCursor c = setupTest(); | ||||
502 | QTextTable *table1 = addTable(c, 10, 3); | ||||
503 | | ||||
504 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
505 | QVERIFY(provider); | ||||
506 | provider->setSuggestedRect(QRect(100, 100, 200, 110)); | ||||
507 | provider->maxPosition = 10; // guard against loop | ||||
508 | | ||||
509 | table1->mergeCells(0,0,2,1); | ||||
510 | table1->mergeCells(0,1,2,1); | ||||
511 | table1->mergeCells(0,2,2,1); | ||||
512 | | ||||
513 | table1->mergeCells(2,0,2,1); | ||||
514 | table1->mergeCells(2,1,2,1); | ||||
515 | table1->mergeCells(2,2,2,1); | ||||
516 | | ||||
517 | table1->mergeCells(4,0,2,1); | ||||
518 | table1->mergeCells(4,1,2,1); | ||||
519 | table1->mergeCells(4,2,2,1); | ||||
520 | | ||||
521 | table1->mergeCells(6,0,2,1); | ||||
522 | table1->mergeCells(6,1,2,1); | ||||
523 | table1->mergeCells(6,2,2,1); | ||||
524 | | ||||
525 | table1->mergeCells(8,0,2,1); | ||||
526 | table1->mergeCells(8,1,2,1); | ||||
527 | table1->mergeCells(8,2,2,1); | ||||
528 | | ||||
529 | m_layout->layout(); | ||||
530 | | ||||
531 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
532 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
533 | } | ||||
534 | QVERIFY2(provider->m_areas.count() <= 5, "Table should fit in max 5 areas, possibly in 3"); | ||||
535 | | ||||
536 | // check if table is layed out at all | ||||
537 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
538 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
539 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
540 | } | ||||
541 | | ||||
542 | void TestTableLayout::testTwoTablesMergedRowsSpansAreas() | ||||
543 | { | ||||
544 | QTextCursor c = setupTest(); | ||||
545 | QTextTable *table1 = addTable(c, 4, 3); | ||||
546 | QTextTable *table2 = addTable(c, 3, 3); | ||||
547 | | ||||
548 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
549 | QVERIFY(provider); | ||||
550 | provider->setSuggestedRect(QRect(100, 100, 200, 90)); | ||||
551 | provider->maxPosition = 10; // guard against loop | ||||
552 | | ||||
553 | table2->mergeCells(0,0,2,1); | ||||
554 | table2->mergeCells(0,1,2,1); | ||||
555 | table2->mergeCells(0,2,2,1); | ||||
556 | | ||||
557 | m_layout->layout(); | ||||
558 | | ||||
559 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
560 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
561 | } | ||||
562 | | ||||
563 | QCOMPARE(provider->m_areas.count(), 2); | ||||
564 | | ||||
565 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
566 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
567 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
568 | | ||||
569 | // intention: there should not be room left for another row in area 0, so table2 should start in next area | ||||
570 | point = provider->area(0)->referenceRect().bottomLeft() + QPointF(0., -10.); | ||||
571 | p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
572 | QVERIFY2(table2 != p.table, "table2 found in area 0, possibly due font size"); | ||||
573 | | ||||
574 | point = provider->area(1)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
575 | p = provider->area(1)->hitTest(point, Qt::FuzzyHit); | ||||
576 | QVERIFY2(table2 == p.table, "table2 not found in area 1"); | ||||
577 | } | ||||
578 | | ||||
579 | void TestTableLayout::testTwoTablesMergedRowsSpansThreeAreas() | ||||
580 | { | ||||
581 | QTextCursor c = setupTest(); | ||||
582 | QTextTable *table1 = addTable(c, 4, 3); | ||||
583 | QTextTable *table2 = addTable(c, 8, 3); // should need 2 areas | ||||
584 | | ||||
585 | MockRootAreaProvider *provider = dynamic_cast<MockRootAreaProvider*>(m_layout->provider()); | ||||
586 | QVERIFY(provider); | ||||
587 | provider->setSuggestedRect(QRect(100, 100, 200, 90)); | ||||
588 | provider->maxPosition = 10; // guard against loop | ||||
589 | | ||||
590 | table2->mergeCells(0,0,2,1); | ||||
591 | table2->mergeCells(0,1,2,1); | ||||
592 | table2->mergeCells(0,2,2,1); | ||||
593 | | ||||
594 | m_layout->layout(); | ||||
595 | | ||||
596 | for (int i = 0; i < provider->m_areas.count(); ++i) { | ||||
597 | qInfo()<<"area:"<<i<<"referenceRect:"<<provider->area(i)->referenceRect(); | ||||
598 | } | ||||
599 | | ||||
600 | QCOMPARE(provider->m_areas.count(), 3); | ||||
601 | | ||||
602 | QPointF point = provider->area(0)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
603 | KoPointedAt p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
604 | QVERIFY2(table1 == p.table, "table1 not found in area 0"); | ||||
605 | | ||||
606 | // intention: there should not be room left for another row in area 0, so table2 should start in next area | ||||
607 | point = provider->area(0)->referenceRect().bottomLeft() + QPointF(0., -10.); | ||||
608 | p = provider->area(0)->hitTest(point, Qt::FuzzyHit); | ||||
609 | QVERIFY2(table2 != p.table, "table2 found in area 0, possibly due font size"); | ||||
610 | | ||||
611 | point = provider->area(1)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
612 | p = provider->area(1)->hitTest(point, Qt::FuzzyHit); | ||||
613 | QVERIFY2(table2 == p.table, "table2 not found in area 1"); | ||||
614 | | ||||
615 | point = provider->area(2)->referenceRect().topLeft() + QPointF(0., 20.); | ||||
616 | p = provider->area(2)->hitTest(point, Qt::FuzzyHit); | ||||
617 | QVERIFY2(table2 == p.table, "table2 not found in area 2"); | ||||
618 | } | ||||
619 | | ||||
372 | QTEST_MAIN(TestTableLayout) | 620 | QTEST_MAIN(TestTableLayout) |