File indexing completed on 2024-04-28 16:21:33

0001 /* This file is part of the KDE project
0002    Copyright 2010 Marijn Kruisselbrink <mkruisselbrink@kde.org>
0003    Copyright 2006 Stefan Nikolaus <stefan.nikolaus@kdemail.net>
0004    Copyright 2003 Norbert Andres <nandres@web.de>
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 CALLIGRA_SHEETS_STYLE
0023 #define CALLIGRA_SHEETS_STYLE
0024 
0025 #include <QFont>
0026 #include <QSharedDataPointer>
0027 #include <QTextCharFormat>
0028 
0029 #include <KoXmlReader.h>
0030 
0031 #include "Currency.h"
0032 #include "Format.h"
0033 #include "Global.h"
0034 
0035 namespace Calligra
0036 {
0037 namespace Sheets
0038 {
0039 class Conditions;
0040 class CustomStyle;
0041 class SharedSubStyle;
0042 class Style;
0043 class StyleManager;
0044 class SubStyle;
0045 class ValueParser;
0046 
0047 // used for preloading OASIS auto styles
0048 typedef QHash<QString, Style>       Styles;
0049 // needs to be ordered (QMap) for the style dialog
0050 typedef QMap<QString, CustomStyle*> CustomStyles;
0051 
0052 CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
0053 
0054 /**
0055  * \ingroup Style
0056  * A cell style.
0057  */
0058 class CALLIGRA_SHEETS_ODF_EXPORT Style
0059 {
0060 public:
0061     enum HAlign {
0062         Left = 1,
0063         Center = 2,
0064         Right = 3,
0065         Justified = 4,
0066         HAlignUndefined = 0
0067     };
0068 
0069     enum VAlign {
0070         Top = 1,
0071         Middle = 2,
0072         Bottom = 3,
0073         VDistributed = 4,
0074         VJustified = 5,
0075         VAlignUndefined = 0
0076     };
0077 
0078     enum FloatFormat {
0079         DefaultFloatFormat = 0,
0080         AlwaysSigned = 1,
0081         AlwaysUnsigned = 2,
0082         OnlyNegSigned = DefaultFloatFormat
0083     };
0084 
0085     enum FloatColor {
0086         DefaultFloatColor = 0,
0087         NegRed = 1,
0088         AllBlack = DefaultFloatColor,
0089         NegBrackets = 3,
0090         NegRedBrackets = 4
0091     };
0092 
0093     /// The style type
0094     enum StyleType {
0095         BUILTIN,   ///< built-in style (the default style)
0096         CUSTOM,    ///< custom style (defined in the StyleManager dialog)
0097         AUTO,      ///< automatically generated on cell format changes
0098         TENTATIVE  ///< @internal temporary state
0099     };
0100 
0101     enum Key {
0102         // special cases
0103         DefaultStyleKey,
0104         /**
0105          * The NamedStyleKey has two functions:
0106          * \li In Style: On lookup the Style is composed (\see StyleStorage::composeStyle()).
0107          *               For named styles just the style's name is stored. On lookup, these styles
0108          *               are looked up in the StyleManager and their attributes, including all
0109          *               attributes of the parents, are filled in the composed style. Additionally,
0110          *               the name of the named style is stored in the NamedStyleKey attribute.
0111          *               This is especially useful while saving the styles.
0112          * \li In CustomStyle: It simply refers to the parent style.
0113          */
0114         NamedStyleKey,
0115         // borders
0116         LeftPen,
0117         RightPen,
0118         TopPen,
0119         BottomPen,
0120         FallDiagonalPen,
0121         GoUpDiagonalPen,
0122         // layout
0123         HorizontalAlignment,
0124         VerticalAlignment,
0125         MultiRow,
0126         VerticalText,
0127         Angle,
0128         ShrinkToFit,
0129         Indentation,
0130         // content format
0131         Prefix,
0132         Postfix,
0133         Precision,
0134         ThousandsSep,
0135         FormatTypeKey,
0136         FloatFormatKey,
0137         FloatColorKey,
0138         CurrencyFormat,
0139         CustomFormat,
0140         // background
0141         BackgroundBrush,
0142         BackgroundColor,
0143         // font
0144         FontColor,
0145         FontFamily,
0146         FontSize,
0147         FontBold,
0148         FontItalic,
0149         FontStrike,
0150         FontUnderline,
0151         //misc
0152         DontPrintText,
0153         NotProtected,
0154         HideAll,
0155         HideFormula
0156     };
0157 
0158     Style();
0159     Style(const Style& style);
0160     virtual ~Style();
0161 
0162     virtual StyleType type() const;
0163 
0164     QString parentName() const;
0165     void setParentName(const QString& name);
0166 
0167 
0168     bool loadXML(KoXmlElement& format, Paste::Mode pm = Paste::Normal);
0169     void saveXML(QDomDocument& doc, QDomElement& format, const StyleManager* styleManager) const;
0170 
0171     void clearAttribute(Key key);
0172     bool hasAttribute(Key key) const;
0173 
0174 
0175     uint bottomPenValue() const;
0176     uint rightPenValue() const;
0177     uint leftPenValue() const;
0178     uint topPenValue() const;
0179 
0180     QColor  fontColor()       const;
0181     QColor  backgroundColor() const;
0182     QPen    rightBorderPen()  const;
0183     QPen    bottomBorderPen() const;
0184     QPen    leftBorderPen()   const;
0185     QPen    topBorderPen()    const;
0186     QPen    fallDiagonalPen() const;
0187     QPen    goUpDiagonalPen() const;
0188     QBrush  backgroundBrush() const;
0189     QString customFormat()    const;
0190     QString prefix()          const;
0191     QString postfix()         const;
0192     QString fontFamily()      const;
0193 
0194     HAlign      halign()      const;
0195     VAlign      valign()      const;
0196     FloatFormat floatFormat() const;
0197     FloatColor  floatColor()  const;
0198     Format::Type  formatType()  const;
0199 
0200     Currency currency() const;
0201 
0202     QFont  font()         const;
0203     bool   bold()         const;
0204     bool   italic()       const;
0205     bool   underline()    const;
0206     bool   strikeOut()    const;
0207     uint   fontFlags()    const;
0208     int    fontSize()     const;
0209     int    precision()    const;
0210     bool   thousandsSep() const;
0211     int    angle()        const;
0212     double indentation()  const;
0213     bool   shrinkToFit()  const;
0214     bool   verticalText() const;
0215     bool   wrapText()     const;
0216     bool   printText()    const;
0217     bool   hideAll()      const;
0218     bool   hideFormula()  const;
0219     bool   notProtected() const;
0220     bool   isDefault()    const;
0221     bool   isEmpty()      const;
0222 
0223 
0224 public:
0225     void setHAlign(HAlign align);
0226     void setVAlign(VAlign align);
0227     void setFont(QFont const & font);
0228     void setFontFamily(QString const & fam);
0229     void setFontBold(bool enable);
0230     void setFontItalic(bool enable);
0231     void setFontUnderline(bool enable);
0232     void setFontStrikeOut(bool enable);
0233     void setFontSize(int size);
0234     void setFontColor(QColor const & color);
0235     void setRightBorderPen(QPen const & pen);
0236     void setBottomBorderPen(QPen const & pen);
0237     void setLeftBorderPen(QPen const & pen);
0238     void setTopBorderPen(QPen const & pen);
0239     void setFallDiagonalPen(QPen const & pen);
0240     void setGoUpDiagonalPen(QPen const & pen);
0241     void setAngle(int angle);
0242     void setIndentation(double indent);
0243     void setBackgroundBrush(QBrush const & brush);
0244     void setFloatFormat(FloatFormat format);
0245     void setFloatColor(FloatColor color);
0246     void setFormatType(Format::Type format);
0247     void setCustomFormat(QString const & strFormat);
0248     void setPrecision(int precision);
0249     void setThousandsSep(bool thousandsSep);
0250     void setPrefix(QString const & prefix);
0251     void setPostfix(QString const & postfix);
0252     void setCurrency(Currency const & currency);
0253     void setWrapText(bool enable);
0254     void setHideAll(bool enable);
0255     void setHideFormula(bool enable);
0256     void setNotProtected(bool enable);
0257     void setDontPrintText(bool enable);
0258     void setVerticalText(bool enable);
0259     void setShrinkToFit(bool enable);
0260     void setBackgroundColor(QColor const & color);
0261     void setDefault();
0262     void clear();
0263 
0264     static bool compare(const SubStyle* one, const SubStyle* two);
0265 
0266 
0267     /** Returns true if both styles have the same properties */
0268     bool operator== (const Style& style) const;
0269     inline bool operator!=(const Style& other) const {
0270         return !operator==(other);
0271     }
0272     friend CALLIGRA_SHEETS_ODF_EXPORT uint qHash(const Style& style);
0273     void operator=(const Style& style);
0274     Style operator-(const Style& style) const;
0275     /// Insert and replace substyles from style
0276     void merge(const Style& style);
0277 
0278     /**
0279      * The keys, that are contained in this style, but not in \p other and
0280      * the keys, that are contained in both but differ in value.
0281      * \return a set of keys, in which this style and \p other differ.
0282      */
0283     QSet<Key> difference(const Style& other) const;
0284 
0285     void dump() const;
0286 
0287     /**
0288      * Return the properties of this style that can be represented as a QTextCharFormat
0289      */
0290     QTextCharFormat asCharFormat() const;
0291 
0292     /** Defined style elements - used when saving the style */
0293     virtual QSet<Style::Key> definedKeys(const StyleManager *) const;
0294 
0295 protected:
0296     QList<SharedSubStyle> subStyles() const;
0297 
0298     SharedSubStyle createSubStyle(Key key, const QVariant& value);
0299     virtual void insertSubStyle(Key key, const QVariant& value);
0300     void insertSubStyle(const SharedSubStyle& subStyle);
0301     bool releaseSubStyle(Key key);
0302 
0303 private:
0304     friend class StyleStorage;
0305     friend class StyleStorageLoaderJob;
0306     friend class BorderColorCommand;
0307 
0308     class Private;
0309     QSharedDataPointer<Private> d;
0310 };
0311 
0312 
0313 
0314 /**
0315  * \ingroup Style
0316  * A named cell style.
0317  */
0318 class CALLIGRA_SHEETS_ODF_EXPORT CustomStyle : public Style
0319 {
0320 public:
0321     /**
0322      * Constructor.
0323      * Creates a custom style.
0324      * \param name The name of this style.
0325      * \param parent The style whose attributes are inherited - the parent style.
0326      */
0327     explicit CustomStyle(const QString& name, CustomStyle* parent = 0);
0328     CustomStyle(const CustomStyle& style);
0329     ~CustomStyle() override;
0330     CustomStyle& operator=(const CustomStyle& other);
0331 
0332     StyleType type() const override;
0333     void setType(StyleType type);
0334 
0335     void setName(QString const & name);
0336     QString const & name() const;
0337 
0338     bool loadXML(KoXmlElement const & style, QString const & name);
0339     void save(QDomDocument & doc, QDomElement & styles, const StyleManager* styleManager);
0340 
0341     //bool operator==(const CustomStyle& other) const;
0342     //inline bool operator!=(const CustomStyle& other) const {
0343     //    return !operator==(other);
0344     //}
0345 
0346     /**
0347      * @return the number of references to this style.
0348      */
0349     int usage() const;
0350 
0351     QSet<Style::Key> definedKeys(const StyleManager *) const override;
0352 private:
0353     friend class StyleManager;
0354 
0355     /**
0356      * Constructor.
0357      * Constructs the default cell style.
0358      */
0359     CustomStyle();
0360 
0361     class Private;
0362     QSharedDataPointer<Private> d;
0363 };
0364 
0365 
0366 /**
0367  * \ingroup Style
0368  * A single style attribute.
0369  */
0370 class CALLIGRA_SHEETS_ODF_TEST_EXPORT SubStyle : public QSharedData
0371 {
0372 public:
0373     SubStyle() {}
0374     virtual ~SubStyle() {}
0375     virtual Style::Key type() const {
0376         return Style::DefaultStyleKey;
0377     }
0378     virtual void dump() const {
0379         debugSheetsStyle << debugData();
0380     }
0381     virtual QString debugData(bool withName = true) const {
0382         QString out; if (withName) out = name(Style::DefaultStyleKey); return out;
0383     }
0384     virtual uint koHash() const { return uint(type()); }
0385     static QString name(Style::Key key);
0386 };
0387 
0388 // Provides a default SubStyle for the tree.
0389 // Otherwise, we would have QSharedDataPointer<SubStyle>() as default,
0390 // which has a null pointer and crashes.
0391 // Also, this makes the code more readable:
0392 // QSharedDataPointer<SubStyle> vs. SharedSubStyle
0393 class SharedSubStyle
0394 {
0395 public:
0396     inline SharedSubStyle() : d(s_defaultStyle.d){}
0397     inline SharedSubStyle(SubStyle* subStyle) : d(subStyle) {}
0398     inline const SubStyle *operator->() const {
0399         return d.data();
0400     }
0401     inline const SubStyle *data() const {
0402         return d.data();
0403     }
0404     inline bool operator<(const SharedSubStyle& o) const {
0405         return d.data() < o.d.data();
0406     }
0407     inline bool operator==(const SharedSubStyle& o) const {
0408         return d.data() == o.d.data();
0409     }
0410     inline bool operator!() const {
0411         return !d;
0412     }
0413 
0414 private:
0415     QSharedDataPointer<SubStyle> d;
0416     static SharedSubStyle s_defaultStyle;
0417 };
0418 
0419 class NamedStyle : public SubStyle
0420 {
0421 public:
0422     NamedStyle(const QString& n) : SubStyle(), name(n) {}
0423     Style::Key type() const override {
0424         return Style::NamedStyleKey;
0425     }
0426     void dump() const override {
0427         debugSheetsStyle << debugData();
0428     }
0429     QString debugData(bool withName = true) const override {
0430         QString out; if (withName) out = SubStyle::name(Style::NamedStyleKey) + ' '; out += name; return out;
0431     }
0432     uint koHash() const override { return uint(type()) ^ qHash(name); }
0433     QString name;
0434 };
0435 
0436 
0437 static inline uint qHash(const QColor& color)
0438 { return uint(color.rgb()); }
0439 
0440 static inline uint qHash(const QPen& pen)
0441 { return qHash(pen.color()) ^ 37 * uint(pen.style()); }
0442 
0443 static inline uint qHash(const QBrush& brush)
0444 { return qHash(brush.color()) ^ 91 * uint(brush.style()); }
0445 
0446 template<Style::Key key, class Value1>
0447 class SubStyleOne : public SubStyle
0448 {
0449 public:
0450     SubStyleOne(const Value1& v = Value1()) : SubStyle(), value1(v) {}
0451     Style::Key type() const override {
0452         return key;
0453     }
0454     void dump() const override {
0455         debugSheetsStyle << debugData();
0456     }
0457     QString debugData(bool withName = true) const override {
0458         QString out; if (withName) out = name(key) + ' '; QDebug qdbg(&out); qdbg << value1; return out;
0459     }
0460     uint koHash() const override { return uint(type()) ^ qHash(value1); }
0461     Value1 value1;
0462 };
0463 
0464 } // namespace Sheets
0465 } // namespace Calligra
0466 
0467 Q_DECLARE_TYPEINFO(Calligra::Sheets::Style, Q_MOVABLE_TYPE);
0468 Q_DECLARE_TYPEINFO(Calligra::Sheets::CustomStyle, Q_MOVABLE_TYPE);
0469 Q_DECLARE_TYPEINFO(Calligra::Sheets::SharedSubStyle, Q_MOVABLE_TYPE);
0470 
0471 CALLIGRA_SHEETS_ODF_TEST_EXPORT QDebug operator<<( QDebug dbg, const Calligra::Sheets::Style *style );
0472 CALLIGRA_SHEETS_ODF_TEST_EXPORT QDebug operator<<( QDebug dbg, const Calligra::Sheets::Style &style );
0473 
0474 #endif // CALLIGRA_SHEETS_STYLE