1 /* This file is part of the KDE project
2 Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org>
3 Copyright 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
4 Copyright 2003 Norbert Andres <nandres@web.de>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20 */
21
22 #ifndef CALLIGRA_SHEETS_STYLE
23 #define CALLIGRA_SHEETS_STYLE
24
25 #include <QFont>
26 #include <QSharedDataPointer>
27 #include <QTextCharFormat>
28
29 #include <KoXmlReader.h>
30
31 #include "Currency.h"
32 #include "Format.h"
33 #include "Global.h"
34
35 namespace Calligra
36 {
37 namespace Sheets
38 {
39 class Conditions;
40 class CustomStyle;
41 class SharedSubStyle;
42 class Style;
43 class StyleManager;
44 class SubStyle;
45 class ValueParser;
46
47 // used for preloading OASIS auto styles
48 typedef QHash<QString, Style> Styles;
49 // needs to be ordered (QMap) for the style dialog
50 typedef QMap<QString, CustomStyle*> CustomStyles;
51
52 CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
53
54 /**
55 * \ingroup Style
56 * A cell style.
57 */
58 class CALLIGRA_SHEETS_ODF_EXPORT Style
59 {
60 public:
61 enum HAlign {
62 Left = 1,
63 Center = 2,
64 Right = 3,
65 Justified = 4,
66 HAlignUndefined = 0
67 };
68
69 enum VAlign {
70 Top = 1,
71 Middle = 2,
72 Bottom = 3,
73 VDistributed = 4,
74 VJustified = 5,
75 VAlignUndefined = 0
76 };
77
78 enum FloatFormat {
79 DefaultFloatFormat = 0,
80 AlwaysSigned = 1,
81 AlwaysUnsigned = 2,
82 OnlyNegSigned = DefaultFloatFormat
83 };
84
85 enum FloatColor {
86 DefaultFloatColor = 0,
87 NegRed = 1,
88 AllBlack = DefaultFloatColor,
89 NegBrackets = 3,
90 NegRedBrackets = 4
91 };
92
93 /// The style type
94 enum StyleType {
95 BUILTIN, ///< built-in style (the default style)
96 CUSTOM, ///< custom style (defined in the StyleManager dialog)
97 AUTO, ///< automatically generated on cell format changes
98 TENTATIVE ///< @internal temporary state
99 };
100
101 enum Key {
102 // special cases
103 DefaultStyleKey,
104 /**
105 * The NamedStyleKey has two functions:
106 * \li In Style: On lookup the Style is composed (\see StyleStorage::composeStyle()).
107 * For named styles just the style's name is stored. On lookup, these styles
108 * are looked up in the StyleManager and their attributes, including all
109 * attributes of the parents, are filled in the composed style. Additionally,
110 * the name of the named style is stored in the NamedStyleKey attribute.
111 * This is especially useful while saving the styles.
112 * \li In CustomStyle: It simply refers to the parent style.
113 */
114 NamedStyleKey,
115 // borders
116 LeftPen,
117 RightPen,
118 TopPen,
119 BottomPen,
120 FallDiagonalPen,
121 GoUpDiagonalPen,
122 // layout
123 HorizontalAlignment,
124 VerticalAlignment,
125 MultiRow,
126 VerticalText,
127 Angle,
128 ShrinkToFit,
129 Indentation,
130 // content format
131 Prefix,
132 Postfix,
133 Precision,
134 ThousandsSep,
135 FormatTypeKey,
136 FloatFormatKey,
137 FloatColorKey,
138 CurrencyFormat,
139 CustomFormat,
140 // background
141 BackgroundBrush,
142 BackgroundColor,
143 // font
144 FontColor,
145 FontFamily,
146 FontSize,
147 FontBold,
148 FontItalic,
149 FontStrike,
150 FontUnderline,
151 //misc
152 DontPrintText,
153 NotProtected,
154 HideAll,
155 HideFormula
156 };
157
158 Style();
159 Style(const Style& style);
160 virtual ~Style();
161
162 virtual StyleType type() const;
163
164 QString parentName() const;
165 void setParentName(const QString& name);
166
167
168 bool loadXML(KoXmlElement& format, Paste::Mode pm = Paste::Normal);
169 void saveXML(QDomDocument& doc, QDomElement& format, const StyleManager* styleManager) const;
170
171 void clearAttribute(Key key);
172 bool hasAttribute(Key key) const;
173
174
175 uint bottomPenValue() const;
176 uint rightPenValue() const;
177 uint leftPenValue() const;
178 uint topPenValue() const;
179
180 QColor fontColor() const;
181 QColor backgroundColor() const;
182 QPen rightBorderPen() const;
183 QPen bottomBorderPen() const;
184 QPen leftBorderPen() const;
185 QPen topBorderPen() const;
186 QPen fallDiagonalPen() const;
187 QPen goUpDiagonalPen() const;
188 QBrush backgroundBrush() const;
189 QString customFormat() const;
190 QString prefix() const;
191 QString postfix() const;
192 QString fontFamily() const;
193
194 HAlign halign() const;
195 VAlign valign() const;
196 FloatFormat floatFormat() const;
197 FloatColor floatColor() const;
198 Format::Type formatType() const;
199
200 Currency currency() const;
201
202 QFont font() const;
203 bool bold() const;
204 bool italic() const;
205 bool underline() const;
206 bool strikeOut() const;
207 uint fontFlags() const;
208 int fontSize() const;
209 int precision() const;
210 bool thousandsSep() const;
211 int angle() const;
212 double indentation() const;
213 bool shrinkToFit() const;
214 bool verticalText() const;
215 bool wrapText() const;
216 bool printText() const;
217 bool hideAll() const;
218 bool hideFormula() const;
219 bool notProtected() const;
220 bool isDefault() const;
221 bool isEmpty() const;
222
223
224 public:
225 void setHAlign(HAlign align);
226 void setVAlign(VAlign align);
227 void setFont(QFont const & font);
228 void setFontFamily(QString const & fam);
229 void setFontBold(bool enable);
230 void setFontItalic(bool enable);
231 void setFontUnderline(bool enable);
232 void setFontStrikeOut(bool enable);
233 void setFontSize(int size);
234 void setFontColor(QColor const & color);
235 void setRightBorderPen(QPen const & pen);
236 void setBottomBorderPen(QPen const & pen);
237 void setLeftBorderPen(QPen const & pen);
238 void setTopBorderPen(QPen const & pen);
239 void setFallDiagonalPen(QPen const & pen);
240 void setGoUpDiagonalPen(QPen const & pen);
241 void setAngle(int angle);
242 void setIndentation(double indent);
243 void setBackgroundBrush(QBrush const & brush);
244 void setFloatFormat(FloatFormat format);
245 void setFloatColor(FloatColor color);
246 void setFormatType(Format::Type format);
247 void setCustomFormat(QString const & strFormat);
248 void setPrecision(int precision);
249 void setThousandsSep(bool thousandsSep);
250 void setPrefix(QString const & prefix);
251 void setPostfix(QString const & postfix);
252 void setCurrency(Currency const & currency);
253 void setWrapText(bool enable);
254 void setHideAll(bool enable);
255 void setHideFormula(bool enable);
256 void setNotProtected(bool enable);
257 void setDontPrintText(bool enable);
258 void setVerticalText(bool enable);
259 void setShrinkToFit(bool enable);
260 void setBackgroundColor(QColor const & color);
261 void setDefault();
262 void clear();
263
264 static bool compare(const SubStyle* one, const SubStyle* two);
265
266
267 /** Returns true if both styles have the same properties */
268 bool operator== (const Style& style) const;
269 inline bool operator!=(const Style& other) const {
270 return !operator==(other);
271 }
272 friend CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
273 void operator=(const Style& style);
274 Style operator-(const Style& style) const;
275 /// Insert and replace substyles from style
276 void merge(const Style& style);
277
278 /**
279 * The keys, that are contained in this style, but not in \p other and
280 * the keys, that are contained in both but differ in value.
281 * \return a set of keys, in which this style and \p other differ.
282 */
283 QSet<Key> difference(const Style& other) const;
284
285 void dump() const;
286
287 /**
288 * Return the properties of this style that can be represented as a QTextCharFormat
289 */
290 QTextCharFormat asCharFormat() const;
291
292 /** Defined style elements - used when saving the style */
293 virtual QSet<Style::Key> definedKeys(const StyleManager *) const;
294
295 protected:
296 QList<SharedSubStyle> subStyles() const;
297
298 SharedSubStyle createSubStyle(Key key, const QVariant& value);
299 virtual void insertSubStyle(Key key, const QVariant& value);
300 void insertSubStyle(const SharedSubStyle& subStyle);
301 bool releaseSubStyle(Key key);
302
303 private:
304 friend class StyleStorage;
305 friend class StyleStorageLoaderJob;
306 friend class BorderColorCommand;
307
308 class Private;
309 QSharedDataPointer<Private> d;
310 };
311
312
313
314 /**
315 * \ingroup Style
316 * A named cell style.
317 */
318 class CALLIGRA_SHEETS_ODF_EXPORT CustomStyle : public Style
319 {
320 public:
321 /**
322 * Constructor.
323 * Creates a custom style.
324 * \param name The name of this style.
325 * \param parent The style whose attributes are inherited - the parent style.
326 */
327 explicit CustomStyle(const QString& name, CustomStyle* parent = 0);
328 CustomStyle(const CustomStyle& style);
329 ~CustomStyle() override;
330 CustomStyle& operator=(const CustomStyle& other);
331
332 StyleType type() const override;
333 void setType(StyleType type);
334
335 void setName(QString const & name);
336 QString const & name() const;
337
338 bool loadXML(KoXmlElement const & style, QString const & name);
339 void save(QDomDocument & doc, QDomElement & styles, const StyleManager* styleManager);
340
341 //bool operator==(const CustomStyle& other) const;
342 //inline bool operator!=(const CustomStyle& other) const {
343 // return !operator==(other);
344 //}
345
346 /**
347 * @return the number of references to this style.
348 */
349 int usage() const;
350
351 QSet<Style::Key> definedKeys(const StyleManager *) const override;
352 private:
353 friend class StyleManager;
354
355 /**
356 * Constructor.
357 * Constructs the default cell style.
358 */
359 CustomStyle();
360
361 class Private;
362 QSharedDataPointer<Private> d;
363 };
364
365
366 /**
367 * \ingroup Style
368 * A single style attribute.
369 */
370 class CALLIGRA_SHEETS_ODF_TEST_EXPORT SubStyle : public QSharedData
371 {
372 public:
SubStyle()373 SubStyle() {}
~SubStyle()374 virtual ~SubStyle() {}
type()375 virtual Style::Key type() const {
376 return Style::DefaultStyleKey;
377 }
dump()378 virtual void dump() const {
379 debugSheetsStyle << debugData();
380 }
381 virtual QString debugData(bool withName = true) const {
382 QString out; if (withName) out = name(Style::DefaultStyleKey); return out;
383 }
koHash()384 virtual uint koHash() const { return uint(type()); }
385 static QString name(Style::Key key);
386 };
387
388 // Provides a default SubStyle for the tree.
389 // Otherwise, we would have QSharedDataPointer<SubStyle>() as default,
390 // which has a null pointer and crashes.
391 // Also, this makes the code more readable:
392 // QSharedDataPointer<SubStyle> vs. SharedSubStyle
393 class SharedSubStyle
394 {
395 public:
SharedSubStyle()396 inline SharedSubStyle() : d(s_defaultStyle.d){}
SharedSubStyle(SubStyle * subStyle)397 inline SharedSubStyle(SubStyle* subStyle) : d(subStyle) {}
398 inline const SubStyle *operator->() const {
399 return d.data();
400 }
data()401 inline const SubStyle *data() const {
402 return d.data();
403 }
404 inline bool operator<(const SharedSubStyle& o) const {
405 return d.data() < o.d.data();
406 }
407 inline bool operator==(const SharedSubStyle& o) const {
408 return d.data() == o.d.data();
409 }
410 inline bool operator!() const {
411 return !d;
412 }
413
414 private:
415 QSharedDataPointer<SubStyle> d;
416 static SharedSubStyle s_defaultStyle;
417 };
418
419 class NamedStyle : public SubStyle
420 {
421 public:
NamedStyle(const QString & n)422 NamedStyle(const QString& n) : SubStyle(), name(n) {}
type()423 Style::Key type() const override {
424 return Style::NamedStyleKey;
425 }
dump()426 void dump() const override {
427 debugSheetsStyle << debugData();
428 }
429 QString debugData(bool withName = true) const override {
430 QString out; if (withName) out = SubStyle::name(Style::NamedStyleKey) + ' '; out += name; return out;
431 }
koHash()432 uint koHash() const override { return uint(type()) ^ qHash(name); }
433 QString name;
434 };
435
436
qHash(const QColor & color)437 static inline uint qHash(const QColor& color)
438 { return uint(color.rgb()); }
439
qHash(const QPen & pen)440 static inline uint qHash(const QPen& pen)
441 { return qHash(pen.color()) ^ 37 * uint(pen.style()); }
442
qHash(const QBrush & brush)443 static inline uint qHash(const QBrush& brush)
444 { return qHash(brush.color()) ^ 91 * uint(brush.style()); }
445
446 template<Style::Key key, class Value1>
447 class SubStyleOne : public SubStyle
448 {
449 public:
SubStyle()450 SubStyleOne(const Value1& v = Value1()) : SubStyle(), value1(v) {}
type()451 Style::Key type() const override {
452 return key;
453 }
dump()454 void dump() const override {
455 debugSheetsStyle << debugData();
456 }
457 QString debugData(bool withName = true) const override {
458 QString out; if (withName) out = name(key) + ' '; QDebug qdbg(&out); qdbg << value1; return out;
459 }
koHash()460 uint koHash() const override { return uint(type()) ^ qHash(value1); }
461 Value1 value1;
462 };
463
464 } // namespace Sheets
465 } // namespace Calligra
466
467 Q_DECLARE_TYPEINFO(Calligra::Sheets::Style, Q_MOVABLE_TYPE);
468 Q_DECLARE_TYPEINFO(Calligra::Sheets::CustomStyle, Q_MOVABLE_TYPE);
469 Q_DECLARE_TYPEINFO(Calligra::Sheets::SharedSubStyle, Q_MOVABLE_TYPE);
470
471 CALLIGRA_SHEETS_ODF_TEST_EXPORT QDebug operator<<( QDebug dbg, const Calligra::Sheets::Style *style );
472 CALLIGRA_SHEETS_ODF_TEST_EXPORT QDebug operator<<( QDebug dbg, const Calligra::Sheets::Style &style );
473
474 #endif // CALLIGRA_SHEETS_STYLE
475