Warning, file /office/calligra/libs/flake/KoMarkerData.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) 2011 Thorsten Zachmann <zachmann@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #include "KoMarkerData.h"
0021 
0022 #include <FlakeDebug.h>
0023 #include <KoStyleStack.h>
0024 #include <KoXmlNS.h>
0025 #include <KoUnit.h>
0026 #include <KoOdfLoadingContext.h>
0027 #include <KoGenStyle.h>
0028 #include "KoShapeLoadingContext.h"
0029 #include "KoMarker.h"
0030 #include "KoMarkerSharedLoadingData.h"
0031 
0032 /**
0033  * This defines the factor the width of the arrow is widened 
0034  * when the width of the line is changed.
0035  */
0036 static const qreal ResizeFactor = 1.5;
0037 
0038 static const struct {
0039     const char * m_markerPositionLoad;
0040     const char * m_markerWidthLoad;
0041     const char * m_markerCenterLoad;
0042     const char * m_markerPositionSave;
0043     const char * m_markerWidthSave;
0044     const char * m_markerCenterSave;
0045 } markerOdfData[] = {
0046     { "marker-start", "marker-start-width", "marker-start-center", "draw:marker-start", "draw:marker-start-width", "draw:marker-start-center" },
0047     { "marker-end"  , "marker-end-width",   "marker-end-center", "draw:marker-end"  , "draw:marker-end-width",   "draw:marker-end-center" }
0048 };
0049 
0050 class Q_DECL_HIDDEN KoMarkerData::Private
0051 {
0052 public:
0053     Private(KoMarker *marker, qreal baseWidth, KoMarkerData::MarkerPosition position, bool center)
0054     : marker(marker)
0055     , baseWidth(baseWidth)
0056     , position(position)
0057     , center(center)
0058     {}
0059 
0060     QExplicitlySharedDataPointer<KoMarker> marker;
0061     qreal baseWidth;
0062     MarkerPosition position;
0063     bool center;
0064 };
0065 
0066 KoMarkerData::KoMarkerData(KoMarker *marker, qreal width, MarkerPosition position, bool center)
0067 : d(new Private(marker, width, position, center))
0068 {
0069 }
0070 
0071 KoMarkerData::KoMarkerData(MarkerPosition position)
0072 : d(new Private(0, 0, position, false))
0073 {
0074 }
0075 
0076 KoMarkerData::KoMarkerData()
0077 : d(0)
0078 {
0079     Q_ASSERT(0);
0080 }
0081 
0082 KoMarkerData::KoMarkerData(const KoMarkerData &other)
0083 : d(new Private(other.d->marker.data(), other.d->baseWidth, other.d->position, other.d->center))
0084 {
0085 }
0086 
0087 KoMarkerData::~KoMarkerData()
0088 {
0089     delete d;
0090 }
0091 
0092 
0093 KoMarker *KoMarkerData::marker() const
0094 {
0095     return d->marker.data();
0096 }
0097 
0098 void KoMarkerData::setMarker(KoMarker *marker)
0099 {
0100     d->marker = QExplicitlySharedDataPointer<KoMarker>(marker);
0101 }
0102 
0103 qreal KoMarkerData::width(qreal penWidth) const
0104 {
0105     return d->baseWidth + penWidth * ResizeFactor;
0106 }
0107 
0108 void KoMarkerData::setWidth(qreal width, qreal penWidth)
0109 {
0110     d->baseWidth = qMax(qreal(0.0), width - penWidth * ResizeFactor);
0111 }
0112 
0113 KoMarkerData::MarkerPosition KoMarkerData::position() const
0114 {
0115     return d->position;
0116 }
0117 
0118 void KoMarkerData::setPosition(MarkerPosition position)
0119 {
0120     d->position = position;
0121 }
0122 
0123 bool KoMarkerData::center() const
0124 {
0125     return d->center;
0126 }
0127 
0128 void KoMarkerData::setCenter(bool center)
0129 {
0130     d->center = center;
0131 }
0132 
0133 KoMarkerData &KoMarkerData::operator=(const KoMarkerData &other)
0134 {
0135     if (this != &other) {
0136         d->marker = other.d->marker;
0137         d->baseWidth = other.d->baseWidth;
0138         d->position = other.d->position;
0139         d->center = other.d->center;
0140     }
0141     return (*this);
0142 }
0143 
0144 bool KoMarkerData::loadOdf(qreal penWidth, KoShapeLoadingContext &context)
0145 {
0146     KoMarkerSharedLoadingData *markerShared = dynamic_cast<KoMarkerSharedLoadingData*>(context.sharedData(MARKER_SHARED_LOADING_ID));
0147     if (markerShared) {
0148         KoStyleStack &styleStack = context.odfLoadingContext().styleStack();
0149         // draw:marker-end="Arrow" draw:marker-end-width="0.686cm" draw:marker-end-center="true"
0150         const QString markerStart(styleStack.property(KoXmlNS::draw, markerOdfData[d->position].m_markerPositionLoad));
0151         const QString markerStartWidth(styleStack.property(KoXmlNS::draw, markerOdfData[d->position].m_markerWidthLoad));
0152         if (!markerStart.isEmpty() && !markerStartWidth.isEmpty()) {
0153             KoMarker *marker = markerShared->marker(markerStart);
0154             if (marker) {
0155                 setMarker(marker);
0156                 qreal markerWidth = KoUnit::parseValue(markerStartWidth);
0157                 setWidth(markerWidth, penWidth);
0158                 setCenter(styleStack.property(KoXmlNS::draw, markerOdfData[d->position].m_markerCenterLoad) == "true");
0159             }
0160         }
0161     }
0162     return true;
0163 }
0164 
0165 void KoMarkerData::saveStyle(KoGenStyle &style, qreal penWidth, KoShapeSavingContext &context) const
0166 {
0167     if (d->marker) {
0168         QString markerRef = d->marker->saveOdf(context);
0169         style.addProperty(markerOdfData[d->position].m_markerPositionSave, markerRef, KoGenStyle::GraphicType);
0170         style.addPropertyPt(markerOdfData[d->position].m_markerWidthSave, width(penWidth), KoGenStyle::GraphicType);
0171         style.addProperty(markerOdfData[d->position].m_markerCenterSave, d->center, KoGenStyle::GraphicType);
0172     }
0173 }