SimpleRootAreaProvider.cpp 7.12 KB
Newer Older
1
/* This file is part of the KDE project
C. Boemann's avatar
C. Boemann committed
2
 * Copyright (C) 2011 C. Boemann <cbo@boemann.dk>
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "SimpleRootAreaProvider.h"

#include "TextShape.h"

24
#include <KoBorder.h>
25 26 27
#include <KoTextLayoutRootArea.h>
#include <KoTextLayoutObstruction.h>

28
SimpleRootAreaProvider::SimpleRootAreaProvider(KoTextShapeData *data, TextShape *textshape)
29
    : m_textShape(textshape)
30
    , m_area(0)
31
    , m_textShapeData(data)
32
    , m_fixAutogrow(false)
33

34 35 36
{
}

37
KoTextLayoutRootArea *SimpleRootAreaProvider::provide(KoTextDocumentLayout *documentLayout, const RootAreaConstraint &, int requestedPosition, bool *isNewRootArea)
38
{
39
    if (m_area == 0) {
40
        *isNewRootArea = true;
41
        m_area = new KoTextLayoutRootArea(documentLayout);
42 43
        m_area->setAssociatedShape(m_textShape);
        m_textShapeData->setRootArea(m_area);
44

45
        return m_area;
46
    }
47 48
    if (requestedPosition == 0) {
        *isNewRootArea = false;
Jarosław Staniek's avatar
Jarosław Staniek committed
49
        return m_area;
50
    }
51 52 53 54 55
    return 0;
}

void SimpleRootAreaProvider::releaseAllAfter(KoTextLayoutRootArea *afterThis)
{
Sebastian Sauer's avatar
Sebastian Sauer committed
56
    Q_UNUSED(afterThis);
57
}
58

59
void SimpleRootAreaProvider::doPostLayout(KoTextLayoutRootArea *rootArea, bool isNewRootArea)
60
{
61 62
    Q_UNUSED(isNewRootArea);

63
    m_textShape->update();
Casper Boemann's avatar
Casper Boemann committed
64

65
    QSizeF newSize = m_textShape->size()
66 67
                     - QSizeF(m_textShapeData->leftPadding() + m_textShapeData->rightPadding(),
                              m_textShapeData->topPadding() + m_textShapeData->bottomPadding());
68

69 70 71 72 73 74
    KoBorder *border = m_textShape->border();

    if (border) {
        newSize -= QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder));
    }

75
    if (m_textShapeData->verticalAlignment() & Qt::AlignBottom) {
76
        // Do nothing
77 78
    }
    if (m_textShapeData->verticalAlignment() & Qt::AlignVCenter) {
79
        // Do nothing
80
    }
81
    if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight
82
            || m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowHeight) {
83 84
        qreal height = rootArea->bottom() - rootArea->top();
        if (height > newSize.height()) {
85
            newSize.setHeight(height);
86 87 88 89 90
        }
        if (m_textShape->shapeId() == "AnnotationTextShapeID") {
            if (height < newSize.height()) {
                newSize.setHeight(rootArea->bottom() - rootArea->top());
            }
91
        }
Casper Boemann's avatar
Casper Boemann committed
92 93
    }
    if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight
94
            || m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidth) {
95
        qreal width = rootArea->right() - rootArea->left();
96 97 98
        if (width > newSize.width()) {
            newSize.setWidth(rootArea->right() - rootArea->left());
        }
Casper Boemann's avatar
Casper Boemann committed
99
    }
100

101
    qreal newBottom = rootArea->top() + newSize.height();
102
    KoFlake::AnchorPosition sizeAnchor = KoFlake::TopLeft;
103 104 105 106

    if (m_textShapeData->verticalAlignment() & Qt::AlignBottom) {
        if (true /*FIXME test no page based shapes interfering*/) {
            rootArea->setVerticalAlignOffset(newBottom - rootArea->bottom());
107
            sizeAnchor = KoFlake::BottomLeft;
108 109 110 111 112
        }
    }
    if (m_textShapeData->verticalAlignment() & Qt::AlignVCenter) {
        if (true /*FIXME test no page based shapes interfering*/) {
            rootArea->setVerticalAlignOffset((newBottom - rootArea->bottom()) / 2);
113
            sizeAnchor = KoFlake::Center;
114 115
        }
    }
