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();
    }
}
示例#2
0
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;
    }
示例#3
0
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 {
 Helper() {
     pageManager = new KWPageManager();
     KWPage page = pageManager->appendPage();
     KoPageLayout pageLayout = page.pageStyle().pageLayout();
     pageLayout.width = 200;
     pageLayout.height = 200;
     page.pageStyle().setPageLayout(pageLayout);
     pageStyle = page.pageStyle();
 }
示例#5
0
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;
    }
KWChangePageStyleCommand::KWChangePageStyleCommand(KWDocument *document, KWPage &page, const KWPageStyle &newStyle, KUndo2Command *parent)
    : KUndo2Command(kundo2_i18n("Set Page Style"), parent),
    m_document(document),
    m_newStyle(newStyle),
    m_oldStyle(page.pageStyle()),
    m_page(page)
{
    Q_ASSERT(m_page.isValid());
}
void TestPageCommands::testInsertPageCommand3() // restore all properties
{
    KWDocument document;
    KWPageInsertCommand command1(&document, 0);
    command1.redo();

    KWPage page = command1.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);

    KWPageInsertCommand command2(&document, 1); // append one page.
    command2.redo();

    QCOMPARE(command2.page().pageStyle(), style);
    QCOMPARE(command2.page().width(), 400.);

    // undo and redo, remember order is important
    command2.undo();
    command1.undo();
    command1.redo();
    command2.redo();

    QVERIFY(command1.page() != page);
    QCOMPARE(command1.page().pageNumber(), 1);
    KWPageStyle style2 = command1.page().pageStyle();
    QCOMPARE(style2, style);
    QCOMPARE(style2.hasMainTextFrame(), false);
    QCOMPARE(style2.footnoteDistance(), 10.);
    KoPageLayout layout2 = style2.pageLayout();
    QCOMPARE(layout2, layout);

    QCOMPARE(command2.page().pageStyle(), style);
    QCOMPARE(command2.page().width(), 400.);
}
示例#8
0
void TestTextFrameSorting::testRtlSorting()
{
    KWTextFrameSet tfs(0);
    KWFrame * frame1 = createFrame(QPointF(10, 10), tfs);
    KWFrame * frame2 = createFrame(QPointF(120, 10), tfs);

    KWPageManager pm;
    KWPage page = pm.appendPage();
    page.setDirectionHint(KOdfText::RightLeftTopBottom);
    QCOMPARE(page.directionHint(), KOdfText::RightLeftTopBottom);
    KOdfPageLayoutData layout = page.pageStyle().pageLayout();
    layout.width = 200;
    page.pageStyle().setPageLayout(layout);
    tfs.setPageManager(&pm);

    qSort(tfs.m_frames.begin(), tfs.m_frames.end(), KWTextFrameSet::sortTextFrames);

    // in RTL columns also sort right-to-left
    QCOMPARE(tfs.m_frames[0], frame2);
    QCOMPARE(tfs.m_frames[1], frame1);
}
示例#9
0
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);
}
示例#10
0
void TestTextFrameSorting::testSortingOnPagespread()
{
    KWTextFrameSet tfs(0);
    KWFrame * frame1 = createFrame(QPointF(10, 200), tfs);
    KWFrame * frame2 = createFrame(QPointF(120, 10), tfs);
    KWFrame * frame3 = createFrame(QPointF(10, 10), tfs);
    KWFrame * frame4 = createFrame(QPointF(340, 10), tfs);
    KWFrame * frame5 = createFrame(QPointF(230, 10), tfs);

    KWPageManager pm;
    KWPage page = pm.appendPage();
    page.setPageNumber(2);
    KOdfPageLayoutData layout = page.pageStyle().pageLayout();
    layout.width = 450;
    layout.height = 150;
    page.setDirectionHint(KOdfText::LeftRightTopBottom);
    page.setPageSide(KWPage::PageSpread);
    page.pageStyle().setPageLayout(layout);
    page = pm.appendPage();
    page.setDirectionHint(KOdfText::LeftRightTopBottom);
    layout.width = 200;
    page.pageStyle().setPageLayout(layout);
    tfs.setPageManager(&pm);

    QCOMPARE(page.offsetInDocument(), 150.);

    // test KWPageManager::pageNumber first
    QCOMPARE(pm.begin().pageNumber(), 2);
    QCOMPARE(pm.pageNumber(frame2->shape()), 2);
    QCOMPARE(pm.pageNumber(frame1->shape()), 4);

    QCOMPARE(KWTextFrameSet::sortTextFrames(frame4, frame5), false);
    QCOMPARE(KWTextFrameSet::sortTextFrames(frame5, frame4), true);
    QCOMPARE(KWTextFrameSet::sortTextFrames(frame2, frame4), true);
    QCOMPARE(KWTextFrameSet::sortTextFrames(frame1, frame4), false);

    qSort(tfs.m_frames.begin(), tfs.m_frames.end(), KWTextFrameSet::sortTextFrames);

    QCOMPARE(tfs.m_frames[0], frame3);
    QCOMPARE(tfs.m_frames[1], frame2);
    QCOMPARE(tfs.m_frames[2], frame5);
    QCOMPARE(tfs.m_frames[3], frame4);
    QCOMPARE(tfs.m_frames[4], frame1);
}
示例#11
0
void KWFrameGeometry::open(KShape *shape)
{
    KWPage page = m_state->document()->pageManager()->page(shape);
    m_topOfPage = page.offsetInDocument();
    m_originalPosition = shape->position();
    m_originalSize = shape->size();
    QPointF position = shape->absolutePosition(widget.positionSelector->position());

    widget.xPos->changeValue(position.x());
    widget.yPos->changeValue(position.y() - m_topOfPage);
    widget.width->changeValue(m_originalSize.width());
    widget.height->changeValue(m_originalSize.height());

    if (m_frame == 0) {
        // default values for new frames
        widget.leftMargin->changeValue(MM_TO_POINT(3));
        widget.rightMargin->changeValue(MM_TO_POINT(3));
        widget.topMargin->changeValue(MM_TO_POINT(3));
        widget.bottomMargin->changeValue(MM_TO_POINT(3));
    }

    connect(widget.protectSize, SIGNAL(stateChanged(int)),
            this, SLOT(protectSizeChanged(int)));

    m_originalGeometryLock = shape->isGeometryProtected();
    if (m_originalGeometryLock) {
        widget.protectSize->setCheckState(Qt::Checked);
        KWTextFrame *tf = dynamic_cast<KWTextFrame*>(shape->applicationData());
        if (tf && static_cast<KWTextFrameSet*>(tf->frameSet())->textFrameSetType() != KWord::OtherTextFrameSet)
            widget.protectSize->setEnabled(false); // auto-generated frame, can't edit
    }

    connect(widget.xPos, SIGNAL(valueChanged(double)), this, SLOT(updateShape()));
    connect(widget.yPos, SIGNAL(valueChanged(double)), this, SLOT(updateShape()));
    connect(widget.width, SIGNAL(valueChanged(double)), this, SLOT(updateShape()));
    connect(widget.height, SIGNAL(valueChanged(double)), this, SLOT(updateShape()));
}
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.);
}
示例#13
0
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();
}
示例#14
0
void TestFrameLayout::headerPerPage()
{
    Helper helper;
    m_frames.clear();
    KWPage page = helper.pageManager->begin();
    KWFrameLayout bfl(helper.pageManager, m_frames);
    connect(&bfl, SIGNAL(newFrameSet(KWFrameSet*)), this, SLOT(addFS(KWFrameSet*)));

    KWPageStyle myStyle("myStyle");
    myStyle.setHeaderPolicy(Words::HFTypeUniform);
    helper.pageManager->addPageStyle(myStyle);
    KWPage page2 = helper.pageManager->appendPage(myStyle);
    QVERIFY(page.pageStyle() != page2.pageStyle());
    QCOMPARE(bfl.m_pageStyles.count(), 0);

    KWTextFrameSet *fs = bfl.getOrCreate(Words::OddPagesHeaderTextFrameSet, page);
    QVERIFY(fs);
    QCOMPARE(fs->textFrameSetType(), Words::OddPagesHeaderTextFrameSet);

    QCOMPARE(bfl.m_pageStyles.count(), 1);
    QVERIFY(bfl.m_pageStyles.contains(page.pageStyle()));
    KWFrameLayout::FrameSets fsets = bfl.m_pageStyles[page.pageStyle()];
    QCOMPARE(fsets.oddHeaders, fs);
    QCOMPARE(fsets.evenHeaders, (void*) 0);
    QCOMPARE(fsets.oddFooters, (void*) 0);
    QCOMPARE(fsets.evenFooters, (void*) 0);

    KWTextFrameSet *fs2 = bfl.getOrCreate(Words::OddPagesHeaderTextFrameSet, page2);
    QVERIFY(fs2);
    QCOMPARE(fs2->textFrameSetType(), Words::OddPagesHeaderTextFrameSet);

    QVERIFY(fs != fs2);
    QCOMPARE(bfl.getOrCreate(Words::OddPagesHeaderTextFrameSet, page2), fs2);
    QCOMPARE(bfl.getOrCreate(Words::OddPagesHeaderTextFrameSet, page), fs);

    QCOMPARE(bfl.m_pageStyles.count(), 2);
    QVERIFY(bfl.m_pageStyles.contains(page.pageStyle()));
    QVERIFY(bfl.m_pageStyles.contains(page2.pageStyle()));
    fsets = bfl.m_pageStyles[page.pageStyle()];
    QCOMPARE(fsets.oddHeaders, fs);
    QCOMPARE(fsets.evenHeaders, (void*) 0);
    QCOMPARE(fsets.oddFooters, (void*) 0);
    QCOMPARE(fsets.evenFooters, (void*) 0);
    KWFrameLayout::FrameSets fsets2 = bfl.m_pageStyles[page2.pageStyle()];
    QCOMPARE(fsets2.oddHeaders, fs2);
    QCOMPARE(fsets2.evenHeaders, (void*) 0);
    QCOMPARE(fsets2.oddFooters, (void*) 0);
    QCOMPARE(fsets2.evenFooters, (void*) 0);
}
示例#15
0
    style5.setColumns(columns);
    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();
示例#16
0
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;
}
示例#17
0
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;
}
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;
}
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));
    }
}
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));
}
QImage TextContentsModelImpl::thumbnail(int index, int width) const
{
    KWPage page = d->document->pageManager()->page( index + 1 );
    return page.thumbnail(QSize{ width, int((page.height() / page.width()) * width)}, d->canvas->shapeManager());
}