xref: /trunk/main/xmloff/source/style/xmlnume.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmloff.hxx"
30 
31 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
32 #include <com/sun/star/style/NumberingType.hpp>
33 #include <com/sun/star/style/XStyle.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/container/XIndexReplace.hpp>
36 #include <com/sun/star/awt/XBitmap.hpp>
37 #include <com/sun/star/awt/FontDescriptor.hpp>
38 #include <com/sun/star/text/HoriOrientation.hpp>
39 #include <com/sun/star/text/VertOrientation.hpp>
40 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
41 // --> OD 2008-01-16 #newlistlevelattrs#
42 #include <com/sun/star/text/PositionAndSpaceMode.hpp>
43 #include <com/sun/star/text/LabelFollow.hpp>
44 // <--
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 
48 #include <rtl/ustrbuf.hxx>
49 
50 #include <tools/debug.hxx>
51 
52 #include <xmloff/nmspmap.hxx>
53 #include "xmloff/xmlnmspe.hxx"
54 #include <xmloff/xmltoken.hxx>
55 #include <xmloff/xmluconv.hxx>
56 #include "fonthdl.hxx"
57 #include "xmloff/XMLTextListAutoStylePool.hxx"
58 #include <xmloff/xmlnume.hxx>
59 #include <xmloff/xmlexp.hxx>
60 #include <tools/fontenum.hxx>
61 
62 
63 using ::rtl::OUString;
64 using ::rtl::OUStringBuffer;
65 
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::style;
69 using namespace ::com::sun::star::text;
70 using namespace ::com::sun::star::container;
71 using namespace ::com::sun::star::beans;
72 using namespace ::xmloff::token;
73 
74 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE[] = "SymbolTextDistance";
75 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PARENT_NUMBERING[] = "ParentNumbering";
76 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_CHAR_STYLE_NAME[] = "CharStyleName";
77 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_CHAR[] = "BulletChar";
78 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_RELSIZE[] = "BulletRelSize";
79 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_COLOR[] = "BulletColor";
80 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHIC_BITMAP[] = "GraphicBitmap";
81 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHIC_SIZE[] = "GraphicSize";
82 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_VERT_ORIENT[] = "VertOrient";
83 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_NUMBERINGTYPE[] = "NumberingType";
84 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_HEADING_STYLE_NAME[] = "HeadingStyleName";
85 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_PREFIX[] = "Prefix";
86 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_SUFFIX[] = "Suffix";
87 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_ADJUST[] = "Adjust";
88 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LEFT_MARGIN[] = "LeftMargin";
89 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET[] = "FirstLineOffset";
90 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_BULLET_FONT[] = "BulletFont";
91 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_GRAPHICURL[] = "GraphicURL";
92 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_START_WITH[] = "StartWith";
93 // --> OD 2008-01-15 #newlistlevelattrs#
94 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE[] = "PositionAndSpaceMode";
95 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY[] = "LabelFollowedBy";
96 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION[] = "ListtabStopPosition";
97 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_FIRST_LINE_INDENT[] = "FirstLineIndent";
98 static sal_Char __READONLY_DATA XML_UNO_NAME_NRULE_INDENT_AT[] = "IndentAt";
99 // <--
100 
101 void SvxXMLNumRuleExport::exportLevelStyles( const uno::Reference< ::com::sun::star::container::XIndexReplace > & xNumRule,
102                                              sal_Bool bOutline )
103 {
104     sal_Int32 nCount = xNumRule ->getCount();
105     for( sal_Int32 i=0; i<nCount; i++ )
106     {
107         uno::Any aEntry( xNumRule->getByIndex( i ) );
108         uno::Sequence<beans::PropertyValue> aSeq;
109         if( aEntry >>= aSeq )
110         {
111             exportLevelStyle( i, aSeq, bOutline );
112         }
113     }
114 }
115 
116 void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel,
117                                     const uno::Sequence<beans::PropertyValue>& rProps,
118                                     sal_Bool bOutline )
119 {
120     sal_Int16 eType = NumberingType::CHAR_SPECIAL;
121 
122     sal_Int16 eAdjust = HoriOrientation::LEFT;
123     OUString sPrefix, sSuffix;
124     OUString sTextStyleName;
125     sal_Bool bHasColor = sal_False;
126     sal_Int32 nColor = 0;
127     sal_Int32 nSpaceBefore = 0, nMinLabelWidth = 0, nMinLabelDist = 0;
128 
129     sal_Int16 nStartValue = 1, nDisplayLevels = 1, nBullRelSize = 0;
130 
131     sal_Unicode cBullet = 0xf095;
132     OUString sBulletFontName, sBulletFontStyleName ;
133     sal_Int16 eBulletFontFamily = FAMILY_DONTKNOW;
134     sal_Int16 eBulletFontPitch = PITCH_DONTKNOW;
135     rtl_TextEncoding eBulletFontEncoding = RTL_TEXTENCODING_DONTKNOW;
136 
137     OUString sImageURL;
138     uno::Reference< ::com::sun::star::awt::XBitmap >  xBitmap;
139     sal_Int32 nImageWidth = 0, nImageHeight = 0;
140     sal_Int16 eImageVertOrient = VertOrientation::LINE_CENTER;
141 
142     // --> OD 2008-01-15 #newlistlevelattrs#
143     sal_Int16 ePosAndSpaceMode = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION;
144     sal_Int16 eLabelFollowedBy = LabelFollow::LISTTAB;
145     sal_Int32 nListtabStopPosition( 0 );
146     sal_Int32 nFirstLineIndent( 0 );
147     sal_Int32 nIndentAt( 0 );
148     // <--
149 
150     const sal_Int32 nCount = rProps.getLength();
151     const beans::PropertyValue* pPropArray = rProps.getConstArray();
152     for( sal_Int32 i=0; i<nCount; i++ )
153     {
154         const beans::PropertyValue& rProp = pPropArray[i];
155 
156         if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_NUMBERINGTYPE, sizeof(XML_UNO_NAME_NRULE_NUMBERINGTYPE)-1 ) )
157         {
158             rProp.Value >>= eType;
159         }
160         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_PREFIX, sizeof(XML_UNO_NAME_NRULE_PREFIX)-1 ) )
161         {
162             rProp.Value >>= sPrefix;
163         }
164         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_SUFFIX, sizeof(XML_UNO_NAME_NRULE_SUFFIX)-1 ) )
165         {
166             rProp.Value >>= sSuffix;
167         }
168         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_CHAR, sizeof(XML_UNO_NAME_NRULE_BULLET_CHAR)-1 ) )
169         {
170             OUString sValue;
171             rProp.Value >>= sValue;
172             if( sValue.getLength() > 0 )
173             {
174                 cBullet = (sal_Unicode)sValue[0];
175             }
176         }
177         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_RELSIZE, sizeof(XML_UNO_NAME_NRULE_BULLET_RELSIZE)-1 ) )
178         {
179             rProp.Value >>= nBullRelSize;
180         }
181         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_ADJUST, sizeof(XML_UNO_NAME_NRULE_ADJUST)-1 ) )
182         {
183             sal_Int16 nValue = 0;
184             rProp.Value >>= nValue;
185             eAdjust = nValue;
186         }
187         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_FONT, sizeof(XML_UNO_NAME_NRULE_BULLET_FONT)-1 ) )
188         {
189             awt::FontDescriptor rFDesc;
190             if( rProp.Value >>= rFDesc )
191             {
192                 sBulletFontName = rFDesc.Name;
193                 sBulletFontStyleName = rFDesc.StyleName;
194                 eBulletFontFamily = (sal_Int16)rFDesc.Family;
195                 eBulletFontPitch = (sal_Int16)rFDesc.Pitch;
196                 eBulletFontEncoding = (rtl_TextEncoding)rFDesc.CharSet;
197             }
198         }
199         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHICURL, sizeof(XML_UNO_NAME_NRULE_GRAPHICURL)-1 ) )
200         {
201             rProp.Value >>= sImageURL;
202         }
203         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHIC_BITMAP, sizeof(XML_UNO_NAME_NRULE_GRAPHIC_BITMAP)-1 ) )
204         {
205             rProp.Value >>= xBitmap;
206         }
207         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_BULLET_COLOR, sizeof(XML_UNO_NAME_NRULE_BULLET_COLOR)-1 ) )
208         {
209             rProp.Value >>= nColor;
210             bHasColor = sal_True;
211         }
212         else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_START_WITH, sizeof(XML_UNO_NAME_NRULE_START_WITH)-1 ) )
213         {
214             rProp.Value >>= nStartValue;
215         }
216         else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LEFT_MARGIN, sizeof(XML_UNO_NAME_NRULE_LEFT_MARGIN)-1 ) )
217         {
218             rProp.Value >>= nSpaceBefore;
219         }
220         else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET, sizeof(XML_UNO_NAME_NRULE_FIRST_LINE_OFFSET)-1 ) )
221         {
222             rProp.Value >>= nMinLabelWidth;
223         }
224         else  if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE, sizeof(XML_UNO_NAME_NRULE_SYMBOL_TEXT_DISTANCE)-1 ) )
225         {
226             rProp.Value >>= nMinLabelDist;
227         }
228         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_PARENT_NUMBERING, sizeof(XML_UNO_NAME_NRULE_PARENT_NUMBERING)-1 ) )
229         {
230             rProp.Value >>= nDisplayLevels;
231             if( nDisplayLevels > nLevel+1 )
232                 nDisplayLevels = static_cast<sal_Int16>( nLevel )+1;
233         }
234         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_CHAR_STYLE_NAME, sizeof(XML_UNO_NAME_NRULE_CHAR_STYLE_NAME)-1 ) )
235         {
236             rProp.Value >>= sTextStyleName;
237         }
238         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_GRAPHIC_SIZE, sizeof(XML_UNO_NAME_NRULE_GRAPHIC_SIZE)-1 ) )
239         {
240             awt::Size aSize;
241             if( rProp.Value >>= aSize )
242             {
243                 nImageWidth = aSize.Width;
244                 nImageHeight = aSize.Height;
245             }
246         }
247         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_VERT_ORIENT, sizeof(XML_UNO_NAME_NRULE_VERT_ORIENT)-1 ) )
248         {
249             sal_Int16 nValue = 0;
250             rProp.Value >>= nValue;
251             eImageVertOrient = nValue;
252         }
253         // --> OD 2008-01-16 #newlistlevelattrs#
254         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE,
255                                           sizeof(XML_UNO_NAME_NRULE_POSITION_AND_SPACE_MODE)-1 ) )
256         {
257             sal_Int16 nValue = 0;
258             rProp.Value >>= nValue;
259             ePosAndSpaceMode = nValue;
260         }
261         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY,
262                                           sizeof(XML_UNO_NAME_NRULE_LABEL_FOLLOWED_BY)-1 ) )
263         {
264             sal_Int16 nValue = 0;
265             rProp.Value >>= nValue;
266             eLabelFollowedBy = nValue;
267         }
268         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION,
269                                           sizeof(XML_UNO_NAME_NRULE_LISTTAB_STOP_POSITION)-1 ) )
270         {
271             rProp.Value >>= nListtabStopPosition;
272         }
273         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_FIRST_LINE_INDENT,
274                                           sizeof(XML_UNO_NAME_NRULE_FIRST_LINE_INDENT)-1 ) )
275         {
276             rProp.Value >>= nFirstLineIndent;
277         }
278         else if( rProp.Name.equalsAsciiL( XML_UNO_NAME_NRULE_INDENT_AT,
279                                           sizeof(XML_UNO_NAME_NRULE_INDENT_AT)-1 ) )
280         {
281             rProp.Value >>= nIndentAt;
282         }
283         // <--
284     }
285 
286     if( bOutline && (NumberingType::CHAR_SPECIAL == eType ||
287                      NumberingType::BITMAP == eType) )
288     {
289         DBG_ASSERT( !bOutline,
290            "SvxXMLNumRuleExport::exportLevelStyle: invalid style for outline" );
291         return;
292     }
293 
294     GetExport().CheckAttrList();
295 
296     // text:level
297     OUStringBuffer sTmp;
298     sTmp.append( nLevel + 1 );
299     GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_LEVEL, sTmp.makeStringAndClear() );
300     // #i110694#: no style-name on list-level-style-image
301     // #i116149#: neither prefix/suffix
302     if (NumberingType::BITMAP != eType)
303     {
304         if (sTextStyleName.getLength() > 0)
305         {
306             GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
307                     GetExport().EncodeStyleName( sTextStyleName ) );
308         }
309         if (sPrefix.getLength() > 0)
310         {
311             GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_PREFIX,
312                     sPrefix );
313         }
314         if (sSuffix.getLength() > 0)
315         {
316             GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_SUFFIX,
317                     sSuffix );
318         }
319     }
320 
321     enum XMLTokenEnum eElem = XML_LIST_LEVEL_STYLE_NUMBER;
322     if( NumberingType::CHAR_SPECIAL == eType )
323     {
324         // <text:list-level-style-bullet>
325         eElem = XML_LIST_LEVEL_STYLE_BULLET;
326 
327         if( cBullet )
328         {
329             if( cBullet < ' ' )
330             {
331                 cBullet = 0xF000 + 149;
332             }
333             // text:bullet-char="..."
334             sTmp.append( cBullet );
335             GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_BULLET_CHAR,
336                           sTmp.makeStringAndClear() );
337         }
338 
339     }
340     else if( NumberingType::BITMAP == eType )
341     {
342         // <text:list-level-style-image>
343 
344         eElem = XML_LIST_LEVEL_STYLE_IMAGE;
345 
346 
347         if( sImageURL.getLength() )
348         {
349             OUString sURL( GetExport().AddEmbeddedGraphicObject( sImageURL ) );
350             if( sURL.getLength() )
351             {
352                 GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sURL );
353 
354                 GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE );
355                 GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED );
356                 GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD );
357             }
358         }
359         else
360         {
361             DBG_ASSERT( !xBitmap.is(),
362                         "embedded images are not supported by now" );
363         }
364     }
365     else
366     {
367         // <text:list-level-style-number> or <text:outline-level-style>
368         if( bOutline )
369             eElem = XML_OUTLINE_LEVEL_STYLE;
370         else
371             eElem = XML_LIST_LEVEL_STYLE_NUMBER;
372 
373         GetExport().GetMM100UnitConverter().convertNumFormat( sTmp, eType );
374         GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_FORMAT,
375                                   sTmp.makeStringAndClear() );
376         GetExport().GetMM100UnitConverter().convertNumLetterSync( sTmp, eType );
377         if( sTmp.getLength() )
378             GetExport().AddAttribute( XML_NAMESPACE_STYLE,
379                                       XML_NUM_LETTER_SYNC,
380                                       sTmp.makeStringAndClear() );
381 
382         if( nStartValue != 1 )
383         {
384             sTmp.append( (sal_Int32)nStartValue );
385             GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE,
386                           sTmp.makeStringAndClear() );
387         }
388         if( nDisplayLevels > 1 && NumberingType::NUMBER_NONE != eType )
389         {
390             sTmp.append( (sal_Int32)nDisplayLevels );
391             GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_DISPLAY_LEVELS,
392                           sTmp.makeStringAndClear() );
393         }
394     }
395 
396     {
397         SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, eElem,
398                                   sal_True, sal_True );
399 
400         // --> OD 2008-01-16 #newlistlevelattrs#
401         OUStringBuffer sBuffer;
402         if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION )
403         {
404             // --> OD 2008-06-05 #i89178#
405             // optimization of XML stream size:
406             // suppress export of property list-level-position-and-space-mode,
407             // if its value is "label-width-and-position" - its the default value
408 //            GetExport().AddAttribute( XML_NAMESPACE_TEXT,
409 //                                      XML_LIST_LEVEL_POSITION_AND_SPACE_MODE,
410 //                                      XML_LABEL_WIDTH_AND_POSITION );
411             // <--
412 
413             nSpaceBefore += nMinLabelWidth;
414             nMinLabelWidth = -nMinLabelWidth;
415             if( nSpaceBefore != 0 )
416             {
417                 GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nSpaceBefore );
418                 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_SPACE_BEFORE,
419                               sBuffer.makeStringAndClear() );
420             }
421             if( nMinLabelWidth != 0 )
422             {
423                 GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nMinLabelWidth );
424                 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_WIDTH,
425                               sBuffer.makeStringAndClear() );
426             }
427             if( nMinLabelDist > 0 )
428             {
429                 GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nMinLabelDist );
430                 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_DISTANCE,
431                               sBuffer.makeStringAndClear() );
432             }
433         }
434         // --> OD 2008-06-06 #i89178#
435         // check, if properties for position-and-space-mode LABEL_ALIGNMENT
436         // are allowed to be exported.
437         else if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT &&
438                   mbExportPositionAndSpaceModeLabelAlignment )
439         // <--
440         {
441             GetExport().AddAttribute( XML_NAMESPACE_TEXT,
442                                       XML_LIST_LEVEL_POSITION_AND_SPACE_MODE,
443                                       XML_LABEL_ALIGNMENT );
444         }
445         // <--
446         if( HoriOrientation::LEFT != eAdjust )
447         {
448             enum XMLTokenEnum eValue = XML_TOKEN_INVALID;
449             switch( eAdjust )
450             {
451             case HoriOrientation::RIGHT:    eValue = XML_END;   break;
452             case HoriOrientation::CENTER:   eValue = XML_CENTER;    break;
453             }
454             if( eValue != XML_TOKEN_INVALID )
455                 GetExport().AddAttribute( XML_NAMESPACE_FO, XML_TEXT_ALIGN, eValue );
456         }
457 
458         if( NumberingType::BITMAP == eType )
459         {
460             enum XMLTokenEnum eValue = XML_TOKEN_INVALID;
461             switch( eImageVertOrient )
462             {
463             case VertOrientation::BOTTOM:   // yes, its OK: BOTTOM means that the baseline
464                                     // hits the frame at its topmost position
465             case VertOrientation::LINE_TOP:
466             case VertOrientation::CHAR_TOP:
467                 eValue = XML_TOP;
468                 break;
469             case VertOrientation::CENTER:
470             case VertOrientation::LINE_CENTER:
471             case VertOrientation::CHAR_CENTER:
472                 eValue = XML_MIDDLE;
473                 break;
474             case VertOrientation::TOP:      // yes, its OK: TOP means that the baseline
475                                     // hits the frame at its bottommost position
476             case VertOrientation::LINE_BOTTOM:
477             case VertOrientation::CHAR_BOTTOM:
478                 eValue = XML_BOTTOM;
479                 break;
480             }
481             if( eValue != XML_TOKEN_INVALID )
482                 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_POS, eValue );
483 
484             eValue = XML_TOKEN_INVALID;
485             switch( eImageVertOrient )
486             {
487             case VertOrientation::TOP:
488             case VertOrientation::CENTER:
489             case VertOrientation::BOTTOM:
490                 eValue = XML_BASELINE;
491                 break;
492             case VertOrientation::LINE_TOP:
493             case VertOrientation::LINE_CENTER:
494             case VertOrientation::LINE_BOTTOM:
495                 eValue = XML_LINE;
496                 break;
497             case VertOrientation::CHAR_TOP:
498             case VertOrientation::CHAR_CENTER:
499             case VertOrientation::CHAR_BOTTOM:
500                 eValue = XML_CHAR;
501                 break;
502             }
503             if( eValue != XML_TOKEN_INVALID )
504                 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_REL, eValue );
505 
506             if( nImageWidth > 0 )
507             {
508                 GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nImageWidth );
509                 GetExport().AddAttribute( XML_NAMESPACE_FO, XML_WIDTH,
510                               sBuffer.makeStringAndClear() );
511             }
512 
513             if( nImageHeight > 0 )
514             {
515                 GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nImageHeight );
516                 GetExport().AddAttribute( XML_NAMESPACE_FO, XML_HEIGHT,
517                               sBuffer.makeStringAndClear() );
518             }
519         }
520 
521         // --> OD 2008-01-16 #newlistlevelattrs#
522 //        if( GetExport().GetAttrList().getLength() > 0 )
523         {
524             SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
525                                       XML_LIST_LEVEL_PROPERTIES, sal_True, sal_True );
526 
527             // --> OD 2008-06-06 #i89178#
528             // check, if properties for position-and-space-mode LABEL_ALIGNMENT
529             // are allowed to be exported.
530             if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT &&
531                  mbExportPositionAndSpaceModeLabelAlignment )
532             // <--
533             {
534                 enum XMLTokenEnum eValue = XML_LISTTAB;
535                 if ( eLabelFollowedBy == LabelFollow::SPACE )
536                 {
537                     eValue = XML_SPACE;
538                 }
539                 else if ( eLabelFollowedBy == LabelFollow::NOTHING )
540                 {
541                     eValue = XML_NOTHING;
542                 }
543                 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
544                                           XML_LABEL_FOLLOWED_BY, eValue );
545 
546                 if ( eLabelFollowedBy == LabelFollow::LISTTAB &&
547                      nListtabStopPosition > 0 )
548                 {
549                     GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nListtabStopPosition );
550                     GetExport().AddAttribute( XML_NAMESPACE_TEXT,
551                                               XML_LIST_TAB_STOP_POSITION,
552                                               sBuffer.makeStringAndClear() );
553                 }
554 
555                 if ( nFirstLineIndent != 0 )
556                 {
557                     GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nFirstLineIndent );
558                     GetExport().AddAttribute( XML_NAMESPACE_FO,
559                                               XML_TEXT_INDENT,
560                                               sBuffer.makeStringAndClear() );
561                 }
562 
563                 if ( nIndentAt != 0 )
564                 {
565                     GetExport().GetMM100UnitConverter().convertMeasure( sBuffer, nIndentAt );
566                     GetExport().AddAttribute( XML_NAMESPACE_FO,
567                                               XML_MARGIN_LEFT,
568                                               sBuffer.makeStringAndClear() );
569                 }
570 
571                 SvXMLElementExport aLabelAlignmentElement( GetExport(), XML_NAMESPACE_STYLE,
572                                              XML_LIST_LEVEL_LABEL_ALIGNMENT,
573                                              sal_True, sal_True );
574             }
575         }
576         // <--
577 
578         if( NumberingType::CHAR_SPECIAL == eType )
579         {
580             if( sBulletFontName.getLength() )
581             {
582                 OUString sStyleName =
583                     GetExport().GetFontAutoStylePool()->Find(
584                         sBulletFontName, sBulletFontStyleName,
585                         eBulletFontFamily, eBulletFontPitch,
586                         eBulletFontEncoding );
587 
588                 if( sStyleName.getLength() )
589                 {
590                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
591                                                   XML_FONT_NAME,
592                                                   sStyleName );
593                 }
594                 else
595                 {
596                     Any aAny;
597                     OUString sTemp;
598 
599                     const SvXMLUnitConverter& rUnitConv =
600                         GetExport().GetMM100UnitConverter();
601                     XMLFontFamilyNamePropHdl aFamilyNameHdl;
602                     aAny <<= sBulletFontName;
603                     if( aFamilyNameHdl.exportXML( sTemp, aAny, rUnitConv ) )
604                         GetExport().AddAttribute( XML_NAMESPACE_FO,
605                                                   XML_FONT_FAMILY, sTemp );
606 
607                     if( sBulletFontStyleName.getLength() )
608                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
609                                                   XML_FONT_STYLE_NAME,
610                                                   sBulletFontStyleName );
611 
612                     XMLFontFamilyPropHdl aFamilyHdl;
613                     aAny <<= (sal_Int16)eBulletFontFamily;
614                     if( aFamilyHdl.exportXML( sTemp, aAny, rUnitConv  ) )
615                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
616                                                   XML_FONT_FAMILY_GENERIC,
617                                                   sTemp );
618 
619                     XMLFontPitchPropHdl aPitchHdl;
620                     aAny <<= (sal_Int16)eBulletFontPitch;
621                     if( aPitchHdl.exportXML( sTemp, aAny, rUnitConv  ) )
622                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
623                                                   XML_FONT_PITCH, sTemp );
624 
625                     XMLFontEncodingPropHdl aEncHdl;
626                     aAny <<= (sal_Int16)eBulletFontEncoding;
627                     if( aEncHdl.exportXML( sTemp, aAny, rUnitConv  ) )
628                         GetExport().AddAttribute( XML_NAMESPACE_STYLE,
629                                                   XML_FONT_CHARSET, sTemp );
630                 }
631             }
632         }
633         if( NumberingType::BITMAP != eType )
634         {
635             // fo:color = "#..."
636             if( bHasColor )
637             {
638                 const Color aColor( nColor );
639                 if( aColor.GetColor() == 0xffffffff )
640                 {
641                     GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_USE_WINDOW_FONT_COLOR, XML_TRUE );
642                 }
643                 else
644                 {
645                     SvXMLUnitConverter::convertColor( sBuffer, aColor );
646                     GetExport().AddAttribute( XML_NAMESPACE_FO, XML_COLOR,
647                                   sBuffer.makeStringAndClear() );
648                 }
649             }
650             // fo:height="...%"
651             if( nBullRelSize )
652             {
653                 GetExport().GetMM100UnitConverter().convertPercent( sTmp, nBullRelSize );
654                 GetExport().AddAttribute( XML_NAMESPACE_FO, XML_FONT_SIZE,
655                               sTmp.makeStringAndClear() );
656             }
657         }
658         if( GetExport().GetAttrList().getLength() > 0 )
659         {
660             SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE,
661                                       XML_TEXT_PROPERTIES, sal_True, sal_True );
662         }
663         if( NumberingType::BITMAP == eType && sImageURL.getLength() )
664         {
665             // optional office:binary-data
666             GetExport().AddEmbeddedGraphicObjectAsBase64( sImageURL );
667         }
668     }
669 }
670 
671 
672 uno::Reference< ::com::sun::star::container::XIndexReplace >  SvxXMLNumRuleExport::GetUNONumRule() const
673 {
674     return uno::Reference< ::com::sun::star::container::XIndexReplace > ();
675 }
676 
677 void SvxXMLNumRuleExport::AddListStyleAttributes()
678 {
679 }
680 
681 
682 SvxXMLNumRuleExport::SvxXMLNumRuleExport( SvXMLExport& rExp ) :
683     rExport( rExp ),
684     sNumberingRules( RTL_CONSTASCII_USTRINGPARAM( "NumberingRules" ) ),
685     sIsPhysical( RTL_CONSTASCII_USTRINGPARAM( "IsPhysical" ) ),
686     sIsContinuousNumbering( RTL_CONSTASCII_USTRINGPARAM( "IsContinuousNumbering" ) ),
687     // --> OD 2008-06-06 #i89178#
688     mbExportPositionAndSpaceModeLabelAlignment( true )
689     // <--
690 {
691     switch ( GetExport().getDefaultVersion() )
692     {
693         case SvtSaveOptions::ODFVER_010:
694         case SvtSaveOptions::ODFVER_011:
695         {
696             mbExportPositionAndSpaceModeLabelAlignment = false;
697         }
698         break;
699         default: // ODFVER_UNKNOWN or ODFVER_012
700         {
701             mbExportPositionAndSpaceModeLabelAlignment = true;
702         }
703     }
704 }
705 
706 SvxXMLNumRuleExport::~SvxXMLNumRuleExport()
707 {
708 }
709 
710 // --> OD 2008-06-17 #i90780#
711 // refactoring: removing unused methods
712 //void SvxXMLNumRuleExport::Export( const OUString& rName,
713 //                                sal_Bool bContNumbering )
714 //{
715 //  GetExport().CheckAttrList();
716 
717 //  // style:name="..."
718 //  if( rName.getLength() )
719 //  {
720 //      sal_Bool bEncoded = sal_False;
721 //      GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
722 //                        GetExport().EncodeStyleName( rName, &bEncoded ) );
723 //      if( bEncoded )
724 //          GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
725 //                                   rName);
726 //  }
727 
728 //  // text:consecutive-numbering="..."
729 //  if( bContNumbering )
730 //      GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_CONSECUTIVE_NUMBERING,
731 //                         XML_TRUE );
732 
733 //  // other application specific attributes
734 //  AddListStyleAttributes();
735 
736 //  OUString sElem = GetExport().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_TEXT,
737 //                                 GetXMLToken(XML_LIST_STYLE) );
738 //  GetExport().IgnorableWhitespace();
739 //  GetExport().StartElement( XML_NAMESPACE_TEXT, XML_LIST_STYLE, sal_False );
740 
741 //  uno::Reference< ::com::sun::star::container::XIndexReplace >  xNumRule = GetUNONumRule();
742 //  if( xNumRule.is() )
743 //      exportLevelStyles( xNumRule );
744 
745 //  GetExport().EndElement( XML_NAMESPACE_TEXT, XML_LIST_STYLE, sal_True );
746 //}
747 
748 //void SvxXMLNumRuleExport::ExportOutline()
749 //{
750 //  GetExport().IgnorableWhitespace( );
751 //  GetExport().StartElement( XML_NAMESPACE_TEXT, XML_OUTLINE_STYLE, sal_False );
752 
753 //  uno::Reference< ::com::sun::star::container::XIndexReplace >  xNumRule = GetUNONumRule();
754 //  if( xNumRule.is() )
755 //      exportLevelStyles( xNumRule, sal_True );
756 
757 //  GetExport().EndElement( XML_NAMESPACE_TEXT, XML_OUTLINE_STYLE, sal_True );
758 //}
759 // <--
760 
761 void SvxXMLNumRuleExport::exportNumberingRule(
762         const OUString& rName,
763         const Reference< XIndexReplace >& rNumRule )
764 {
765     Reference< XPropertySet > xPropSet( rNumRule, UNO_QUERY );
766     Reference< XPropertySetInfo > xPropSetInfo;
767     if( xPropSet.is() )
768         xPropSetInfo = xPropSet->getPropertySetInfo();
769 
770     GetExport().CheckAttrList();
771 
772     // style:name="..."
773     if( rName.getLength() )
774     {
775         sal_Bool bEncoded = sal_False;
776         GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
777                           GetExport().EncodeStyleName( rName, &bEncoded ) );
778         if( bEncoded )
779             GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
780                                  rName);
781     }
782 
783     // text:consecutive-numbering="..."
784     sal_Bool bContNumbering = sal_False;
785     if( xPropSetInfo.is() &&
786         xPropSetInfo->hasPropertyByName( sIsContinuousNumbering ) )
787     {
788         Any aAny( xPropSet->getPropertyValue( sIsContinuousNumbering ) );
789         bContNumbering = *(sal_Bool *)aAny.getValue();
790     }
791     if( bContNumbering )
792         GetExport().AddAttribute( XML_NAMESPACE_TEXT,
793                                   XML_CONSECUTIVE_NUMBERING, XML_TRUE );
794 
795     // other application specific attributes
796     AddListStyleAttributes();
797 
798     {
799         SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, XML_LIST_STYLE ,
800                                   sal_True, sal_True );
801         exportLevelStyles( rNumRule );
802     }
803 }
804 
805 sal_Bool SvxXMLNumRuleExport::exportStyle( const Reference< XStyle >& rStyle )
806 {
807     Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
808     Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
809 
810     Any aAny;
811 
812     // Don't export styles that aren't existing really. This may be the
813     // case for StarOffice Writer's pool styles.
814     if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
815     {
816         aAny = xPropSet->getPropertyValue( sIsPhysical );
817         if( !*(sal_Bool *)aAny.getValue() )
818             return sal_False;
819     }
820 
821     aAny = xPropSet->getPropertyValue( sNumberingRules );
822     Reference<XIndexReplace> xNumRule;
823     aAny >>= xNumRule;
824 
825     OUString sName = rStyle->getName();
826 
827     exportNumberingRule( sName, xNumRule );
828 
829     return sal_True;
830 }
831 
832 void SvxXMLNumRuleExport::exportOutline()
833 {
834     Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(),
835                                                         UNO_QUERY );
836     DBG_ASSERT( xCNSupplier.is(), "no chapter numbering supplier" );
837 
838     if( xCNSupplier.is() )
839     {
840         Reference< XIndexReplace > xNumRule( xCNSupplier->getChapterNumberingRules() );
841         DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );
842 
843         if( xNumRule.is() )
844         {
845             // --> OD 2008-06-17 #i90780#
846             // Outline style has property style:name since ODF 1.2
847             // Thus, export this property and adjust fix for issue #i69627#
848             OUString sOutlineStyleName;
849             {
850                 Reference<XPropertySet> xNumRulePropSet(
851                     xCNSupplier->getChapterNumberingRules(), UNO_QUERY );
852                 if (xNumRulePropSet.is())
853                 {
854                     const OUString sName( RTL_CONSTASCII_USTRINGPARAM("Name") );
855                     xNumRulePropSet->getPropertyValue( sName ) >>= sOutlineStyleName;
856                 }
857             }
858             const SvtSaveOptions::ODFDefaultVersion nODFVersion =
859                                                 GetExport().getDefaultVersion();
860             if ( ( nODFVersion == SvtSaveOptions::ODFVER_010 ||
861                    nODFVersion == SvtSaveOptions::ODFVER_011 ) &&
862                  GetExport().writeOutlineStyleAsNormalListStyle() )
863             {
864                 exportNumberingRule( sOutlineStyleName, xNumRule );
865             }
866             else
867             {
868                 if ( nODFVersion != SvtSaveOptions::ODFVER_010 &&
869                      nODFVersion != SvtSaveOptions::ODFVER_011 )
870                 {
871                     // style:name="..."
872                     GetExport().CheckAttrList();
873                     if ( sOutlineStyleName.getLength() > 0 )
874                      {
875                         sal_Bool bEncoded = sal_False;
876                         GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME,
877                                         GetExport().EncodeStyleName( sOutlineStyleName,
878                                                                      &bEncoded ) );
879                         if( bEncoded )
880                             GetExport().AddAttribute( XML_NAMESPACE_STYLE,
881                                                       XML_DISPLAY_NAME,
882                                                       sOutlineStyleName );
883                     }
884                 }
885                 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT,
886                                           XML_OUTLINE_STYLE, sal_True, sal_True );
887                 exportLevelStyles( xNumRule, sal_True );
888             }
889         }
890     }
891 }
892 
893 void SvxXMLNumRuleExport::exportStyles( sal_Bool bUsed,
894                                         XMLTextListAutoStylePool *pPool,
895                                         sal_Bool bExportChapterNumbering )
896 {
897     if( bExportChapterNumbering )
898         exportOutline();
899 
900     Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY );
901     DBG_ASSERT( xFamiliesSupp.is(), "No XStyleFamiliesSupplier from XModel for export!" );
902     if( xFamiliesSupp.is() )
903     {
904         Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
905         DBG_ASSERT( xFamiliesSupp.is(), "getStyleFamilies() from XModel failed for export!" );
906 
907         if( xFamilies.is() )
908         {
909             const OUString aNumberStyleName( RTL_CONSTASCII_USTRINGPARAM( "NumberingStyles" ));
910 
911             Reference< XIndexAccess > xStyles;
912             if( xFamilies->hasByName( aNumberStyleName ) )
913             {
914                 xFamilies->getByName( aNumberStyleName ) >>= xStyles;
915 
916                 DBG_ASSERT( xStyles.is(), "Style not found for export!" );
917 
918                 if( xStyles.is() )
919                 {
920                     const sal_Int32 nStyles = xStyles->getCount();
921 
922                     for( sal_Int32 i=0; i < nStyles; i++ )
923                     {
924                         Reference< XStyle > xStyle;
925                         xStyles->getByIndex( i ) >>= xStyle;
926 
927                         if( !bUsed || xStyle->isInUse() )
928                         {
929                             exportStyle( xStyle );
930                             if( pPool )
931                                 pPool->RegisterName( xStyle->getName() );
932                         }
933                     }
934                 }
935             }
936         }
937     }
938 }
939 
940 sal_Bool SvxXMLNumRuleExport::GetOutlineStyles( XMLStringVector& rStyleNames,
941    const ::com::sun::star::uno::Reference<
942                 ::com::sun::star::frame::XModel > & rModel  )
943 {
944     Reference< XChapterNumberingSupplier > xCNSupplier( rModel,
945                                                         UNO_QUERY );
946     sal_Int32 nLevels = 0;
947     Reference< XIndexReplace > xNumRule;
948     if( xCNSupplier.is() )
949     {
950         xNumRule = xCNSupplier->getChapterNumberingRules();
951         if( xNumRule.is() )
952             nLevels = xNumRule->getCount();
953     }
954 
955     rStyleNames.resize( nLevels );
956     for( sal_Int32 i=0; i<nLevels; i++ )
957     {
958         uno::Any aEntry( xNumRule->getByIndex( i ) );
959         uno::Sequence<beans::PropertyValue> aSeq;
960         if( aEntry >>= aSeq )
961         {
962             const sal_Int32 nCount = aSeq.getLength();
963             const beans::PropertyValue* pPropArray = aSeq.getConstArray();
964             for( sal_Int32 j=0; j<nCount; j++ )
965             {
966                 const beans::PropertyValue& rProp = pPropArray[j];
967 
968                 if( rProp.Name.equalsAsciiL(
969                             XML_UNO_NAME_NRULE_HEADING_STYLE_NAME,
970                             sizeof(XML_UNO_NAME_NRULE_HEADING_STYLE_NAME)-1 ) )
971                 {
972                     rProp.Value >>= rStyleNames[i];
973                     break;
974                 }
975             }
976         }
977     }
978 
979     return nLevels != 0;
980 }
981