1 /* This file is part of the KDE project
2  * Copyright (C) 2006-2010 Thomas Zander <zander@kde.org>
3  * Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in>
4  * Copyright (C) 2010 Nandita Suri <suri.nandita@gmail.com>
5  * Copyright (C) 2011 Lukáš Tvrdý <lukas.tvrdy@ixonos.com>
6  * Copyright (C) 2011-2012 Gopalakrishna Bhat A <gopalakbhat@gmail.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public License
19  * along with this library; see the file COPYING.LIB.  If not, write to
20  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 #ifndef KOLISTSTYLE_H
24 #define KOLISTSTYLE_H
25 
26 #include "kotext_export.h"
27 
28 #include <QTextFormat>
29 #include <QTextListFormat>
30 
31 #include <KoXmlReader.h>
32 
33 class KoListLevelProperties;
34 class KoShapeLoadingContext;
35 class KoShapeSavingContext;
36 class KoGenStyle;
37 
38 class QTextBlock;
39 
40 /**
41  * This class groups all styling-options for lists.
42  * See KoParagraphStyle::setListStyle()
43  * The list-style represents several list-levels, where each level is represented by the
44  * KoListLevelProperties class. The top most list level is 1.
45  *
46  * list level1
47  *   list level2
48  *   list level2
49  *     list level3
50  * list level1
51  *
52  * A list-style as such represents cross paragraph relations. The most obvious evidence of this
53  * is with a numbered list where a counter is automatically increased from one paragraph to the next.
54  *
55  * If the list is interrupted by a praragraph with another list-style the counting will start from
56  * fresh when the list resumes. However you can set the list to continue if you like.
57  *
58  * Following from the above you can use the same paragraph style for several paragraphs and the
59  * the counter will increase. If you want a paragraph to be on a sub level you do however need to
60  * create a new paragraph-style when another listLevel set.
61  */
62 class  KOTEXT_EXPORT KoListStyle : public QObject
63 {
64     Q_OBJECT
65     Q_ENUMS(Style Property)
66 public:
67     // ListIdType will be 32-bit in 32 bit machines and 64 bit in 64 bit machines
68     typedef quintptr ListIdType;
69 
70     /// This is used to specify what type of list label to use
71     enum LabelType {
72         /// List style with no numbering
73         None = 1,
74         /// an unicode char for the bullet
75         BulletCharLabelType,
76         /// an image for the bullet
77         ImageLabelType,
78         NumberLabelType
79     };
80 
81     /// further properties
82     enum Property {
83         // Housekeeping
84         Level = QTextFormat::UserProperty + 1000,          ///< list nesting level, is 1 or higher, or zero when implied
85         ListId,         ///< A group of lists together are called 1 (user intended) list in ODF. Store the listId here
86         StyleId,        ///< The id stored in the listFormat to link the list to this style.
87         IsOutline,      ///< If true then this list is an outline list (for header paragraphs)
88 
89         // Label
90         NumberFormat, ///< The KoOdfNumberFormat::FormattingSpecification
91         ListItemPrefix, ///< The text to be printed before the listItem
92         ListItemSuffix, ///< The text to be printed after the listItem
93         StartValue,     ///< First value to use
94         DisplayLevel,   ///< show this many parent levels. Is always lower than the (implied) level.
95         CharacterStyleId,///< CharacterStyle used for markup of the counter
96         CharacterProperties, ///< This stores the character properties of the list style
97         BulletCharacter,///< an int with the unicode value of the character (for CustomCharItem)
98         RelativeBulletSize,     ///< size in percent relative to the height of the text
99         LetterSynchronization, ///< If letters are used for numbering, when true increment all at the same time. (aa, bb)
100         Width,          ///< The width, in pt, of  a picture bullet.
101         Height,         ///< The height, in pt, of a picture bullet.
102         BulletImage,    ///< Bullet image stored as a key for lookup in the imageCollection
103 
104         // Geometry mode
105         AlignmentMode,   ///< Is true if list-level-position-and-space-mode=label-alignment
106 
107         // Geometry properties for old mode
108         Indent,         ///< The space (margin) to include for all paragraphs
109         MinimumWidth,   ///< The minimum width, in pt, of the listItem including the prefix/suffix.
110         MinimumDistance, ///< The minimum distance, in pt, between the counter and the text
111 
112         // Geometry properties for label-alignment mode
113         Alignment,      ///< Alignment of the counter
114         Margin,         ///< Stores the margin of the list - not ODF but convenience when auto generating new levels
115         MarginIncrease, ///< Stores the margin increase of the list
116         TextIndent,     ///< Stores the text indent of list item
117         LabelFollowedBy,  ///< Label followed by one of the enums ListLabelFollowedBy
118         TabStopPosition   ///< Specifies the additional tab stops
119     };
120 
121     enum ListLabelFollowedBy
122     {
123         ListTab,  ///< Label is followed by a list tab
124         Space,    ///< Label followed by a Space
125         Nothing      ///< Nothing is present between label and the text
126     };
127 
128     /**
129      * Constructor
130      * Create a new list style which uses numbered (KoListStyle::ListDecimal) listitems.
131      */
132     explicit KoListStyle(QObject *parent = 0);
133 
134     /// Destructor
135     ~KoListStyle() override;
136 
137     /// creates a clone of this style with the specified parent
138     KoListStyle *clone(QObject *parent = 0);
139 
140     /// each style has a unique ID (non persistent) given out by the styleManager
141     int styleId() const;
142 
143     /// each style has a unique ID (non persistent) given out by the styleManager
144     void setStyleId(int id);
145 
146     /**
147      * Return the properties for the specified list level.
148      * A list style can contain properties for more than one level, when a paragraph is added to this list
149      * it will be added at a certain level and it will then be using the properties of that level.
150      * The gain from using one list style for multiple levels is in allowing a way to format the list label.
151      * A list item which is of level '4' will be able to have a display level of up to 4, which means that not
152      * only is the counter of the current level displayed, the counters of the higher levels can be displayed as
153      * well.
154      * Adding level properties for lower levels will have the effect that the counter of that level will be displayed
155      * in the specified format instead of being inherited from the list style at the higher level.
156      */
157     KoListLevelProperties levelProperties(int level) const;
158 
159     /**
160      * Set the properties for a level.
161      * @param properties the new properties for the level, including the level number.
162      * @see level()
163      */
164     void setLevelProperties(const KoListLevelProperties &properties);
165 
166     /**
167      * @return if there are the properties for a level set.
168      * @param level the level for which to check
169      * @see level()
170      */
171     bool hasLevelProperties(int level) const;
172 
173     /**
174      * Remove any properties that were set for a level.
175      * @param level the level for which to remove
176      * @see level()
177      */
178     void removeLevelProperties(int level);
179 
180     /// return a QTextListFormat that contains formatting information for the level.
181     QTextListFormat listFormat(int level) const;
182 
183     /// return the configured list levels that hasLevelProperties would return true to.
184     QList<int> listLevels() const;
185 
186     /// return the name of the style.
187     QString name() const;
188 
189     /// set a user-visible name on the style.
190     void setName(const QString &name);
191 
192     /**
193      * Apply this style to a block by adding the block to the proper list.
194      */
195     void applyStyle(const QTextBlock &block, int level = 0);
196 
197     bool operator==(const KoListStyle &other) const;
198     bool operator!=(const KoListStyle &other) const;
199 
200     /**
201      * Load the style from the \a KoStyleStack style stack using the
202      * OpenDocument format.
203      */
204     void loadOdf(KoShapeLoadingContext& context, const KoXmlElement& style = KoXmlElement());
205 
206     /**
207      * Save the style to a KoGenStyle object using the OpenDocument format
208      */
209     void saveOdf(KoGenStyle &style, KoShapeSavingContext &context) const;
210 
211     /// copy all the properties from the other style to this style, effectively duplicating it.
212     void copyProperties(KoListStyle *other);
213 
214     /**
215      * Check if list has numbering in one of it's list levels
216      */
217     bool isNumberingStyle() const;
218 
219     /**
220      * Returns true if this list style is a outline style
221      */
222     bool isOulineStyle() const;
223 
224     /// returns true if style is a numbering style
225     static bool isNumberingStyle(int style);
226 
227 Q_SIGNALS:
228     void nameChanged(const QString &newName);
229     void styleChanged(int level);
230 
231 private:
232     friend class ChangeListCommand;
233     friend class ChangeListLevelCommand;
234 
235     void refreshLevelProperties(const KoListLevelProperties &properties);
236 
237     class Private;
238     Private * const d;
239 };
240 
241 Q_DECLARE_METATYPE(KoListStyle *)
242 
243 #endif
244