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
35class KoGenStyle;
36class KoGenStyles;
37class KoOdfStylesReader;
38class KoStyleStack;
39
40namespace Calligra
41{
42namespace Sheets
43{
44class Conditions;
45class CustomStyle;
46class SharedSubStyle;
47class Style;
48class StyleManager;
49class StyleManipulator;
50class SubStyle;
51class ValueParser;
52
53// used for preloading OASIS auto styles
54typedef QHash<QString, Style> Styles;
55// needs to be ordered (QMap) for the style dialog
56typedef QMap<QString, CustomStyle*> CustomStyles;
57
58CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
59
60/**
61 * \ingroup Style
62 * A cell style.
63 */
64class CALLIGRA_SHEETS_ODF_EXPORT Style
65{
66public:
67 enum HAlign {
68 Left = 1,
69 Center = 2,
70 Right = 3,
71 Justified = 4,
72 HAlignUndefined = 0
73 };
74
75 enum VAlign {
76 Top = 1,
77 Middle = 2,
78 Bottom = 3,
79 VDistributed = 4,
80 VJustified = 5,
81 VAlignUndefined = 0
82 };
83
84 enum FloatFormat {
85 DefaultFloatFormat = 0,
86 AlwaysSigned = 1,
87 AlwaysUnsigned = 2,
88 OnlyNegSigned = DefaultFloatFormat
89 };
90
91 enum FloatColor {
92 DefaultFloatColor = 0,
93 NegRed = 1,
94 AllBlack = DefaultFloatColor,
95 NegBrackets = 3,
96 NegRedBrackets = 4
97 };
98
99 /// The style type
100 enum StyleType {
101 BUILTIN, ///< built-in style (the default style)
102 CUSTOM, ///< custom style (defined in the StyleManager dialog)
103 AUTO, ///< automatically generated on cell format changes
104 TENTATIVE ///< @internal temporary state
105 };
106
107 enum Key {
108 // special cases
109 DefaultStyleKey,
110 /**
111 * The NamedStyleKey has two functions:
112 * \li In Style: On lookup the Style is composed (\see StyleStorage::composeStyle()).
113 * For named styles just the style's name is stored. On lookup, these styles
114 * are looked up in the StyleManager and their attributes, including all
115 * attributes of the parents, are filled in the composed style. Additionally,
116 * the name of the named style is stored in the NamedStyleKey attribute.
117 * This is especially useful while saving the styles.
118 * \li In CustomStyle: It simply refers to the parent style.
119 */
120 NamedStyleKey,
121 // borders
122 LeftPen,
123 RightPen,
124 TopPen,
125 BottomPen,
126 FallDiagonalPen,
127 GoUpDiagonalPen,
128 // layout
129 HorizontalAlignment,
130 VerticalAlignment,
131 MultiRow,
132 VerticalText,
133 Angle,
134 ShrinkToFit,
135 Indentation,
136 // content format
137 Prefix,
138 Postfix,
139 Precision,
140 ThousandsSep,
141 FormatTypeKey,
142 FloatFormatKey,
143 FloatColorKey,
144 CurrencyFormat,
145 CustomFormat,
146 // background
147 BackgroundBrush,
148 BackgroundColor,
149 // font
150 FontColor,
151 FontFamily,
152 FontSize,
153 FontBold,
154 FontItalic,
155 FontStrike,
156 FontUnderline,
157 //misc
158 DontPrintText,
159 NotProtected,
160 HideAll,
161 HideFormula
162 };
163
164 Style();
165 Style(const Style& style);
166 virtual ~Style();
167
168 virtual StyleType type() const;
169
170 QString parentName() const;
171 void setParentName(const QString& name);
172
173
174 bool loadXML(KoXmlElement& format, Paste::Mode pm = Paste::Normal);
175 void saveXML(QDomDocument& doc, QDomElement& format, const StyleManager* styleManager) const;
176 void loadOdfStyle(KoOdfStylesReader& stylesReader, const KoXmlElement& element,
177 Conditions& conditions, const StyleManager* styleManager,
178 const ValueParser *parser);
179 void loadOdfDataStyle(KoOdfStylesReader& stylesReader, const QString& dataStyleName,
180 Conditions& conditions, const StyleManager* styleManager,
181 const ValueParser *parser);
182
183 /**
184 * Saves an OASIS automatic style.
185 * Reimplemented by CustomStyle for OASIS user styles.
186 * \return the OASIS style's name
187 */
188 virtual QString saveOdf(KoGenStyle& style, KoGenStyles& mainStyles,
189 const StyleManager* manager) const;
190
191
192 void clearAttribute(Key key);
193 bool hasAttribute(Key key) const;
194 void loadAttributes(const QList<SharedSubStyle>& subStyles);
195
196
197 uint bottomPenValue() const;
198 uint rightPenValue() const;
199 uint leftPenValue() const;
200 uint topPenValue() const;
201
202 QColor fontColor() const;
203 QColor backgroundColor() const;
204 QPen rightBorderPen() const;
205 QPen bottomBorderPen() const;
206 QPen leftBorderPen() const;
207 QPen topBorderPen() const;
208 QPen fallDiagonalPen() const;
209 QPen goUpDiagonalPen() const;
210 QBrush backgroundBrush() const;
211 QString customFormat() const;
212 QString prefix() const;
213 QString postfix() const;
214 QString fontFamily() const;
215
216 HAlign halign() const;
217 VAlign valign() const;
218 FloatFormat floatFormat() const;
219 FloatColor floatColor() const;
220 Format::Type formatType() const;
221
222 Currency currency() const;
223
224 QFont font() const;
225 bool bold() const;
226 bool italic() const;
227 bool underline() const;
228 bool strikeOut() const;
229 uint fontFlags() const;
230 int fontSize() const;
231 int precision() const;
232 bool thousandsSep() const;
233 int angle() const;
234 double indentation() const;
235 bool shrinkToFit() const;
236 bool verticalText() const;
237 bool wrapText() const;
238 bool printText() const;
239 bool hideAll() const;
240 bool hideFormula() const;
241 bool notProtected() const;
242 bool isDefault() const;
243 bool isEmpty() const;
244
245protected:
246 /**
247 * Helper function for saveOdf
248 * Does the real work by determining the used attributes.
249 */
250 void saveOdfStyle(const QSet<Key>& subStyles, KoGenStyle &style,
251 KoGenStyles &mainStyles, const StyleManager* manager) const;
252
253 void loadOdfDataStyle(KoOdfStylesReader& stylesReader, const KoXmlElement& element,
254 Conditions& conditions, const StyleManager* styleManager,
255 const ValueParser *parser);
256 void loadOdfParagraphProperties(KoOdfStylesReader& stylesReader, const KoStyleStack& element);
257 void loadOdfTableCellProperties(KoOdfStylesReader& stylesReader, const KoStyleStack& element);
258 void loadOdfTextProperties(KoOdfStylesReader& stylesReader, const KoStyleStack& element);
259
260public:
261 void setHAlign(HAlign align);
262 void setVAlign(VAlign align);
263 void setFont(QFont const & font);
264 void setFontFamily(QString const & fam);
265 void setFontBold(bool enable);
266 void setFontItalic(bool enable);
267 void setFontUnderline(bool enable);
268 void setFontStrikeOut(bool enable);
269 void setFontSize(int size);
270 void setFontColor(QColor const & color);
271 void setRightBorderPen(QPen const & pen);
272 void setBottomBorderPen(QPen const & pen);
273 void setLeftBorderPen(QPen const & pen);
274 void setTopBorderPen(QPen const & pen);
275 void setFallDiagonalPen(QPen const & pen);
276 void setGoUpDiagonalPen(QPen const & pen);
277 void setAngle(int angle);
278 void setIndentation(double indent);
279 void setBackgroundBrush(QBrush const & brush);
280 void setFloatFormat(FloatFormat format);
281 void setFloatColor(FloatColor color);
282 void setFormatType(Format::Type format);
283 void setCustomFormat(QString const & strFormat);
284 void setPrecision(int precision);
285 void setThousandsSep(bool thousandsSep);
286 void setPrefix(QString const & prefix);
287 void setPostfix(QString const & postfix);
288 void setCurrency(Currency const & currency);
289 void setWrapText(bool enable);
290 void setHideAll(bool enable);
291 void setHideFormula(bool enable);
292 void setNotProtected(bool enable);
293 void setDontPrintText(bool enable);
294 void setVerticalText(bool enable);
295 void setShrinkToFit(bool enable);
296 void setBackgroundColor(QColor const & color);
297 void setDefault();
298 void clear();
299
300
301 // static functions
302 //
303 static Format::Type dateType(const QString&);
304 static Format::Type timeType(const QString&);
305 static Format::Type fractionType(const QString&);
306 static Format::Type numberType(const QString&);
307 static Currency numberCurrency(const QString&);
308
309 /**
310 * @return the name of the data style (number, currency, percentage, date,
311 * boolean, text)
312 */
313 static QString saveOdfStyleNumeric(KoGenStyle &style, KoGenStyles &mainStyles, Format::Type _style,
314 const QString &_prefix, const QString &_postfix, int _precision, const QString& symbol,
315 bool thousandsSep);
316 static QString saveOdfStyleNumericDate(KoGenStyles &mainStyles, Format::Type _style,
317 const QString &_prefix, const QString &_suffix);
318 static QString saveOdfStyleNumericFraction(KoGenStyles &mainStyles, Format::Type _style,
319 const QString &_prefix, const QString &_suffix);
320 static QString saveOdfStyleNumericTime(KoGenStyles& mainStyles, Format::Type _style,
321 const QString &_prefix, const QString &_suffix);
322 static QString saveOdfStyleNumericCustom(KoGenStyles&mainStyles, Format::Type _style,
323 const QString &_prefix, const QString &_suffix);
324 static QString saveOdfStyleNumericScientific(KoGenStyles&mainStyles, Format::Type _style,
325 const QString &_prefix, const QString &_suffix, int _precision, bool thousandsSep);
326 static QString saveOdfStyleNumericPercentage(KoGenStyles&mainStyles, Format::Type _style, int _precision,
327 const QString &_prefix, const QString &_suffix);
328 static QString saveOdfStyleNumericMoney(KoGenStyles&mainStyles, Format::Type _style,
329 const QString& symbol, int _precision,
330 const QString &_prefix, const QString &_suffix);
331 static QString saveOdfStyleNumericText(KoGenStyles&mainStyles, Format::Type _style, int _precision,
332 const QString &_prefix, const QString &_suffix);
333 static QString saveOdfStyleNumericNumber(KoGenStyles&mainStyles, Format::Type _style, int _precision,
334 const QString &_prefix, const QString &_suffix, bool thousandsSep);
335 static QString saveOdfBackgroundStyle(KoGenStyles &mainStyles, const QBrush &brush);
336
337 /**
338 * Returns the name of a color. This is the same as returned by QColor::name, but an internal cache
339 * is used to reduce the overhead when asking for the name of the same color.
340 */
341 static QString colorName(const QColor& color);
342
343 static bool compare(const SubStyle* one, const SubStyle* two);
344
345
346 /** Returns true if both styles have the same properties */
347 bool operator== (const Style& style) const;
348 inline bool operator!=(const Style& other) const {
349 return !operator==(other);
350 }
351 friend CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
352 void operator=(const Style& style);
353 Style operator-(const Style& style) const;
354 void merge(const Style& style);
355
356 /**
357 * The keys, that are contained in this style, but not in \p other and
358 * the keys, that are contained in both but differ in value.
359 * \return a set of keys, in which this style and \p other differ.
360 */
361 QSet<Key> difference(const Style& other) const;
362
363 void dump() const;
364
365 /**
366 * Return the properties of this style that can be represented as a QTextCharFormat
367 */
368 QTextCharFormat asCharFormat() const;
369protected:
370 QList<SharedSubStyle> subStyles() const;
371
372 SharedSubStyle createSubStyle(Key key, const QVariant& value);
373 virtual void insertSubStyle(Key key, const QVariant& value);
374 void insertSubStyle(const SharedSubStyle& subStyle);
375 bool releaseSubStyle(Key key);
376
377private:
378 friend class StyleStorage;
379 friend class StyleStorageLoaderJob;
380 friend class BorderColorCommand;
381
382 class Private;
383 QSharedDataPointer<Private> d;
384};
385
386
387
388/**
389 * \ingroup Style
390 * A named cell style.
391 */
392class CALLIGRA_SHEETS_ODF_EXPORT CustomStyle : public Style
393{
394public:
395 /**
396 * Constructor.
397 * Creates a custom style.
398 * \param name The name of this style.
399 * \param parent The style whose attributes are inherited - the parent style.
400 */
401 explicit CustomStyle(const QString& name, CustomStyle* parent = 0);
402 CustomStyle(const CustomStyle& style);
403 virtual ~CustomStyle();
404 CustomStyle& operator=(const CustomStyle& other);
405
406 virtual StyleType type() const;
407 void setType(StyleType type);
408
409 void setName(QString const & name);
410 QString const & name() const;
411
412 bool loadXML(KoXmlElement const & style, QString const & name);
413 void save(QDomDocument & doc, QDomElement & styles, const StyleManager* styleManager);
414
415 /**
416 * Loads the style properties from @p style .
417 * Determines also the parent's name.
418 * @param stylesReader map of all styles
419 * @param style the DOM element defining the style
420 * @param name the style's new name
421 */
422 void loadOdf(KoOdfStylesReader& stylesReader, const KoXmlElement& style,
423 const QString& name, Conditions& conditions,
424 const StyleManager* styleManager, const ValueParser *parser);
425
426 /**
427 * @reimp
428 * Stores an OASIS user style.
429 * @return the OASIS style's name
430 */
431 virtual QString saveOdf(KoGenStyle& style, KoGenStyles &mainStyles,
432 const StyleManager* manager) const;
433
434
435 //bool operator==(const CustomStyle& other) const;
436 //inline bool operator!=(const CustomStyle& other) const {
437 // return !operator==(other);
438 //}
439
440 /**
441 * @return the number of references to this style.
442 */
443 int usage() const;
444
445private:
446 friend class StyleManager;
447
448 /**
449 * Constructor.
450 * Constructs the default cell style.
451 */
452 CustomStyle();
453
454 class Private;
455 QSharedDataPointer<Private> d;
456};
457
458
459/**
460 * \ingroup Style
461 * A single style attribute.
462 */
463class CALLIGRA_SHEETS_ODF_TEST_EXPORT SubStyle : public QSharedData
464{
465public:
466 SubStyle() {}
467 virtual ~SubStyle() {}
468 virtual Style::Key type() const {
469 return Style::DefaultStyleKey;
470 }
471 virtual void dump() const {
472 kDebug() << debugData();
473 }
474 virtual QString debugData(bool withName = true) const {
475 QString out; if (withName) out = name(Style::DefaultStyleKey); return out;
476 }
477 virtual uint koHash() const { return uint(type()); }
478 static QString name(Style::Key key);
479};
480
481// Provides a default SubStyle for the tree.
482// Otherwise, we would have QSharedDataPointer<SubStyle>() as default,
483// which has a null pointer and crashes.
484// Also, this makes the code more readable:
485// QSharedDataPointer<SubStyle> vs. SharedSubStyle
486class SharedSubStyle
487{
488public:
489 inline SharedSubStyle() : d(s_defaultStyle.d){}
490 inline SharedSubStyle(SubStyle* subStyle) : d(subStyle) {}
491 inline const SubStyle *operator->() const {
492 return d.data();
493 }
494 inline const SubStyle *data() const {
495 return d.data();
496 }
497 inline bool operator<(const SharedSubStyle& o) const {
498 return d.data() < o.d.data();
499 }
500 inline bool operator==(const SharedSubStyle& o) const {
501 return d.data() == o.d.data();
502 }
503 inline bool operator!() const {
504 return !d;
505 }
506
507private:
508 QSharedDataPointer<SubStyle> d;
509 static SharedSubStyle s_defaultStyle;
510};
511
512class NamedStyle : public SubStyle
513{
514public:
515 NamedStyle(const QString& n) : SubStyle(), name(n) {}
516 virtual Style::Key type() const {
517 return Style::NamedStyleKey;
518 }
519 virtual void dump() const {
520 kDebug() << debugData();
521 }
522 virtual QString debugData(bool withName = true) const {
523 QString out; if (withName) out = SubStyle::name(Style::NamedStyleKey) + ' '; out += name; return out;
524 }
525 virtual uint koHash() const { return uint(type()) ^ qHash(name); }
526 QString name;
527};
528
529
530static inline uint qHash(const QColor& color)
531{ return uint(color.rgb()); }
532
533static inline uint qHash(const QPen& pen)
534{ return qHash(pen.color()) ^ 37 * uint(pen.style()); }
535
536static inline uint qHash(const QBrush& brush)
537{ return qHash(brush.color()) ^ 91 * uint(brush.style()); }
538
539template<Style::Key key, class Value1>
540class SubStyleOne : public SubStyle
541{
542public:
543 SubStyleOne(const Value1& v = Value1()) : SubStyle(), value1(v) {}
544 virtual Style::Key type() const {
545 return key;
546 }
547 virtual void dump() const {
548 kDebug(36006) << debugData();
549 }
550 virtual QString debugData(bool withName = true) const {
551 QString out; if (withName) out = name(key) + ' '; QDebug qdbg(&out); qdbg << value1; return out;
552 }
553 virtual uint koHash() const { return uint(type()) ^ qHash(value1); }
554 Value1 value1;
555};
556
557} // namespace Sheets
558} // namespace Calligra
559
560Q_DECLARE_TYPEINFO(Calligra::Sheets::Style, Q_MOVABLE_TYPE);
561Q_DECLARE_TYPEINFO(Calligra::Sheets::CustomStyle, Q_MOVABLE_TYPE);
562Q_DECLARE_TYPEINFO(Calligra::Sheets::SharedSubStyle, Q_MOVABLE_TYPE);
563
564#endif // CALLIGRA_SHEETS_STYLE
565