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(); } }
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.); }
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; }