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