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