116 117
    newSize += QSizeF(m_textShapeData->leftPadding() + m_textShapeData->rightPadding(),
                      m_textShapeData->topPadding() + m_textShapeData->bottomPadding());
118 119 120 121 122
    if (border) {
        newSize += QSizeF(border->borderWidth(KoBorder::LeftBorder) + border->borderWidth(KoBorder::RightBorder), border->borderWidth(KoBorder::TopBorder) + border->borderWidth(KoBorder::BottomBorder));
    }

    if (newSize != m_textShape->size()) {
123 124 125 126
        // OO grows to both sides so when to small the initial layouting needs
        // to keep that into account.
        if (m_fixAutogrow) {
            m_fixAutogrow = false;
127
            QSizeF tmpSize = m_textShape->size();
128
            tmpSize.setWidth(newSize.width());
129
            QPointF centerpos = rootArea->associatedShape()->absolutePosition(KoFlake::Center);
130
            m_textShape->setSize(tmpSize);
131
            m_textShape->setAbsolutePosition(centerpos, KoFlake::Center);
132
            centerpos = rootArea->associatedShape()->absolutePosition(sizeAnchor);
133 134
            m_textShape->setSize(newSize);
            m_textShape->setAbsolutePosition(centerpos, sizeAnchor);
135
        }
136
        m_textShape->setSize(newSize);
137 138
    }

139
    m_textShape->update();
140
}
141

142 143 144 145 146 147 148
void SimpleRootAreaProvider::updateAll()
{
    if (m_area && m_area->associatedShape()) {
        m_area->associatedShape()->update();
    }
}

149
QRectF SimpleRootAreaProvider::suggestRect(KoTextLayoutRootArea *rootArea)
150
{
151 152 153 154 155 156 157 158
    //Come up with a rect, but actually we don't need the height, as we set it to infinite below
    // Still better keep it for completeness sake
    QRectF rect(QPointF(), m_textShape->size());
    rect.adjust(m_textShapeData->leftPadding(), m_textShapeData->topPadding(), -m_textShapeData->rightPadding(), - m_textShapeData->bottomPadding());

    KoBorder *border = m_textShape->border();
    if (border) {
        rect.adjust(border->borderWidth(KoBorder::LeftBorder),  border->borderWidth(KoBorder::TopBorder),
159
                    -border->borderWidth(KoBorder::RightBorder), - border->borderWidth(KoBorder::BottomBorder));
160
    }
161

Casper Boemann's avatar
Casper Boemann committed
162 163
    // In simple cases we always set height way too high so that we have no breaking
    // If the shape grows afterwards or not is handled in doPostLayout()
164
    rect.setHeight(1E6);
Casper Boemann's avatar
Casper Boemann committed
165

166
    if (m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidthAndHeight
167
            || m_textShapeData->resizeMethod() == KoTextShapeData::AutoGrowWidth) {
Casper Boemann's avatar
Casper Boemann committed
168
        rootArea->setNoWrap(1E6);
169
    }
Thorsten Zachmann's avatar
Thorsten Zachmann committed
170 171 172 173 174 175

    // Make sure the size is not negative due to padding and border with
    // This can happen on vertical lines containing text on shape.
    if (rect.width() < 0) {
        rect.setWidth(0);
    }
176
    return rect;
177
}
178

179
QList<KoTextLayoutObstruction *> SimpleRootAreaProvider::relevantObstructions(KoTextLayoutRootArea *rootArea)
180
{
Sebastian Sauer's avatar
Sebastian Sauer committed
181 182
    Q_UNUSED(rootArea);

183 184 185 186 187 188
    QList<KoTextLayoutObstruction *> obstructions;
    /*
        m_textShape->boundingRect();
        QList<KoShape *> shapes;
        shapes = manager->shapesAt(canvasRect):
    */
189 190
    return obstructions;
}