/src/libreoffice/xmloff/source/style/xmlnume.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #include <sal/config.h> |
21 | | |
22 | | #include <com/sun/star/frame/XModel.hpp> |
23 | | #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> |
24 | | #include <com/sun/star/style/NumberingType.hpp> |
25 | | #include <com/sun/star/style/XStyle.hpp> |
26 | | #include <com/sun/star/container/XIndexReplace.hpp> |
27 | | #include <com/sun/star/awt/XBitmap.hpp> |
28 | | #include <com/sun/star/graphic/XGraphic.hpp> |
29 | | #include <com/sun/star/awt/FontDescriptor.hpp> |
30 | | #include <com/sun/star/text/HoriOrientation.hpp> |
31 | | #include <com/sun/star/text/VertOrientation.hpp> |
32 | | #include <com/sun/star/text/XChapterNumberingSupplier.hpp> |
33 | | #include <com/sun/star/text/PositionAndSpaceMode.hpp> |
34 | | #include <com/sun/star/text/LabelFollow.hpp> |
35 | | #include <com/sun/star/beans/PropertyValue.hpp> |
36 | | #include <com/sun/star/beans/XPropertySet.hpp> |
37 | | |
38 | | #include <o3tl/any.hxx> |
39 | | #include <o3tl/temporary.hxx> |
40 | | #include <rtl/ustrbuf.hxx> |
41 | | #include <sal/log.hxx> |
42 | | |
43 | | #include <sax/tools/converter.hxx> |
44 | | |
45 | | #include <xmloff/xmlnamespace.hxx> |
46 | | #include <xmloff/xmltoken.hxx> |
47 | | #include <xmloff/xmluconv.hxx> |
48 | | #include "fonthdl.hxx" |
49 | | #include <xmloff/xmlnume.hxx> |
50 | | #include <xmloff/xmlexp.hxx> |
51 | | #include <tools/fontenum.hxx> |
52 | | #include <vcl/vclenum.hxx> |
53 | | |
54 | | using namespace ::com::sun::star; |
55 | | using namespace ::com::sun::star::uno; |
56 | | using namespace ::com::sun::star::style; |
57 | | using namespace ::com::sun::star::text; |
58 | | using namespace ::com::sun::star::container; |
59 | | using namespace ::com::sun::star::beans; |
60 | | using namespace ::xmloff::token; |
61 | | |
62 | | void SvxXMLNumRuleExport::exportLevelStyles( const uno::Reference< css::container::XIndexReplace > & xNumRule, |
63 | | bool bOutline ) |
64 | 36 | { |
65 | 36 | sal_Int32 nCount = xNumRule ->getCount(); |
66 | 396 | for( sal_Int32 i=0; i<nCount; i++ ) |
67 | 360 | { |
68 | 360 | uno::Any aEntry( xNumRule->getByIndex( i ) ); |
69 | 360 | uno::Sequence<beans::PropertyValue> aSeq; |
70 | 360 | if( aEntry >>= aSeq ) |
71 | 360 | { |
72 | 360 | exportLevelStyle( i, aSeq, bOutline ); |
73 | 360 | } |
74 | 360 | } |
75 | 36 | } |
76 | | |
77 | | void SvxXMLNumRuleExport::exportLevelStyle( sal_Int32 nLevel, |
78 | | const uno::Sequence<beans::PropertyValue>& rProps, |
79 | | bool bOutline ) |
80 | 360 | { |
81 | 360 | sal_Int16 eType = NumberingType::CHAR_SPECIAL; |
82 | | |
83 | 360 | sal_Int16 eAdjust = HoriOrientation::LEFT; |
84 | 360 | OUString sPrefix, sSuffix, sListFormat; |
85 | 360 | OUString sTextStyleName; |
86 | 360 | bool bIsLegal = false; |
87 | 360 | bool bHasColor = false; |
88 | 360 | sal_Int32 nColor = 0; |
89 | 360 | sal_Int32 nSpaceBefore = 0, nMinLabelWidth = 0, nMinLabelDist = 0; |
90 | | |
91 | 360 | sal_Int16 nStartValue = 1, nDisplayLevels = 1, nBullRelSize = 0; |
92 | | |
93 | 360 | sal_UCS4 cBullet = 0xf095; |
94 | 360 | OUString sBulletFontName, sBulletFontStyleName ; |
95 | 360 | FontFamily eBulletFontFamily = FAMILY_DONTKNOW; |
96 | 360 | FontPitch eBulletFontPitch = PITCH_DONTKNOW; |
97 | 360 | rtl_TextEncoding eBulletFontEncoding = RTL_TEXTENCODING_DONTKNOW; |
98 | | |
99 | 360 | uno::Reference<graphic::XGraphic> xGraphic; |
100 | | |
101 | 360 | sal_Int32 nImageWidth = 0, nImageHeight = 0; |
102 | 360 | sal_Int16 eImageVertOrient = VertOrientation::LINE_CENTER; |
103 | | |
104 | 360 | sal_Int16 ePosAndSpaceMode = PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION; |
105 | 360 | sal_Int16 eLabelFollowedBy = LabelFollow::LISTTAB; |
106 | 360 | sal_Int32 nListtabStopPosition( 0 ); |
107 | 360 | sal_Int32 nFirstLineIndent( 0 ); |
108 | 360 | sal_Int32 nIndentAt( 0 ); |
109 | | |
110 | 360 | for( const beans::PropertyValue& rProp : rProps ) |
111 | 4.68k | { |
112 | 4.68k | if( rProp.Name == "NumberingType" ) |
113 | 360 | { |
114 | 360 | rProp.Value >>= eType; |
115 | 360 | } |
116 | 4.32k | else if( rProp.Name == "Prefix" ) |
117 | 360 | { |
118 | 360 | rProp.Value >>= sPrefix; |
119 | 360 | } |
120 | 3.96k | else if( rProp.Name == "Suffix" ) |
121 | 360 | { |
122 | 360 | rProp.Value >>= sSuffix; |
123 | 360 | } |
124 | 3.60k | else if (rProp.Name == "ListFormat") |
125 | 0 | { |
126 | 0 | rProp.Value >>= sListFormat; |
127 | 0 | } |
128 | 3.60k | else if (rProp.Name == "IsLegal") |
129 | 0 | { |
130 | 0 | rProp.Value >>= bIsLegal; |
131 | 0 | } |
132 | 3.60k | else if (rProp.Name == "BulletChar") |
133 | 360 | { |
134 | 360 | OUString sValue; |
135 | 360 | rProp.Value >>= sValue; |
136 | 360 | if( !sValue.isEmpty() ) |
137 | 360 | { |
138 | 360 | cBullet = sValue.iterateCodePoints(&o3tl::temporary(sal_Int32(0))); |
139 | 360 | } |
140 | 360 | } |
141 | 3.24k | else if( rProp.Name == "BulletRelSize" ) |
142 | 360 | { |
143 | 360 | rProp.Value >>= nBullRelSize; |
144 | 360 | } |
145 | 2.88k | else if( rProp.Name == "Adjust" ) |
146 | 360 | { |
147 | 360 | sal_Int16 nValue = 0; |
148 | 360 | rProp.Value >>= nValue; |
149 | 360 | eAdjust = nValue; |
150 | 360 | } |
151 | 2.52k | else if( rProp.Name == "BulletFont" ) |
152 | 360 | { |
153 | 360 | awt::FontDescriptor rFDesc; |
154 | 360 | if( rProp.Value >>= rFDesc ) |
155 | 360 | { |
156 | 360 | sBulletFontName = rFDesc.Name; |
157 | 360 | sBulletFontStyleName = rFDesc.StyleName; |
158 | 360 | eBulletFontFamily = static_cast< FontFamily >( rFDesc.Family ); |
159 | 360 | eBulletFontPitch = static_cast< FontPitch >( rFDesc.Pitch ); |
160 | 360 | eBulletFontEncoding = static_cast<rtl_TextEncoding>(rFDesc.CharSet); |
161 | 360 | } |
162 | 360 | } |
163 | 2.16k | else if( rProp.Name == "GraphicBitmap" ) |
164 | 0 | { |
165 | 0 | uno::Reference<awt::XBitmap> xBitmap; |
166 | 0 | rProp.Value >>= xBitmap; |
167 | 0 | xGraphic.set(xBitmap, uno::UNO_QUERY); |
168 | 0 | } |
169 | 2.16k | else if( rProp.Name == "BulletColor" ) |
170 | 360 | { |
171 | 360 | rProp.Value >>= nColor; |
172 | 360 | bHasColor = true; |
173 | 360 | } |
174 | 1.80k | else if( rProp.Name == "StartWith" ) |
175 | 360 | { |
176 | 360 | rProp.Value >>= nStartValue; |
177 | 360 | } |
178 | 1.44k | else if( rProp.Name == "LeftMargin" ) |
179 | 360 | { |
180 | 360 | rProp.Value >>= nSpaceBefore; |
181 | 360 | } |
182 | 1.08k | else if( rProp.Name == "FirstLineOffset" ) |
183 | 360 | { |
184 | 360 | rProp.Value >>= nMinLabelWidth; |
185 | 360 | } |
186 | 720 | else if( rProp.Name == "SymbolTextDistance" ) |
187 | 360 | { |
188 | 360 | rProp.Value >>= nMinLabelDist; |
189 | 360 | } |
190 | 360 | else if( rProp.Name == "ParentNumbering" ) |
191 | 0 | { |
192 | 0 | rProp.Value >>= nDisplayLevels; |
193 | 0 | if( nDisplayLevels > nLevel+1 ) |
194 | 0 | nDisplayLevels = static_cast<sal_Int16>( nLevel )+1; |
195 | 0 | } |
196 | 360 | else if( rProp.Name == "CharStyleName" ) |
197 | 0 | { |
198 | 0 | rProp.Value >>= sTextStyleName; |
199 | 0 | } |
200 | 360 | else if( rProp.Name == "GraphicSize" ) |
201 | 360 | { |
202 | 360 | awt::Size aSize; |
203 | 360 | if( rProp.Value >>= aSize ) |
204 | 360 | { |
205 | 360 | nImageWidth = aSize.Width; |
206 | 360 | nImageHeight = aSize.Height; |
207 | 360 | } |
208 | 360 | } |
209 | 0 | else if( rProp.Name == "VertOrient" ) |
210 | 0 | { |
211 | 0 | sal_Int16 nValue = 0; |
212 | 0 | rProp.Value >>= nValue; |
213 | 0 | eImageVertOrient = nValue; |
214 | 0 | } |
215 | 0 | else if( rProp.Name == "PositionAndSpaceMode" ) |
216 | 0 | { |
217 | 0 | sal_Int16 nValue = 0; |
218 | 0 | rProp.Value >>= nValue; |
219 | 0 | ePosAndSpaceMode = nValue; |
220 | 0 | } |
221 | 0 | else if( rProp.Name == "LabelFollowedBy" ) |
222 | 0 | { |
223 | 0 | sal_Int16 nValue = 0; |
224 | 0 | rProp.Value >>= nValue; |
225 | 0 | eLabelFollowedBy = nValue; |
226 | 0 | } |
227 | 0 | else if( rProp.Name == "ListtabStopPosition" ) |
228 | 0 | { |
229 | 0 | rProp.Value >>= nListtabStopPosition; |
230 | 0 | } |
231 | 0 | else if( rProp.Name == "FirstLineIndent" ) |
232 | 0 | { |
233 | 0 | rProp.Value >>= nFirstLineIndent; |
234 | 0 | } |
235 | 0 | else if( rProp.Name == "IndentAt" ) |
236 | 0 | { |
237 | 0 | rProp.Value >>= nIndentAt; |
238 | 0 | } |
239 | 4.68k | } |
240 | | |
241 | 360 | if( bOutline && (NumberingType::CHAR_SPECIAL == eType || |
242 | 0 | NumberingType::BITMAP == eType) ) |
243 | 0 | { |
244 | 0 | SAL_WARN_IF( bOutline, "xmloff", |
245 | 0 | "SvxXMLNumRuleExport::exportLevelStyle: invalid style for outline" ); |
246 | 0 | return; |
247 | 0 | } |
248 | | |
249 | 360 | GetExport().CheckAttrList(); |
250 | | |
251 | | // text:level |
252 | 360 | OUStringBuffer sTmp; |
253 | 360 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_LEVEL, OUString::number( nLevel + 1 ) ); |
254 | | // #i110694#: no style-name on list-level-style-image |
255 | | // #i116149#: neither prefix/suffix |
256 | 360 | if (NumberingType::BITMAP != eType) |
257 | 360 | { |
258 | 360 | if (!sTextStyleName.isEmpty()) |
259 | 0 | { |
260 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME, |
261 | 0 | GetExport().EncodeStyleName( sTextStyleName ) ); |
262 | 0 | } |
263 | 360 | if (bIsLegal) |
264 | 0 | { |
265 | 0 | if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
266 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_IS_LEGAL, u"true"_ustr); |
267 | 0 | } |
268 | 360 | if (!sListFormat.isEmpty()) |
269 | 0 | { |
270 | 0 | if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
271 | 0 | { |
272 | | // Write only in extended mode: in ODF 1.3 we write only prefix/suffix, |
273 | | // no list format yet available. Praying we did not lost some formatting. |
274 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_NUM_LIST_FORMAT, sListFormat); |
275 | 0 | } |
276 | 0 | } |
277 | 360 | if (!sPrefix.isEmpty()) |
278 | 0 | { |
279 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_PREFIX, |
280 | 0 | sPrefix ); |
281 | 0 | } |
282 | 360 | if (!sSuffix.isEmpty()) |
283 | 0 | { |
284 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, |
285 | 0 | sSuffix ); |
286 | 0 | } |
287 | 360 | } |
288 | | |
289 | 360 | enum XMLTokenEnum eElem = XML_LIST_LEVEL_STYLE_NUMBER; |
290 | 360 | if( NumberingType::CHAR_SPECIAL == eType ) |
291 | 360 | { |
292 | | // <text:list-level-style-bullet> |
293 | 360 | eElem = XML_LIST_LEVEL_STYLE_BULLET; |
294 | | |
295 | 360 | if( cBullet ) |
296 | 360 | { |
297 | 360 | if( cBullet < ' ' ) |
298 | 0 | { |
299 | 0 | cBullet = 0xF000 + 149; |
300 | 0 | } |
301 | | // text:bullet-char="..." |
302 | 360 | sTmp.append(OUString(&cBullet, 1)); |
303 | 360 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_BULLET_CHAR, |
304 | 360 | sTmp.makeStringAndClear() ); |
305 | 360 | } |
306 | 0 | else |
307 | 0 | { |
308 | | // If 'cBullet' is zero, XML_BULLET_CHAR must exist with blank. |
309 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_BULLET_CHAR, u""_ustr); |
310 | 0 | } |
311 | 360 | } |
312 | 0 | else if( NumberingType::BITMAP == eType ) |
313 | 0 | { |
314 | | // <text:list-level-style-image> |
315 | |
|
316 | 0 | eElem = XML_LIST_LEVEL_STYLE_IMAGE; |
317 | |
|
318 | 0 | if (xGraphic.is()) |
319 | 0 | { |
320 | 0 | OUString sUsedMimeType; |
321 | 0 | OUString sInternalURL = GetExport().AddEmbeddedXGraphic(xGraphic, sUsedMimeType); |
322 | 0 | if (!sInternalURL.isEmpty()) |
323 | 0 | { |
324 | 0 | GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, sInternalURL); |
325 | 0 | GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); |
326 | 0 | GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_SHOW, XML_EMBED ); |
327 | 0 | GetExport().AddAttribute( XML_NAMESPACE_XLINK, XML_ACTUATE, XML_ONLOAD ); |
328 | 0 | } |
329 | 0 | } |
330 | 0 | else |
331 | 0 | { |
332 | 0 | SAL_WARN_IF(xGraphic.is(), "xmloff", "embedded images are not supported by now"); |
333 | 0 | } |
334 | 0 | } |
335 | 0 | else |
336 | 0 | { |
337 | | // <text:list-level-style-number> or <text:outline-level-style> |
338 | 0 | if( bOutline ) |
339 | 0 | eElem = XML_OUTLINE_LEVEL_STYLE; |
340 | 0 | else |
341 | 0 | eElem = XML_LIST_LEVEL_STYLE_NUMBER; |
342 | |
|
343 | 0 | GetExport().GetMM100UnitConverter().convertNumFormat( sTmp, eType ); |
344 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NUM_FORMAT, |
345 | 0 | sTmp.makeStringAndClear() ); |
346 | 0 | SvXMLUnitConverter::convertNumLetterSync( sTmp, eType ); |
347 | 0 | if( !sTmp.isEmpty() ) |
348 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
349 | 0 | XML_NUM_LETTER_SYNC, |
350 | 0 | sTmp.makeStringAndClear() ); |
351 | |
|
352 | 0 | if( nStartValue != 1 ) |
353 | 0 | { |
354 | 0 | sTmp.append( static_cast<sal_Int32>(nStartValue) ); |
355 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE, |
356 | 0 | sTmp.makeStringAndClear() ); |
357 | 0 | } |
358 | 0 | if( nDisplayLevels > 1 && NumberingType::NUMBER_NONE != eType ) |
359 | 0 | { |
360 | 0 | sTmp.append( static_cast<sal_Int32>(nDisplayLevels) ); |
361 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_DISPLAY_LEVELS, |
362 | 0 | sTmp.makeStringAndClear() ); |
363 | 0 | } |
364 | 0 | } |
365 | | |
366 | 360 | { |
367 | 360 | SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, eElem, |
368 | 360 | true, true ); |
369 | | |
370 | 360 | if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_WIDTH_AND_POSITION ) |
371 | 360 | { |
372 | 360 | nSpaceBefore += nMinLabelWidth; |
373 | 360 | nMinLabelWidth = -nMinLabelWidth; |
374 | 360 | if( nSpaceBefore != 0 ) |
375 | 324 | { |
376 | 324 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
377 | 324 | nSpaceBefore ); |
378 | 324 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_SPACE_BEFORE, sAttr ); |
379 | 324 | } |
380 | 360 | if( nMinLabelWidth != 0 ) |
381 | 360 | { |
382 | 360 | OUString s = GetExport().GetMM100UnitConverter().convertMeasureToXML( nMinLabelWidth ); |
383 | 360 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_WIDTH, s); |
384 | 360 | } |
385 | 360 | if( nMinLabelDist > 0 ) |
386 | 0 | { |
387 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
388 | 0 | nMinLabelDist ); |
389 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_MIN_LABEL_DISTANCE, sAttr); |
390 | 0 | } |
391 | 360 | } |
392 | | /* Check, if properties for position-and-space-mode LABEL_ALIGNMENT |
393 | | are allowed to be exported. (#i89178#) |
394 | | */ |
395 | 0 | else if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT && |
396 | 0 | mbExportPositionAndSpaceModeLabelAlignment ) |
397 | 0 | { |
398 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, |
399 | 0 | XML_LIST_LEVEL_POSITION_AND_SPACE_MODE, |
400 | 0 | XML_LABEL_ALIGNMENT ); |
401 | 0 | } |
402 | 360 | if( HoriOrientation::LEFT != eAdjust ) |
403 | 0 | { |
404 | 0 | enum XMLTokenEnum eValue = XML_TOKEN_INVALID; |
405 | 0 | switch( eAdjust ) |
406 | 0 | { |
407 | 0 | case HoriOrientation::RIGHT: eValue = XML_END; break; |
408 | 0 | case HoriOrientation::CENTER: eValue = XML_CENTER; break; |
409 | 0 | } |
410 | 0 | if( eValue != XML_TOKEN_INVALID ) |
411 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, XML_TEXT_ALIGN, eValue ); |
412 | 0 | } |
413 | | |
414 | 360 | if( NumberingType::BITMAP == eType ) |
415 | 0 | { |
416 | 0 | enum XMLTokenEnum eValue = XML_TOKEN_INVALID; |
417 | 0 | switch( eImageVertOrient ) |
418 | 0 | { |
419 | 0 | case VertOrientation::BOTTOM: // yes, it's OK: BOTTOM means that the baseline |
420 | | // hits the frame at its topmost position |
421 | 0 | case VertOrientation::LINE_TOP: |
422 | 0 | case VertOrientation::CHAR_TOP: |
423 | 0 | eValue = XML_TOP; |
424 | 0 | break; |
425 | 0 | case VertOrientation::CENTER: |
426 | 0 | case VertOrientation::LINE_CENTER: |
427 | 0 | case VertOrientation::CHAR_CENTER: |
428 | 0 | eValue = XML_MIDDLE; |
429 | 0 | break; |
430 | 0 | case VertOrientation::TOP: // yes, it's OK: TOP means that the baseline |
431 | | // hits the frame at its bottommost position |
432 | 0 | case VertOrientation::LINE_BOTTOM: |
433 | 0 | case VertOrientation::CHAR_BOTTOM: |
434 | 0 | eValue = XML_BOTTOM; |
435 | 0 | break; |
436 | 0 | } |
437 | 0 | if( eValue != XML_TOKEN_INVALID ) |
438 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_POS, eValue ); |
439 | |
|
440 | 0 | eValue = XML_TOKEN_INVALID; |
441 | 0 | switch( eImageVertOrient ) |
442 | 0 | { |
443 | 0 | case VertOrientation::TOP: |
444 | 0 | case VertOrientation::CENTER: |
445 | 0 | case VertOrientation::BOTTOM: |
446 | 0 | eValue = XML_BASELINE; |
447 | 0 | break; |
448 | 0 | case VertOrientation::LINE_TOP: |
449 | 0 | case VertOrientation::LINE_CENTER: |
450 | 0 | case VertOrientation::LINE_BOTTOM: |
451 | 0 | eValue = XML_LINE; |
452 | 0 | break; |
453 | 0 | case VertOrientation::CHAR_TOP: |
454 | 0 | case VertOrientation::CHAR_CENTER: |
455 | 0 | case VertOrientation::CHAR_BOTTOM: |
456 | 0 | eValue = XML_CHAR; |
457 | 0 | break; |
458 | 0 | } |
459 | 0 | if( eValue != XML_TOKEN_INVALID ) |
460 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_VERTICAL_REL, eValue ); |
461 | |
|
462 | 0 | if( nImageWidth > 0 ) |
463 | 0 | { |
464 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
465 | 0 | nImageWidth ); |
466 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, XML_WIDTH, sAttr ); |
467 | 0 | } |
468 | |
|
469 | 0 | if( nImageHeight > 0 ) |
470 | 0 | { |
471 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
472 | 0 | nImageHeight ); |
473 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, XML_HEIGHT, sAttr ); |
474 | 0 | } |
475 | 0 | } |
476 | | |
477 | 360 | { |
478 | 360 | SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE, |
479 | 360 | XML_LIST_LEVEL_PROPERTIES, true, true ); |
480 | | |
481 | | /* Check, if properties for position-and-space-mode LABEL_ALIGNMENT |
482 | | are allowed to be exported. (#i89178#) |
483 | | */ |
484 | 360 | if ( ePosAndSpaceMode == PositionAndSpaceMode::LABEL_ALIGNMENT && |
485 | 0 | mbExportPositionAndSpaceModeLabelAlignment ) |
486 | 0 | { |
487 | 0 | enum XMLTokenEnum eValue = XML_LISTTAB; |
488 | 0 | if ( eLabelFollowedBy == LabelFollow::SPACE ) |
489 | 0 | { |
490 | 0 | eValue = XML_SPACE; |
491 | 0 | } |
492 | 0 | else if ( eLabelFollowedBy == LabelFollow::NOTHING ) |
493 | 0 | { |
494 | 0 | eValue = XML_NOTHING; |
495 | 0 | } |
496 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, |
497 | 0 | XML_LABEL_FOLLOWED_BY, eValue ); |
498 | |
|
499 | 0 | if (eLabelFollowedBy == LabelFollow::NEWLINE) |
500 | 0 | { |
501 | 0 | eValue = XML_NEWLINE; |
502 | 0 | GetExport().AddAttribute( XML_NAMESPACE_LO_EXT, |
503 | 0 | XML_LABEL_FOLLOWED_BY, eValue ); |
504 | 0 | } |
505 | |
|
506 | 0 | if ( eLabelFollowedBy == LabelFollow::LISTTAB && |
507 | 0 | nListtabStopPosition > 0 ) |
508 | 0 | { |
509 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
510 | 0 | nListtabStopPosition ); |
511 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, |
512 | 0 | XML_LIST_TAB_STOP_POSITION, |
513 | 0 | sAttr ); |
514 | 0 | } |
515 | |
|
516 | 0 | if ( nFirstLineIndent != 0 ) |
517 | 0 | { |
518 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
519 | 0 | nFirstLineIndent ); |
520 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, |
521 | 0 | XML_TEXT_INDENT, |
522 | 0 | sAttr ); |
523 | 0 | } |
524 | |
|
525 | 0 | if ( nIndentAt != 0 ) |
526 | 0 | { |
527 | 0 | OUString sAttr = GetExport().GetMM100UnitConverter().convertMeasureToXML( |
528 | 0 | nIndentAt ); |
529 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, |
530 | 0 | XML_MARGIN_LEFT, |
531 | 0 | sAttr ); |
532 | 0 | } |
533 | |
|
534 | 0 | SvXMLElementExport aLabelAlignmentElement( GetExport(), XML_NAMESPACE_STYLE, |
535 | 0 | XML_LIST_LEVEL_LABEL_ALIGNMENT, |
536 | 0 | true, true ); |
537 | 0 | } |
538 | 360 | } |
539 | | |
540 | 360 | if( NumberingType::CHAR_SPECIAL == eType ) |
541 | 360 | { |
542 | 360 | if( !sBulletFontName.isEmpty() ) |
543 | 360 | { |
544 | 360 | OUString sStyleName = |
545 | 360 | GetExport().GetFontAutoStylePool()->Find( |
546 | 360 | sBulletFontName, sBulletFontStyleName, |
547 | 360 | eBulletFontFamily, eBulletFontPitch, |
548 | 360 | eBulletFontEncoding ); |
549 | | |
550 | 360 | if( !sStyleName.isEmpty() ) |
551 | 0 | { |
552 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
553 | 0 | XML_FONT_NAME, |
554 | 0 | sStyleName ); |
555 | 0 | } |
556 | 360 | else |
557 | 360 | { |
558 | 360 | OUString sTemp; |
559 | | |
560 | 360 | const SvXMLUnitConverter& rUnitConv = |
561 | 360 | GetExport().GetMM100UnitConverter(); |
562 | 360 | XMLFontFamilyNamePropHdl aFamilyNameHdl; |
563 | 360 | if( aFamilyNameHdl.exportXML( sTemp, Any(sBulletFontName), rUnitConv ) ) |
564 | 360 | GetExport().AddAttribute( XML_NAMESPACE_FO, |
565 | 360 | XML_FONT_FAMILY, sTemp ); |
566 | | |
567 | 360 | if( !sBulletFontStyleName.isEmpty() ) |
568 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
569 | 0 | XML_FONT_STYLE_NAME, |
570 | 0 | sBulletFontStyleName ); |
571 | | |
572 | 360 | XMLFontFamilyPropHdl aFamilyHdl; |
573 | 360 | if( aFamilyHdl.exportXML( sTemp, Any(static_cast<sal_Int16>(eBulletFontFamily)), rUnitConv ) ) |
574 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
575 | 0 | XML_FONT_FAMILY_GENERIC, |
576 | 0 | sTemp ); |
577 | | |
578 | 360 | XMLFontPitchPropHdl aPitchHdl; |
579 | 360 | if( aPitchHdl.exportXML( sTemp, Any(static_cast<sal_Int16>(eBulletFontPitch)), rUnitConv ) ) |
580 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
581 | 0 | XML_FONT_PITCH, sTemp ); |
582 | | |
583 | 360 | XMLFontEncodingPropHdl aEncHdl; |
584 | 360 | if( aEncHdl.exportXML( sTemp, Any(static_cast<sal_Int16>(eBulletFontEncoding)), rUnitConv ) ) |
585 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
586 | 0 | XML_FONT_CHARSET, sTemp ); |
587 | 360 | } |
588 | 360 | } |
589 | 360 | } |
590 | 360 | if( NumberingType::BITMAP != eType ) |
591 | 360 | { |
592 | | // fo:color = "#..." |
593 | 360 | if( bHasColor ) |
594 | 360 | { |
595 | 360 | if (0xffffffff == static_cast<sal_uInt32>(nColor)) |
596 | 360 | { |
597 | 360 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_USE_WINDOW_FONT_COLOR, XML_TRUE ); |
598 | 360 | } |
599 | 0 | else |
600 | 0 | { |
601 | 0 | OUStringBuffer sBuffer; |
602 | 0 | ::sax::Converter::convertColor( sBuffer, nColor ); |
603 | 0 | GetExport().AddAttribute( XML_NAMESPACE_FO, XML_COLOR, |
604 | 0 | sBuffer.makeStringAndClear() ); |
605 | 0 | } |
606 | 360 | } |
607 | | // fo:height="...%" |
608 | 360 | if( nBullRelSize ) |
609 | 360 | { |
610 | 360 | ::sax::Converter::convertPercent( sTmp, nBullRelSize ); |
611 | 360 | GetExport().AddAttribute( XML_NAMESPACE_FO, XML_FONT_SIZE, |
612 | 360 | sTmp.makeStringAndClear() ); |
613 | 360 | } |
614 | 360 | } |
615 | 360 | if( GetExport().GetAttrList().getLength() > 0 ) |
616 | 360 | { |
617 | 360 | SvXMLElementExport aElement( GetExport(), XML_NAMESPACE_STYLE, |
618 | 360 | XML_TEXT_PROPERTIES, true, true ); |
619 | 360 | } |
620 | 360 | if (xGraphic.is() && NumberingType::BITMAP == eType) |
621 | 0 | { |
622 | | // optional office:binary-data |
623 | 0 | GetExport().AddEmbeddedXGraphicAsBase64(xGraphic); |
624 | 0 | } |
625 | 360 | } |
626 | 360 | } |
627 | | |
628 | | |
629 | | constexpr OUStringLiteral gsNumberingRules( u"NumberingRules" ); |
630 | | constexpr OUString gsIsPhysical( u"IsPhysical"_ustr ); |
631 | | constexpr OUString gsIsContinuousNumbering( u"IsContinuousNumbering"_ustr ); |
632 | | |
633 | | SvxXMLNumRuleExport::SvxXMLNumRuleExport( SvXMLExport& rExp ) : |
634 | 106 | m_rExport( rExp ), |
635 | | // Let list style creation depend on Load/Save option "ODF format version" (#i89178#) |
636 | 106 | mbExportPositionAndSpaceModeLabelAlignment( true ) |
637 | 106 | { |
638 | 106 | switch (GetExport().getSaneDefaultVersion()) |
639 | 106 | { |
640 | 0 | case SvtSaveOptions::ODFSVER_010: |
641 | 0 | case SvtSaveOptions::ODFSVER_011: |
642 | 0 | { |
643 | 0 | mbExportPositionAndSpaceModeLabelAlignment = false; |
644 | 0 | } |
645 | 0 | break; |
646 | 106 | default: // >= ODFSVER_012 |
647 | 106 | { |
648 | 106 | mbExportPositionAndSpaceModeLabelAlignment = true; |
649 | 106 | } |
650 | 106 | } |
651 | 106 | } |
652 | | |
653 | | void SvxXMLNumRuleExport::exportNumberingRule( |
654 | | const OUString& rName, bool bIsHidden, |
655 | | const Reference< XIndexReplace >& rNumRule ) |
656 | 36 | { |
657 | 36 | Reference< XPropertySet > xPropSet( rNumRule, UNO_QUERY ); |
658 | 36 | Reference< XPropertySetInfo > xPropSetInfo; |
659 | 36 | if( xPropSet.is() ) |
660 | 0 | xPropSetInfo = xPropSet->getPropertySetInfo(); |
661 | | |
662 | 36 | GetExport().CheckAttrList(); |
663 | | |
664 | | // style:name="..." |
665 | 36 | if( !rName.isEmpty() ) |
666 | 36 | { |
667 | 36 | bool bEncoded = false; |
668 | 36 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, |
669 | 36 | GetExport().EncodeStyleName( rName, &bEncoded ) ); |
670 | 36 | if( bEncoded ) |
671 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, |
672 | 0 | rName); |
673 | 36 | } |
674 | | |
675 | | // style:hidden="..." |
676 | 36 | if (bIsHidden |
677 | 0 | && GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED) |
678 | 0 | { |
679 | 0 | GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_HIDDEN, u"true"_ustr); |
680 | 0 | GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_HIDDEN, u"true"_ustr); // FIXME for compatibility |
681 | 0 | } |
682 | | |
683 | | // text:consecutive-numbering="..." |
684 | 36 | bool bContNumbering = false; |
685 | 36 | if( xPropSetInfo.is() && |
686 | 0 | xPropSetInfo->hasPropertyByName( gsIsContinuousNumbering ) ) |
687 | 0 | { |
688 | 0 | Any aAny( xPropSet->getPropertyValue( gsIsContinuousNumbering ) ); |
689 | 0 | bContNumbering = *o3tl::doAccess<bool>(aAny); |
690 | 0 | } |
691 | 36 | if( bContNumbering ) |
692 | 0 | GetExport().AddAttribute( XML_NAMESPACE_TEXT, |
693 | 0 | XML_CONSECUTIVE_NUMBERING, XML_TRUE ); |
694 | | |
695 | 36 | { |
696 | 36 | SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, XML_LIST_STYLE , |
697 | 36 | true, true ); |
698 | 36 | exportLevelStyles( rNumRule ); |
699 | 36 | } |
700 | 36 | } |
701 | | |
702 | | void SvxXMLNumRuleExport::exportStyle( const Reference< XStyle >& rStyle ) |
703 | 0 | { |
704 | 0 | Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY ); |
705 | 0 | Reference< XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo(); |
706 | |
|
707 | 0 | Any aAny; |
708 | | |
709 | | // Don't export styles that aren't existing really. This may be the |
710 | | // case for StarOffice Writer's pool styles. |
711 | 0 | if( xPropSetInfo->hasPropertyByName( gsIsPhysical ) ) |
712 | 0 | { |
713 | 0 | aAny = xPropSet->getPropertyValue( gsIsPhysical ); |
714 | 0 | if( !*o3tl::doAccess<bool>(aAny) ) |
715 | 0 | return; |
716 | 0 | } |
717 | | |
718 | 0 | aAny = xPropSet->getPropertyValue( gsNumberingRules ); |
719 | 0 | Reference<XIndexReplace> xNumRule; |
720 | 0 | aAny >>= xNumRule; |
721 | |
|
722 | 0 | OUString sName = rStyle->getName(); |
723 | |
|
724 | 0 | bool bHidden = false; |
725 | 0 | if ( xPropSetInfo->hasPropertyByName( u"Hidden"_ustr ) ) |
726 | 0 | { |
727 | 0 | aAny = xPropSet->getPropertyValue( u"Hidden"_ustr ); |
728 | 0 | aAny >>= bHidden; |
729 | 0 | } |
730 | |
|
731 | 0 | exportNumberingRule( sName, bHidden, xNumRule ); |
732 | 0 | } |
733 | | |
734 | | void SvxXMLNumRuleExport::exportOutline() |
735 | 0 | { |
736 | 0 | Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(), |
737 | 0 | UNO_QUERY ); |
738 | 0 | SAL_WARN_IF( !xCNSupplier.is(), "xmloff", "no chapter numbering supplier" ); |
739 | | |
740 | 0 | if( !xCNSupplier.is() ) |
741 | 0 | return; |
742 | | |
743 | 0 | Reference< XIndexReplace > xNumRule( xCNSupplier->getChapterNumberingRules() ); |
744 | 0 | SAL_WARN_IF( !xNumRule.is(), "xmloff", "no chapter numbering rules" ); |
745 | | |
746 | 0 | if( !xNumRule.is() ) |
747 | 0 | return; |
748 | | |
749 | | /* Outline style has property style:name since ODF 1.2 |
750 | | Thus, export this property and adjust fix for issue #i69627# (#i90780#) |
751 | | */ |
752 | 0 | OUString sOutlineStyleName; |
753 | 0 | { |
754 | 0 | Reference<XPropertySet> xNumRulePropSet( |
755 | 0 | xCNSupplier->getChapterNumberingRules(), UNO_QUERY ); |
756 | 0 | if (xNumRulePropSet.is()) |
757 | 0 | { |
758 | 0 | xNumRulePropSet->getPropertyValue( u"Name"_ustr ) >>= sOutlineStyleName; |
759 | 0 | } |
760 | 0 | } |
761 | 0 | const SvtSaveOptions::ODFSaneDefaultVersion nODFVersion = |
762 | 0 | GetExport().getSaneDefaultVersion(); |
763 | 0 | if ((nODFVersion == SvtSaveOptions::ODFSVER_010 || |
764 | 0 | nODFVersion == SvtSaveOptions::ODFSVER_011) |
765 | 0 | && GetExport().writeOutlineStyleAsNormalListStyle()) |
766 | 0 | { |
767 | 0 | exportNumberingRule( sOutlineStyleName, false, xNumRule ); |
768 | 0 | } |
769 | 0 | else |
770 | 0 | { |
771 | 0 | if (nODFVersion != SvtSaveOptions::ODFSVER_010 && |
772 | 0 | nODFVersion != SvtSaveOptions::ODFSVER_011) |
773 | 0 | { |
774 | | // style:name="..." |
775 | 0 | GetExport().CheckAttrList(); |
776 | 0 | if ( !sOutlineStyleName.isEmpty() ) |
777 | 0 | { |
778 | 0 | bool bEncoded = false; |
779 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, |
780 | 0 | GetExport().EncodeStyleName( sOutlineStyleName, |
781 | 0 | &bEncoded ) ); |
782 | 0 | if( bEncoded ) |
783 | 0 | GetExport().AddAttribute( XML_NAMESPACE_STYLE, |
784 | 0 | XML_DISPLAY_NAME, |
785 | 0 | sOutlineStyleName ); |
786 | 0 | } |
787 | 0 | } |
788 | 0 | SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, |
789 | 0 | XML_OUTLINE_STYLE, true, true ); |
790 | 0 | exportLevelStyles( xNumRule, true ); |
791 | 0 | } |
792 | 0 | } |
793 | | |
794 | | void SvxXMLNumRuleExport::exportStyles( bool bUsed, bool bExportChapterNumbering ) |
795 | 0 | { |
796 | 0 | if( bExportChapterNumbering ) |
797 | 0 | exportOutline(); |
798 | |
|
799 | 0 | Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY ); |
800 | 0 | SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", "No XStyleFamiliesSupplier from XModel for export!" ); |
801 | 0 | if( !xFamiliesSupp.is() ) |
802 | 0 | return; |
803 | | |
804 | 0 | Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() ); |
805 | 0 | SAL_WARN_IF( !xFamiliesSupp.is(), "xmloff", "getStyleFamilies() from XModel failed for export!" ); |
806 | | |
807 | 0 | if( !xFamilies.is() ) |
808 | 0 | return; |
809 | | |
810 | 0 | static constexpr OUString aNumberStyleName( u"NumberingStyles"_ustr ); |
811 | |
|
812 | 0 | Reference< XIndexAccess > xStyles; |
813 | 0 | if( !xFamilies->hasByName( aNumberStyleName ) ) |
814 | 0 | return; |
815 | | |
816 | 0 | xFamilies->getByName( aNumberStyleName ) >>= xStyles; |
817 | |
|
818 | 0 | SAL_WARN_IF( !xStyles.is(), "xmloff", "Style not found for export!" ); |
819 | | |
820 | 0 | if( !xStyles.is() ) |
821 | 0 | return; |
822 | | |
823 | 0 | const sal_Int32 nStyles = xStyles->getCount(); |
824 | |
|
825 | 0 | for( sal_Int32 i=0; i < nStyles; i++ ) |
826 | 0 | { |
827 | 0 | Reference< XStyle > xStyle; |
828 | 0 | xStyles->getByIndex( i ) >>= xStyle; |
829 | |
|
830 | 0 | if( !bUsed || xStyle->isInUse() ) |
831 | 0 | exportStyle( xStyle ); |
832 | |
|
833 | 0 | } |
834 | 0 | } |
835 | | |
836 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |