Warning, file /office/calligra/libs/text/KoAnchorInlineObject.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /* This file is part of the KDE project
0002  * Copyright (C) 2007, 2009-2010 Thomas Zander <zander@kde.org>
0003  * Copyright (C) 2010 Ko Gmbh <cbo@kogmbh.com>
0004  * Copyright (C) 2011 Matus Hanzes <matus.hanzes@ixonos.com>
0005  * Copyright (C) 2013 C. Boemann <cbo@boemann.dk>
0006  *
0007  * This library is free software; you can redistribute it and/or
0008  * modify it under the terms of the GNU Library General Public
0009  * License as published by the Free Software Foundation; either
0010  * version 2 of the License, or (at your option) any later version.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Library General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Library General Public License
0018  * along with this library; see the file COPYING.LIB.  If not, write to
0019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020  * Boston, MA 02110-1301, USA.
0021  */
0022 
0023 #include "KoAnchorInlineObject.h"
0024 #include "KoInlineObject_p.h"
0025 #include "KoShapeAnchor.h"
0026 
0027 #include <KoShapeSavingContext.h>
0028 #include <KoShapeLoadingContext.h>
0029 #include <KoShape.h>
0030 
0031 #include <QTextInlineObject>
0032 #include <QFontMetricsF>
0033 #include "TextDebug.h"
0034 
0035 // #define DEBUG_PAINTING
0036 
0037 class KoAnchorInlineObjectPrivate : public KoInlineObjectPrivate
0038 {
0039 public:
0040     KoAnchorInlineObjectPrivate(KoShapeAnchor *p)
0041         : parent(p)
0042         , document(0)
0043         , position(-1)
0044         , inlineObjectAscent(0)
0045         , inlineObjectDescent(0)
0046     {
0047     }
0048 
0049     KoShapeAnchor *parent;
0050     const QTextDocument *document;
0051     int position;
0052     QTextCharFormat format;
0053     qreal inlineObjectAscent;
0054     qreal inlineObjectDescent;
0055 };
0056 
0057 KoAnchorInlineObject::KoAnchorInlineObject(KoShapeAnchor *parent)
0058     : KoInlineObject(*(new KoAnchorInlineObjectPrivate(parent)), false)
0059 {
0060     Q_ASSERT(parent);
0061     parent->setTextLocation(this);
0062 }
0063 
0064 KoAnchorInlineObject::~KoAnchorInlineObject()
0065 {
0066 }
0067 
0068 KoShapeAnchor *KoAnchorInlineObject::anchor() const
0069 {
0070     Q_D(const KoAnchorInlineObject);
0071     return d->parent;
0072 }
0073 
0074 void KoAnchorInlineObject::updatePosition(const QTextDocument *document, int posInDocument, const QTextCharFormat &format)
0075 {
0076     Q_D(KoAnchorInlineObject);
0077     d->document = document;
0078     d->position = posInDocument;
0079     d->format = format;
0080     if (d->parent->placementStrategy() != 0) {
0081         d->parent->placementStrategy()->updateContainerModel();
0082     }
0083 }
0084 
0085 void KoAnchorInlineObject::resize(const QTextDocument *document, QTextInlineObject &object, int posInDocument, const QTextCharFormat &format, QPaintDevice *pd)
0086 {
0087     Q_UNUSED(document);
0088     Q_UNUSED(posInDocument);
0089     Q_D(KoAnchorInlineObject);
0090 
0091     if (!d->parent->shape()->isVisible()) {
0092         // Per default the shape this anchor presents is hidden and we only make it visible once an explicit resize-request
0093         // was made. This prevents shapes that are anchored at e.g. hidden textboxes to not become visible as long as they
0094         // are not asked to resize.
0095         d->parent->shape()->setVisible(true);
0096     }
0097 
0098     // important detail; top of anchored shape is at the baseline.
0099     QFontMetricsF fm(format.font(), pd);
0100     if (d->parent->anchorType() == KoShapeAnchor::AnchorAsCharacter) {
0101         QPointF offset = d->parent->offset();
0102         offset.setX(0);
0103         d->parent->setOffset(offset);
0104         object.setWidth(d->parent->shape()->size().width());
0105         if (d->parent->verticalRel() == KoShapeAnchor::VBaseline) {
0106             // baseline implies special meaning of the position attribute:
0107             switch (d->parent->verticalPos()) {
0108             case KoShapeAnchor::VFromTop:
0109                 object.setAscent(qMax((qreal) 0, -offset.y()));
0110                 object.setDescent(qMax((qreal) 0, d->parent->shape()->size().height() + offset.y()));
0111                 break;
0112             case KoShapeAnchor::VTop:
0113                 object.setAscent(d->parent->shape()->size().height());
0114                 object.setDescent(0);
0115                 break;
0116             case KoShapeAnchor::VMiddle:
0117                 object.setAscent(d->parent->shape()->size().height()/2);
0118                 object.setDescent(d->parent->shape()->size().height()/2);
0119                 break;
0120             case KoShapeAnchor::VBottom:
0121                 object.setAscent(0);
0122                 object.setDescent(d->parent->shape()->size().height());
0123                 break;
0124             default:
0125                 break;
0126             }
0127         } else {
0128             qreal boundTop = fm.ascent();
0129             switch (d->parent->verticalPos()) {
0130             case KoShapeAnchor::VFromTop:
0131                  object.setAscent(qMax((qreal) 0, -offset.y()));
0132                  object.setDescent(qMax((qreal) 0, d->parent->shape()->size().height() + offset.y()));
0133                  break;
0134             case KoShapeAnchor::VTop:
0135                 object.setAscent(boundTop);
0136                 object.setDescent(qMax((qreal) 0, d->parent->shape()->size().height() - boundTop));
0137                 break;
0138             case KoShapeAnchor::VMiddle:
0139                 object.setAscent(d->parent->shape()->size().height()/2);
0140                 object.setDescent(d->parent->shape()->size().height()/2);
0141                 break;
0142             case KoShapeAnchor::VBottom:
0143                 object.setAscent(0);
0144                 object.setDescent(d->parent->shape()->size().height());
0145                 break;
0146             default:
0147                 break;
0148             }
0149         }
0150         d->inlineObjectAscent = object.ascent();
0151         d->inlineObjectDescent = object.descent();
0152     } else {
0153         object.setWidth(0);
0154         object.setAscent(0);
0155         object.setDescent(0);
0156     }
0157 }
0158 
0159 void KoAnchorInlineObject::paint(QPainter &, QPaintDevice *, const QTextDocument *, const QRectF &, const QTextInlineObject &, int , const QTextCharFormat &)
0160 {
0161 }
0162 
0163 int KoAnchorInlineObject::position() const
0164 {
0165     Q_D(const KoAnchorInlineObject);
0166     return d->position;
0167 }
0168 
0169 const QTextDocument *KoAnchorInlineObject::document() const
0170 {
0171     Q_D(const KoAnchorInlineObject);
0172     return d->document;
0173 }
0174 
0175 qreal KoAnchorInlineObject::inlineObjectAscent() const
0176 {
0177     Q_D(const KoAnchorInlineObject);
0178     return d->inlineObjectAscent;
0179 }
0180 
0181 qreal KoAnchorInlineObject::inlineObjectDescent() const
0182 {
0183     Q_D(const KoAnchorInlineObject);
0184     return d->inlineObjectDescent;
0185 }
0186 
0187 bool KoAnchorInlineObject::loadOdf(const KoXmlElement &, KoShapeLoadingContext &)
0188 {
0189     // do nothing
0190     return true;
0191 }
0192 
0193 void KoAnchorInlineObject::saveOdf(KoShapeSavingContext &context)
0194 {
0195     Q_D(KoAnchorInlineObject);
0196     d->parent->saveOdf(context);
0197 }