1 /* AbiSource
2  *
3  * Copyright (C) 2005 Daniel d'Andrada T. de Carvalho
4  * <daniel.carvalho@indt.org.br>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301 USA.
20  */
21 
22 
23 #ifndef _ODI_STYLE_STYLE_H_
24 #define _ODI_STYLE_STYLE_H_
25 
26 // Internal includes
27 #include "ODi_ListenerState.h"
28 
29 // Internal classes
30 class ODi_FontFaceDecls;
31 class ODi_Abi_Data;
32 
33 // AbiWord classes
34 class PD_Document;
35 
36 
37 /**
38  * An OpenDocument regular style (<style:style>).
39  */
40 class ODi_Style_Style : public ODi_ListenerState {
41 
42 public:
43 
44     // Used to specify whether a given cell has a border (top, left, etc).
45     enum HAVE_BORDER {
46         HAVE_BORDER_YES,
47         HAVE_BORDER_NO,
48         HAVE_BORDER_UNSPECIFIED
49     };
50 
51 
52     ODi_Style_Style(ODi_ElementStack& rElementStack,
53 		    ODi_Abi_Data & rAbiData);
54 
~ODi_Style_Style()55     virtual ~ODi_Style_Style() {}
56 
57     void startElement(const gchar* pName, const gchar** ppAtts,
58                       ODi_ListenerStateAction& rAction);
59 
60     void endElement(const gchar* pName, ODi_ListenerStateAction& rAction);
61 
charData(const gchar *,int)62     void charData (const gchar* /*pBuffer*/, int /*length*/) {}
63 
64 
getDisplayName()65     const std::string& getDisplayName() const {return m_displayName;}
setDisplayName(std::string & rDisplayName)66     void setDisplayName(std::string& rDisplayName) {
67         m_displayName = rDisplayName;
68     }
69 
70     /**
71      * Defines an AbiWord style that is equivalent to this
72      * OpenDocument style.
73      *
74      * Called by text and paragraph styles.
75      *
76      * @param pDocument The AbiWord document on which the style will be defined.
77      */
78     void defineAbiStyle(PD_Document* pDocument);
getAbiData(void)79     ODi_Abi_Data & getAbiData(void)
80       { return m_rAbiData;}
81 
82     /**
83      * Builds the AbiWord "props" attribute value that describes this
84      * Style.
85      */
86     void buildAbiPropsAttrString(ODi_FontFaceDecls& rFontFaceDecls);
87 
88     /**
89      * @param rProps The string that will have appended to it the properties of this
90      *               style.
91      * @param appendParentProps If TRUE, it will append all parent props before appending its own props.
92      *                          If FALSE, it will append only its own props.
93      */
94     void getAbiPropsAttrString(std::string& rProps, bool appendParentProps=TRUE) const;
95 
setParentStyleName(const gchar * pParentStyleName)96     void setParentStyleName(const gchar* pParentStyleName) {
97         m_parentStyleName = pParentStyleName ? pParentStyleName : "";
98     }
99 
getParent()100     const ODi_Style_Style* getParent() const {
101         return m_pParentStyle;
102     }
103 
setParentStylePointer(const ODi_Style_Style * pParentStyle)104     void setParentStylePointer(const ODi_Style_Style* pParentStyle) {
105         m_pParentStyle = pParentStyle;
106     }
107 
setNextStylePointer(const ODi_Style_Style * pNextStyle)108     void setNextStylePointer(const ODi_Style_Style* pNextStyle) {
109         m_pNextStyle = pNextStyle;
110     }
111 
112 
getBreakBefore()113     const std::string& getBreakBefore() const {return m_breakBefore;}
getBreakAfter()114     const std::string& getBreakAfter() const {return m_breakAfter;}
115 
getName()116     const std::string& getName() const {return m_name;}
setName(std::string & rName)117     void setName(std::string& rName) {
118         m_name = rName;
119     }
120 
getParentName()121     const std::string& getParentName() const {return m_parentStyleName;}
setParentName(const char * pName)122     void setParentName(const char* pName) {if (pName) m_parentStyleName.assign(pName);}
setParentName(const std::string & rName)123     void setParentName(const std::string& rName) {m_parentStyleName = rName;}
124 
getNextStyleName()125     inline const std::string& getNextStyleName() const {return m_nextStyleName;}
setNextStyleName(const char * pName)126     inline void setNextStyleName(const char* pName) {if (pName) m_nextStyleName.assign(pName);}
setNextStyleName(const std::string & rName)127     void setNextStyleName(const std::string& rName) {m_nextStyleName = rName;}
128 
getListStyleName()129 	const std::string& getListStyleName() const {return m_listStyleName;}
130 
hasProperties()131     bool hasProperties() const {
132         return !m_listStyleName.empty() ||
133                !m_masterPageName.empty() ||
134 
135                !m_lineHeight.empty() ||
136                !m_align.empty() ||
137                !m_breakBefore.empty() ||
138                !m_breakAfter.empty() ||
139                !m_widows.empty() ||
140                !m_orphans.empty() ||
141                !m_marginLeft.empty() ||
142                !m_marginRight.empty() ||
143                !m_marginTop.empty() ||
144                !m_marginBottom.empty() ||
145                !m_bgcolor.empty() ||
146                !m_keepWithNext.empty() ||
147                !m_textIndent.empty() ||
148                !m_direction.empty() ||
149 
150                !m_color.empty() ||
151                !m_textDecoration.empty() ||
152                !m_textPos.empty() ||
153                !m_fontName.empty() ||
154                !m_fontSize.empty() ||
155                !m_lang.empty() ||
156                !m_fontStyle.empty() ||
157                !m_fontWeight.empty() ||
158                !m_display.empty() ||
159                !m_transform.empty() ||
160 
161                !m_columns.empty() ||
162                !m_columnGap.empty() ||
163 
164                !m_wrap.empty() ||
165 	       !m_HorizRel.empty() ||
166 	       !m_HorizPos.empty() ||
167 	       !m_VerticalPos.empty() ||
168 	       !m_VerticalRel.empty() ||
169 
170                !m_backgroundColor.empty() ||
171                !m_backgroundImageID.empty() ||
172 
173                !m_columnWidth.empty() ||
174                !m_columnRelWidth.empty() ||
175 
176                !m_minRowHeight.empty() ||
177                !m_TableMarginLeft.empty() ||
178                !m_TableMarginRight.empty() ||
179                !m_TableWidth.empty() ||
180                !m_TableRelWidth.empty() ||
181                !m_rowHeight.empty() ||
182 
183 	       !m_paddingLeft.empty() ||
184 	       !m_paddingRight.empty() ||
185 	       !m_paddingTop.empty()||
186 	       !m_paddingBot.empty()||
187 	       !m_mergeBorders.empty()||
188 
189 	  (m_haveTopBorder == HAVE_BORDER_YES) ||
190 	  (m_haveBottomBorder == HAVE_BORDER_YES) ||
191 	  (m_haveLeftBorder == HAVE_BORDER_YES) ||
192 	  (m_haveRightBorder == HAVE_BORDER_YES) ||
193 
194                !m_tabStops.empty();
195     }
196 
isAutomatic()197     bool isAutomatic() const {return m_bAutomatic;}
getMarginLeft()198     const std::string* getMarginLeft() const {return &m_marginLeft;}
getTextIndent()199     const std::string* getTextIndent() const {return &m_textIndent;}
getFamily()200     const std::string* getFamily() const {return &m_family;}
getFontName()201     const std::string* getFontName() const {return &m_fontName;}
202 
203     /**
204      * @param local If "true", It returns the plain value of the corresponding
205      *              variable. Otherwise, it considers the final value of this
206      *              property, taking into account its value on the parent styles.
207      */
208     const std::string* getWrap(bool local) const;
209     const std::string* getHorizPos(bool local) const;
210     const std::string* getVerticalPos(bool local) const;
211 
212     const std::string* getBackgroundColor() const;
213     const std::string* getBackgroundImageID() const;
214 
getColumnWidth()215     const std::string* getColumnWidth() const {return &m_columnWidth;}
getColumnRelWidth()216     const std::string* getColumnRelWidth() const {return &m_columnRelWidth;}
217 
getMinRowHeight()218     const std::string* getMinRowHeight() const {return &m_minRowHeight;}
getRowHeight()219     const std::string* getRowHeight() const {return &m_rowHeight;}
220 
221 
getBorderTop_thickness()222     const std::string* getBorderTop_thickness() const {return &m_borderTop_thickness;}
getBorderTop_color()223     const std::string* getBorderTop_color() const {return &m_borderTop_color;}
hasTopBorder()224     HAVE_BORDER hasTopBorder() const {return m_haveTopBorder;}
225 
getBorderBottom_thickness()226     const std::string* getBorderBottom_thickness() const {return &m_borderBottom_thickness;}
getBorderBottom_color()227     const std::string* getBorderBottom_color() const {return &m_borderBottom_color;}
hasBottomBorder()228     HAVE_BORDER hasBottomBorder() const {return m_haveBottomBorder;}
229 
getBorderLeft_thickness()230     const std::string* getBorderLeft_thickness() const {return &m_borderLeft_thickness;}
getBorderLeft_color()231     const std::string* getBorderLeft_color() const {return &m_borderLeft_color;}
hasLeftBorder()232     HAVE_BORDER hasLeftBorder() const {return m_haveLeftBorder;}
233 
getBorderRight_thickness()234     const std::string* getBorderRight_thickness() const {return &m_borderRight_thickness;}
getBorderRight_color()235     const std::string* getBorderRight_color() const {return &m_borderRight_color;}
hasRightBorder()236     HAVE_BORDER hasRightBorder() const {return m_haveRightBorder;}
237 
getMasterPageName()238     const std::string* getMasterPageName() const {return &m_masterPageName;}
239 
getTableMarginLeft()240     const std::string* getTableMarginLeft() const {return &m_TableMarginLeft;}
getTableMarginRight()241     const std::string* getTableMarginRight() const {return &m_TableMarginRight;}
getTableWidth()242     const std::string* getTableWidth() const {return &m_TableWidth;}
getTableRelWidth()243     const std::string* getTableRelWidth() const {return &m_TableRelWidth;}
244 
getVerticalAlign()245     const std::string* getVerticalAlign() const {return &m_VerticalAlign;}
246 private:
247 
248     // <style:style />
249     void _parse_style_style(const gchar** ppAtts);
250 
251     // <style:paragraph-properties />
252     void _parse_style_paragraphProperties(const gchar** ppProps);
253 
254     // <style:tab-stop />
255     void _parse_style_tabStopProperties(const gchar** ppProps);
256 
257     // <style:text-properties />
258     void _parse_style_textProperties(const gchar** ppProps);
259 
260     // <style:section-properties />
261     void _parse_style_sectionProperties(const gchar** ppProps);
262 
263     // <style:graphic-properties />
264     void _parse_style_graphicProperties(const gchar** ppProps);
265 
266     // <style:table-properties />
267     void _parse_style_tableProperties(const gchar** ppProps);
268 
269     // <style:table-column-properties />
270     void _parse_style_tableColumnProperties(const gchar** ppProps);
271 
272     // <style:table-row-properties />
273     void _parse_style_tableRowProperties(const gchar** ppProps);
274 
275     // <style:table-cell-properties />
276     void _parse_style_tableCellProperties(const gchar** ppProps);
277 
278     // <style:background-image />
279     void _parse_style_background_image(const gchar** ppProps);
280 
281     /**
282      * If pString is "0.0556in solid #0000ff", rColor will receive "#0000ff",
283      * rLength "0.0556in" and rHaveBorder "yes".
284      *
285      * If pString is "none", both rColor and rLenght will be empty and
286      * rHaveBorder will be "no"
287      */
288     void _stripColorLength(std::string& rColor, std::string& rLength,
289                            HAVE_BORDER& rHaveBorder,
290                            const gchar* pString) const;
291 
292     /**
293      * This function shouldn't exist. The code should use
294      * UT_isValidDimensionString instead. The problem with the UT function is
295      * that it doesn't check the dimension specifier and only accepts NULL
296      * terminated strings.
297      *
298      * @param length 0 for NULL terminated strings.
299      */
300     bool _isValidDimensionString(const gchar* pString, UT_uint32 length=0) const;
301 
302     // true if it is an OpenDocument automatic style.
303     // ie., it's defined inside a <office:automatic-styles> element.
304     bool m_bAutomatic;
305 
306     const ODi_Style_Style* m_pParentStyle;
307     const ODi_Style_Style* m_pNextStyle;
308 
309     std::string m_abiPropsAttr;
310 
311 
312     // <attribute name="style:name">
313     std::string m_name;
314 
315     // <attribute name="style:display-name"> (optional)
316     // If this attribute is not present, the display name equals the style name.
317     // In AbiWord, maps to the "name" attribute.
318     std::string m_displayName;
319 
320     // Maps to the "type" attribute.
321     // OpenDocument | AbiWord
322     // "character"  - "C"
323     // "paragraph"  - "P"
324     // "section"    - none (AbiWord don't have section styles)
325     //
326     // An exception is "graphic" styles. AbiWord don't have then.
327     std::string m_family;
328 
329     // <attribute name="style:parent-style-name"> (optional)
330     // If a parent style is not specified, a default parent style defined by
331     // the application is used.
332     //
333     // In AbiWord, maps to the "basedon" attribute.
334     std::string m_parentStyleName;
335 
336     // <attribute name="style:next-style-name">
337     // By default, the current style is used as the next style.
338     // In AbiWord, maps to the "followedby" attribute.
339     std::string m_nextStyleName;
340 
341     // <attribute name="style:list-style-name"> (optional)
342     //
343     // Is only applied to headings and to paragraphs that are contained in a
344     // list, where the list does not specify a list style itself, and the list
345     // has no list style specification for any of its parents.
346     //
347     // Maps to AbiWord, but not directly.
348     std::string m_listStyleName;
349 
350     // <attribute name="style:master-page-name"> (optional)
351     //
352     // If this attribute is associated with a style, a page break is inserted
353     // when the style is applied and the specified master page is applied to the
354     // preceding page.
355     // This attribute is ignored if it is associated with a paragraph style that
356     // is applied to a paragraph within a table.
357     //
358     // Maps to AbiWord, but not directly.
359     std::string m_masterPageName;
360 
361 
362     ////
363     // <style:paragraph-properties> attributes
364     // These goes inside the Abi "props" attribute
365     std::string m_lineHeight;
366     std::string m_align;
367     std::string m_breakBefore; // fo:break-before
368     std::string m_breakAfter; // fo:break-after
369     std::string m_widows;
370     std::string m_orphans;
371     std::string m_marginLeft;
372     std::string m_marginRight;
373     std::string m_marginTop;
374     std::string m_marginBottom;
375     std::string m_bgcolor;
376     std::string m_keepWithNext;
377     std::string m_textIndent; // fo:text-indent
378     std::string m_direction; // style:writing-mode
379     std::string m_defaultTabInterval; // style:tab-stop-distance
380     std::string m_tabStops; // style:tab-stops
381 
382     ////
383     // <style:text-properties />
384     // These goes inside the Abi "props" attribute
385     std::string m_color;
386     std::string m_textDecoration;
387     std::string m_textPos;
388     std::string m_fontName;
389     std::string m_fontSize;
390     std::string m_lang;
391     std::string m_fontStyle;
392     std::string m_fontWeight;
393     std::string m_display; //text:display
394     std::string m_transform; //fo:text-transform
395 
396 
397     // fo:background-color
398     // For <style:table-properties> and <style:table-cell-properties>
399     std::string m_backgroundColor;
400 
401     // <style:bakground-image>
402     std::string m_backgroundImageID; // xlink:href
403 
404     // For <style:table-properties
405     // fo:margin-left
406     // fo:margin-right
407     // style:width
408     // style:rel-width
409 
410     std::string   m_TableMarginLeft;
411     std::string   m_TableMarginRight;
412     std::string   m_TableWidth;
413     std::string   m_TableRelWidth;
414 
415 
416     ////
417     // <style:section-properties>
418     // These goes inside the Abi "props" attribute
419     std::string m_columns;
420     std::string m_columnGap;
421 
422     ////
423     // <style:graphic-properties>
424     std::string m_wrap; // style:wrap
425     std::string m_HorizRel; // style:horizontal-rel
426     std::string m_HorizPos; // style:horizontal-pos
427     std::string m_VerticalPos; // style:vertical-pos
428     std::string m_VerticalRel; //  style:vertical-rel
429 
430     ////
431     // <style:table-column-properties>
432     // style:column-width
433     // rel-column-width
434     std::string m_columnWidth; // style:column-width
435     std::string m_columnRelWidth; // style:rel-column-width
436 
437     ////
438     // <style:table-row-properties>
439     std::string m_minRowHeight; // style:min-row-height
440     std::string m_rowHeight; // style:row-height
441 
442 
443     ////
444     // <style:table-cell-properties>
445 
446     // style:vertical-align
447     std::string m_VerticalAlign;
448 
449     // fo:border-top
450     std::string m_borderTop_thickness;
451     std::string m_borderTop_color;
452     HAVE_BORDER m_haveTopBorder;
453 
454     // fo:border-bottom
455     std::string m_borderBottom_thickness;
456     std::string m_borderBottom_color;
457     HAVE_BORDER m_haveBottomBorder;
458 
459     // fo:border-left
460     std::string m_borderLeft_thickness;
461     std::string m_borderLeft_color;
462     HAVE_BORDER m_haveLeftBorder;
463 
464     // fo:border-right
465     std::string m_borderRight_thickness;
466     std::string m_borderRight_color;
467     HAVE_BORDER m_haveRightBorder;
468 
469     // fo:padding
470     std::string m_paddingLeft;
471     std::string m_paddingRight;
472     std::string m_paddingTop;
473     std::string m_paddingBot;
474 
475     // style:merge-borders
476     std::string m_mergeBorders;
477 
478     ODi_Abi_Data& m_rAbiData;
479 
480     // OBS: If "fo:border" is defined, its value will fill all "fo:border-*"
481 };
482 
483 #endif //_ODI_STYLE_STYLE_H_
484