1 /* This file is part of the KDE project
2  *
3  * Copyright (C) 2009 Inge wallin <inge@lysator.liu.se>
4  * Copyright (C) 2009 Thomas Zander <zander@kde.org>
5  * Copyright (C) 2011 Pierre Ducroquet <pinaraf@pinaraf.info>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 
24 #ifndef KOBORDER_H
25 #define KOBORDER_H
26 
27 #include "koodf_export.h"
28 
29 #include <QPen>
30 #include <QSharedData>
31 #include <QMetaType>
32 
33 #include "KoXmlReaderForward.h"
34 #include "KoGenStyle.h"
35 
36 class QPainter;
37 class KoStyleStack;
38 class KoBorderPrivate;
39 
40 class QColor;
41 
42 /**
43  * A container for all properties of a generic border as defined by ODF.
44  *
45  * A border is used in at least the following contexts:
46  *  - paragraph
47  *  - page
48  *  - table
49  *  - table cell
50  *
51  */
52 
53 class KOODF_EXPORT KoBorder
54 {
55 public:
56 
57     // Names of the border sides.
58     //
59     // The "rect" we refer to below is the rectangle around the object
60     // with the border. This could be a page, a cell, a paragraph, etc.
61     enum BorderSide {
62         TopBorder = 0, ///< References the border at the top of the rect
63         LeftBorder,    ///< References the border at the left side of the rect
64         BottomBorder,  ///< References the border at the bottom of the rect
65         RightBorder,   ///< References the border at the right side of the rect
66         TlbrBorder, ///< References the border from top left corner to bottom right corner of cell
67         BltrBorder  ///< References the border from bottom left corner to top right corner of cell
68     };
69 
70     /// Names of the different types of borders.
71     //
72     // Note that some of the border types are legacies from the old Words format.
73     enum BorderStyle {
74         BorderNone, ///< no border. This value forces the computed value of 'border-width' to be '0'.
75         BorderDotted,   ///< The border is a series of dots.
76         BorderDashed,   ///< The border is a series of short line segments.
77         BorderSolid,    ///< The border is a single line segment.
78         BorderDouble,   ///< The border is two solid lines. The sum of the two lines and the space between them equals the value of 'border-width'.
79         BorderGroove,   ///< The border looks as though it were carved into the canvas. (old words type)
80         BorderRidge,    ///< The opposite of 'groove': the border looks as though it were coming out of the canvas. (old words type)
81         BorderInset,    ///< The border makes the entire box look as though it were embedded in the canvas. (old words type)
82         BorderOutset,   ///< The opposite of 'inset': the border makes the entire box look as though it were coming out of the canvas. (old words type)
83 
84         BorderDashedLong,    ///< Dashed single border with long spaces
85         BorderTriple,    ///< Triple lined border
86         BorderSlash,    ///< slash border
87         BorderWave,    ///< wave border
88         BorderDoubleWave,    ///< double wave border
89 
90         // words legacy
91         BorderDashDot,
92         BorderDashDotDot
93     };
94 
95     /// Holds data about one border line.
96     struct KOODF_EXPORT BorderData {
97         BorderData();
98 
99         /// Compare the border data with another one
100         bool operator==(const BorderData &other) const;
101 
102         BorderStyle  style; ///< The border style. (see KoBorder::BorderStyle)
103         QPen outerPen;      ///< Holds the outer line when borderstyle is double and the whole line otherwise
104         QPen innerPen;      ///< Holds the inner line when borderstyle is double
105         qreal spacing;      ///< Holds the spacing between the outer and inner lines.
106     };
107 
108 
109     /// Constructor
110     KoBorder();
111     KoBorder(const KoBorder &kb);
112 
113     /// Destructor
114     ~KoBorder();
115 
116     /// Assignment
117     KoBorder &operator=(const KoBorder &other);
118 
119     /// Compare the border with another one
120     bool operator==(const KoBorder &other) const;
121     bool operator!=(const KoBorder &other) const { return !operator==(other); }
122 
123     void setBorderStyle(BorderSide side, BorderStyle style);
124     BorderStyle borderStyle(BorderSide side) const;
125     void setBorderColor(BorderSide side, const QColor &color);
126     QColor borderColor(BorderSide side) const;
127     void setBorderWidth(BorderSide side, qreal width);
128     qreal borderWidth(BorderSide side) const;
129     void setOuterBorderWidth(BorderSide side, qreal width);
130     qreal outerBorderWidth(BorderSide side) const;
131     void setInnerBorderWidth(BorderSide side, qreal width);
132     qreal innerBorderWidth(BorderSide side) const;
133     void setBorderSpacing(BorderSide side, qreal width);
134     qreal borderSpacing(BorderSide side) const;
135 
136     BorderData borderData(BorderSide side) const;
137     void setBorderData(BorderSide side, const BorderData &data);
138 
139     bool hasBorder() const;
140     bool hasBorder(BorderSide side) const;
141 
142     enum BorderPaintArea {
143         PaintOnLine,
144         PaintInsideLine
145     };
146     void paint(QPainter &painter, const QRectF &borderRect,
147                BorderPaintArea whereToPaint = PaintInsideLine) const;
148 
149     /**
150      * Load the style from the element
151      *
152      * @param style  the element containing the style to read from
153      * @return true when border attributes were found
154      */
155     bool loadOdf(const KoXmlElement &style);
156     bool loadOdf(const KoStyleStack &styleStack);
157     void saveOdf(KoGenStyle &style, KoGenStyle::PropertyType type = KoGenStyle::DefaultType) const;
158 
159 
160     // Some public functions used in other places where borders are handled.
161     // Example: KoParagraphStyle
162     // FIXME: These places should be made to use KoBorder instead.
163     static BorderStyle odfBorderStyle(const QString &borderstyle, bool *converted = 0);
164     static QString odfBorderStyleString(BorderStyle borderstyle);
165     static QString msoBorderStyleString(BorderStyle borderstyle);
166 
167  private:
168     void paintBorderSide(QPainter &painter, QPointF lineStart, QPointF lineEnd,
169                          BorderData *borderData, bool isVertical,
170                          BorderData *neighbour1, BorderData *neighbor2,
171                          int inwardsAcross) const;
172 
173     void parseAndSetBorder(const QString &border,
174                            bool hasSpecialBorder, const QString &specialBorderString);
175     void parseAndSetBorder(const BorderSide borderSide, const QString &border,
176                            bool hasSpecialBorder, const QString &specialBorderString);
177 
178 private:
179     QSharedDataPointer<KoBorderPrivate> d;
180 };
181 
182 Q_DECLARE_METATYPE(KoBorder)
183 
184 
185 #endif
186