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/brshitem.hxx>
27 : #include <vcl/font.hxx>
28 : #include <editeng/editids.hrc>
29 : #include <editeng/editrids.hrc>
30 : #include <editeng/numdef.hxx>
31 : #include <vcl/graph.hxx>
32 : #include <vcl/window.hxx>
33 : #include <vcl/svapp.hxx>
34 : #include <editeng/unolingu.hxx>
35 : #include <com/sun/star/text/XNumberingFormatter.hpp>
36 : #include <com/sun/star/text/DefaultNumberingProvider.hpp>
37 : #include <com/sun/star/text/XDefaultNumberingProvider.hpp>
38 : #include <com/sun/star/style/NumberingType.hpp>
39 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
40 : #include <com/sun/star/beans/PropertyValue.hpp>
41 : #include <comphelper/processfactory.hxx>
42 :
43 : #include <editeng/unonrule.hxx>
44 :
45 : #define MM100_TO_TWIP(MM100) ((MM100*72L+63L)/127L)
46 :
47 : #define DEF_WRITER_LSPACE 500 //Standard Indentation
48 : #define DEF_DRAW_LSPACE 800 //Standard Indentation
49 :
50 : #define NUMITEM_VERSION_01 0x01
51 : #define NUMITEM_VERSION_02 0x02
52 : #define NUMITEM_VERSION_03 0x03
53 : #define NUMITEM_VERSION_04 0x04
54 :
55 : using namespace ::com::sun::star;
56 : using namespace ::com::sun::star::lang;
57 : using namespace ::com::sun::star::uno;
58 : using namespace ::com::sun::star::text;
59 : using namespace ::com::sun::star::beans;
60 : using namespace ::com::sun::star::style;
61 :
62 : sal_Int32 SvxNumberType::nRefCount = 0;
63 24 : com::sun::star::uno::Reference<com::sun::star::text::XNumberingFormatter> SvxNumberType::xFormatter = 0;
64 142 : static void lcl_getFormatter(com::sun::star::uno::Reference<com::sun::star::text::XNumberingFormatter>& _xFormatter)
65 : {
66 142 : if(!_xFormatter.is())
67 : {
68 : try
69 : {
70 6 : Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
71 6 : Reference<XDefaultNumberingProvider> xRet = text::DefaultNumberingProvider::create(xContext);
72 6 : _xFormatter = Reference<XNumberingFormatter> (xRet, UNO_QUERY);
73 : }
74 0 : catch(const Exception&)
75 : {
76 : SAL_WARN("editeng", "service missing: \"com.sun.star.text.DefaultNumberingProvider\"");
77 : }
78 : }
79 142 : }
80 :
81 7237 : SvxNumberType::SvxNumberType(sal_Int16 nType) :
82 : nNumType(nType),
83 7237 : bShowSymbol(sal_True)
84 : {
85 7237 : nRefCount++;
86 7237 : }
87 :
88 50955 : SvxNumberType::SvxNumberType(const SvxNumberType& rType) :
89 : nNumType(rType.nNumType),
90 50955 : bShowSymbol(rType.bShowSymbol)
91 : {
92 50955 : nRefCount++;
93 50955 : }
94 :
95 56566 : SvxNumberType::~SvxNumberType()
96 : {
97 56566 : if(!--nRefCount)
98 4 : xFormatter = 0;
99 56566 : }
100 :
101 142 : String SvxNumberType::GetNumStr( sal_uLong nNo ) const
102 : {
103 142 : const LanguageTag& rLang = Application::GetSettings().GetLanguageTag();
104 142 : return GetNumStr( nNo, rLang.getLocale() );
105 : }
106 :
107 142 : String SvxNumberType::GetNumStr( sal_uLong nNo, const Locale& rLocale ) const
108 : {
109 142 : lcl_getFormatter(xFormatter);
110 142 : String aTmpStr;
111 142 : if(!xFormatter.is())
112 0 : return aTmpStr;
113 :
114 142 : if(bShowSymbol)
115 : {
116 142 : switch(nNumType)
117 : {
118 : case NumberingType::CHAR_SPECIAL:
119 : case NumberingType::BITMAP:
120 0 : break;
121 : default:
122 : {
123 : // '0' allowed for ARABIC numberings
124 142 : if(NumberingType::ARABIC == nNumType && 0 == nNo )
125 0 : aTmpStr = '0';
126 : else
127 : {
128 142 : Sequence< PropertyValue > aProperties(2);
129 142 : PropertyValue* pValues = aProperties.getArray();
130 142 : pValues[0].Name = rtl::OUString("NumberingType");
131 142 : pValues[0].Value <<= nNumType;
132 142 : pValues[1].Name = rtl::OUString("Value");
133 142 : pValues[1].Value <<= (sal_Int32)nNo;
134 :
135 : try
136 : {
137 142 : aTmpStr = xFormatter->makeNumberingString( aProperties, rLocale );
138 : }
139 0 : catch(const Exception&)
140 : {
141 142 : }
142 : }
143 : }
144 : }
145 : }
146 142 : return aTmpStr;
147 : }
148 :
149 5508 : SvxNumberFormat::SvxNumberFormat( sal_Int16 eType,
150 : SvxNumPositionAndSpaceMode ePositionAndSpaceMode )
151 : : SvxNumberType(eType),
152 : eNumAdjust(SVX_ADJUST_LEFT),
153 : nInclUpperLevels(0),
154 : nStart(1),
155 : cBullet(SVX_DEF_BULLET),
156 : nBulletRelSize(100),
157 : nBulletColor(COL_BLACK),
158 : mePositionAndSpaceMode( ePositionAndSpaceMode ),
159 : nFirstLineOffset(0),
160 : nAbsLSpace(0),
161 : nLSpace(0),
162 : nCharTextDistance(0),
163 : meLabelFollowedBy( LISTTAB ),
164 : mnListtabPos( 0 ),
165 : mnFirstLineIndent( 0 ),
166 : mnIndentAt( 0 ),
167 : pGraphicBrush(0),
168 : eVertOrient(text::VertOrientation::NONE),
169 5508 : pBulletFont(0)
170 : {
171 5508 : }
172 :
173 49813 : SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat& rFormat) :
174 : SvxNumberType(rFormat),
175 : mePositionAndSpaceMode( rFormat.mePositionAndSpaceMode ),
176 : pGraphicBrush(0),
177 49813 : pBulletFont(0)
178 : {
179 49813 : *this = rFormat;
180 49813 : }
181 :
182 134466 : SvxNumberFormat::~SvxNumberFormat()
183 : {
184 54434 : delete pGraphicBrush;
185 54434 : delete pBulletFont;
186 80032 : }
187 :
188 0 : SvStream& SvxNumberFormat::Store(SvStream &rStream, FontToSubsFontConverter pConverter)
189 : {
190 0 : if(pConverter && pBulletFont)
191 : {
192 0 : cBullet = ConvertFontToSubsFontChar(pConverter, cBullet);
193 0 : String sFontName = GetFontToSubsFontName(pConverter);
194 0 : pBulletFont->SetName(sFontName);
195 : }
196 :
197 0 : rStream << (sal_uInt16)NUMITEM_VERSION_04;
198 :
199 0 : rStream << (sal_uInt16)GetNumberingType();
200 0 : rStream << (sal_uInt16)eNumAdjust;
201 0 : rStream << (sal_uInt16)nInclUpperLevels;
202 0 : rStream << nStart;
203 0 : rStream << (sal_uInt16)cBullet;
204 :
205 0 : rStream << nFirstLineOffset;
206 0 : rStream << nAbsLSpace;
207 0 : rStream << nLSpace;
208 :
209 0 : rStream << nCharTextDistance;
210 0 : rtl_TextEncoding eEnc = osl_getThreadTextEncoding();
211 0 : rStream.WriteUniOrByteString(sPrefix, eEnc);
212 0 : rStream.WriteUniOrByteString(sSuffix, eEnc);
213 0 : rStream.WriteUniOrByteString(sCharStyleName, eEnc);
214 0 : if(pGraphicBrush)
215 : {
216 0 : rStream << (sal_uInt16)1;
217 :
218 : // in SD or SI force bullet itself to be stored,
219 : // for that purpose throw away link when link and graphic
220 : // are present, so Brush save is forced
221 0 : if(pGraphicBrush->GetGraphicLink() && pGraphicBrush->GetGraphic())
222 : {
223 0 : String aEmpty;
224 0 : pGraphicBrush->SetGraphicLink(aEmpty);
225 : }
226 :
227 0 : pGraphicBrush->Store(rStream, BRUSH_GRAPHIC_VERSION);
228 : }
229 : else
230 0 : rStream << (sal_uInt16)0;
231 :
232 0 : rStream << (sal_uInt16)eVertOrient;
233 0 : if(pBulletFont)
234 : {
235 0 : rStream << (sal_uInt16)1;
236 0 : rStream << *pBulletFont;
237 : }
238 : else
239 0 : rStream << (sal_uInt16)0;
240 0 : rStream << aGraphicSize;
241 :
242 0 : Color nTempColor = nBulletColor;
243 0 : if(COL_AUTO == nBulletColor.GetColor())
244 0 : nTempColor = COL_BLACK;
245 0 : rStream << nTempColor;
246 0 : rStream << nBulletRelSize;
247 0 : rStream << (sal_uInt16)IsShowSymbol();
248 :
249 0 : rStream << ( sal_uInt16 ) mePositionAndSpaceMode;
250 0 : rStream << ( sal_uInt16 ) meLabelFollowedBy;
251 0 : rStream << ( sal_Int32 ) mnListtabPos;
252 0 : rStream << ( sal_Int32 ) mnFirstLineIndent;
253 0 : rStream << ( sal_Int32 ) mnIndentAt;
254 :
255 0 : return rStream;
256 : }
257 :
258 49917 : SvxNumberFormat& SvxNumberFormat::operator=( const SvxNumberFormat& rFormat )
259 : {
260 49917 : if (& rFormat == this) { return *this; }
261 :
262 49917 : SetNumberingType(rFormat.GetNumberingType());
263 49917 : eNumAdjust = rFormat.eNumAdjust ;
264 49917 : nInclUpperLevels = rFormat.nInclUpperLevels ;
265 49917 : nStart = rFormat.nStart ;
266 49917 : cBullet = rFormat.cBullet ;
267 49917 : mePositionAndSpaceMode = rFormat.mePositionAndSpaceMode;
268 49917 : nFirstLineOffset = rFormat.nFirstLineOffset;
269 49917 : nAbsLSpace = rFormat.nAbsLSpace ;
270 49917 : nLSpace = rFormat.nLSpace ;
271 49917 : nCharTextDistance = rFormat.nCharTextDistance ;
272 49917 : meLabelFollowedBy = rFormat.meLabelFollowedBy;
273 49917 : mnListtabPos = rFormat.mnListtabPos;
274 49917 : mnFirstLineIndent = rFormat.mnFirstLineIndent;
275 49917 : mnIndentAt = rFormat.mnIndentAt;
276 49917 : eVertOrient = rFormat.eVertOrient ;
277 49917 : sPrefix = rFormat.sPrefix ;
278 49917 : sSuffix = rFormat.sSuffix ;
279 49917 : aGraphicSize = rFormat.aGraphicSize ;
280 49917 : nBulletColor = rFormat.nBulletColor ;
281 49917 : nBulletRelSize = rFormat.nBulletRelSize;
282 49917 : SetShowSymbol(rFormat.IsShowSymbol());
283 49917 : sCharStyleName = rFormat.sCharStyleName;
284 49917 : DELETEZ(pGraphicBrush);
285 49917 : if(rFormat.pGraphicBrush)
286 : {
287 0 : pGraphicBrush = new SvxBrushItem(*rFormat.pGraphicBrush);
288 0 : pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
289 : }
290 49917 : DELETEZ(pBulletFont);
291 49917 : if(rFormat.pBulletFont)
292 27668 : pBulletFont = new Font(*rFormat.pBulletFont);
293 49917 : return *this;
294 : }
295 :
296 24320 : sal_Bool SvxNumberFormat::operator==( const SvxNumberFormat& rFormat) const
297 : {
298 134410 : if( GetNumberingType() != rFormat.GetNumberingType() ||
299 : eNumAdjust != rFormat.eNumAdjust ||
300 : nInclUpperLevels != rFormat.nInclUpperLevels ||
301 : nStart != rFormat.nStart ||
302 : cBullet != rFormat.cBullet ||
303 : mePositionAndSpaceMode != rFormat.mePositionAndSpaceMode ||
304 : nFirstLineOffset != rFormat.nFirstLineOffset ||
305 : nAbsLSpace != rFormat.nAbsLSpace ||
306 : nLSpace != rFormat.nLSpace ||
307 : nCharTextDistance != rFormat.nCharTextDistance ||
308 : meLabelFollowedBy != rFormat.meLabelFollowedBy ||
309 : mnListtabPos != rFormat.mnListtabPos ||
310 : mnFirstLineIndent != rFormat.mnFirstLineIndent ||
311 : mnIndentAt != rFormat.mnIndentAt ||
312 : eVertOrient != rFormat.eVertOrient ||
313 20197 : sPrefix != rFormat.sPrefix ||
314 20197 : sSuffix != rFormat.sSuffix ||
315 20197 : aGraphicSize != rFormat.aGraphicSize ||
316 20197 : nBulletColor != rFormat.nBulletColor ||
317 : nBulletRelSize != rFormat.nBulletRelSize ||
318 14651 : IsShowSymbol() != rFormat.IsShowSymbol() ||
319 14651 : sCharStyleName != rFormat.sCharStyleName
320 : )
321 9858 : return sal_False;
322 28924 : if (
323 0 : (pGraphicBrush && !rFormat.pGraphicBrush) ||
324 14462 : (!pGraphicBrush && rFormat.pGraphicBrush) ||
325 0 : (pGraphicBrush && *pGraphicBrush != *rFormat.pGraphicBrush)
326 : )
327 : {
328 0 : return sal_False;
329 : }
330 44262 : if (
331 7884 : (pBulletFont && !rFormat.pBulletFont) ||
332 14247 : (!pBulletFont && rFormat.pBulletFont) ||
333 7669 : (pBulletFont && *pBulletFont != *rFormat.pBulletFont)
334 : )
335 : {
336 700 : return sal_False;
337 : }
338 13762 : return sal_True;
339 : }
340 :
341 19405 : void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem,
342 : const Size* pSize, const sal_Int16* pOrient)
343 : {
344 19405 : if(!pBrushItem)
345 : {
346 19405 : delete pGraphicBrush;
347 19405 : pGraphicBrush = 0;
348 : }
349 0 : else if ( !pGraphicBrush || (pGraphicBrush && !(*pBrushItem == *pGraphicBrush)) )
350 : {
351 0 : delete pGraphicBrush;
352 0 : pGraphicBrush = (SvxBrushItem*)pBrushItem->Clone();
353 0 : pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
354 : }
355 :
356 19405 : if(pOrient)
357 19405 : eVertOrient = *pOrient;
358 : else
359 0 : eVertOrient = text::VertOrientation::NONE;
360 19405 : if(pSize)
361 19405 : aGraphicSize = *pSize;
362 : else
363 0 : aGraphicSize.Width() = aGraphicSize.Height() = 0;
364 19405 : }
365 :
366 0 : void SvxNumberFormat::SetGraphic( const String& rName )
367 : {
368 : const String* pName;
369 0 : if( pGraphicBrush &&
370 0 : 0 != (pName = pGraphicBrush->GetGraphicLink())
371 0 : && *pName == rName )
372 0 : return ;
373 :
374 0 : delete pGraphicBrush;
375 0 : String sTmp;
376 0 : pGraphicBrush = new SvxBrushItem( rName, sTmp, GPOS_AREA, 0 );
377 0 : pGraphicBrush->SetDoneLink( STATIC_LINK( this, SvxNumberFormat, GraphicArrived) );
378 0 : if( eVertOrient == text::VertOrientation::NONE )
379 0 : eVertOrient = text::VertOrientation::TOP;
380 :
381 0 : aGraphicSize.Width() = aGraphicSize.Height() = 0;
382 : }
383 :
384 0 : void SvxNumberFormat::SetVertOrient(sal_Int16 eSet)
385 : {
386 0 : eVertOrient = eSet;
387 0 : }
388 :
389 38810 : sal_Int16 SvxNumberFormat::GetVertOrient() const
390 : {
391 38810 : return eVertOrient;
392 : }
393 :
394 1677 : void SvxNumberFormat::SetBulletFont(const Font* pFont)
395 : {
396 1677 : delete pBulletFont;
397 1677 : pBulletFont = pFont ? new Font(*pFont): 0;
398 1677 : }
399 :
400 6635 : SvxNumberFormat::SvxNumPositionAndSpaceMode SvxNumberFormat::GetPositionAndSpaceMode() const
401 : {
402 6635 : return mePositionAndSpaceMode;
403 : }
404 1662 : void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode )
405 : {
406 1662 : mePositionAndSpaceMode = ePositionAndSpaceMode;
407 1662 : }
408 :
409 0 : short SvxNumberFormat::GetLSpace() const
410 : {
411 0 : return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nLSpace : 0;
412 : }
413 5498 : short SvxNumberFormat::GetAbsLSpace() const
414 : {
415 : return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
416 : ? nAbsLSpace
417 5498 : : static_cast<short>( GetFirstLineIndent() + GetIndentAt() );
418 : }
419 8207 : short SvxNumberFormat::GetFirstLineOffset() const
420 : {
421 : return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
422 : ? nFirstLineOffset
423 8207 : : static_cast<short>( GetFirstLineIndent() );
424 : }
425 2709 : short SvxNumberFormat::GetCharTextDistance() const
426 : {
427 2709 : return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nCharTextDistance : 0;
428 : }
429 :
430 3648 : void SvxNumberFormat::SetLabelFollowedBy( const LabelFollowedBy eLabelFollowedBy )
431 : {
432 3648 : meLabelFollowedBy = eLabelFollowedBy;
433 3648 : }
434 285 : SvxNumberFormat::LabelFollowedBy SvxNumberFormat::GetLabelFollowedBy() const
435 : {
436 285 : return meLabelFollowedBy;
437 : }
438 3666 : void SvxNumberFormat::SetListtabPos( const long nListtabPos )
439 : {
440 3666 : mnListtabPos = nListtabPos;
441 3666 : }
442 227 : long SvxNumberFormat::GetListtabPos() const
443 : {
444 227 : return mnListtabPos;
445 : }
446 4198 : void SvxNumberFormat::SetFirstLineIndent( const long nFirstLineIndent )
447 : {
448 4198 : mnFirstLineIndent = nFirstLineIndent;
449 4198 : }
450 1025 : long SvxNumberFormat::GetFirstLineIndent() const
451 : {
452 1025 : return mnFirstLineIndent;
453 : }
454 4216 : void SvxNumberFormat::SetIndentAt( const long nIndentAt )
455 : {
456 4216 : mnIndentAt = nIndentAt;
457 4216 : }
458 730 : long SvxNumberFormat::GetIndentAt() const
459 : {
460 730 : return mnIndentAt;
461 : }
462 :
463 0 : IMPL_STATIC_LINK( SvxNumberFormat, GraphicArrived, void *, EMPTYARG )
464 : {
465 : // if necessary, set the GrfSize:
466 0 : if( !pThis->aGraphicSize.Width() || !pThis->aGraphicSize.Height() )
467 : {
468 0 : const Graphic* pGrf = pThis->pGraphicBrush->GetGraphic();
469 0 : if( pGrf )
470 0 : pThis->aGraphicSize = SvxNumberFormat::GetGraphicSizeMM100( pGrf );
471 : }
472 0 : pThis->NotifyGraphicArrived();
473 0 : return 0;
474 : }
475 :
476 0 : void SvxNumberFormat::NotifyGraphicArrived()
477 : {
478 0 : }
479 :
480 0 : Size SvxNumberFormat::GetGraphicSizeMM100(const Graphic* pGraphic)
481 : {
482 0 : const MapMode aMapMM100( MAP_100TH_MM );
483 0 : const Size& rSize = pGraphic->GetPrefSize();
484 0 : Size aRetSize;
485 0 : if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
486 : {
487 0 : OutputDevice* pOutDev = Application::GetDefaultDevice();
488 0 : MapMode aOldMap( pOutDev->GetMapMode() );
489 0 : pOutDev->SetMapMode( aMapMM100 );
490 0 : aRetSize = pOutDev->PixelToLogic( rSize );
491 0 : pOutDev->SetMapMode( aOldMap );
492 : }
493 : else
494 0 : aRetSize = OutputDevice::LogicToLogic( rSize, pGraphic->GetPrefMapMode(), aMapMM100 );
495 0 : return aRetSize;
496 : }
497 :
498 0 : String SvxNumberFormat::CreateRomanString( sal_uLong nNo, sal_Bool bUpper )
499 : {
500 0 : nNo %= 4000; // more can not be displayed
501 : // i, ii, iii, iv, v, vi, vii, vii, viii, ix
502 : // (Dummy),1000,500,100,50,10,5,1
503 : const char *cRomanArr = bUpper
504 : ? "MDCLXVI--" // +2 Dummy entries!
505 0 : : "mdclxvi--"; // +2 Dummy entries!
506 :
507 0 : String sRet;
508 0 : sal_uInt16 nMask = 1000;
509 0 : while( nMask )
510 : {
511 0 : sal_uInt8 nZahl = sal_uInt8(nNo / nMask);
512 0 : sal_uInt8 nDiff = 1;
513 0 : nNo %= nMask;
514 :
515 0 : if( 5 < nZahl )
516 : {
517 0 : if( nZahl < 9 )
518 0 : sRet += sal_Unicode(*(cRomanArr-1));
519 0 : ++nDiff;
520 0 : nZahl -= 5;
521 : }
522 0 : switch( nZahl )
523 : {
524 0 : case 3: { sRet += sal_Unicode(*cRomanArr); }
525 0 : case 2: { sRet += sal_Unicode(*cRomanArr); }
526 0 : case 1: { sRet += sal_Unicode(*cRomanArr); }
527 0 : break;
528 :
529 : case 4: {
530 0 : sRet += sal_Unicode(*cRomanArr);
531 0 : sRet += sal_Unicode(*(cRomanArr-nDiff));
532 : }
533 0 : break;
534 0 : case 5: { sRet += sal_Unicode(*(cRomanArr-nDiff)); }
535 0 : break;
536 : }
537 :
538 0 : nMask /= 10; // for the next decade
539 0 : cRomanArr += 2;
540 : }
541 0 : return sRet;
542 : }
543 :
544 800 : const String& SvxNumberFormat::GetCharFmtName()const
545 : {
546 800 : return sCharStyleName;
547 : }
548 :
549 : sal_Int32 SvxNumRule::nRefCount = 0;
550 : static SvxNumberFormat* pStdNumFmt = 0;
551 : static SvxNumberFormat* pStdOutlineNumFmt = 0;
552 234 : SvxNumRule::SvxNumRule( sal_uLong nFeatures,
553 : sal_uInt16 nLevels,
554 : sal_Bool bCont,
555 : SvxNumRuleType eType,
556 : SvxNumberFormat::SvxNumPositionAndSpaceMode
557 : eDefaultNumberFormatPositionAndSpaceMode )
558 : : nLevelCount(nLevels),
559 : nFeatureFlags(nFeatures),
560 : eNumberingType(eType),
561 234 : bContinuousNumbering(bCont)
562 : {
563 234 : ++nRefCount;
564 2574 : for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++)
565 : {
566 2340 : if(i < nLevels)
567 : {
568 2052 : aFmts[i] = new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER);
569 : // It is a distinction between writer and draw
570 2052 : if(nFeatures & NUM_CONTINUOUS)
571 : {
572 880 : if ( eDefaultNumberFormatPositionAndSpaceMode ==
573 : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
574 : {
575 880 : aFmts[i]->SetLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE) );
576 880 : aFmts[i]->SetAbsLSpace( MM100_TO_TWIP(DEF_WRITER_LSPACE * (i+1)) );
577 880 : aFmts[i]->SetFirstLineOffset(MM100_TO_TWIP(-DEF_WRITER_LSPACE));
578 : }
579 0 : else if ( eDefaultNumberFormatPositionAndSpaceMode ==
580 : SvxNumberFormat::LABEL_ALIGNMENT )
581 : {
582 : // first line indent of general numbering in inch: -0,25 inch
583 0 : const long cFirstLineIndent = -1440/4;
584 : // indent values of general numbering in inch:
585 : // 0,5 0,75 1,0 1,25 1,5
586 : // 1,75 2,0 2,25 2,5 2,75
587 0 : const long cIndentAt = 1440/4;
588 0 : aFmts[i]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT );
589 0 : aFmts[i]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB );
590 0 : aFmts[i]->SetListtabPos( cIndentAt * (i+2) );
591 0 : aFmts[i]->SetFirstLineIndent( cFirstLineIndent );
592 0 : aFmts[i]->SetIndentAt( cIndentAt * (i+2) );
593 : }
594 : }
595 : else
596 : {
597 1172 : aFmts[i]->SetLSpace( DEF_DRAW_LSPACE );
598 1172 : aFmts[i]->SetAbsLSpace( DEF_DRAW_LSPACE * (i) );
599 : }
600 : }
601 : else
602 288 : aFmts[i] = 0;
603 2340 : aFmtsSet[i] = sal_False;
604 : }
605 234 : }
606 :
607 1728 : SvxNumRule::SvxNumRule(const SvxNumRule& rCopy)
608 : {
609 1728 : ++nRefCount;
610 1728 : aLocale = rCopy.aLocale;
611 1728 : nLevelCount = rCopy.nLevelCount ;
612 1728 : nFeatureFlags = rCopy.nFeatureFlags ;
613 1728 : bContinuousNumbering = rCopy.bContinuousNumbering;
614 1728 : eNumberingType = rCopy.eNumberingType;
615 1728 : memset( aFmts, 0, sizeof( aFmts ));
616 19008 : for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++)
617 : {
618 17280 : if(rCopy.aFmts[i])
619 15534 : aFmts[i] = new SvxNumberFormat(*rCopy.aFmts[i]);
620 : else
621 1746 : aFmts[i] = 0;
622 17280 : aFmtsSet[i] = rCopy.aFmtsSet[i];
623 : }
624 1728 : }
625 :
626 0 : SvStream& SvxNumRule::Store(SvStream &rStream)
627 : {
628 0 : rStream<<(sal_uInt16)NUMITEM_VERSION_03;
629 0 : rStream<<nLevelCount;
630 : //first save of nFeatureFlags for old versions
631 0 : rStream<<(sal_uInt16)nFeatureFlags;
632 0 : rStream<<(sal_uInt16)bContinuousNumbering;
633 0 : rStream<<(sal_uInt16)eNumberingType;
634 :
635 0 : FontToSubsFontConverter pConverter = 0;
636 0 : sal_Bool bConvertBulletFont = rStream.GetVersion() <= SOFFICE_FILEFORMAT_50;
637 0 : for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++)
638 : {
639 0 : if(aFmts[i])
640 : {
641 0 : rStream << sal_uInt16(1);
642 0 : if(bConvertBulletFont && aFmts[i]->GetBulletFont())
643 : {
644 0 : if(!pConverter)
645 : pConverter =
646 0 : CreateFontToSubsFontConverter(aFmts[i]->GetBulletFont()->GetName(),
647 0 : FONTTOSUBSFONT_EXPORT|FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS);
648 : }
649 0 : aFmts[i]->Store(rStream, pConverter);
650 : }
651 : else
652 0 : rStream << sal_uInt16(0);
653 : }
654 : //second save of nFeatureFlags for new versions
655 0 : rStream<<(sal_uInt16)nFeatureFlags;
656 0 : if(pConverter)
657 0 : DestroyFontToSubsFontConverter(pConverter);
658 :
659 0 : return rStream;
660 : }
661 :
662 5307 : SvxNumRule::~SvxNumRule()
663 : {
664 21340 : for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++)
665 19400 : delete aFmts[i];
666 1940 : if(!--nRefCount)
667 : {
668 15 : DELETEZ(pStdNumFmt);
669 15 : DELETEZ(pStdOutlineNumFmt);
670 : }
671 3367 : }
672 :
673 0 : SvxNumRule& SvxNumRule::operator=( const SvxNumRule& rCopy )
674 : {
675 0 : nLevelCount = rCopy.nLevelCount;
676 0 : nFeatureFlags = rCopy.nFeatureFlags;
677 0 : bContinuousNumbering = rCopy.bContinuousNumbering;
678 0 : eNumberingType = rCopy.eNumberingType;
679 0 : for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++)
680 : {
681 0 : delete aFmts[i];
682 0 : if(rCopy.aFmts[i])
683 0 : aFmts[i] = new SvxNumberFormat(*rCopy.aFmts[i]);
684 : else
685 0 : aFmts[i] = 0;
686 0 : aFmtsSet[i] = rCopy.aFmtsSet[i];
687 : }
688 0 : return *this;
689 : }
690 :
691 8044 : int SvxNumRule::operator==( const SvxNumRule& rCopy) const
692 : {
693 8044 : if(nLevelCount != rCopy.nLevelCount ||
694 : nFeatureFlags != rCopy.nFeatureFlags ||
695 : bContinuousNumbering != rCopy.bContinuousNumbering ||
696 : eNumberingType != rCopy.eNumberingType)
697 3291 : return sal_False;
698 11141 : for(sal_uInt16 i = 0; i < nLevelCount; i++)
699 : {
700 84384 : if (
701 21096 : (aFmtsSet[i] != rCopy.aFmtsSet[i]) ||
702 10548 : (!aFmts[i] && rCopy.aFmts[i]) ||
703 21096 : (aFmts[i] && !rCopy.aFmts[i]) ||
704 21096 : (aFmts[i] && *aFmts[i] != *rCopy.aFmts[i])
705 : )
706 : {
707 4160 : return sal_False;
708 : }
709 : }
710 593 : return sal_True;
711 : }
712 :
713 28717 : const SvxNumberFormat* SvxNumRule::Get(sal_uInt16 nLevel)const
714 : {
715 : DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" );
716 28717 : if( nLevel < SVX_MAX_NUM )
717 28717 : return aFmtsSet[nLevel] ? aFmts[nLevel] : 0;
718 : else
719 0 : return 0;
720 : }
721 :
722 6658 : const SvxNumberFormat& SvxNumRule::GetLevel(sal_uInt16 nLevel)const
723 : {
724 6658 : if(!pStdNumFmt)
725 : {
726 5 : pStdNumFmt = new SvxNumberFormat(SVX_NUM_ARABIC);
727 5 : pStdOutlineNumFmt = new SvxNumberFormat(SVX_NUM_NUMBER_NONE);
728 : }
729 :
730 : DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" );
731 :
732 6658 : return ( ( nLevel < SVX_MAX_NUM ) && aFmts[nLevel] ) ?
733 6658 : *aFmts[nLevel] : eNumberingType == SVX_RULETYPE_NUMBERING ?
734 19974 : *pStdNumFmt : *pStdOutlineNumFmt;
735 : }
736 :
737 9084 : void SvxNumRule::SetLevel( sal_uInt16 i, const SvxNumberFormat& rNumFmt, sal_Bool bIsValid )
738 : {
739 : DBG_ASSERT(i < SVX_MAX_NUM, "Wrong Level" );
740 :
741 9084 : if( (i < SVX_MAX_NUM) && (!aFmtsSet[i] || !(rNumFmt == *Get( i ))) )
742 : {
743 8216 : delete aFmts[ i ];
744 8216 : aFmts[ i ] = new SvxNumberFormat( rNumFmt );
745 8216 : aFmtsSet[i] = bIsValid;
746 : }
747 9084 : }
748 :
749 0 : String SvxNumRule::MakeNumString( const SvxNodeNum& rNum, sal_Bool bInclStrings ) const
750 : {
751 0 : String aStr;
752 0 : if( SVX_NO_NUM > rNum.GetLevel() && !( SVX_NO_NUMLEVEL & rNum.GetLevel() ) )
753 : {
754 0 : const SvxNumberFormat& rMyNFmt = GetLevel( rNum.GetLevel() );
755 0 : if( SVX_NUM_NUMBER_NONE != rMyNFmt.GetNumberingType() )
756 : {
757 0 : sal_uInt8 i = rNum.GetLevel();
758 :
759 0 : if( !IsContinuousNumbering() &&
760 0 : 1 < rMyNFmt.GetIncludeUpperLevels() ) // only on own level?
761 : {
762 0 : sal_uInt8 n = rMyNFmt.GetIncludeUpperLevels();
763 0 : if( 1 < n )
764 : {
765 0 : if( i+1 >= n )
766 0 : i -= n - 1;
767 : else
768 0 : i = 0;
769 : }
770 : }
771 :
772 0 : for( ; i <= rNum.GetLevel(); ++i )
773 : {
774 0 : const SvxNumberFormat& rNFmt = GetLevel( i );
775 0 : if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() )
776 : {
777 0 : continue;
778 : }
779 :
780 0 : sal_Bool bDot = sal_True;
781 0 : if( rNum.GetLevelVal()[ i ] )
782 : {
783 0 : if(SVX_NUM_BITMAP != rNFmt.GetNumberingType())
784 0 : aStr += rNFmt.GetNumStr( rNum.GetLevelVal()[ i ], aLocale );
785 : else
786 0 : bDot = sal_False;
787 : }
788 : else
789 0 : aStr += sal_Unicode('0'); // all 0-levels are a 0
790 0 : if( i != rNum.GetLevel() && bDot)
791 0 : aStr += sal_Unicode('.');
792 : }
793 : }
794 :
795 0 : if( bInclStrings )
796 : {
797 0 : aStr.Insert( rMyNFmt.GetPrefix(), 0 );
798 0 : aStr += rMyNFmt.GetSuffix();
799 : }
800 : }
801 0 : return aStr;
802 : }
803 :
804 : // changes linked to embedded bitmaps
805 80 : sal_Bool SvxNumRule::UnLinkGraphics()
806 : {
807 80 : sal_Bool bRet = sal_False;
808 880 : for(sal_uInt16 i = 0; i < GetLevelCount(); i++)
809 : {
810 800 : SvxNumberFormat aFmt(GetLevel(i));
811 800 : const SvxBrushItem* pBrush = aFmt.GetBrush();
812 : const String* pLinkStr;
813 : const Graphic* pGraphic;
814 800 : if(SVX_NUM_BITMAP == aFmt.GetNumberingType())
815 : {
816 0 : if(pBrush &&
817 : 0 != (pLinkStr = pBrush->GetGraphicLink()) &&
818 0 : pLinkStr->Len() &&
819 : 0 !=(pGraphic = pBrush->GetGraphic()))
820 : {
821 0 : SvxBrushItem aTempItem(*pBrush);
822 0 : aTempItem.SetGraphicLink( String());
823 0 : aTempItem.SetGraphic(*pGraphic);
824 0 : sal_Int16 eOrient = aFmt.GetVertOrient();
825 0 : aFmt.SetGraphicBrush( &aTempItem, &aFmt.GetGraphicSize(), &eOrient );
826 0 : bRet = sal_True;
827 : }
828 : }
829 800 : else if((SVX_NUM_BITMAP|LINK_TOKEN) == aFmt.GetNumberingType())
830 0 : aFmt.SetNumberingType(SVX_NUM_BITMAP);
831 800 : SetLevel(i, aFmt);
832 800 : }
833 80 : return bRet;
834 : }
835 :
836 88 : SvxNumBulletItem::SvxNumBulletItem(SvxNumRule& rRule) :
837 : SfxPoolItem(SID_ATTR_NUMBERING_RULE),
838 88 : pNumRule(new SvxNumRule(rRule))
839 : {
840 88 : }
841 :
842 146 : SvxNumBulletItem::SvxNumBulletItem(SvxNumRule& rRule, sal_uInt16 _nWhich ) :
843 : SfxPoolItem(_nWhich),
844 146 : pNumRule(new SvxNumRule(rRule))
845 : {
846 146 : }
847 :
848 0 : SfxPoolItem* SvxNumBulletItem::Create(SvStream &s, sal_uInt16 n) const
849 : {
850 0 : return SfxPoolItem::Create(s, n );
851 : }
852 :
853 1170 : SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem& rCopy) :
854 1170 : SfxPoolItem(rCopy.Which())
855 : {
856 1170 : pNumRule = new SvxNumRule(*rCopy.pNumRule);
857 1170 : }
858 :
859 3368 : SvxNumBulletItem::~SvxNumBulletItem()
860 : {
861 1382 : delete pNumRule;
862 1986 : }
863 :
864 8044 : int SvxNumBulletItem::operator==( const SfxPoolItem& rCopy) const
865 : {
866 8044 : return *pNumRule == *((SvxNumBulletItem&)rCopy).pNumRule;
867 : }
868 :
869 554 : SfxPoolItem* SvxNumBulletItem::Clone( SfxItemPool * ) const
870 : {
871 554 : return new SvxNumBulletItem(*this);
872 : }
873 :
874 1776 : sal_uInt16 SvxNumBulletItem::GetVersion( sal_uInt16 /*nFileVersion*/ ) const
875 : {
876 1776 : return NUMITEM_VERSION_03;
877 : }
878 :
879 0 : SvStream& SvxNumBulletItem::Store(SvStream &rStream, sal_uInt16 /*nItemVersion*/ )const
880 : {
881 0 : pNumRule->Store(rStream);
882 0 : return rStream;
883 : }
884 :
885 0 : bool SvxNumBulletItem::QueryValue( com::sun::star::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const
886 : {
887 0 : rVal <<= SvxCreateNumRule( pNumRule );
888 0 : return true;
889 : }
890 :
891 45 : bool SvxNumBulletItem::PutValue( const com::sun::star::uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
892 : {
893 45 : uno::Reference< container::XIndexReplace > xRule;
894 45 : if( rVal >>= xRule )
895 : {
896 : try
897 : {
898 45 : SvxNumRule* pNewRule = new SvxNumRule( SvxGetNumRule( xRule ) );
899 90 : if( pNewRule->GetLevelCount() != pNumRule->GetLevelCount() ||
900 45 : pNewRule->GetNumRuleType() != pNumRule->GetNumRuleType() )
901 : {
902 0 : SvxNumRule* pConverted = SvxConvertNumRule( pNewRule, pNumRule->GetLevelCount(), pNumRule->GetNumRuleType() );
903 0 : delete pNewRule;
904 0 : pNewRule = pConverted;
905 : }
906 45 : delete pNumRule;
907 45 : pNumRule = pNewRule;
908 45 : return true;
909 : }
910 0 : catch(const lang::IllegalArgumentException&)
911 : {
912 : }
913 : }
914 0 : return false;
915 : }
916 :
917 0 : SvxNumRule* SvxConvertNumRule( const SvxNumRule* pRule, sal_uInt16 nLevels, SvxNumRuleType eType )
918 : {
919 0 : const sal_uInt16 nSrcLevels = pRule->GetLevelCount();
920 0 : SvxNumRule* pNewRule = new SvxNumRule( pRule->GetFeatureFlags(), nLevels, pRule->IsContinuousNumbering(), eType );
921 :
922 0 : for( sal_uInt16 nLevel = 0; (nLevel < nLevels) && (nLevel < nSrcLevels); nLevel++ )
923 0 : pNewRule->SetLevel( nLevel, pRule->GetLevel( nLevel ) );
924 :
925 0 : return pNewRule;
926 72 : }
927 :
928 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|