void KWCopyShape::paint(QPainter &painter, const KoViewConverter &converter, KoShapePaintingContext &paintcontext) { Q_ASSERT(m_original); //paint all child shapes KoShapeContainer* container = dynamic_cast<KoShapeContainer*>(m_original); if (container) { QList<KoShape*> sortedObjects = container->shapes(); sortedObjects.append(m_original); qSort(sortedObjects.begin(), sortedObjects.end(), KoShape::compareShapeZIndex); // Do the following to revert the absolute transformation of the // container that is re-applied in shape->absoluteTransformation() // later on. The transformation matrix of the container has already // been applied once before this function is called. QTransform baseMatrix = container->absoluteTransformation(&converter).inverted() * painter.transform(); KWPage copypage = m_pageManager->page(this); Q_ASSERT(copypage.isValid()); foreach(KoShape *shape, sortedObjects) { painter.save(); if (shape != m_original) { painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); } KoTextShapeData *data = qobject_cast<KoTextShapeData*>(shape->userData()); if (data == 0) { shape->paint(painter, converter, paintcontext); } else { // Since the rootArea is shared between the copyShape and the originalShape we need to // temporary switch the used KoTextPage to be sure the proper page-numbers are displayed. KWPage originalpage = m_pageManager->page(shape); Q_ASSERT(originalpage.isValid()); KoTextLayoutRootArea *area = data->rootArea(); bool wasBlockChanges = false; if (area) { // We need to block documentChanged() signals emitted cause for example page-variables // may change there content to result in us marking root-areas dirty for relayout else // we could end in an infinite relayout ping-pong. wasBlockChanges = area->documentLayout()->changesBlocked(); area->documentLayout()->setBlockChanges(true); area->setPage(new KWPage(copypage)); } shape->paint(painter, converter, paintcontext); if (area) { area->setPage(new KWPage(originalpage)); area->documentLayout()->setBlockChanges(wasBlockChanges); } } painter.restore(); if (shape->stroke()) { painter.save(); painter.setTransform(shape->absoluteTransformation(&converter) * baseMatrix); shape->stroke()->paint(shape, painter, converter); painter.restore(); } } } else {
QVariant TextContentsModelImpl::data(int index, Calligra::Components::ContentsModel::Role role) const { if(d->entries.count() > 0) { auto entry = d->entries.at(index); switch(role) { case ContentsModel::TitleRole: return entry.title; case ContentsModel::LevelRole: return entry.level; case ContentsModel::ThumbnailRole: { if(d->thumbnails.contains(entry.pageNumber)) { return d->thumbnails.value(entry.pageNumber); } if(d->thumbnailSize.isNull()) { return QImage{}; } QImage thumb = entry.page->thumbnail(d->thumbnailSize, d->canvas->shapeManager()); d->thumbnails.insert(entry.pageNumber, thumb); return thumb; } case ContentsModel::ContentIndexRole: { return entry.pageNumber - 1; } default: return QVariant(); } } //Fallback behaviour when we don't have a ToC KWPage page = d->document->pageManager()->page(index + 1); if(!page.isValid()) return QVariant(); switch(role) { case ContentsModel::TitleRole: return QString(i18n("Page %1")).arg(page.pageNumber()); case ContentsModel::LevelRole: return 0; case ContentsModel::ThumbnailRole: { if(d->thumbnails.contains(index)) { return d->thumbnails.value(index); } if(d->thumbnailSize.isNull()) { return QImage{}; } QImage thumb = page.thumbnail(d->thumbnailSize, d->canvas->shapeManager()); d->thumbnails.insert(index, thumb); return thumb; } case ContentsModel::ContentIndexRole: { return index; } default: return QVariant(); } }
KWPageSettingsDialog::KWPageSettingsDialog(QWidget *parent, KWDocument *document, const KWPage &page) : KoPageLayoutDialog(parent, page.pageStyle().pageLayout()), m_document(document), m_page(page) { Q_ASSERT(document); showUnitchooser(true); Q_ASSERT(page.isValid()); m_columns = new KWDocumentColumns(this, m_page.pageStyle().columns()); addPage(m_columns, i18n("Columns")); m_headerFooter = new KWHeaderFooter(this, m_page.pageStyle()); addPage(m_headerFooter, i18n("Header/Footer")); showPageSpread(true); showTextDirection(true); // TODO can we hide this in selected usecases? Use the resource manager bidi-check maybe? //showApplyToDocument(true); // TODO uncommand when we can handle it. bool simpleSetup = document->pageCount() == 1 || (document->pageCount() == 2 && page.pageSide() == KWPage::PageSpread); if (!simpleSetup) { // if there is one style, its still a simple doc bool onlyOneStyle = true; foreach (const KWPage &p, document->pageManager()->pages()) { if (p.pageStyle() != m_page.pageStyle()) { onlyOneStyle = false; break; } } if (onlyOneStyle) simpleSetup = true; }
void KWGui::pageSetupChanged() { const KWPageManager *pm = m_view->kwdocument()->pageManager(); const KWPage firstPage = pm->begin(); const KWPage lastPage = pm->last(); int height = 0; if (lastPage.isValid()) height = lastPage.offsetInDocument() + lastPage.height(); m_verticalRuler->setRulerLength(height); updateRulers(); int width = 0; if (firstPage.isValid()) width = firstPage.width(); m_horizontalRuler->setRulerLength(width); m_horizontalRuler->setActiveRange(0, width); m_verticalRuler->setActiveRange(0, height); updateRulers(); }
KWPageSettingsDialog::KWPageSettingsDialog(QWidget *parent, KWDocument *document, const KWPage &page) : KoPageLayoutDialog(parent, page.pageStyle().pageLayout()), m_document(document), m_page(page), m_pageStyle(page.pageStyle()) { Q_ASSERT(document); setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel); connect(buttonBox(), SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonClicked(QAbstractButton*))); showUnitchooser(true); Q_ASSERT(page.isValid()); m_columns = new KWDocumentColumns(this, m_page.pageStyle().columns()); KPageWidgetItem *columnsPage = addPage(m_columns, i18n("Columns")); QWidget *pageStyleWidget = new QWidget(this); QHBoxLayout *pageStyleLayout = new QHBoxLayout(pageStyleWidget); pageStyleLayout->setMargin(0); KPageWidgetItem *stylePage = addPage(pageStyleWidget, i18n("Style")); m_pageStylesView = new QListWidget(this); pageStyleLayout->addWidget(m_pageStylesView, 1); connect(m_pageStylesView, SIGNAL(currentRowChanged(int)), this, SLOT(pageStyleCurrentRowChanged(int))); QVBoxLayout *pageStyleLayout2 = new QVBoxLayout(); pageStyleLayout->addLayout(pageStyleLayout2); m_clonePageStyleButton = new QPushButton(i18n("Clone"), pageStyleWidget); connect(m_clonePageStyleButton, SIGNAL(clicked()), this, SLOT(pageStyleCloneClicked())); pageStyleLayout2->addWidget(m_clonePageStyleButton); m_deletePageStyleButton = new QPushButton(i18n("Delete"), pageStyleWidget); connect(m_deletePageStyleButton, SIGNAL(clicked()), this, SLOT(pageStyleDeleteClicked())); pageStyleLayout2->addWidget(m_deletePageStyleButton); pageStyleLayout2->addStretch(); foreach(KPageWidgetItem *item, QList<KPageWidgetItem*>() << columnsPage << stylePage) m_pages[item->name()] = item; reloadPageStyles(); showPageSpread(false); //TODO better would be allow n pages to face rather then only 2 showTextDirection(true); // TODO can we hide this in selected usecases? Use the resource manager bidi-check maybe? //showApplyToDocument(true); // TODO uncommand when we can handle it. #if 0 bool simpleSetup = m_document->pageCount() == 1 || (m_document->pageCount() == 2 && page.pageSide() == KWPage::PageSpread); if (!simpleSetup) { // if there is one style, its still a simple doc bool onlyOneStyle = true; foreach (const KWPage &p, m_document->pageManager()->pages()) { if (p.pageStyle() != m_page.pageStyle()) { onlyOneStyle = false; break; } } if (onlyOneStyle) simpleSetup = true; }
void TestPageCommands::testRemovePageCommand3() // test restore all properties { KWDocument document; KWPageInsertCommand insertCommand(&document, 0); insertCommand.redo(); KWPage page = insertCommand.page(); KWPageStyle style = page.pageStyle(); style.setHasMainTextFrame(false); style.setFootnoteDistance(10); KoPageLayout layout; layout.width = 400; layout.height = 300; layout.leftMargin = 4; layout.rightMargin = 6; layout.topMargin = 7; layout.bottomMargin = 5; style.setPageLayout(layout); page.setPageStyle(style); KWPageRemoveCommand command(&document, page); command.redo(); QVERIFY(!page.isValid()); command.undo(); page = document.pageManager()->begin(); QVERIFY(page.isValid()); QVERIFY(insertCommand.page() != page); QCOMPARE(page.pageNumber(), 1); KWPageStyle style2 = page.pageStyle(); QCOMPARE(style2, style); QCOMPARE(style2.hasMainTextFrame(), false); QCOMPARE(style2.footnoteDistance(), 10.); KoPageLayout layout2 = style2.pageLayout(); QCOMPARE(layout2, layout); QCOMPARE(page.pageStyle(), style); QCOMPARE(page.width(), 400.); }
void KWCanvasBase::clipToDocument(const KoShape *shape, QPointF &move) const { Q_ASSERT(shape); const QPointF absPos = shape->absolutePosition(); const QPointF destination = absPos + move; qreal bottomOfPage = 0.0; KWPage page; foreach (const KWPage &p, m_document->pageManager()->pages()) { bottomOfPage += p.height(); if (bottomOfPage >= absPos.y()) page = p; if (bottomOfPage >= destination.y()) { page = p; break; } } if (!page.isValid()) { // shape was not in any page to begin with, can't propose anything sane... move.setX(0); move.setY(0); return; } QRectF pageRect(page.rect().adjusted(5, 5, -5, -5)); QPainterPath path(shape->absoluteTransformation(0).map(shape->outline())); QRectF shapeBounds = path.boundingRect(); shapeBounds.moveTopLeft(shapeBounds.topLeft() + move); if (!shapeBounds.intersects(pageRect)) { if (shapeBounds.left() > pageRect.right()) // need to move to the left some move.setX(move.x() + (pageRect.right() - shapeBounds.left())); else if (shapeBounds.right() < pageRect.left()) // need to move to the right some move.setX(move.x() + pageRect.left() - shapeBounds.right()); if (shapeBounds.top() > pageRect.bottom()) // need to move up some move.setY(move.y() + (pageRect.bottom() - shapeBounds.top())); else if (shapeBounds.bottom() < pageRect.top()) // need to move down some move.setY(move.y() + pageRect.top() - shapeBounds.bottom()); } // Also make sure any anchoring restrictions are adhered to KWFrameLayout::proposeShapeMove(shape, move, page); }
void TestPageCommands::testPageSpread() { // setup a doc with multiple pages like; // 1: S1, 2: S1, 3: S1, 4: S2, 5: S1, 6:S2, 7: S2 KWDocument document; KWPageManager *manager = document.pageManager(); KWPageStyle style("pagestyle1"); KoPageLayout lay = style.pageLayout(); lay.width = 300; lay.height = 500; style.setPageLayout(lay); KWPageStyle style2("pagestyle2"); lay = style.pageLayout(); lay.width = 400; lay.height = 400; style2.setPageLayout(lay); KWPage p1 = manager->appendPage(style); KWPage p2 = manager->appendPage(style); KWPage p3 = manager->appendPage(style); KWPage p4 = manager->appendPage(style2); KWPage p5 = manager->appendPage(style); KWPage p6 = manager->appendPage(style2); KWPage p7 = manager->appendPage(style2); KWFrameSet *fs = new KWFrameSet(); for (int i = 1; i <= manager->pageCount(); ++i) { // create one frame per page. Positioned relative to the top of the page. KWPage page = manager->page(i); QVERIFY(page.isValid()); MockShape *shape = new MockShape(); new KWFrame(shape, fs); shape->setPosition(QPointF(-10, page.offsetInDocument() + 10)); } document.addFrameSet(fs); // when changing S1 from normal to pagespread I expect // page 1 to stay the same. // page 2 to become a pagespread // page 3 to be deleted // page 4 to stay the same. // page 5 to become a page spread and gets pageNumber 6 // page 6 to become page 7 and become a Right page // page 7 to become page 8 and become a Left page // there will be a new KWPage for page 5 // all frames to be moved so they are still at the same relative location // to their original page' top KWPageStyle style3("dummy"); lay.leftMargin = -1; lay.rightMargin = -1; lay.pageEdge = 7; lay.bindingSide = 13; style2.setPageLayout(lay); KWPageStylePropertiesCommand cmd(&document, style, style3); cmd.redo(); QCOMPARE(manager->pageCount(), 7); QEXPECT_FAIL("", "Not done yet", Abort); QCOMPARE(p1.height(), 500.); QCOMPARE(p1.width(), 300.); QCOMPARE(p1.pageSide(), KWPage::Right); QCOMPARE(p1.pageNumber(), 1); QCOMPARE(p2.height(), 500.); QCOMPARE(p2.width(), 600.); QCOMPARE(p2.pageSide(), KWPage::PageSpread); QCOMPARE(p2.pageNumber(), 2); QVERIFY(!p3.isValid()); QCOMPARE(p4.pageSide(), KWPage::Left); QCOMPARE(p4.width(), 300.); QCOMPARE(p4.height(), 500.); QCOMPARE(p4.pageNumber(), 4); QCOMPARE(p5.width(), 600.); QCOMPARE(p5.height(), 500.); QCOMPARE(p5.pageSide(), KWPage::PageSpread); QCOMPARE(p5.pageNumber(), 6); QCOMPARE(p6.pageSide(), KWPage::Right); QCOMPARE(p6.width(), 400.); QCOMPARE(p6.pageNumber(), 7); QCOMPARE(p7.pageSide(), KWPage::Left); QCOMPARE(p7.width(), 400.); QCOMPARE(p7.pageNumber(), 8); KWPage newPage5 = manager->page(5); QCOMPARE(newPage5.pageStyle(), style); QCOMPARE(newPage5.width(), 400.); QCOMPARE(newPage5.height(), 400.); QCOMPARE(newPage5.pageSide(), KWPage::Left); QCOMPARE(fs->frames()[0]->shape()->position(), QPointF(-10, 10)); // TODO figure out what the actual numbers should be below QCOMPARE(fs->frames()[1]->shape()->position(), QPointF(-10, 10)); QCOMPARE(fs->frames()[2]->shape()->position(), QPointF(-10, 10)); QCOMPARE(fs->frames()[3]->shape()->position(), QPointF(-10, 10)); QCOMPARE(fs->frames()[4]->shape()->position(), QPointF(-10, 10)); QCOMPARE(fs->frames()[5]->shape()->position(), QPointF(-10, 10)); QCOMPARE(fs->frames()[6]->shape()->position(), QPointF(-10, 10)); }
void TestPageCommands::testPageStylePropertiesCommand2() { /* make setup where multiple, interspaced pages use the style we want to change. add some frames. check if the frames moved properly when the page gets a new size check that all pages got their new size check that the name of the style did not change */ KWDocument document; KWPageManager *manager = document.pageManager(); KWPageStyle style("pagestyle1"); KoPageLayout lay = style.pageLayout(); lay.width = 300; lay.height = 500; style.setPageLayout(lay); KWPageStyle style2("pagestyle2"); lay = style.pageLayout(); lay.width = 400; lay.height = 400; style2.setPageLayout(lay); KWPage p1 = manager->appendPage(style2); KWPage p2 = manager->appendPage(style); KWPage p3 = manager->appendPage(style); KWPage p4 = manager->appendPage(style2); KWPage p5 = manager->appendPage(style2); KWPage p6 = manager->appendPage(style); KWPage p7 = manager->appendPage(style); KWPage p8 = manager->appendPage(style); KWPage p9 = manager->appendPage(style2); QCOMPARE(manager->pageCount(), 9); KWFrameSet *fs = new KWFrameSet(); for (int i = 1; i <= manager->pageCount(); ++i) { // create one frame per page. Positioned relative to the top of the page. KWPage page = manager->page(i); QVERIFY(page.isValid()); MockShape *shape = new MockShape(); new KWFrame(shape, fs); shape->setPosition(QPointF(-10, page.offsetInDocument() + 10)); } document.addFrameSet(fs); // lets prepare to change the style to a new page size. KWPageStyle newStyle("foo"); lay = newStyle.pageLayout(); lay.width = 350; lay.height = 1000; newStyle.setPageLayout(lay); KWPageStylePropertiesCommand command(&document, style, newStyle); // nothing happens in constructor before redo; for (int i = 1; i <= manager->pageCount(); ++i) { KWPage page = manager->page(i); QVERIFY(page.height() <= 500); // not 1000 yet QVERIFY(page.isValid()); KoShape *shape = fs->frames().at(i-1)->shape(); QCOMPARE(shape->position(), QPointF(-10, page.offsetInDocument() + 10)); } const qreal lastPageOffset = p9.offsetInDocument(); command.redo(); QCOMPARE(manager->pageCount(), 9); QCOMPARE(p1.height(), 400.); QCOMPARE(p4.height(), 400.); QCOMPARE(p5.height(), 400.); QCOMPARE(p9.height(), 400.); QCOMPARE(p2.height(), 1000.); QCOMPARE(p3.height(), 1000.); QCOMPARE(p6.height(), 1000.); QCOMPARE(p7.height(), 1000.); QCOMPARE(p8.height(), 1000.); QCOMPARE(lastPageOffset + 2500, p9.offsetInDocument()); for (int i = 1; i <= manager->pageCount(); ++i) { KWPage page = manager->page(i); QVERIFY(page.isValid()); KoShape *shape = fs->frames().at(i-1)->shape(); QCOMPARE(shape->position(), QPointF(-10, page.offsetInDocument() + 10)); } }
QList<KWViewMode::ViewMap> KWViewModeNormal::mapExposedRects(const QRectF &viewRect, KoViewConverter *viewConverter) const { QList<ViewMap> answer; if (!viewConverter) return answer; #if 1 if (m_pageTops.isEmpty()) return answer; KWPage page = m_pageManager->begin(); const int pageOffset = page.pageNumber(); // Perform a binary search for page-index using our m_pageTops cache. int begin = 0; int end = m_pageTops.count() - 1; int index = 0; const qreal value = viewConverter->viewToDocument(viewRect.topLeft()).y(); if (m_pageTops.value(end) <= value) { // check extremes. Only end is needed since begin is zero. begin = end; index = end; } while (end - begin > 1) { index = begin + (end - begin) / 2; qreal diff = m_pageTops.value(index) - value; if (diff < 0) begin = index; else if (diff > 0) end = index; else break; } // index is now the number of the first possible page that can // contain the viewRect. The next step is to find the // corresponding Page. Since we have no way to get to the Nth // page directly we have to enumerate them from the beginning. // // We use 1 since we might hit a pagespread in the binary search, // so start one page early. while (index > 1) { page = page.next(); --index; } // From here we loop through some more pages after the found one // and see if they intersect with the page in question. When we // have two pages in row that don't intersect we break the loop. qreal offsetX = 0.0; int emptyPages = 0; for(; page.isValid(); page = page.next()) { Q_ASSERT_X(page.pageNumber()-pageOffset < m_pageTops.count(), __FUNCTION__, QString("Pagemanager has more pages than viewmode (%1>%2 with pageOffset=%3 and pageNumber=%4 and pageCount=%5). Make sure you add pages via the document!") .arg(page.pageNumber()-pageOffset).arg(m_pageTops.count()) .arg(pageOffset).arg(page.pageNumber()).arg(m_pageManager->pageCount()).toLocal8Bit()); // Some invariants const QRectF pageRect = page.rect(); const qreal offsetY = m_pageTops[page.pageNumber() - pageOffset] - pageRect.top(); bool pageIntersects = false; // 1. First handle the page itself. const QRectF zoomedPage = viewConverter->documentToView(pageRect); ViewMap vm; vm.page = page; //kDebug(32003) <<"page" << page.pageNumber(); vm.distance = viewConverter->documentToView(QPointF(offsetX, offsetY)); const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width(), zoomedPage.height()); QRectF intersection = targetPage.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm.distance); vm.clipRect = intersection.toRect(); answer.append(vm); pageIntersects = true; } // 2. Then handle the annotation area if annotations are active. // // The reason we don't do them together with the page // itself is because the pages have a gap between them, but // the annotation area should be unbroken. // // NOTE: 'annotation' below means the annotation area. // // FIXME: We should only do this if the annotation area is // actually shown. How can we inside the KWViewMode // know if annotations are active? if (1 /* annotations are shown */) { const QRectF annotationRect = pageRect.adjusted(page.width(), 0, KWCanvasBase::AnnotationAreaWidth, GAP); const QRectF zoomedAnnotation = viewConverter->documentToView(annotationRect); ViewMap vm2; vm2.page = page; vm2.distance = viewConverter->documentToView(QPointF(offsetX, offsetY)); const QRectF targetAnnotation(zoomedAnnotation.x() + vm2.distance.x(), zoomedAnnotation.y() + vm2.distance.y(), zoomedAnnotation.width(), zoomedAnnotation.height()); intersection = targetAnnotation.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm2.distance); vm2.clipRect = intersection.toRect(); answer.append(vm2); pageIntersects = true; } } // Record whether this page had an intersection with the view rect. if (pageIntersects) { emptyPages = 0; } else { ++emptyPages; } if (emptyPages > 2) // Since we show at max 2 pages side by side this is an easy rule break; if (m_pageSpreadMode) { if (page.pageSide() == KWPage::Left) offsetX = page.width() + GAP; else offsetX = 0.0; } } #else KWPage page = m_pageManager->begin(); Q_ASSERT(page.isValid()); qreal offsetX = 0.0; const int pageOffset = page.pageNumber(); for(; page.isValid(); page = page.next()) { const QRectF pageRect = page.rect(); const QRectF zoomedPage = viewConverter->documentToView(pageRect); ViewMap vm; vm.page = page; const qreal offsetY = m_pageTops[page.pageNumber() - pageOffset] - pageRect.top(); vm.distance = viewConverter->documentToView(QPointF(offsetX, offsetY)); #if 0 const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); QRectF intersection = targetPage.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm.distance); vm.clipRect = intersection.toRect(); answer.append(vm); } #else const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); vm.clipRect = targetPage.toRect(); answer.append(vm); #endif } #endif return answer; }
QList<KWViewMode::ViewMap> KWViewModeNormal::mapExposedRects(const QRectF &viewRect, KoViewConverter *viewConverter) const { QList<ViewMap> answer; if (!viewConverter) return answer; #if 1 if (m_pageTops.isEmpty()) return answer; KWPage page = m_pageManager->begin(); qreal offsetX = 0.0; const int pageOffset = page.pageNumber(); int begin = 0; int end = m_pageTops.count() - 1; int index = 0; const qreal value = viewConverter->viewToDocument(viewRect.topLeft()).y(); if (m_pageTops.value(end) <= value) { // check extremes. Only end is needed since begin is zero. begin = end; index = end; } while (end - begin > 1) { // binary search for page-index using our m_pageTops cache. index = begin + (end - begin) / 2; qreal diff = m_pageTops.value(index) - value; if (diff < 0) begin = index; else if (diff > 0) end = index; else break; } while (index > 1) { // 1 since we might hit a pagespread in the binary search, so start one page early page = page.next(); --index; } int emptyPages = 0; for(; page.isValid(); page = page.next()) { Q_ASSERT_X(page.pageNumber()-pageOffset < m_pageTops.count(), __FUNCTION__, QString("Pagemanager has more pages than viewmode (%1>%2 with pageOffset=%3 and pageNumber=%4 and pageCount=%5). Make sure you add pages via the document!") .arg(page.pageNumber()-pageOffset).arg(m_pageTops.count()).arg(pageOffset).arg(page.pageNumber()).arg(m_pageManager->pageCount()).toLocal8Bit()); const QRectF pageRect = page.rect(); const QRectF zoomedPage = viewConverter->documentToView(pageRect); ViewMap vm; vm.page = page; //kDebug(32003) <<"page" << page.pageNumber(); const qreal offsetY = m_pageTops[page.pageNumber() - pageOffset] - pageRect.top(); vm.distance = viewConverter->documentToView(QPointF(offsetX, offsetY)); const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); QRectF intersection = targetPage.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm.distance); vm.clipRect = intersection.toRect(); answer.append(vm); emptyPages = 0; } else { emptyPages++; } if (emptyPages > 2) // Since we show at max 2 pages side by side this is an easy rule break; if (m_pageSpreadMode) { if (page.pageSide() == KWPage::Left) offsetX = page.width() + GAP; else offsetX = 0.0; } } #else KWPage page = m_pageManager->begin(); Q_ASSERT(page.isValid()); qreal offsetX = 0.0; const int pageOffset = page.pageNumber(); for(; page.isValid(); page = page.next()) { const QRectF pageRect = page.rect(); const QRectF zoomedPage = viewConverter->documentToView(pageRect); ViewMap vm; vm.page = page; const qreal offsetY = m_pageTops[page.pageNumber() - pageOffset] - pageRect.top(); vm.distance = viewConverter->documentToView(QPointF(offsetX, offsetY)); #if 0 const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); QRectF intersection = targetPage.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm.distance); vm.clipRect = intersection.toRect(); answer.append(vm); } #else const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); vm.clipRect = targetPage.toRect(); answer.append(vm); #endif } #endif return answer; }
QList<KWViewMode::ViewMap> KWViewModeNormal::clipRectToDocument(const QRect &viewRect) const { QList<ViewMap> answer; if (m_pageTops.isEmpty()) return answer; KWPage page = m_pageManager->begin(); qreal offsetX = 0.0; const int pageOffset = page.pageNumber(); int begin = 0; int end = m_pageTops.count() - 1; int index = 0; const qreal value = m_viewConverter->viewToDocument(viewRect.topLeft()).y(); if (m_pageTops.value(end) <= value) { // check extremes. Only end is needed since begin is zero. begin = end; index = end; } while (end - begin > 1) { // binary search for page-index using our m_pageTops cache. index = begin + (end - begin) / 2; qreal diff = m_pageTops.value(index) - value; if (diff < 0) begin = index; else if (diff > 0) end = index; else break; } while (index > 1) { // 1 since we might hit a pagespread in the binary search, so start one page early page = page.next(); --index; if (page.pageSide() == KWPage::PageSpread) --index; } int emptyPages = 0; while (page.isValid()) { #ifndef NDEBUG if (page.pageNumber() - pageOffset >= m_pageTops.count()) { kWarning(32003) << "ERROR; pagemanager has more pages than viewmode (" << m_pageManager->pageCount() << ">" << m_pageTops.count() << "). Make sure you add pages via the document!"; break; } #endif const QRectF pageRect = page.rect(); const QRectF zoomedPage = m_viewConverter->documentToView(pageRect); ViewMap vm; vm.page = page; //kDebug(32003) <<"page" << page.pageNumber(); const qreal offsetY = m_pageTops[page.pageNumber() - pageOffset] - pageRect.top(); vm.distance = m_viewConverter->documentToView(QPointF(offsetX, offsetY)); const QRectF targetPage(zoomedPage.x() + vm.distance.x(), zoomedPage.y() + vm.distance.y(), zoomedPage.width() , zoomedPage.height()); QRectF intersection = targetPage.intersect(viewRect); if (! intersection.isEmpty()) { intersection.moveTopLeft(intersection.topLeft() - vm.distance); vm.clipRect = intersection.toRect(); answer.append(vm); emptyPages = 0; } else { emptyPages++; } if (emptyPages > 2) // Since we show at max 2 pages side by side this is an easy rule break; if (m_pageSpreadMode) { if (page.pageSide() == KWPage::Left) offsetX = page.width() + GAP; else offsetX = 0.0; } page = page.next(); } return answer; }
styles.insert(style5.name(), style5); KWPageManager manager; foreach (const QString &styleName, pages) { QVERIFY(styles.contains(styleName)); manager.appendPage(styles[styleName]); } m_frames.clear(); KWTextFrameSet tfs(0, (Words::TextFrameSetType) frameSetType); m_frames << &tfs; KWFrameLayout frameLayout(&manager, m_frames); connect(&frameLayout, SIGNAL(newFrameSet(KWFrameSet*)), this, SLOT(addFS(KWFrameSet*))); KWPage page = manager.page(pageNumber); QVERIFY(page.isValid()); tfs.setPageStyle(page.pageStyle()); frameLayout.createNewFramesForPage(pageNumber); QCOMPARE(tfs.frameCount(), expectedFrameCount); foreach(KoShape *shape, tfs.shapes()) { QVERIFY (page.rect().contains(shape->position())); } } void TestFrameLayout::testCopyFramesForPage() { Helper helper; m_frames.clear(); KWPage page = helper.pageManager->begin();