xref: /trunk/main/xmloff/source/style/xmlnume.cxx (revision cdf0e10c)
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