File: | home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx |
Warning: | line 550, column 25 1st function call argument is an uninitialized value |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <algorithm> | |||
23 | ||||
24 | #include <editeng/numitem.hxx> | |||
25 | ||||
26 | #include <com/sun/star/text/VertOrientation.hpp> | |||
27 | #include <editeng/brushitem.hxx> | |||
28 | #include <rtl/ustrbuf.hxx> | |||
29 | #include <vcl/font.hxx> | |||
30 | #include <vcl/settings.hxx> | |||
31 | #include <editeng/editids.hrc> | |||
32 | #include <editeng/numdef.hxx> | |||
33 | #include <vcl/graph.hxx> | |||
34 | #include <vcl/outdev.hxx> | |||
35 | #include <vcl/svapp.hxx> | |||
36 | #include <com/sun/star/text/XNumberingFormatter.hpp> | |||
37 | #include <com/sun/star/text/DefaultNumberingProvider.hpp> | |||
38 | #include <com/sun/star/text/XDefaultNumberingProvider.hpp> | |||
39 | #include <com/sun/star/style/NumberingType.hpp> | |||
40 | #include <com/sun/star/lang/IllegalArgumentException.hpp> | |||
41 | #include <com/sun/star/beans/PropertyValue.hpp> | |||
42 | #include <comphelper/fileformat.h> | |||
43 | #include <comphelper/processfactory.hxx> | |||
44 | #include <tools/mapunit.hxx> | |||
45 | #include <tools/stream.hxx> | |||
46 | #include <tools/debug.hxx> | |||
47 | #include <tools/GenericTypeSerializer.hxx> | |||
48 | #include <tools/UnitConversion.hxx> | |||
49 | #include <unotools/configmgr.hxx> | |||
50 | #include <libxml/xmlwriter.h> | |||
51 | #include <editeng/unonrule.hxx> | |||
52 | #include <sal/log.hxx> | |||
53 | #include <i18nlangtag/languagetag.hxx> | |||
54 | #include <editeng/legacyitem.hxx> | |||
55 | ||||
56 | #define DEF_WRITER_LSPACE500 500 //Standard Indentation | |||
57 | #define DEF_DRAW_LSPACE800 800 //Standard Indentation | |||
58 | ||||
59 | #define NUMITEM_VERSION_030x03 0x03 | |||
60 | #define NUMITEM_VERSION_040x04 0x04 | |||
61 | ||||
62 | using namespace ::com::sun::star; | |||
63 | using namespace ::com::sun::star::lang; | |||
64 | using namespace ::com::sun::star::uno; | |||
65 | using namespace ::com::sun::star::text; | |||
66 | using namespace ::com::sun::star::beans; | |||
67 | using namespace ::com::sun::star::style; | |||
68 | ||||
69 | sal_Int32 SvxNumberType::nRefCount = 0; | |||
70 | css::uno::Reference<css::text::XNumberingFormatter> SvxNumberType::xFormatter; | |||
71 | static void lcl_getFormatter(css::uno::Reference<css::text::XNumberingFormatter>& _xFormatter) | |||
72 | { | |||
73 | if(_xFormatter.is()) | |||
74 | return; | |||
75 | ||||
76 | try | |||
77 | { | |||
78 | Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() ); | |||
79 | Reference<XDefaultNumberingProvider> xRet = text::DefaultNumberingProvider::create(xContext); | |||
80 | _xFormatter.set(xRet, UNO_QUERY); | |||
81 | } | |||
82 | catch(const Exception&) | |||
83 | { | |||
84 | SAL_WARN("editeng", "service missing: \"com.sun.star.text.DefaultNumberingProvider\"")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "editeng")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng" ), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "84" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng" ), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "84" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng" ), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "84" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "service missing: \"com.sun.star.text.DefaultNumberingProvider\"" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("editeng" ), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "84" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
85 | } | |||
86 | } | |||
87 | ||||
88 | SvxNumberType::SvxNumberType(SvxNumType nType) : | |||
89 | nNumType(nType), | |||
90 | bShowSymbol(true) | |||
91 | { | |||
92 | nRefCount++; | |||
93 | } | |||
94 | ||||
95 | SvxNumberType::SvxNumberType(const SvxNumberType& rType) : | |||
96 | nNumType(rType.nNumType), | |||
97 | bShowSymbol(rType.bShowSymbol) | |||
98 | { | |||
99 | nRefCount++; | |||
100 | } | |||
101 | ||||
102 | SvxNumberType::~SvxNumberType() | |||
103 | { | |||
104 | if(!--nRefCount) | |||
105 | xFormatter = nullptr; | |||
106 | } | |||
107 | ||||
108 | OUString SvxNumberType::GetNumStr( sal_Int32 nNo ) const | |||
109 | { | |||
110 | LanguageTag aLang = utl::ConfigManager::IsFuzzing() ? | |||
111 | LanguageTag("en-US") : | |||
112 | Application::GetSettings().GetLanguageTag(); | |||
113 | return GetNumStr( nNo, aLang.getLocale() ); | |||
114 | } | |||
115 | ||||
116 | OUString SvxNumberType::GetNumStr( sal_Int32 nNo, const css::lang::Locale& rLocale ) const | |||
117 | { | |||
118 | lcl_getFormatter(xFormatter); | |||
119 | if(!xFormatter.is()) | |||
120 | return OUString(); | |||
121 | ||||
122 | if(bShowSymbol) | |||
123 | { | |||
124 | switch(nNumType) | |||
125 | { | |||
126 | case NumberingType::CHAR_SPECIAL: | |||
127 | case NumberingType::BITMAP: | |||
128 | break; | |||
129 | default: | |||
130 | { | |||
131 | // '0' allowed for ARABIC numberings | |||
132 | if(NumberingType::ARABIC == nNumType && 0 == nNo ) | |||
133 | return OUString('0'); | |||
134 | else | |||
135 | { | |||
136 | Sequence< PropertyValue > aProperties(2); | |||
137 | PropertyValue* pValues = aProperties.getArray(); | |||
138 | pValues[0].Name = "NumberingType"; | |||
139 | pValues[0].Value <<= static_cast<sal_uInt16>(nNumType); | |||
140 | pValues[1].Name = "Value"; | |||
141 | pValues[1].Value <<= nNo; | |||
142 | ||||
143 | try | |||
144 | { | |||
145 | return xFormatter->makeNumberingString( aProperties, rLocale ); | |||
146 | } | |||
147 | catch(const Exception&) | |||
148 | { | |||
149 | } | |||
150 | } | |||
151 | } | |||
152 | } | |||
153 | } | |||
154 | return OUString(); | |||
155 | } | |||
156 | ||||
157 | void SvxNumberType::dumpAsXml( xmlTextWriterPtr pWriter ) const | |||
158 | { | |||
159 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SvxNumberType")); | |||
160 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("NumType"), BAD_CAST(xmlChar *)(OString::number(nNumType).getStr())); | |||
161 | xmlTextWriterEndElement(pWriter); | |||
162 | } | |||
163 | ||||
164 | SvxNumberFormat::SvxNumberFormat( SvxNumType eType ) | |||
165 | : SvxNumberType(eType), | |||
166 | eNumAdjust(SvxAdjust::Left), | |||
167 | nInclUpperLevels(0), | |||
168 | nStart(1), | |||
169 | cBullet(SVX_DEF_BULLET(0xF000 + 149)), | |||
170 | nBulletRelSize(100), | |||
171 | nBulletColor(COL_BLACK), | |||
172 | mePositionAndSpaceMode( LABEL_WIDTH_AND_POSITION ), | |||
173 | nFirstLineOffset(0), | |||
174 | nAbsLSpace(0), | |||
175 | nCharTextDistance(0), | |||
176 | meLabelFollowedBy( LISTTAB ), | |||
177 | mnListtabPos( 0 ), | |||
178 | mnFirstLineIndent( 0 ), | |||
179 | mnIndentAt( 0 ), | |||
180 | eVertOrient(text::VertOrientation::NONE) | |||
181 | { | |||
182 | } | |||
183 | ||||
184 | SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat& rFormat) : | |||
185 | SvxNumberType(rFormat), | |||
186 | mePositionAndSpaceMode( rFormat.mePositionAndSpaceMode ) | |||
187 | { | |||
188 | *this = rFormat; | |||
189 | } | |||
190 | ||||
191 | SvxNumberFormat::SvxNumberFormat( SvStream &rStream ) | |||
192 | : nStart(0) | |||
193 | , nBulletRelSize(100) | |||
194 | , nFirstLineOffset(0) | |||
195 | , nAbsLSpace(0) | |||
196 | , nCharTextDistance(0) | |||
197 | { | |||
198 | sal_uInt16 nTmp16(0); | |||
199 | sal_Int32 nTmp32(0); | |||
200 | rStream.ReadUInt16( nTmp16 ); // Version number | |||
201 | ||||
202 | rStream.ReadUInt16( nTmp16 ); SetNumberingType( static_cast<SvxNumType>(nTmp16) ); | |||
203 | rStream.ReadUInt16( nTmp16 ); eNumAdjust = static_cast<SvxAdjust>(nTmp16); | |||
204 | rStream.ReadUInt16( nTmp16 ); nInclUpperLevels = nTmp16; | |||
205 | rStream.ReadUInt16( nStart ); | |||
206 | rStream.ReadUInt16( nTmp16 ); cBullet = static_cast<sal_Unicode>(nTmp16); | |||
207 | ||||
208 | sal_Int16 temp = 0; | |||
209 | rStream.ReadInt16( temp ); | |||
210 | nFirstLineOffset = temp; | |||
211 | temp = 0; | |||
212 | rStream.ReadInt16( temp ); | |||
213 | nAbsLSpace = temp; | |||
214 | rStream.SeekRel(2); //skip old now unused nLSpace; | |||
215 | ||||
216 | rStream.ReadInt16( nCharTextDistance ); | |||
217 | ||||
218 | sPrefix = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); | |||
219 | sSuffix = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); | |||
220 | sCharStyleName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); | |||
221 | ||||
222 | sal_uInt16 hasGraphicBrush = 0; | |||
223 | rStream.ReadUInt16( hasGraphicBrush ); | |||
224 | if ( hasGraphicBrush ) | |||
225 | { | |||
226 | pGraphicBrush.reset(new SvxBrushItem(SID_ATTR_BRUSH( 10000 + 1 ))); | |||
227 | legacy::SvxBrush::Create(*pGraphicBrush, rStream, BRUSH_GRAPHIC_VERSION); | |||
228 | } | |||
229 | else pGraphicBrush = nullptr; | |||
230 | rStream.ReadUInt16( nTmp16 ); eVertOrient = nTmp16; | |||
231 | ||||
232 | sal_uInt16 hasBulletFont = 0; | |||
233 | rStream.ReadUInt16( hasBulletFont ); | |||
234 | if ( hasBulletFont ) | |||
235 | { | |||
236 | pBulletFont.reset( new vcl::Font() ); | |||
237 | ReadFont( rStream, *pBulletFont ); | |||
238 | } | |||
239 | else pBulletFont = nullptr; | |||
240 | ||||
241 | tools::GenericTypeSerializer aSerializer(rStream); | |||
242 | aSerializer.readSize(aGraphicSize); | |||
243 | aSerializer.readColor(nBulletColor); | |||
244 | ||||
245 | rStream.ReadUInt16( nBulletRelSize ); | |||
246 | rStream.ReadUInt16( nTmp16 ); SetShowSymbol( nTmp16 != 0 ); | |||
247 | ||||
248 | rStream.ReadUInt16( nTmp16 ); mePositionAndSpaceMode = static_cast<SvxNumPositionAndSpaceMode>(nTmp16); | |||
249 | rStream.ReadUInt16( nTmp16 ); meLabelFollowedBy = static_cast<LabelFollowedBy>(nTmp16); | |||
250 | rStream.ReadInt32( nTmp32 ); mnListtabPos = nTmp32; | |||
251 | rStream.ReadInt32( nTmp32 ); mnFirstLineIndent = nTmp32; | |||
252 | rStream.ReadInt32( nTmp32 ); mnIndentAt = nTmp32; | |||
253 | } | |||
254 | ||||
255 | SvxNumberFormat::~SvxNumberFormat() | |||
256 | { | |||
257 | } | |||
258 | ||||
259 | void SvxNumberFormat::Store(SvStream &rStream, FontToSubsFontConverter pConverter) | |||
260 | { | |||
261 | if(pConverter && pBulletFont) | |||
262 | { | |||
263 | cBullet = ConvertFontToSubsFontChar(pConverter, cBullet); | |||
264 | OUString sFontName = GetFontToSubsFontName(pConverter); | |||
265 | pBulletFont->SetFamilyName(sFontName); | |||
266 | } | |||
267 | ||||
268 | tools::GenericTypeSerializer aSerializer(rStream); | |||
269 | ||||
270 | rStream.WriteUInt16( NUMITEM_VERSION_040x04 ); | |||
271 | ||||
272 | rStream.WriteUInt16( GetNumberingType() ); | |||
273 | rStream.WriteUInt16( static_cast<sal_uInt16>(eNumAdjust) ); | |||
274 | rStream.WriteUInt16( nInclUpperLevels ); | |||
275 | rStream.WriteUInt16( nStart ); | |||
276 | rStream.WriteUInt16( cBullet ); | |||
277 | ||||
278 | rStream.WriteInt16( | |||
279 | sal_Int16(std::clamp<sal_Int32>(nFirstLineOffset, SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)), SAL_MAX_INT16((sal_Int16) 0x7FFF))) ); | |||
280 | //TODO: better way to handle out-of-bounds value? | |||
281 | rStream.WriteInt16( | |||
282 | sal_Int16(std::clamp<sal_Int32>(nAbsLSpace, SAL_MIN_INT16((sal_Int16) (-0x7FFF - 1)), SAL_MAX_INT16((sal_Int16) 0x7FFF))) ); | |||
283 | //TODO: better way to handle out-of-bounds value? | |||
284 | rStream.WriteInt16( 0 ); // write a dummy for old now unused nLSpace | |||
285 | ||||
286 | rStream.WriteInt16( nCharTextDistance ); | |||
287 | rtl_TextEncoding eEnc = osl_getThreadTextEncoding(); | |||
288 | rStream.WriteUniOrByteString(sPrefix, eEnc); | |||
289 | rStream.WriteUniOrByteString(sSuffix, eEnc); | |||
290 | rStream.WriteUniOrByteString(sCharStyleName, eEnc); | |||
291 | if(pGraphicBrush) | |||
292 | { | |||
293 | rStream.WriteUInt16( 1 ); | |||
294 | ||||
295 | // in SD or SI force bullet itself to be stored, | |||
296 | // for that purpose throw away link when link and graphic | |||
297 | // are present, so Brush save is forced | |||
298 | if(!pGraphicBrush->GetGraphicLink().isEmpty() && pGraphicBrush->GetGraphic()) | |||
299 | { | |||
300 | pGraphicBrush->SetGraphicLink(""); | |||
301 | } | |||
302 | ||||
303 | legacy::SvxBrush::Store(*pGraphicBrush, rStream, BRUSH_GRAPHIC_VERSION); | |||
304 | } | |||
305 | else | |||
306 | rStream.WriteUInt16( 0 ); | |||
307 | ||||
308 | rStream.WriteUInt16( eVertOrient ); | |||
309 | if(pBulletFont) | |||
310 | { | |||
311 | rStream.WriteUInt16( 1 ); | |||
312 | WriteFont( rStream, *pBulletFont ); | |||
313 | } | |||
314 | else | |||
315 | rStream.WriteUInt16( 0 ); | |||
316 | ||||
317 | aSerializer.writeSize(aGraphicSize); | |||
318 | ||||
319 | Color nTempColor = nBulletColor; | |||
320 | if(COL_AUTO == nBulletColor) | |||
321 | nTempColor = COL_BLACK; | |||
322 | ||||
323 | aSerializer.writeColor(nTempColor); | |||
324 | rStream.WriteUInt16( nBulletRelSize ); | |||
325 | rStream.WriteUInt16( sal_uInt16(IsShowSymbol()) ); | |||
326 | ||||
327 | rStream.WriteUInt16( mePositionAndSpaceMode ); | |||
328 | rStream.WriteUInt16( meLabelFollowedBy ); | |||
329 | rStream.WriteInt32( mnListtabPos ); | |||
330 | rStream.WriteInt32( mnFirstLineIndent ); | |||
331 | rStream.WriteInt32( mnIndentAt ); | |||
332 | } | |||
333 | ||||
334 | SvxNumberFormat& SvxNumberFormat::operator=( const SvxNumberFormat& rFormat ) | |||
335 | { | |||
336 | if (& rFormat == this) { return *this; } | |||
337 | ||||
338 | SvxNumberType::SetNumberingType(rFormat.GetNumberingType()); | |||
339 | eNumAdjust = rFormat.eNumAdjust ; | |||
340 | nInclUpperLevels = rFormat.nInclUpperLevels ; | |||
341 | nStart = rFormat.nStart ; | |||
342 | cBullet = rFormat.cBullet ; | |||
343 | mePositionAndSpaceMode = rFormat.mePositionAndSpaceMode; | |||
344 | nFirstLineOffset = rFormat.nFirstLineOffset; | |||
345 | nAbsLSpace = rFormat.nAbsLSpace ; | |||
346 | nCharTextDistance = rFormat.nCharTextDistance ; | |||
347 | meLabelFollowedBy = rFormat.meLabelFollowedBy; | |||
348 | mnListtabPos = rFormat.mnListtabPos; | |||
349 | mnFirstLineIndent = rFormat.mnFirstLineIndent; | |||
350 | mnIndentAt = rFormat.mnIndentAt; | |||
351 | eVertOrient = rFormat.eVertOrient; | |||
352 | sPrefix = rFormat.sPrefix; | |||
353 | sSuffix = rFormat.sSuffix; | |||
354 | sListFormat = rFormat.sListFormat; | |||
355 | aGraphicSize = rFormat.aGraphicSize ; | |||
356 | nBulletColor = rFormat.nBulletColor ; | |||
357 | nBulletRelSize = rFormat.nBulletRelSize; | |||
358 | SetShowSymbol(rFormat.IsShowSymbol()); | |||
359 | sCharStyleName = rFormat.sCharStyleName; | |||
360 | pGraphicBrush.reset(); | |||
361 | if(rFormat.pGraphicBrush) | |||
362 | { | |||
363 | pGraphicBrush.reset( new SvxBrushItem(*rFormat.pGraphicBrush) ); | |||
364 | } | |||
365 | pBulletFont.reset(); | |||
366 | if(rFormat.pBulletFont) | |||
367 | pBulletFont.reset( new vcl::Font(*rFormat.pBulletFont) ); | |||
368 | return *this; | |||
369 | } | |||
370 | ||||
371 | bool SvxNumberFormat::operator==( const SvxNumberFormat& rFormat) const | |||
372 | { | |||
373 | if( GetNumberingType() != rFormat.GetNumberingType() || | |||
374 | eNumAdjust != rFormat.eNumAdjust || | |||
375 | nInclUpperLevels != rFormat.nInclUpperLevels || | |||
376 | nStart != rFormat.nStart || | |||
377 | cBullet != rFormat.cBullet || | |||
378 | mePositionAndSpaceMode != rFormat.mePositionAndSpaceMode || | |||
379 | nFirstLineOffset != rFormat.nFirstLineOffset || | |||
380 | nAbsLSpace != rFormat.nAbsLSpace || | |||
381 | nCharTextDistance != rFormat.nCharTextDistance || | |||
382 | meLabelFollowedBy != rFormat.meLabelFollowedBy || | |||
383 | mnListtabPos != rFormat.mnListtabPos || | |||
384 | mnFirstLineIndent != rFormat.mnFirstLineIndent || | |||
385 | mnIndentAt != rFormat.mnIndentAt || | |||
386 | eVertOrient != rFormat.eVertOrient || | |||
387 | sPrefix != rFormat.sPrefix || | |||
388 | sSuffix != rFormat.sSuffix || | |||
389 | sListFormat != rFormat.sListFormat || | |||
390 | aGraphicSize != rFormat.aGraphicSize || | |||
391 | nBulletColor != rFormat.nBulletColor || | |||
392 | nBulletRelSize != rFormat.nBulletRelSize || | |||
393 | IsShowSymbol() != rFormat.IsShowSymbol() || | |||
394 | sCharStyleName != rFormat.sCharStyleName | |||
395 | ) | |||
396 | return false; | |||
397 | if ( | |||
398 | (pGraphicBrush && !rFormat.pGraphicBrush) || | |||
399 | (!pGraphicBrush && rFormat.pGraphicBrush) || | |||
400 | (pGraphicBrush && *pGraphicBrush != *rFormat.pGraphicBrush) | |||
401 | ) | |||
402 | { | |||
403 | return false; | |||
404 | } | |||
405 | if ( | |||
406 | (pBulletFont && !rFormat.pBulletFont) || | |||
407 | (!pBulletFont && rFormat.pBulletFont) || | |||
408 | (pBulletFont && *pBulletFont != *rFormat.pBulletFont) | |||
409 | ) | |||
410 | { | |||
411 | return false; | |||
412 | } | |||
413 | return true; | |||
414 | } | |||
415 | ||||
416 | void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem, | |||
417 | const Size* pSize, const sal_Int16* pOrient) | |||
418 | { | |||
419 | if (!pBrushItem) | |||
420 | pGraphicBrush.reset(); | |||
421 | else if ( !pGraphicBrush || (*pBrushItem != *pGraphicBrush) ) | |||
422 | pGraphicBrush.reset(pBrushItem->Clone()); | |||
423 | ||||
424 | if(pOrient) | |||
425 | eVertOrient = *pOrient; | |||
426 | else | |||
427 | eVertOrient = text::VertOrientation::NONE; | |||
428 | if(pSize) | |||
429 | aGraphicSize = *pSize; | |||
430 | else | |||
431 | { | |||
432 | aGraphicSize.setWidth(0); | |||
433 | aGraphicSize.setHeight(0); | |||
434 | } | |||
435 | } | |||
436 | ||||
437 | void SvxNumberFormat::SetGraphic( const OUString& rName ) | |||
438 | { | |||
439 | if( pGraphicBrush && pGraphicBrush->GetGraphicLink() == rName ) | |||
440 | return ; | |||
441 | ||||
442 | pGraphicBrush.reset( new SvxBrushItem( rName, "", GPOS_AREA, 0 ) ); | |||
443 | if( eVertOrient == text::VertOrientation::NONE ) | |||
444 | eVertOrient = text::VertOrientation::TOP; | |||
445 | ||||
446 | aGraphicSize.setWidth(0); | |||
447 | aGraphicSize.setHeight(0); | |||
448 | } | |||
449 | ||||
450 | sal_Int16 SvxNumberFormat::GetVertOrient() const | |||
451 | { | |||
452 | return eVertOrient; | |||
453 | } | |||
454 | ||||
455 | void SvxNumberFormat::SetBulletFont(const vcl::Font* pFont) | |||
456 | { | |||
457 | pBulletFont.reset( pFont ? new vcl::Font(*pFont): nullptr ); | |||
458 | } | |||
459 | ||||
460 | void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode ) | |||
461 | { | |||
462 | mePositionAndSpaceMode = ePositionAndSpaceMode; | |||
463 | } | |||
464 | ||||
465 | sal_Int32 SvxNumberFormat::GetAbsLSpace() const | |||
466 | { | |||
467 | return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION | |||
468 | ? nAbsLSpace | |||
469 | : static_cast<sal_Int32>( GetFirstLineIndent() + GetIndentAt() ); | |||
470 | } | |||
471 | sal_Int32 SvxNumberFormat::GetFirstLineOffset() const | |||
472 | { | |||
473 | return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION | |||
474 | ? nFirstLineOffset | |||
475 | : static_cast<sal_Int32>( GetFirstLineIndent() ); | |||
476 | } | |||
477 | short SvxNumberFormat::GetCharTextDistance() const | |||
478 | { | |||
479 | return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nCharTextDistance : 0; | |||
480 | } | |||
481 | ||||
482 | void SvxNumberFormat::SetLabelFollowedBy( const LabelFollowedBy eLabelFollowedBy ) | |||
483 | { | |||
484 | meLabelFollowedBy = eLabelFollowedBy; | |||
485 | } | |||
486 | void SvxNumberFormat::SetListtabPos( const long nListtabPos ) | |||
487 | { | |||
488 | mnListtabPos = nListtabPos; | |||
489 | } | |||
490 | void SvxNumberFormat::SetFirstLineIndent( const long nFirstLineIndent ) | |||
491 | { | |||
492 | mnFirstLineIndent = nFirstLineIndent; | |||
493 | } | |||
494 | void SvxNumberFormat::SetIndentAt( const long nIndentAt ) | |||
495 | { | |||
496 | mnIndentAt = nIndentAt; | |||
497 | } | |||
498 | ||||
499 | Size SvxNumberFormat::GetGraphicSizeMM100(const Graphic* pGraphic) | |||
500 | { | |||
501 | const MapMode aMapMM100( MapUnit::Map100thMM ); | |||
502 | const Size& rSize = pGraphic->GetPrefSize(); | |||
503 | Size aRetSize; | |||
504 | if ( pGraphic->GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel ) | |||
505 | { | |||
506 | OutputDevice* pOutDev = Application::GetDefaultDevice(); | |||
507 | MapMode aOldMap( pOutDev->GetMapMode() ); | |||
508 | pOutDev->SetMapMode( aMapMM100 ); | |||
509 | aRetSize = pOutDev->PixelToLogic( rSize ); | |||
510 | pOutDev->SetMapMode( aOldMap ); | |||
511 | } | |||
512 | else | |||
513 | aRetSize = OutputDevice::LogicToLogic( rSize, pGraphic->GetPrefMapMode(), aMapMM100 ); | |||
514 | return aRetSize; | |||
515 | } | |||
516 | ||||
517 | OUString SvxNumberFormat::CreateRomanString( sal_uLong nNo, bool bUpper ) | |||
518 | { | |||
519 | nNo %= 4000; // more can not be displayed | |||
520 | // i, ii, iii, iv, v, vi, vii, vii, viii, ix | |||
521 | // (Dummy),1000,500,100,50,10,5,1 | |||
522 | const char *cRomanArr = bUpper | |||
| ||||
523 | ? "MDCLXVI--" // +2 Dummy entries! | |||
524 | : "mdclxvi--"; // +2 Dummy entries! | |||
525 | ||||
526 | OUStringBuffer sRet; | |||
527 | sal_uInt16 nMask = 1000; | |||
528 | while( nMask ) | |||
529 | { | |||
530 | sal_uInt8 nNumber = sal_uInt8(nNo / nMask); | |||
531 | sal_uInt8 nDiff = 1; | |||
532 | nNo %= nMask; | |||
533 | ||||
534 | if( 5 < nNumber ) | |||
535 | { | |||
536 | if( nNumber < 9 ) | |||
537 | sRet.append(*(cRomanArr-1)); | |||
538 | ++nDiff; | |||
539 | nNumber -= 5; | |||
540 | } | |||
541 | switch( nNumber ) | |||
542 | { | |||
543 | case 3: { sRet.append(*cRomanArr); [[fallthrough]]; } | |||
544 | case 2: { sRet.append(*cRomanArr); [[fallthrough]]; } | |||
545 | case 1: { sRet.append(*cRomanArr); } | |||
546 | break; | |||
547 | ||||
548 | case 4: { | |||
549 | sRet.append(*cRomanArr); | |||
550 | sRet.append(*(cRomanArr-nDiff)); | |||
| ||||
551 | } | |||
552 | break; | |||
553 | case 5: { sRet.append(*(cRomanArr-nDiff)); } | |||
554 | break; | |||
555 | } | |||
556 | ||||
557 | nMask /= 10; // for the next decade | |||
558 | cRomanArr += 2; | |||
559 | } | |||
560 | return sRet.makeStringAndClear(); | |||
561 | } | |||
562 | ||||
563 | OUString SvxNumberFormat::GetCharFormatName()const | |||
564 | { | |||
565 | return sCharStyleName; | |||
566 | } | |||
567 | ||||
568 | sal_Int32 SvxNumRule::nRefCount = 0; | |||
569 | static SvxNumberFormat* pStdNumFmt = nullptr; | |||
570 | static SvxNumberFormat* pStdOutlineNumFmt = nullptr; | |||
571 | SvxNumRule::SvxNumRule( SvxNumRuleFlags nFeatures, | |||
572 | sal_uInt16 nLevels, | |||
573 | bool bCont, | |||
574 | SvxNumRuleType eType, | |||
575 | SvxNumberFormat::SvxNumPositionAndSpaceMode | |||
576 | eDefaultNumberFormatPositionAndSpaceMode ) | |||
577 | : nLevelCount(nLevels), | |||
578 | nFeatureFlags(nFeatures), | |||
579 | eNumberingType(eType), | |||
580 | bContinuousNumbering(bCont) | |||
581 | { | |||
582 | ++nRefCount; | |||
583 | for(sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
584 | { | |||
585 | if(i < nLevels) | |||
586 | { | |||
587 | aFmts[i].reset( new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER) ); | |||
588 | // It is a distinction between writer and draw | |||
589 | if(nFeatures & SvxNumRuleFlags::CONTINUOUS) | |||
590 | { | |||
591 | if ( eDefaultNumberFormatPositionAndSpaceMode == | |||
592 | SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) | |||
593 | { | |||
594 | aFmts[i]->SetAbsLSpace( convertMm100ToTwip(DEF_WRITER_LSPACE500 * (i+1)) ); | |||
595 | aFmts[i]->SetFirstLineOffset(convertMm100ToTwip(-DEF_WRITER_LSPACE500)); | |||
596 | } | |||
597 | else if ( eDefaultNumberFormatPositionAndSpaceMode == | |||
598 | SvxNumberFormat::LABEL_ALIGNMENT ) | |||
599 | { | |||
600 | // first line indent of general numbering in inch: -0,25 inch | |||
601 | const long cFirstLineIndent = -1440/4; | |||
602 | // indent values of general numbering in inch: | |||
603 | // 0,5 0,75 1,0 1,25 1,5 | |||
604 | // 1,75 2,0 2,25 2,5 2,75 | |||
605 | const long cIndentAt = 1440/4; | |||
606 | aFmts[i]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT ); | |||
607 | aFmts[i]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB ); | |||
608 | aFmts[i]->SetListtabPos( cIndentAt * (i+2) ); | |||
609 | aFmts[i]->SetFirstLineIndent( cFirstLineIndent ); | |||
610 | aFmts[i]->SetIndentAt( cIndentAt * (i+2) ); | |||
611 | } | |||
612 | } | |||
613 | else | |||
614 | { | |||
615 | aFmts[i]->SetAbsLSpace( DEF_DRAW_LSPACE800 * i ); | |||
616 | } | |||
617 | } | |||
618 | else | |||
619 | aFmts[i] = nullptr; | |||
620 | aFmtsSet[i] = false; | |||
621 | } | |||
622 | } | |||
623 | ||||
624 | SvxNumRule::SvxNumRule(const SvxNumRule& rCopy) | |||
625 | { | |||
626 | ++nRefCount; | |||
627 | nLevelCount = rCopy.nLevelCount ; | |||
628 | nFeatureFlags = rCopy.nFeatureFlags ; | |||
629 | bContinuousNumbering = rCopy.bContinuousNumbering; | |||
630 | eNumberingType = rCopy.eNumberingType; | |||
631 | for(sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
632 | { | |||
633 | if(rCopy.aFmts[i]) | |||
634 | aFmts[i].reset( new SvxNumberFormat(*rCopy.aFmts[i]) ); | |||
635 | else | |||
636 | aFmts[i].reset(); | |||
637 | aFmtsSet[i] = rCopy.aFmtsSet[i]; | |||
638 | } | |||
639 | } | |||
640 | ||||
641 | SvxNumRule::SvxNumRule( SvStream &rStream ) | |||
642 | : nLevelCount(0) | |||
643 | { | |||
644 | sal_uInt16 nTmp16(0); | |||
645 | rStream.ReadUInt16( nTmp16 ); // NUM_ITEM_VERSION | |||
646 | rStream.ReadUInt16( nLevelCount ); | |||
647 | ||||
648 | // first nFeatureFlags of old Versions | |||
649 | rStream.ReadUInt16( nTmp16 ); nFeatureFlags = static_cast<SvxNumRuleFlags>(nTmp16); | |||
650 | rStream.ReadUInt16( nTmp16 ); bContinuousNumbering = nTmp16; | |||
651 | rStream.ReadUInt16( nTmp16 ); eNumberingType = static_cast<SvxNumRuleType>(nTmp16); | |||
652 | ||||
653 | for (sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
654 | { | |||
655 | rStream.ReadUInt16( nTmp16 ); | |||
656 | bool hasNumberingFormat = nTmp16 & 1; | |||
657 | aFmtsSet[i] = nTmp16 & 2; // fdo#68648 reset flag | |||
658 | if ( hasNumberingFormat ){ | |||
659 | aFmts[i].reset( new SvxNumberFormat( rStream ) ); | |||
660 | } | |||
661 | else | |||
662 | { | |||
663 | aFmts[i].reset(); | |||
664 | aFmtsSet[i] = false; // actually only false is valid | |||
665 | } | |||
666 | } | |||
667 | //second nFeatureFlags for new versions | |||
668 | rStream.ReadUInt16( nTmp16 ); nFeatureFlags = static_cast<SvxNumRuleFlags>(nTmp16); | |||
669 | } | |||
670 | ||||
671 | void SvxNumRule::Store( SvStream &rStream ) | |||
672 | { | |||
673 | rStream.WriteUInt16( NUMITEM_VERSION_030x03 ); | |||
674 | rStream.WriteUInt16( nLevelCount ); | |||
675 | //first save of nFeatureFlags for old versions | |||
676 | rStream.WriteUInt16( static_cast<sal_uInt16>(nFeatureFlags) ); | |||
677 | rStream.WriteUInt16( sal_uInt16(bContinuousNumbering) ); | |||
678 | rStream.WriteUInt16( static_cast<sal_uInt16>(eNumberingType) ); | |||
679 | ||||
680 | FontToSubsFontConverter pConverter = nullptr; | |||
681 | bool bConvertBulletFont = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_505050 ) && ( rStream.GetVersion() ); | |||
682 | for(sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
683 | { | |||
684 | sal_uInt16 nSetFlag(aFmtsSet[i] ? 2 : 0); // fdo#68648 store that too | |||
685 | if(aFmts[i]) | |||
686 | { | |||
687 | rStream.WriteUInt16( 1 | nSetFlag ); | |||
688 | if(bConvertBulletFont && aFmts[i]->GetBulletFont()) | |||
689 | { | |||
690 | if(!pConverter) | |||
691 | pConverter = | |||
692 | CreateFontToSubsFontConverter(aFmts[i]->GetBulletFont()->GetFamilyName(), | |||
693 | FontToSubsFontFlags::EXPORT); | |||
694 | } | |||
695 | aFmts[i]->Store(rStream, pConverter); | |||
696 | } | |||
697 | else | |||
698 | rStream.WriteUInt16( 0 | nSetFlag ); | |||
699 | } | |||
700 | //second save of nFeatureFlags for new versions | |||
701 | rStream.WriteUInt16( static_cast<sal_uInt16>(nFeatureFlags) ); | |||
702 | } | |||
703 | ||||
704 | void SvxNumRule::dumpAsXml(xmlTextWriterPtr pWriter) const | |||
705 | { | |||
706 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SvxNumRule")); | |||
707 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("levelCount"), BAD_CAST(xmlChar *)(OString::number(nLevelCount).getStr())); | |||
708 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("continuousNumbering"), BAD_CAST(xmlChar *)(OString::boolean(bContinuousNumbering).getStr())); | |||
709 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("numberingType"), BAD_CAST(xmlChar *)(OString::number(static_cast<int>(eNumberingType)).getStr())); | |||
710 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("featureFlags"), BAD_CAST(xmlChar *)(OString::number(static_cast<int>(nFeatureFlags)).getStr())); | |||
711 | for(sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
712 | { | |||
713 | if(aFmts[i]) | |||
714 | { | |||
715 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("aFmts")); | |||
716 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("i"), BAD_CAST(xmlChar *)(OString::number(i).getStr())); | |||
717 | xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST(xmlChar *)("ptr"), "%p", aFmts[i].get()); | |||
718 | xmlTextWriterEndElement(pWriter); | |||
719 | } | |||
720 | } | |||
721 | xmlTextWriterEndElement(pWriter); | |||
722 | } | |||
723 | ||||
724 | ||||
725 | SvxNumRule::~SvxNumRule() | |||
726 | { | |||
727 | if(!--nRefCount) | |||
728 | { | |||
729 | delete pStdNumFmt; | |||
730 | pStdNumFmt = nullptr; | |||
731 | delete pStdOutlineNumFmt; | |||
732 | pStdOutlineNumFmt = nullptr; | |||
733 | } | |||
734 | } | |||
735 | ||||
736 | SvxNumRule& SvxNumRule::operator=( const SvxNumRule& rCopy ) | |||
737 | { | |||
738 | if (this != &rCopy) | |||
739 | { | |||
740 | nLevelCount = rCopy.nLevelCount; | |||
741 | nFeatureFlags = rCopy.nFeatureFlags; | |||
742 | bContinuousNumbering = rCopy.bContinuousNumbering; | |||
743 | eNumberingType = rCopy.eNumberingType; | |||
744 | for(sal_uInt16 i = 0; i < SVX_MAX_NUM10; i++) | |||
745 | { | |||
746 | if(rCopy.aFmts[i]) | |||
747 | aFmts[i].reset( new SvxNumberFormat(*rCopy.aFmts[i]) ); | |||
748 | else | |||
749 | aFmts[i].reset(); | |||
750 | aFmtsSet[i] = rCopy.aFmtsSet[i]; | |||
751 | } | |||
752 | } | |||
753 | return *this; | |||
754 | } | |||
755 | ||||
756 | bool SvxNumRule::operator==( const SvxNumRule& rCopy) const | |||
757 | { | |||
758 | if(nLevelCount != rCopy.nLevelCount || | |||
759 | nFeatureFlags != rCopy.nFeatureFlags || | |||
760 | bContinuousNumbering != rCopy.bContinuousNumbering || | |||
761 | eNumberingType != rCopy.eNumberingType) | |||
762 | return false; | |||
763 | for(sal_uInt16 i = 0; i < nLevelCount; i++) | |||
764 | { | |||
765 | if ( | |||
766 | (aFmtsSet[i] != rCopy.aFmtsSet[i]) || | |||
767 | (!aFmts[i] && rCopy.aFmts[i]) || | |||
768 | (aFmts[i] && !rCopy.aFmts[i]) || | |||
769 | (aFmts[i] && *aFmts[i] != *rCopy.aFmts[i]) | |||
770 | ) | |||
771 | { | |||
772 | return false; | |||
773 | } | |||
774 | } | |||
775 | return true; | |||
776 | } | |||
777 | ||||
778 | const SvxNumberFormat* SvxNumRule::Get(sal_uInt16 nLevel)const | |||
779 | { | |||
780 | DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" )do { if (true && (!(nLevel < 10))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "780" ": "), "%s", "Wrong Level"); } } while (false); | |||
781 | if( nLevel < SVX_MAX_NUM10 ) | |||
782 | return aFmtsSet[nLevel] ? aFmts[nLevel].get() : nullptr; | |||
783 | else | |||
784 | return nullptr; | |||
785 | } | |||
786 | ||||
787 | const SvxNumberFormat& SvxNumRule::GetLevel(sal_uInt16 nLevel)const | |||
788 | { | |||
789 | if(!pStdNumFmt) | |||
790 | { | |||
791 | pStdNumFmt = new SvxNumberFormat(SVX_NUM_ARABIC); | |||
792 | pStdOutlineNumFmt = new SvxNumberFormat(SVX_NUM_NUMBER_NONE); | |||
793 | } | |||
794 | ||||
795 | DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" )do { if (true && (!(nLevel < 10))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "795" ": "), "%s", "Wrong Level"); } } while (false); | |||
796 | ||||
797 | return ( ( nLevel < SVX_MAX_NUM10 ) && aFmts[nLevel] ) ? | |||
798 | *aFmts[nLevel] : eNumberingType == SvxNumRuleType::NUMBERING ? | |||
799 | *pStdNumFmt : *pStdOutlineNumFmt; | |||
800 | } | |||
801 | ||||
802 | void SvxNumRule::SetLevel( sal_uInt16 i, const SvxNumberFormat& rNumFmt, bool bIsValid ) | |||
803 | { | |||
804 | DBG_ASSERT(i < SVX_MAX_NUM, "Wrong Level" )do { if (true && (!(i < 10))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "804" ": "), "%s", "Wrong Level"); } } while (false); | |||
805 | ||||
806 | if( i >= SVX_MAX_NUM10 ) | |||
807 | return; | |||
808 | ||||
809 | bool bReplace = !aFmtsSet[i]; | |||
810 | if (!bReplace) | |||
811 | { | |||
812 | const SvxNumberFormat *pFmt = Get(i); | |||
813 | bReplace = pFmt == nullptr || rNumFmt != *pFmt; | |||
814 | } | |||
815 | ||||
816 | if (bReplace) | |||
817 | { | |||
818 | aFmts[i].reset( new SvxNumberFormat(rNumFmt) ); | |||
819 | aFmtsSet[i] = bIsValid; | |||
820 | } | |||
821 | } | |||
822 | ||||
823 | void SvxNumRule::SetLevel(sal_uInt16 nLevel, const SvxNumberFormat* pFmt) | |||
824 | { | |||
825 | DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" )do { if (true && (!(nLevel < 10))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/editeng/source/items/numitem.cxx" ":" "825" ": "), "%s", "Wrong Level"); } } while (false); | |||
826 | ||||
827 | if( nLevel < SVX_MAX_NUM10 ) | |||
828 | { | |||
829 | aFmtsSet[nLevel] = nullptr != pFmt; | |||
830 | if(pFmt) | |||
831 | SetLevel(nLevel, *pFmt); | |||
832 | else | |||
833 | { | |||
834 | aFmts[nLevel].reset(); | |||
835 | } | |||
836 | } | |||
837 | } | |||
838 | ||||
839 | OUString SvxNumRule::MakeNumString( const SvxNodeNum& rNum ) const | |||
840 | { | |||
841 | OUStringBuffer aStr; | |||
842 | if( SVX_NO_NUM200 > rNum.GetLevel() && !( SVX_NO_NUMLEVEL0x20 & rNum.GetLevel() ) ) | |||
843 | { | |||
844 | const SvxNumberFormat& rMyNFmt = GetLevel( rNum.GetLevel() ); | |||
845 | aStr.append(rMyNFmt.GetPrefix()); | |||
846 | if( SVX_NUM_NUMBER_NONE != rMyNFmt.GetNumberingType() ) | |||
847 | { | |||
848 | sal_uInt8 i = rNum.GetLevel(); | |||
849 | ||||
850 | if( !IsContinuousNumbering() && | |||
851 | 1 < rMyNFmt.GetIncludeUpperLevels() ) // only on own level? | |||
852 | { | |||
853 | sal_uInt8 n = rMyNFmt.GetIncludeUpperLevels(); | |||
854 | if( 1 < n ) | |||
855 | { | |||
856 | if( i+1 >= n ) | |||
857 | i -= n - 1; | |||
858 | else | |||
859 | i = 0; | |||
860 | } | |||
861 | } | |||
862 | ||||
863 | for( ; i <= rNum.GetLevel(); ++i ) | |||
864 | { | |||
865 | const SvxNumberFormat& rNFmt = GetLevel( i ); | |||
866 | if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() ) | |||
867 | { | |||
868 | continue; | |||
869 | } | |||
870 | ||||
871 | bool bDot = true; | |||
872 | if( rNum.GetLevelVal()[ i ] ) | |||
873 | { | |||
874 | if(SVX_NUM_BITMAP != rNFmt.GetNumberingType()) | |||
875 | { | |||
876 | const LanguageTag& rLang = Application::GetSettings().GetLanguageTag(); | |||
877 | aStr.append(rNFmt.GetNumStr( rNum.GetLevelVal()[ i ], rLang.getLocale() )); | |||
878 | } | |||
879 | else | |||
880 | bDot = false; | |||
881 | } | |||
882 | else | |||
883 | aStr.append("0"); // all 0-levels are a 0 | |||
884 | if( i != rNum.GetLevel() && bDot) | |||
885 | aStr.append("."); | |||
886 | } | |||
887 | } | |||
888 | ||||
889 | aStr.append(rMyNFmt.GetSuffix()); | |||
890 | } | |||
891 | return aStr.makeStringAndClear(); | |||
892 | } | |||
893 | ||||
894 | // changes linked to embedded bitmaps | |||
895 | void SvxNumRule::UnLinkGraphics() | |||
896 | { | |||
897 | for(sal_uInt16 i = 0; i < GetLevelCount(); i++) | |||
898 | { | |||
899 | SvxNumberFormat aFmt(GetLevel(i)); | |||
900 | const SvxBrushItem* pBrush = aFmt.GetBrush(); | |||
901 | if(SVX_NUM_BITMAP == aFmt.GetNumberingType()) | |||
902 | { | |||
903 | if(pBrush && !pBrush->GetGraphicLink().isEmpty()) | |||
904 | { | |||
905 | const Graphic* pGraphic = pBrush->GetGraphic(); | |||
906 | if (pGraphic) | |||
907 | { | |||
908 | SvxBrushItem aTempItem(*pBrush); | |||
909 | aTempItem.SetGraphicLink(""); | |||
910 | aTempItem.SetGraphic(*pGraphic); | |||
911 | sal_Int16 eOrient = aFmt.GetVertOrient(); | |||
912 | aFmt.SetGraphicBrush( &aTempItem, &aFmt.GetGraphicSize(), &eOrient ); | |||
913 | } | |||
914 | } | |||
915 | } | |||
916 | else if((SVX_NUM_BITMAP|LINK_TOKEN0x80) == static_cast<int>(aFmt.GetNumberingType())) | |||
917 | aFmt.SetNumberingType(SVX_NUM_BITMAP); | |||
918 | SetLevel(i, aFmt); | |||
919 | } | |||
920 | } | |||
921 | ||||
922 | SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule) : | |||
923 | SfxPoolItem(SID_ATTR_NUMBERING_RULE( 10000 + 855 )), | |||
924 | pNumRule(new SvxNumRule(rRule)) | |||
925 | { | |||
926 | } | |||
927 | ||||
928 | SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule, sal_uInt16 _nWhich ) : | |||
929 | SfxPoolItem(_nWhich), | |||
930 | pNumRule(new SvxNumRule(rRule)) | |||
931 | { | |||
932 | } | |||
933 | ||||
934 | SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem& rCopy) : | |||
935 | SfxPoolItem(rCopy), | |||
936 | pNumRule(new SvxNumRule(*rCopy.pNumRule)) | |||
937 | { | |||
938 | } | |||
939 | ||||
940 | SvxNumBulletItem::~SvxNumBulletItem() | |||
941 | { | |||
942 | } | |||
943 | ||||
944 | bool SvxNumBulletItem::operator==( const SfxPoolItem& rCopy) const | |||
945 | { | |||
946 | return SfxPoolItem::operator==(rCopy) && | |||
947 | *pNumRule == *static_cast<const SvxNumBulletItem&>(rCopy).pNumRule; | |||
948 | } | |||
949 | ||||
950 | SvxNumBulletItem* SvxNumBulletItem::Clone( SfxItemPool * ) const | |||
951 | { | |||
952 | return new SvxNumBulletItem(*this); | |||
953 | } | |||
954 | ||||
955 | bool SvxNumBulletItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const | |||
956 | { | |||
957 | rVal <<= SvxCreateNumRule( pNumRule.get() ); | |||
958 | return true; | |||
959 | } | |||
960 | ||||
961 | bool SvxNumBulletItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) | |||
962 | { | |||
963 | uno::Reference< container::XIndexReplace > xRule; | |||
964 | if( rVal >>= xRule ) | |||
965 | { | |||
966 | try | |||
967 | { | |||
968 | std::unique_ptr<SvxNumRule> pNewRule(new SvxNumRule( SvxGetNumRule( xRule ) )); | |||
969 | if( pNewRule->GetLevelCount() != pNumRule->GetLevelCount() || | |||
970 | pNewRule->GetNumRuleType() != pNumRule->GetNumRuleType() ) | |||
971 | { | |||
972 | std::unique_ptr<SvxNumRule> pConverted = SvxConvertNumRule( pNewRule.get(), pNumRule->GetLevelCount(), pNumRule->GetNumRuleType() ); | |||
973 | pNewRule = std::move(pConverted); | |||
974 | } | |||
975 | pNumRule = std::move( pNewRule ); | |||
976 | return true; | |||
977 | } | |||
978 | catch(const lang::IllegalArgumentException&) | |||
979 | { | |||
980 | } | |||
981 | } | |||
982 | return false; | |||
983 | } | |||
984 | ||||
985 | void SvxNumBulletItem::dumpAsXml(xmlTextWriterPtr pWriter) const | |||
986 | { | |||
987 | xmlTextWriterStartElement(pWriter, BAD_CAST(xmlChar *)("SvxNumBulletItem")); | |||
988 | xmlTextWriterWriteAttribute(pWriter, BAD_CAST(xmlChar *)("whichId"), BAD_CAST(xmlChar *)(OString::number(Which()).getStr())); | |||
989 | pNumRule->dumpAsXml(pWriter); | |||
990 | xmlTextWriterEndElement(pWriter); | |||
991 | } | |||
992 | ||||
993 | std::unique_ptr<SvxNumRule> SvxConvertNumRule( const SvxNumRule* pRule, sal_uInt16 nLevels, SvxNumRuleType eType ) | |||
994 | { | |||
995 | const sal_uInt16 nSrcLevels = pRule->GetLevelCount(); | |||
996 | std::unique_ptr<SvxNumRule> pNewRule(new SvxNumRule( pRule->GetFeatureFlags(), nLevels, pRule->IsContinuousNumbering(), eType )); | |||
997 | ||||
998 | for( sal_uInt16 nLevel = 0; (nLevel < nLevels) && (nLevel < nSrcLevels); nLevel++ ) | |||
999 | pNewRule->SetLevel( nLevel, pRule->GetLevel( nLevel ) ); | |||
1000 | ||||
1001 | return pNewRule; | |||
1002 | } | |||
1003 | ||||
1004 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |