File indexing completed on 2024-05-19 16:06:26

0001 /* This file is part of the KDE project
0002 
0003    Copyright 2017 Dag Andersen <danders@get2net.dk>
0004    Copyright 2010 Johannes Simon <johannes.simon@gmail.com>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License as published by the Free Software Foundation; either
0009    version 2 of the License, or (at your option) any later version.
0010 
0011    This library is distributed in the hope that it will be useful,
0012    but WITHOUT ANY WARRANTY; without even the implied warranty of
0013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014    Library General Public License for more details.
0015 
0016    You should have received a copy of the GNU Library General Public License
0017    along with this library; see the file COPYING.LIB.  If not, write to
0018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020 */
0021 
0022 #ifndef KCHART_LAYOUT_H
0023 #define KCHART_LAYOUT_H
0024 
0025 // Qt
0026 #include <QList>
0027 #include <QMap>
0028 #include <QSizeF>
0029 
0030 // Calligra
0031 #include <KoShapeContainerModel.h>
0032 #include <KoInsets.h>
0033 
0034 // KoChart
0035 #include "kochart_global.h"
0036 
0037 
0038 
0039 namespace KoChart {
0040 
0041 class PlotArea;
0042 
0043 /**
0044  * A generic chart-style layout with 10 possible positions:
0045  *
0046  *  ----------------------
0047  * | A |       D      | F |
0048  * |---|------------------|
0049  * |   |              |   |
0050  * | B |       I      | G |      (J)
0051  * |   |              |   |
0052  * |---|------------------|
0053  * | C |       E      | H |
0054  *  ----------------------
0055  *
0056  * A - TopStartPosition
0057  * B - StartPosition
0058  * C - BottomStartPosition
0059  * D - TopPosition
0060  * E - BottomPosition
0061  * F - TopEndPosition
0062  * G - EndPosition
0063  * H - BottomEndPosition
0064  * I - CenterPosition
0065  * J - FloatingPosition
0066  *
0067  * A chart can consist of the following elements:
0068  * 
0069  * Title: Positioned at the top in (D)
0070  * Sub-title: Positioned below Title in (D)
0071  * Footer: Position at the bottom in (E)
0072  * Legend: Positiond according to legend-position and alignmnent
0073  *         Note that Legend is the only component with this level of layout control from odf
0074  * 
0075  * Plot area: Positioned in the center (I)
0076  * Axes: Attached to the plot area
0077  * Axis title: Positioned beside the axis it describes
0078  * 
0079  * Each of these elements may be manually positioned and sized,
0080  * but by default the layouting does the job.
0081  */
0082 class ChartLayout : public KoShapeContainerModel
0083 {
0084 public:
0085     ChartLayout();
0086     ~ChartLayout();
0087 
0088     /**
0089      * Add @a shape and register it with GenericItemType
0090      * 
0091      * This is normally called from the resource manager.
0092      * 
0093      * Note that this shape will not be layed out until it gets a proper item type
0094      * set with setItemType()
0095      * 
0096      * Abstract in KoShapeContainerModel so needs to be here.
0097      * 
0098      * @see setItemType()
0099      */
0100     void add(KoShape *shape) override;
0101 
0102     /**
0103      * Removes a shape from the layout.
0104      */
0105     void remove(KoShape *shape) override;
0106 
0107     /**
0108      * Turns clipping of a shape on or off.
0109      */
0110     void setClipped(const KoShape *shape, bool clipping) override;
0111 
0112     /**
0113      * @see setClipping
0114      */
0115     bool isClipped(const KoShape *shape) const override;
0116 
0117     /// reimplemented
0118     void setInheritsTransform(const KoShape *shape, bool inherit) override;
0119     /// reimplemented
0120     bool inheritsTransform(const KoShape *shape) const override;
0121 
0122     /**
0123      * Returns the number of shapes in this layout.
0124      */
0125     int count() const override;
0126 
0127     /**
0128      * Returns a list of shapes in this layout.
0129      */
0130     QList<KoShape*> shapes() const override;
0131 
0132     /**
0133      * Called whenever a property of the container (i.e. the ChartShape) is changed.
0134      */
0135     void containerChanged(KoShapeContainer *container, KoShape::ChangeType type) override;
0136 
0137     /**
0138      * Returns whether a shape is locked for user modifications.
0139      */
0140     bool isChildLocked(const KoShape *shape) const override;
0141 
0142     /**
0143      * Changes the item type of the shape to @p itemType
0144      * The @p itemType controls where the shape is layed out
0145      */
0146     void setItemType(const KoShape *shape, ItemType itemType);
0147 
0148     void proposeMove(KoShape *child, QPointF &move) override;
0149 
0150     /**
0151      * Called whenever a property of a shape in this layout has changed.
0152      *
0153      * All layout items effected by this change will be re-layouted.
0154      */
0155     void childChanged(KoShape *shape, KoShape::ChangeType type) override;
0156 
0157     /**
0158      * Does the layouting of all visible shapes 
0159      *
0160      * Only does a relayout if one has been schedules previously through
0161      * scheduleRelayout().
0162      *
0163      * \see scheduleRelayout
0164      */
0165     void layout();
0166     /// Calculates the layout used by @a layout()
0167     void calculateLayout();
0168 
0169     /**
0170      * Schedules a relayout that is to be done when layout() is called.
0171      *
0172      * \see layout
0173      */
0174     void scheduleRelayout();
0175     /**
0176      * Sets the padding to @p padding that will be applied during layout
0177      */
0178     void setPadding (const KoInsets &padding);
0179     /// Returns the padding defined for this layout
0180     KoInsets padding() const;
0181     /// Set spacing in points to @p hSpacing, @p vSpacing to be used for this layout
0182     void setSpacing(qreal hSpacing, qreal vSpacing);
0183     /// Returns the horizontal and vertical spacing in points defined for this layout
0184     QPointF spacing() const;
0185 
0186     /// Enable/disable layouting (ex: used during odf loading)
0187     void setLayoutingEnabled(bool value);
0188 
0189 private:
0190     /// Set the chart size to @p size and schedule relayout
0191     void setContainerRect(const QRectF &rect);
0192 
0193     qreal xOffset(const QRectF &left, const QRectF &right, bool center = false) const;
0194     qreal yOffset(const QRectF &top, const QRectF &bottom, bool center = false) const;
0195 
0196     void rotateAxisTitles(PlotArea *plotarea);
0197 
0198     void layoutAxisTitles(int pos, const QMultiMap<int, KoShape*> &map, const QRectF &rect, const QRectF plotarea) const;
0199 
0200 #ifdef COMPILING_TESTS
0201 public:
0202 #endif
0203     QString dbg(const QList<KoShape*> &shapes) const;
0204     QString dbg(const KoShape *shape) const;
0205     static qreal relativePosition(qreal start1, qreal length1, qreal start2, qreal length2, qreal start, qreal length);
0206     static QPointF itemPosition(const KoShape *shape);
0207     static QSizeF  itemSize(const KoShape *shape);
0208     static void  setItemSize(KoShape *shape, const QSizeF &size);
0209     static QRectF  itemRect(const KoShape *shape);
0210     static void    setItemPosition(KoShape *shape, const QPointF& pos);
0211     /// Returns the plot area minus axis labels
0212     static QRectF diagramArea(const KoShape *shape);
0213     /// Returns the @p rect minus axis labels
0214     static QRectF diagramArea(const KoShape *shape, const QRectF &rect);
0215 
0216     static bool autoPosition(const KoShape *shape);
0217     static bool autoSize(const KoShape *shape);
0218 
0219 private:
0220     bool m_doingLayout;
0221     bool m_relayoutScheduled;
0222     QRectF m_containerRect;
0223     KoInsets m_padding;
0224     QPointF m_spacing;
0225     bool m_layoutingEnabled;
0226     class LayoutData;
0227     QMap<KoShape*, LayoutData*> m_layoutItems;
0228     QMap<int, KoShape*> m_shapes;
0229 };
0230 
0231 } // namespace KoChart
0232 
0233 #endif // KCHART_CHARTLAYOUT_H