xref: /core/editeng/source/items/paraitem.cxx (revision f83a04c51056445bbf947a31c8c1866a5c30bef1)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <com/sun/star/style/TabStop.hpp>
21 #include <com/sun/star/style/LineSpacing.hpp>
22 #include <com/sun/star/style/LineSpacingMode.hpp>
23 #include <com/sun/star/text/ParagraphHyphenationKeepType.hpp>
24 #include <com/sun/star/uno/Sequence.hxx>
25 #include <libxml/xmlwriter.h>
26 #include <comphelper/extract.hxx>
27 #include <osl/diagnose.h>
28 #include <unotools/localedatawrapper.hxx>
29 #include <unotools/syslocale.hxx>
30 #include <tools/mapunit.hxx>
31 #include <tools/UnitConversion.hxx>
32 #include <svl/itempool.hxx>
33 #include <svl/memberid.h>
34 #include <editeng/editrids.hrc>
35 #include <editeng/lspcitem.hxx>
36 #include <editeng/adjustitem.hxx>
37 #include <editeng/orphitem.hxx>
38 #include <editeng/widwitem.hxx>
39 #include <editeng/tstpitem.hxx>
40 #include <editeng/pmdlitem.hxx>
41 #include <editeng/spltitem.hxx>
42 #include <editeng/hyphenzoneitem.hxx>
43 #include <editeng/scriptspaceitem.hxx>
44 #include <editeng/hngpnctitem.hxx>
45 #include <editeng/forbiddenruleitem.hxx>
46 #include <editeng/paravertalignitem.hxx>
47 #include <editeng/pgrditem.hxx>
48 #include <rtl/ustring.hxx>
49 #include <sal/log.hxx>
50 #include <editeng/memberids.h>
51 #include <editeng/itemtype.hxx>
52 #include <editeng/eerdll.hxx>
53 #include <o3tl/hash_combine.hxx>
54 
55 using namespace ::com::sun::star;
56 
57 
CreateDefault()58 SfxPoolItem* SvxLineSpacingItem::CreateDefault() { return new  SvxLineSpacingItem(LINE_SPACE_DEFAULT_HEIGHT, 0);}
CreateDefault()59 SfxPoolItem* SvxAdjustItem::CreateDefault() { return new  SvxAdjustItem(SvxAdjust::Left, 0);}
CreateDefault()60 SfxPoolItem* SvxWidowsItem::CreateDefault() { return new  SvxWidowsItem(0, 0);}
CreateDefault()61 SfxPoolItem* SvxOrphansItem::CreateDefault() { return new  SvxOrphansItem(0, 0);}
CreateDefault()62 SfxPoolItem* SvxHyphenZoneItem::CreateDefault() { return new  SvxHyphenZoneItem(false, 0);}
CreateDefault()63 SfxPoolItem* SvxTabStopItem::CreateDefault() { return new  SvxTabStopItem(0);}
CreateDefault()64 SfxPoolItem* SvxFormatSplitItem::CreateDefault() { return new  SvxFormatSplitItem(false, 0);}
CreateDefault()65 SfxPoolItem* SvxPageModelItem::CreateDefault() { return new  SvxPageModelItem(TypedWhichId<SvxPageModelItem>(0));}
CreateDefault()66 SfxPoolItem* SvxParaVertAlignItem::CreateDefault() { return new  SvxParaVertAlignItem(Align::Automatic, TypedWhichId<SvxParaVertAlignItem>(0));}
67 
68 namespace {
69 
70 enum class SvxSpecialLineSpace
71 {
72     User,
73     OneLine,
74     OnePointFiveLines,
75     TwoLines,
76     End
77 };
78 
79 }
80 
SvxLineSpacingItem(sal_uInt16 nHeight,const sal_uInt16 nId)81 SvxLineSpacingItem::SvxLineSpacingItem( sal_uInt16 nHeight, const sal_uInt16 nId )
82     : SfxPoolItem(nId)
83 {
84     nPropLineSpace = 100;
85     nInterLineSpace = 0;
86     nLineHeight = nHeight;
87     eLineSpaceRule = SvxLineSpaceRule::Auto;
88     eInterLineSpaceRule = SvxInterLineSpaceRule::Off;
89 }
90 
91 
operator ==(const SfxPoolItem & rAttr) const92 bool SvxLineSpacingItem::operator==( const SfxPoolItem& rAttr ) const
93 {
94     assert(SfxPoolItem::operator==(rAttr));
95 
96     const SvxLineSpacingItem& rLineSpace = static_cast<const SvxLineSpacingItem&>(rAttr);
97     return
98         // Same Linespacing Rule?
99         (eLineSpaceRule == rLineSpace.eLineSpaceRule)
100         // For maximum and minimum Linespacing be the size must coincide.
101         && (eLineSpaceRule == SvxLineSpaceRule::Auto ||
102             nLineHeight == rLineSpace.nLineHeight)
103         // Same Linespacing Rule?
104         && ( eInterLineSpaceRule == rLineSpace.eInterLineSpaceRule )
105         // Either set proportional or additive.
106         && (( eInterLineSpaceRule == SvxInterLineSpaceRule::Off)
107             || (eInterLineSpaceRule == SvxInterLineSpaceRule::Prop
108                 && nPropLineSpace == rLineSpace.nPropLineSpace)
109             || (eInterLineSpaceRule == SvxInterLineSpaceRule::Fix
110                 && (nInterLineSpace == rLineSpace.nInterLineSpace)));
111 }
112 
hashCode() const113 size_t SvxLineSpacingItem::hashCode() const
114 {
115     std::size_t seed(0);
116     o3tl::hash_combine(seed, eLineSpaceRule);
117     o3tl::hash_combine(seed, nLineHeight);
118     o3tl::hash_combine(seed, eInterLineSpaceRule);
119     o3tl::hash_combine(seed, nPropLineSpace);
120     o3tl::hash_combine(seed, nInterLineSpace);
121     return seed;
122 }
123 
124 /* Who does still know why the LineSpacingItem is so complicated?
125    We can not use it for UNO since there are only two values:
126       - a sal_uInt16 for the mode
127       - a sal_uInt32 for all values (distance, height, rel. detail)
128 */
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const129 bool SvxLineSpacingItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
130 {
131     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
132     nMemberId &= ~CONVERT_TWIPS;
133 
134     style::LineSpacing aLSp;
135     switch( eLineSpaceRule )
136     {
137         case SvxLineSpaceRule::Auto:
138             if(eInterLineSpaceRule == SvxInterLineSpaceRule::Fix)
139             {
140                 aLSp.Mode = style::LineSpacingMode::LEADING;
141                 aLSp.Height = ( bConvert ? static_cast<short>(convertTwipToMm100(nInterLineSpace)) : nInterLineSpace);
142             }
143             else if(eInterLineSpaceRule == SvxInterLineSpaceRule::Off)
144             {
145                 aLSp.Mode = style::LineSpacingMode::PROP;
146                 aLSp.Height = 100;
147             }
148             else
149             {
150                 aLSp.Mode = style::LineSpacingMode::PROP;
151                 aLSp.Height = nPropLineSpace;
152             }
153         break;
154         case SvxLineSpaceRule::Fix :
155         case SvxLineSpaceRule::Min :
156             aLSp.Mode = eLineSpaceRule == SvxLineSpaceRule::Fix ? style::LineSpacingMode::FIX : style::LineSpacingMode::MINIMUM;
157             aLSp.Height = ( bConvert ? static_cast<short>(convertTwipToMm100(nLineHeight)) : nLineHeight );
158         break;
159         default:
160             ;//prevent warning about SvxLineSpaceRule::End
161     }
162 
163     switch ( nMemberId )
164     {
165         case 0 :                rVal <<= aLSp; break;
166         case MID_LINESPACE :    rVal <<= aLSp.Mode; break;
167         case MID_HEIGHT :       rVal <<= aLSp.Height; break;
168         default: OSL_FAIL("Wrong MemberId!"); break;
169     }
170 
171     return true;
172 }
173 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)174 bool SvxLineSpacingItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
175 {
176     ASSERT_CHANGE_REFCOUNTED_ITEM;
177     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
178     nMemberId &= ~CONVERT_TWIPS;
179 
180     // fill with current data
181     style::LineSpacing aLSp;
182     uno::Any aAny;
183     bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aLSp );
184 
185     // get new data
186     switch ( nMemberId )
187     {
188         case 0 :                bRet = (rVal >>= aLSp); break;
189         case MID_LINESPACE :    bRet = (rVal >>= aLSp.Mode); break;
190         case MID_HEIGHT :       bRet = (rVal >>= aLSp.Height); break;
191         default: OSL_FAIL("Wrong MemberId!"); break;
192     }
193 
194     if( bRet )
195     {
196         nLineHeight = aLSp.Height;
197         switch( aLSp.Mode )
198         {
199             case style::LineSpacingMode::LEADING:
200             {
201                 eInterLineSpaceRule = SvxInterLineSpaceRule::Fix;
202                 eLineSpaceRule = SvxLineSpaceRule::Auto;
203                 nInterLineSpace = aLSp.Height;
204                 if(bConvert)
205                     nInterLineSpace = o3tl::toTwips(nInterLineSpace, o3tl::Length::mm100);
206 
207             }
208             break;
209             case style::LineSpacingMode::PROP:
210             {
211                 eLineSpaceRule = SvxLineSpaceRule::Auto;
212                 nPropLineSpace = aLSp.Height;
213                 if(100 == aLSp.Height)
214                     eInterLineSpaceRule = SvxInterLineSpaceRule::Off;
215                 else
216                     eInterLineSpaceRule = SvxInterLineSpaceRule::Prop;
217             }
218             break;
219             case style::LineSpacingMode::FIX:
220             case style::LineSpacingMode::MINIMUM:
221             {
222                 eInterLineSpaceRule =  SvxInterLineSpaceRule::Off;
223                 eLineSpaceRule = aLSp.Mode == style::LineSpacingMode::FIX ? SvxLineSpaceRule::Fix : SvxLineSpaceRule::Min;
224                 nLineHeight = aLSp.Height;
225                 if(bConvert)
226                     nLineHeight = o3tl::toTwips(nLineHeight, o3tl::Length::mm100);
227             }
228             break;
229         }
230     }
231 
232     return bRet;
233 }
234 
Clone(SfxItemPool *) const235 SvxLineSpacingItem* SvxLineSpacingItem::Clone( SfxItemPool * ) const
236 {
237     return new SvxLineSpacingItem( *this );
238 }
239 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const240 bool SvxLineSpacingItem::GetPresentation
241 (
242     SfxItemPresentation ePres,
243     MapUnit             eCoreUnit,
244     MapUnit             ePresUnit,
245     OUString&           rText, const IntlWrapper& rIntl
246 )   const
247 {
248     switch ( ePres )
249     {
250         case SfxItemPresentation::Nameless:
251         case SfxItemPresentation::Complete:
252         {
253             switch( GetLineSpaceRule() )
254             {
255                 case SvxLineSpaceRule::Auto:
256                 {
257                     SvxInterLineSpaceRule eInter = GetInterLineSpaceRule();
258 
259                     switch( eInter )
260                     {
261                         // Default single line spacing
262                         case SvxInterLineSpaceRule::Off:
263                             rText = EditResId(RID_SVXITEMS_LINESPACING_SINGLE);
264                             break;
265 
266                         // Default single line spacing
267                         case SvxInterLineSpaceRule::Prop:
268                             if ( 100 == GetPropLineSpace() )
269                             {
270                                 rText = EditResId(RID_SVXITEMS_LINESPACING_SINGLE);
271                                 break;
272                             }
273                             // 1.15 line spacing
274                             if ( 115 == GetPropLineSpace() )
275                             {
276                                 rText = EditResId(RID_SVXITEMS_LINESPACING_115);
277                                 break;
278                             }
279                             // 1.5 line spacing
280                             if ( 150 == GetPropLineSpace() )
281                             {
282                                 rText = EditResId(RID_SVXITEMS_LINESPACING_15);
283                                 break;
284                             }
285                             // double line spacing
286                             if ( 200 == GetPropLineSpace() )
287                             {
288                                 rText = EditResId(RID_SVXITEMS_LINESPACING_DOUBLE);
289                                 break;
290                             }
291                             // the set per cent value
292                             rText = EditResId(RID_SVXITEMS_LINESPACING_PROPORTIONAL) + " " + OUString::number(GetPropLineSpace()) + "%";
293                             break;
294 
295                         case SvxInterLineSpaceRule::Fix:
296                             rText = EditResId(RID_SVXITEMS_LINESPACING_LEADING)  +
297                                     " " + GetMetricText(GetInterLineSpace(), eCoreUnit, ePresUnit, &rIntl) +
298                                     " " + EditResId(GetMetricId(ePresUnit));
299                             break;
300                         default: ;//prevent warning
301                     }
302                 }
303                 break;
304                 case SvxLineSpaceRule::Fix:
305                     rText = EditResId(RID_SVXITEMS_LINESPACING_FIXED)  +
306                             " " + GetMetricText(GetLineHeight(), eCoreUnit, ePresUnit, &rIntl) +
307                             " " + EditResId(GetMetricId(ePresUnit));
308                     break;
309 
310                 case SvxLineSpaceRule::Min:
311                     rText = EditResId(RID_SVXITEMS_LINESPACING_MIN) +
312                             " " + GetMetricText(GetLineHeight(), eCoreUnit, ePresUnit, &rIntl) +
313                             " " + EditResId(GetMetricId(ePresUnit));
314                     break;
315                 default: ;//prevent warning
316             }
317         }
318     }
319     return true;
320 }
321 
322 // class SvxAdjustItem ---------------------------------------------------
323 
getItemInstanceManager() const324 ItemInstanceManager* SvxAdjustItem::getItemInstanceManager() const
325 {
326     static DefaultItemInstanceManager aInstanceManager(ItemType());
327     return &aInstanceManager;
328 }
329 
SvxAdjustItem(const SvxAdjust eAdjst,const sal_uInt16 nId)330 SvxAdjustItem::SvxAdjustItem(const SvxAdjust eAdjst, const sal_uInt16 nId )
331     : SfxPoolItem( nId ),
332     bOneBlock( false ), bLastCenter( false ), bLastBlock( false ),
333     nPropWordSpacing(100),
334     nPropWordSpacingMinimum(100),
335     nPropWordSpacingMaximum(100),
336     nPropLetterSpacingMinimum(0),
337     nPropLetterSpacingMaximum(0)
338 {
339     SetAdjust( eAdjst );
340 }
341 
operator ==(const SfxPoolItem & rAttr) const342 bool SvxAdjustItem::operator==( const SfxPoolItem& rAttr ) const
343 {
344     assert(SfxPoolItem::operator==(rAttr));
345 
346     const SvxAdjustItem& rItem = static_cast<const SvxAdjustItem&>(rAttr);
347     return GetAdjust() == rItem.GetAdjust() &&
348            bOneBlock == rItem.bOneBlock &&
349            bLastCenter == rItem.bLastCenter &&
350            bLastBlock == rItem.bLastBlock &&
351            nPropWordSpacingMinimum == rItem.nPropWordSpacingMinimum &&
352            nPropWordSpacingMaximum == rItem.nPropWordSpacingMaximum &&
353            nPropWordSpacing == rItem.nPropWordSpacing &&
354            nPropLetterSpacingMinimum == rItem.nPropLetterSpacingMinimum &&
355            nPropLetterSpacingMaximum == rItem.nPropLetterSpacingMaximum;
356 }
357 
hashCode() const358 size_t SvxAdjustItem::hashCode() const
359 {
360     std::size_t seed(0);
361     o3tl::hash_combine(seed, GetAdjust());
362     o3tl::hash_combine(seed, bOneBlock);
363     o3tl::hash_combine(seed, bLastCenter);
364     o3tl::hash_combine(seed, bLastBlock);
365     o3tl::hash_combine(seed, nPropWordSpacing);
366     o3tl::hash_combine(seed, nPropWordSpacingMinimum);
367     o3tl::hash_combine(seed, nPropWordSpacingMaximum);
368     o3tl::hash_combine(seed, nPropLetterSpacingMinimum);
369     o3tl::hash_combine(seed, nPropLetterSpacingMaximum);
370     return seed;
371 }
372 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const373 bool SvxAdjustItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
374 {
375     nMemberId &= ~CONVERT_TWIPS;
376     switch( nMemberId )
377     {
378         case MID_PARA_ADJUST      : rVal <<= static_cast<sal_Int16>(GetAdjust()); break;
379         case MID_LAST_LINE_ADJUST : rVal <<= static_cast<sal_Int16>(GetLastBlock()); break;
380         case MID_WORD_SPACING     : rVal <<= static_cast<sal_Int16>(GetPropWordSpacing()); break;
381         case MID_WORD_SPACING_MIN : rVal <<= static_cast<sal_Int16>(GetPropWordSpacingMinimum()); break;
382         case MID_WORD_SPACING_MAX : rVal <<= static_cast<sal_Int16>(GetPropWordSpacingMaximum()); break;
383         case MID_LETTER_SPACING_MIN : rVal <<= GetPropLetterSpacingMinimum(); break;
384         case MID_LETTER_SPACING_MAX : rVal <<= GetPropLetterSpacingMaximum(); break;
385         case MID_EXPAND_SINGLE    :
386         {
387             rVal <<= bOneBlock;
388             break;
389         }
390         default: ;//prevent warning
391     }
392     return true;
393 }
394 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)395 bool SvxAdjustItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
396 {
397     ASSERT_CHANGE_REFCOUNTED_ITEM;
398     nMemberId &= ~CONVERT_TWIPS;
399     switch( nMemberId )
400     {
401         case MID_PARA_ADJUST              :
402         case MID_LAST_LINE_ADJUST :
403         {
404             sal_Int32 eVal = - 1;
405             ::cppu::enum2int(eVal,rVal);
406             if(eVal >= 0 && eVal <= 4)
407             {
408                 SvxAdjust eAdjust = static_cast<SvxAdjust>(eVal);
409                 if(MID_LAST_LINE_ADJUST == nMemberId &&
410                     eAdjust != SvxAdjust::Left &&
411                     eAdjust != SvxAdjust::Block &&
412                     eAdjust != SvxAdjust::Center)
413                         return false;
414                 nMemberId == MID_PARA_ADJUST ? SetAdjust(eAdjust) : SetLastBlock(eAdjust);
415             }
416         }
417         break;
418         case MID_WORD_SPACING :
419         {
420             sal_Int16 nVal = -1;
421             rVal >>= nVal;
422             SetPropWordSpacing(nVal);
423         }
424         break;
425         case MID_WORD_SPACING_MIN :
426         {
427             sal_Int16 nVal = -1;
428             rVal >>= nVal;
429             SetPropWordSpacingMinimum(nVal);
430         }
431         break;
432         case MID_WORD_SPACING_MAX :
433         {
434             sal_Int16 nVal = -1;
435             rVal >>= nVal;
436             SetPropWordSpacingMaximum(nVal);
437         }
438         break;
439         case MID_LETTER_SPACING_MIN :
440         {
441             sal_Int16 nVal = -1;
442             rVal >>= nVal;
443             SetPropLetterSpacingMinimum(nVal);
444         }
445         break;
446         case MID_LETTER_SPACING_MAX :
447         {
448             sal_Int16 nVal = -1;
449             rVal >>= nVal;
450             SetPropLetterSpacingMaximum(nVal);
451         }
452         break;
453         case MID_EXPAND_SINGLE :
454             ASSERT_CHANGE_REFCOUNTED_ITEM;
455             bOneBlock = Any2Bool(rVal);
456             break;
457     }
458     return true;
459 }
460 
Clone(SfxItemPool *) const461 SvxAdjustItem* SvxAdjustItem::Clone( SfxItemPool * ) const
462 {
463     return new SvxAdjustItem( *this );
464 }
465 
GetPresentation(SfxItemPresentation ePres,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const466 bool SvxAdjustItem::GetPresentation
467 (
468     SfxItemPresentation ePres,
469     MapUnit             /*eCoreUnit*/,
470     MapUnit             /*ePresUnit*/,
471     OUString&           rText, const IntlWrapper&
472 )   const
473 {
474     switch ( ePres )
475     {
476         case SfxItemPresentation::Nameless:
477         case SfxItemPresentation::Complete:
478             // TODO Word spacing
479             rText = GetValueTextByPos( static_cast<sal_uInt16>(GetAdjust()) );
480             return true;
481         default: ;//prevent warning
482     }
483     return false;
484 }
485 
486 
GetValueTextByPos(sal_uInt16 nPos)487 OUString SvxAdjustItem::GetValueTextByPos( sal_uInt16 nPos )
488 {
489     static const TranslateId RID_SVXITEMS_ADJUST[] =
490     {
491         RID_SVXITEMS_ADJUST_LEFT,
492         RID_SVXITEMS_ADJUST_RIGHT,
493         RID_SVXITEMS_ADJUST_BLOCK,
494         RID_SVXITEMS_ADJUST_CENTER,
495         RID_SVXITEMS_ADJUST_BLOCKLINE
496     };
497     static_assert(std::size(RID_SVXITEMS_ADJUST) - 1 == static_cast<size_t>(SvxAdjust::BlockLine), "unexpected size");
498     assert(nPos <= sal_uInt16(SvxAdjust::BlockLine) && "enum overflow!");
499     return EditResId(RID_SVXITEMS_ADJUST[nPos]);
500 }
501 
502 
503 // class SvxWidowsItem ---------------------------------------------------
504 
SvxWidowsItem(const sal_uInt8 nL,const sal_uInt16 nId)505 SvxWidowsItem::SvxWidowsItem(const sal_uInt8 nL, const sal_uInt16 nId ) :
506     SfxByteItem( nId, nL )
507 {
508 }
509 
Clone(SfxItemPool *) const510 SvxWidowsItem* SvxWidowsItem::Clone( SfxItemPool * ) const
511 {
512     return new SvxWidowsItem( *this );
513 }
514 
GetPresentation(SfxItemPresentation ePres,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const515 bool SvxWidowsItem::GetPresentation
516 (
517     SfxItemPresentation ePres,
518     MapUnit             /*eCoreUnit*/,
519     MapUnit             /*ePresUnit*/,
520     OUString&           rText, const IntlWrapper&
521 )   const
522 {
523     switch ( ePres )
524     {
525         case SfxItemPresentation::Nameless:
526         {
527             rText = EditResId(RID_SVXITEMS_LINES);
528             break;
529         }
530 
531         case SfxItemPresentation::Complete:
532         {
533             rText = EditResId(RID_SVXITEMS_WIDOWS_COMPLETE) + " " + EditResId(RID_SVXITEMS_LINES);
534             break;
535         }
536 
537         default:
538         {
539             SAL_WARN( "editeng.items", "SvxWidowsItem::GetPresentation(): unknown SfxItemPresentation" );
540         }
541     }
542 
543     rText = rText.replaceFirst( "%1", OUString::number( GetValue() ) );
544     return true;
545 }
546 
547 // class SvxOrphansItem --------------------------------------------------
548 
SvxOrphansItem(const sal_uInt8 nL,const sal_uInt16 nId)549 SvxOrphansItem::SvxOrphansItem(const sal_uInt8 nL, const sal_uInt16 nId ) :
550     SfxByteItem( nId, nL )
551 {
552 }
553 
Clone(SfxItemPool *) const554 SvxOrphansItem* SvxOrphansItem::Clone( SfxItemPool * ) const
555 {
556     return new SvxOrphansItem( *this );
557 }
558 
GetPresentation(SfxItemPresentation ePres,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const559 bool SvxOrphansItem::GetPresentation
560 (
561     SfxItemPresentation ePres,
562     MapUnit             /*eCoreUnit*/,
563     MapUnit             /*ePresUnit*/,
564     OUString&           rText, const IntlWrapper&
565 )   const
566 {
567     switch ( ePres )
568     {
569         case SfxItemPresentation::Nameless:
570         {
571             rText = EditResId(RID_SVXITEMS_LINES);
572             break;
573         }
574 
575         case SfxItemPresentation::Complete:
576         {
577             rText = EditResId(RID_SVXITEMS_ORPHANS_COMPLETE) + " " + EditResId(RID_SVXITEMS_LINES);
578             break;
579         }
580 
581         default:
582         {
583             SAL_WARN( "editeng.items", "SvxOrphansItem::GetPresentation(): unknown SfxItemPresentation" );
584         }
585     }
586 
587     rText = rText.replaceFirst( "%1", OUString::number( GetValue() ) );
588     return true;
589 }
590 
591 // class SvxHyphenZoneItem -----------------------------------------------
592 
SvxHyphenZoneItem(const bool bHyph,const sal_uInt16 nId)593 SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, const sal_uInt16 nId ) :
594     SfxPoolItem( nId ),
595     bHyphen(bHyph),
596     bKeep(false),
597     bNoCapsHyphenation(false),
598     bNoLastWordHyphenation(false),
599     nMinLead(0),
600     nMinTrail(0),
601     nMaxHyphens(255),
602     nMinWordLength(0),
603     nTextHyphenZone(0),
604     nTextHyphenZoneAlways(0),
605     nTextHyphenZoneColumn(0),
606     nTextHyphenZonePage(0),
607     nTextHyphenZoneSpread(0),
608     nKeepType(css::text::ParagraphHyphenationKeepType::COLUMN),
609     bKeepLine(false),
610     nCompoundMinLead(0)
611 {
612 }
613 
614 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const615 bool    SvxHyphenZoneItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
616 {
617     nMemberId &= ~CONVERT_TWIPS;
618     switch(nMemberId)
619     {
620         case  MID_IS_HYPHEN:
621             rVal <<= bHyphen;
622         break;
623         case MID_HYPHEN_KEEP:
624             rVal <<= bKeep;
625         break;
626         case MID_HYPHEN_MIN_LEAD:
627             rVal <<= static_cast<sal_Int16>(nMinLead);
628         break;
629         case MID_HYPHEN_MIN_TRAIL:
630             rVal <<= static_cast<sal_Int16>(nMinTrail);
631         break;
632         case MID_HYPHEN_MAX_HYPHENS:
633             rVal <<= static_cast<sal_Int16>(nMaxHyphens);
634         break;
635         case MID_HYPHEN_NO_CAPS:
636             rVal <<= bNoCapsHyphenation;
637         break;
638         case MID_HYPHEN_NO_LAST_WORD:
639             rVal <<= bNoLastWordHyphenation;
640         break;
641         case MID_HYPHEN_MIN_WORD_LENGTH:
642             rVal <<= static_cast<sal_Int16>(nMinWordLength);
643         break;
644         case MID_HYPHEN_ZONE:
645             rVal <<= static_cast<sal_Int16>(nTextHyphenZone);
646         break;
647         case MID_HYPHEN_ZONE_ALWAYS:
648             rVal <<= static_cast<sal_Int16>(nTextHyphenZoneAlways);
649         break;
650         case MID_HYPHEN_ZONE_COLUMN:
651             rVal <<= static_cast<sal_Int16>(nTextHyphenZoneColumn);
652         break;
653         case MID_HYPHEN_ZONE_PAGE:
654             rVal <<= static_cast<sal_Int16>(nTextHyphenZonePage);
655         break;
656         case MID_HYPHEN_ZONE_SPREAD:
657             rVal <<= static_cast<sal_Int16>(nTextHyphenZoneSpread);
658         break;
659         case MID_HYPHEN_KEEP_TYPE:
660             rVal <<= static_cast<sal_Int16>(nKeepType);
661         break;
662         case MID_HYPHEN_KEEP_LINE:
663             rVal <<= bKeepLine;
664         break;
665         case MID_HYPHEN_COMPOUND_MIN_LEAD:
666             rVal <<= static_cast<sal_Int16>(nCompoundMinLead);
667         break;
668     }
669     return true;
670 }
671 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)672 bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
673 {
674     nMemberId &= ~CONVERT_TWIPS;
675     sal_Int32 nNewVal = 0; // sal_Int32 needs for MID_HYPHEN_KEEP_TYPE
676 
677     if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS &&
678                 nMemberId != MID_HYPHEN_NO_LAST_WORD && nMemberId != MID_HYPHEN_KEEP &&
679                 nMemberId != MID_HYPHEN_KEEP_LINE )
680     {
681         if(!(rVal >>= nNewVal))
682             return false;
683     }
684 
685     switch(nMemberId)
686     {
687         case  MID_IS_HYPHEN:
688             bHyphen = Any2Bool(rVal);
689         break;
690         case  MID_HYPHEN_KEEP:
691             bKeep = Any2Bool(rVal);
692         break;
693         case MID_HYPHEN_MIN_LEAD:
694             nMinLead = static_cast<sal_uInt8>(nNewVal);
695         break;
696         case MID_HYPHEN_MIN_TRAIL:
697             nMinTrail = static_cast<sal_uInt8>(nNewVal);
698         break;
699         case MID_HYPHEN_MAX_HYPHENS:
700             nMaxHyphens = static_cast<sal_uInt8>(nNewVal);
701         break;
702         case MID_HYPHEN_NO_CAPS:
703             bNoCapsHyphenation = Any2Bool(rVal);
704         break;
705         case MID_HYPHEN_NO_LAST_WORD:
706             bNoLastWordHyphenation = Any2Bool(rVal);
707         break;
708         case MID_HYPHEN_MIN_WORD_LENGTH:
709             nMinWordLength = static_cast<sal_uInt8>(nNewVal);
710         break;
711         case MID_HYPHEN_ZONE:
712             nTextHyphenZone = nNewVal;
713         break;
714         case MID_HYPHEN_ZONE_ALWAYS:
715             nTextHyphenZoneAlways = nNewVal;
716         break;
717         case MID_HYPHEN_ZONE_COLUMN:
718             nTextHyphenZoneColumn = nNewVal;
719         break;
720         case MID_HYPHEN_ZONE_PAGE:
721             nTextHyphenZonePage = nNewVal;
722         break;
723         case MID_HYPHEN_ZONE_SPREAD:
724             nTextHyphenZoneSpread = nNewVal;
725         break;
726         case MID_HYPHEN_KEEP_TYPE:
727             nKeepType = static_cast<sal_uInt8>(nNewVal);
728         break;
729         case  MID_HYPHEN_KEEP_LINE:
730             bKeepLine = Any2Bool(rVal);
731         break;
732         case MID_HYPHEN_COMPOUND_MIN_LEAD:
733             nCompoundMinLead = static_cast<sal_uInt8>(nNewVal);
734         break;
735     }
736     return true;
737 }
738 
739 
operator ==(const SfxPoolItem & rAttr) const740 bool SvxHyphenZoneItem::operator==( const SfxPoolItem& rAttr ) const
741 {
742     assert(SfxPoolItem::operator==(rAttr));
743 
744     const SvxHyphenZoneItem& rItem = static_cast<const SvxHyphenZoneItem&>(rAttr);
745     return ( rItem.bHyphen == bHyphen
746             && rItem.bNoCapsHyphenation == bNoCapsHyphenation
747             && rItem.bNoLastWordHyphenation == bNoLastWordHyphenation
748             && rItem.bKeep == bKeep
749             && rItem.nMinLead == nMinLead
750             && rItem.nMinTrail == nMinTrail
751             && rItem.nCompoundMinLead == nCompoundMinLead
752             && rItem.nMaxHyphens == nMaxHyphens
753             && rItem.nMinWordLength == nMinWordLength
754             && rItem.nTextHyphenZone == nTextHyphenZone
755             && rItem.nTextHyphenZoneAlways == nTextHyphenZoneAlways
756             && rItem.nTextHyphenZoneColumn == nTextHyphenZoneColumn
757             && rItem.nTextHyphenZonePage == nTextHyphenZonePage
758             && rItem.nTextHyphenZoneSpread == nTextHyphenZoneSpread
759             && rItem.bKeepLine == bKeepLine
760             && rItem.nKeepType == nKeepType );
761 }
762 
Clone(SfxItemPool *) const763 SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const
764 {
765     return new SvxHyphenZoneItem( *this );
766 }
767 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const768 bool SvxHyphenZoneItem::GetPresentation
769 (
770     SfxItemPresentation ePres,
771     MapUnit             eCoreUnit,
772     MapUnit             ePresUnit,
773     OUString&           rText, const IntlWrapper& rIntl
774 )   const
775 {
776     OUString cpDelimTmp(cpDelim);
777     switch ( ePres )
778     {
779         case SfxItemPresentation::Nameless:
780         {
781             TranslateId pId = RID_SVXITEMS_HYPHEN_FALSE;
782             if ( bHyphen )
783                 pId = RID_SVXITEMS_HYPHEN_TRUE;
784             rText += EditResId(pId) + cpDelimTmp +
785                     OUString::number( nMinLead ) + cpDelimTmp +
786                     OUString::number( nMinTrail ) + cpDelimTmp +
787                     OUString::number( nCompoundMinLead ) + cpDelimTmp +
788                     OUString::number( nMaxHyphens ) + cpDelimTmp +
789                     OUString::number( nMinWordLength ) + cpDelimTmp +
790                     GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) +
791                         " " + EditResId(GetMetricId(ePresUnit)) +
792                     GetMetricText( nTextHyphenZoneAlways, eCoreUnit, ePresUnit, &rIntl ) +
793                         " " + EditResId(GetMetricId(ePresUnit)) +
794                     GetMetricText( nTextHyphenZoneColumn, eCoreUnit, ePresUnit, &rIntl ) +
795                         " " + EditResId(GetMetricId(ePresUnit)) +
796                     GetMetricText( nTextHyphenZonePage, eCoreUnit, ePresUnit, &rIntl ) +
797                         " " + EditResId(GetMetricId(ePresUnit)) +
798                     GetMetricText( nTextHyphenZoneSpread, eCoreUnit, ePresUnit, &rIntl ) +
799                         " " + EditResId(GetMetricId(ePresUnit));
800 
801             if ( bNoCapsHyphenation )
802                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
803 
804             if ( bNoLastWordHyphenation )
805                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
806 
807             if ( bKeep )
808             {
809                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_TRUE) +
810                                  cpDelimTmp + OUString::number( nKeepType );
811                 if ( bKeepLine )
812                     rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE);
813                 else
814                     rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE);
815             }
816             else
817                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_FALSE);
818 
819 
820             return true;
821         }
822         case SfxItemPresentation::Complete:
823         {
824             TranslateId pId = RID_SVXITEMS_HYPHEN_FALSE;
825 
826             if ( bHyphen )
827                 pId = RID_SVXITEMS_HYPHEN_TRUE;
828             rText += EditResId(pId) +
829                     cpDelimTmp +
830                     EditResId(RID_SVXITEMS_HYPHEN_MINLEAD).replaceAll("%1", OUString::number(nMinLead)) +
831                     cpDelimTmp +
832                     EditResId(RID_SVXITEMS_HYPHEN_MINTRAIL).replaceAll("%1", OUString::number(nMinTrail)) +
833                     cpDelimTmp +
834                     EditResId(RID_SVXITEMS_HYPHEN_COMPOUND_MINLEAD).replaceAll("%1", OUString::number(nCompoundMinLead)) +
835                     cpDelimTmp +
836                     EditResId(RID_SVXITEMS_HYPHEN_MAX).replaceAll("%1", OUString::number(nMaxHyphens)) +
837                     cpDelimTmp +
838                     EditResId(RID_SVXITEMS_HYPHEN_MINWORDLEN).replaceAll("%1", OUString::number(nMinWordLength));
839 
840             if ( nTextHyphenZone > 0 || nTextHyphenZoneAlways > 0 ||
841                  nTextHyphenZoneColumn > 0 || nTextHyphenZonePage > 0 ||
842                  nTextHyphenZoneSpread > 0 )
843             {
844                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE) +
845                         GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) +
846                         " " + EditResId(GetMetricId(ePresUnit));
847                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE_ALWAYS) +
848                         GetMetricText( nTextHyphenZoneAlways, eCoreUnit, ePresUnit, &rIntl ) +
849                         " " + EditResId(GetMetricId(ePresUnit));
850                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE_COLUMN) +
851                         GetMetricText( nTextHyphenZoneColumn, eCoreUnit, ePresUnit, &rIntl ) +
852                         " " + EditResId(GetMetricId(ePresUnit));
853                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE_PAGE) +
854                         GetMetricText( nTextHyphenZonePage, eCoreUnit, ePresUnit, &rIntl ) +
855                         " " + EditResId(GetMetricId(ePresUnit));
856                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE_SPREAD) +
857                         GetMetricText( nTextHyphenZoneSpread, eCoreUnit, ePresUnit, &rIntl ) +
858                         " " + EditResId(GetMetricId(ePresUnit));
859             }
860 
861             if ( bNoCapsHyphenation )
862                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE);
863 
864             if ( bNoLastWordHyphenation )
865                 rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE);
866 
867             if ( bKeep )
868             {
869                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_TRUE) + cpDelimTmp;
870 
871                 switch ( nKeepType )
872                 {
873                     case 0:
874                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_AUTO);
875                         break;
876                     case 1:
877                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_SPREAD);
878                         break;
879                     case 2:
880                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_PAGE);
881                         break;
882                     case 3:
883                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_COLUMN);
884                         break;
885                     case 4:
886                         rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_ALWAYS);
887                         break;
888                 }
889 
890                 if ( bKeepLine )
891                     rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_TRUE);
892                 else
893                     rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_LINE_FALSE);
894             }
895             else
896                 rText += EditResId(RID_SVXITEMS_HYPHEN_KEEP_FALSE);
897 
898             return true;
899         }
900         default: ;//prevent warning
901     }
902     return false;
903 }
904 
905 
906 // class SvxTabStop ------------------------------------------------------
907 
SvxTabStop()908 SvxTabStop::SvxTabStop()
909 {
910     nTabPos = 0;
911     eAdjustment = SvxTabAdjust::Left;
912     m_cDecimal = cDfltDecimalChar;
913     cFill = cDfltFillChar;
914     fillDecimal();
915 }
916 
917 
SvxTabStop(const sal_Int32 nPos,const SvxTabAdjust eAdjst,const sal_Unicode cDec,const sal_Unicode cFil)918 SvxTabStop::SvxTabStop( const sal_Int32 nPos, const SvxTabAdjust eAdjst,
919                         const sal_Unicode cDec, const sal_Unicode cFil )
920 {
921     nTabPos = nPos;
922     eAdjustment = eAdjst;
923     m_cDecimal = cDec;
924     cFill = cFil;
925     fillDecimal();
926 }
927 
fillDecimal()928 void SvxTabStop::fillDecimal()
929 {
930     if ( cDfltDecimalChar == m_cDecimal )
931         m_cDecimal = SvtSysLocale().GetLocaleData().getNumDecimalSep()[0];
932 }
933 
dumpAsXml(xmlTextWriterPtr pWriter) const934 void SvxTabStop::dumpAsXml(xmlTextWriterPtr pWriter) const
935 {
936     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTabStop"));
937     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nTabPos"),
938                                 BAD_CAST(OString::number(nTabPos).getStr()));
939     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdjustment"),
940                                 BAD_CAST(OString::number(static_cast<int>(eAdjustment)).getStr()));
941     (void)xmlTextWriterEndElement(pWriter);
942 }
943 
944 // class SvxTabStopItem --------------------------------------------------
945 
SvxTabStopItem(sal_uInt16 _nWhich)946 SvxTabStopItem::SvxTabStopItem( sal_uInt16 _nWhich ) :
947     SfxPoolItem( _nWhich )
948 {
949     const sal_uInt16 nTabs = SVX_TAB_DEFCOUNT, nDist = SVX_TAB_DEFDIST;
950     const SvxTabAdjust eAdjst= SvxTabAdjust::Default;
951 
952     for (sal_uInt16 i = 0; i < nTabs; ++i)
953     {
954         SvxTabStop aTab( (i + 1) * nDist, eAdjst );
955         maTabStops.insert( aTab );
956     }
957 }
958 
959 
SvxTabStopItem(const sal_uInt16 nTabs,const sal_uInt16 nDist,const SvxTabAdjust eAdjst,sal_uInt16 _nWhich)960 SvxTabStopItem::SvxTabStopItem( const sal_uInt16 nTabs,
961                                 const sal_uInt16 nDist,
962                                 const SvxTabAdjust eAdjst,
963                                 sal_uInt16 _nWhich ) :
964     SfxPoolItem( _nWhich )
965 {
966     for ( sal_uInt16 i = 0; i < nTabs; ++i )
967     {
968         SvxTabStop aTab( (i + 1) * nDist, eAdjst );
969         maTabStops.insert( aTab );
970     }
971 }
972 
973 
GetPos(const SvxTabStop & rTab) const974 sal_uInt16 SvxTabStopItem::GetPos( const SvxTabStop& rTab ) const
975 {
976     SvxTabStopArr::const_iterator it = maTabStops.find( rTab );
977     return it != maTabStops.end() ? it - maTabStops.begin() : SVX_TAB_NOTFOUND;
978 }
979 
980 
GetPos(const sal_Int32 nPos) const981 sal_uInt16 SvxTabStopItem::GetPos( const sal_Int32 nPos ) const
982 {
983     SvxTabStopArr::const_iterator it = maTabStops.find( SvxTabStop( nPos ) );
984     return it != maTabStops.end() ? it - maTabStops.begin() : SVX_TAB_NOTFOUND;
985 }
986 
SetDefaultDistance(sal_Int32 nDefaultDistance)987 void SvxTabStopItem::SetDefaultDistance(sal_Int32 nDefaultDistance)
988 {
989     ASSERT_CHANGE_REFCOUNTED_ITEM;
990     mnDefaultDistance = nDefaultDistance;
991 }
992 
GetDefaultDistance() const993 sal_Int32 SvxTabStopItem::GetDefaultDistance() const
994 {
995     return mnDefaultDistance;
996 }
997 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const998 bool SvxTabStopItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
999 {
1000     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1001     nMemberId &= ~CONVERT_TWIPS;
1002     switch ( nMemberId )
1003     {
1004         case MID_TABSTOPS:
1005         {
1006             sal_uInt16 nCount = Count();
1007             uno::Sequence< style::TabStop> aSeq(nCount);
1008             style::TabStop* pArr = aSeq.getArray();
1009             for(sal_uInt16 i = 0; i < nCount; i++)
1010             {
1011                 const SvxTabStop& rTab = (*this)[i];
1012                 pArr[i].Position        = bConvert ? convertTwipToMm100(rTab.GetTabPos()) : rTab.GetTabPos();
1013                 switch(rTab.GetAdjustment())
1014                 {
1015                 case  SvxTabAdjust::Left   : pArr[i].Alignment = style::TabAlign_LEFT; break;
1016                 case  SvxTabAdjust::Right  : pArr[i].Alignment = style::TabAlign_RIGHT; break;
1017                 case  SvxTabAdjust::Decimal: pArr[i].Alignment = style::TabAlign_DECIMAL; break;
1018                 case  SvxTabAdjust::Center : pArr[i].Alignment = style::TabAlign_CENTER; break;
1019                     default: //SvxTabAdjust::Default
1020                         pArr[i].Alignment = style::TabAlign_DEFAULT;
1021 
1022                 }
1023                 pArr[i].DecimalChar     = rTab.GetDecimal();
1024                 pArr[i].FillChar        = rTab.GetFill();
1025             }
1026             rVal <<= aSeq;
1027             break;
1028         }
1029         case MID_STD_TAB:
1030         {
1031             const SvxTabStop &rTab = maTabStops.front();
1032             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(rTab.GetTabPos()) : rTab.GetTabPos());
1033             break;
1034         }
1035         case MID_TABSTOP_DEFAULT_DISTANCE:
1036         {
1037             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(mnDefaultDistance) : mnDefaultDistance);
1038             break;
1039         }
1040     }
1041     return true;
1042 }
1043 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1044 bool SvxTabStopItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1045 {
1046     ASSERT_CHANGE_REFCOUNTED_ITEM;
1047     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1048     nMemberId &= ~CONVERT_TWIPS;
1049     switch ( nMemberId )
1050     {
1051         case MID_TABSTOPS:
1052         {
1053             uno::Sequence< style::TabStop> aSeq;
1054             if(!(rVal >>= aSeq))
1055             {
1056                 uno::Sequence < uno::Sequence < uno::Any >  > aAnySeq;
1057                 if (!(rVal >>= aAnySeq))
1058                     return false;
1059                 auto aAnySeqRange = asNonConstRange(aAnySeq);
1060                 sal_Int32 nLength = aAnySeq.getLength();
1061                 aSeq.realloc( nLength );
1062                 auto pSeq = aSeq.getArray();
1063                 for ( sal_Int32 n=0; n<nLength; n++ )
1064                 {
1065                     uno::Sequence < uno::Any >& rAnySeq = aAnySeqRange[n];
1066                     if ( rAnySeq.getLength() == 4 )
1067                     {
1068                         if (!(rAnySeq[0] >>= pSeq[n].Position)) return false;
1069                         if (!(rAnySeq[1] >>= pSeq[n].Alignment))
1070                         {
1071                             sal_Int32 nVal = 0;
1072                             if (rAnySeq[1] >>= nVal)
1073                                 pSeq[n].Alignment = static_cast<css::style::TabAlign>(nVal);
1074                             else
1075                                 return false;
1076                         }
1077                         if (!(rAnySeq[2] >>= pSeq[n].DecimalChar))
1078                         {
1079                             OUString aVal;
1080                             if ( (rAnySeq[2] >>= aVal) && aVal.getLength() == 1 )
1081                                 pSeq[n].DecimalChar = aVal.toChar();
1082                             else
1083                                 return false;
1084                         }
1085                         if (!(rAnySeq[3] >>= pSeq[n].FillChar))
1086                         {
1087                             OUString aVal;
1088                             if ( (rAnySeq[3] >>= aVal) && aVal.getLength() == 1 )
1089                                 pSeq[n].FillChar = aVal.toChar();
1090                             else
1091                                 return false;
1092                         }
1093                     }
1094                     else
1095                         return false;
1096                 }
1097             }
1098 
1099             maTabStops.clear();
1100             const style::TabStop* pArr = aSeq.getConstArray();
1101             const sal_uInt16 nCount = static_cast<sal_uInt16>(aSeq.getLength());
1102             for(sal_uInt16 i = 0; i < nCount ; i++)
1103             {
1104                 SvxTabAdjust eAdjust = SvxTabAdjust::Default;
1105                 switch(pArr[i].Alignment)
1106                 {
1107                 case style::TabAlign_LEFT   : eAdjust = SvxTabAdjust::Left; break;
1108                 case style::TabAlign_CENTER : eAdjust = SvxTabAdjust::Center; break;
1109                 case style::TabAlign_RIGHT  : eAdjust = SvxTabAdjust::Right; break;
1110                 case style::TabAlign_DECIMAL: eAdjust = SvxTabAdjust::Decimal; break;
1111                 default: ;//prevent warning
1112                 }
1113                 sal_Unicode cFill = pArr[i].FillChar;
1114                 sal_Unicode cDecimal = pArr[i].DecimalChar;
1115                 SvxTabStop aTab( bConvert ? o3tl::toTwips(pArr[i].Position, o3tl::Length::mm100) : pArr[i].Position,
1116                                     eAdjust,
1117                                     cDecimal,
1118                                     cFill );
1119                 Insert(aTab);
1120             }
1121             break;
1122         }
1123         case MID_STD_TAB:
1124         {
1125             sal_Int32 nNewPos = 0;
1126             if (!(rVal >>= nNewPos) )
1127                 return false;
1128             if (bConvert)
1129                 nNewPos = o3tl::toTwips(nNewPos, o3tl::Length::mm100);
1130             if (nNewPos <= 0)
1131                 return false;
1132             const SvxTabStop& rTab = maTabStops.front();
1133             SvxTabStop aNewTab ( nNewPos, rTab.GetAdjustment(), rTab.GetDecimal(), rTab.GetFill() );
1134             Remove( 0 );
1135             Insert( aNewTab );
1136             break;
1137         }
1138         case MID_TABSTOP_DEFAULT_DISTANCE:
1139         {
1140             sal_Int32 nNewDefaultDistance = 0;
1141             if (!(rVal >>= nNewDefaultDistance))
1142                 return false;
1143             if (bConvert)
1144                 nNewDefaultDistance = o3tl::toTwips(nNewDefaultDistance, o3tl::Length::mm100);
1145             if (nNewDefaultDistance < 0)
1146                 return false;
1147             mnDefaultDistance = nNewDefaultDistance;
1148             break;
1149         }
1150     }
1151     return true;
1152 }
1153 
1154 
operator ==(const SfxPoolItem & rAttr) const1155 bool SvxTabStopItem::operator==( const SfxPoolItem& rAttr ) const
1156 {
1157     assert(SfxPoolItem::operator==(rAttr));
1158 
1159     const SvxTabStopItem& rTSI = static_cast<const SvxTabStopItem&>(rAttr);
1160 
1161     if ( mnDefaultDistance != rTSI.GetDefaultDistance() )
1162         return false;
1163 
1164     if ( Count() != rTSI.Count() )
1165         return false;
1166 
1167     for ( sal_uInt16 i = 0; i < Count(); ++i )
1168         if( (*this)[i] != rTSI[i] )
1169             return false;
1170     return true;
1171 }
1172 
hashCode() const1173 size_t SvxTabStopItem::hashCode() const
1174 {
1175     std::size_t seed(0);
1176     o3tl::hash_combine(seed, mnDefaultDistance);
1177     for (const SvxTabStop & rStop : maTabStops)
1178     {
1179         o3tl::hash_combine(seed, rStop.GetTabPos());
1180         o3tl::hash_combine(seed, rStop. GetAdjustment());
1181     }
1182     return seed;
1183 }
1184 
Clone(SfxItemPool *) const1185 SvxTabStopItem* SvxTabStopItem::Clone( SfxItemPool * ) const
1186 {
1187     return new SvxTabStopItem( *this );
1188 }
1189 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const1190 bool SvxTabStopItem::GetPresentation
1191 (
1192     SfxItemPresentation ePres,
1193     MapUnit             eCoreUnit,
1194     MapUnit             ePresUnit,
1195     OUString&           rText, const IntlWrapper& rIntl
1196 )   const
1197 {
1198     rText.clear();
1199     // TODO also consider mnDefaultTabDistance here
1200 
1201     bool bComma = false;
1202 
1203     for ( sal_uInt16 i = 0; i < Count(); ++i )
1204     {
1205         if ( SvxTabAdjust::Default != ((*this)[i]).GetAdjustment() )
1206         {
1207             if ( bComma )
1208                 rText += ",";
1209             rText += GetMetricText(
1210                 ((*this)[i]).GetTabPos(), eCoreUnit, ePresUnit, &rIntl );
1211             if ( SfxItemPresentation::Complete == ePres )
1212             {
1213                 rText += " " + EditResId(GetMetricId(ePresUnit));
1214             }
1215             bComma = true;
1216         }
1217     }
1218     return true;
1219 }
1220 
1221 
Insert(const SvxTabStop & rTab)1222 bool SvxTabStopItem::Insert( const SvxTabStop& rTab )
1223 {
1224     ASSERT_CHANGE_REFCOUNTED_ITEM;
1225     sal_uInt16 nTabPos = GetPos(rTab);
1226     if(SVX_TAB_NOTFOUND != nTabPos )
1227         Remove(nTabPos);
1228     return maTabStops.insert( rTab ).second;
1229 }
1230 
Insert(const SvxTabStopItem * pTabs)1231 void SvxTabStopItem::Insert( const SvxTabStopItem* pTabs )
1232 {
1233     ASSERT_CHANGE_REFCOUNTED_ITEM;
1234     for( sal_uInt16 i = 0; i < pTabs->Count(); i++ )
1235     {
1236         const SvxTabStop& rTab = (*pTabs)[i];
1237         sal_uInt16 nTabPos = GetPos(rTab);
1238         if(SVX_TAB_NOTFOUND != nTabPos)
1239             Remove(nTabPos);
1240     }
1241     for( sal_uInt16 i = 0; i < pTabs->Count(); i++ )
1242     {
1243         maTabStops.insert( (*pTabs)[i] );
1244     }
1245 }
1246 
dumpAsXml(xmlTextWriterPtr pWriter) const1247 void SvxTabStopItem::dumpAsXml(xmlTextWriterPtr pWriter) const
1248 {
1249     (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTabStopItem"));
1250     (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("mnDefaultDistance"),
1251                                       BAD_CAST(OString::number(mnDefaultDistance).getStr()));
1252     for (const auto& rTabStop : maTabStops)
1253         rTabStop.dumpAsXml(pWriter);
1254     (void)xmlTextWriterEndElement(pWriter);
1255 }
1256 
1257 // class SvxFormatSplitItem -------------------------------------------------
~SvxFormatSplitItem()1258 SvxFormatSplitItem::~SvxFormatSplitItem()
1259 {
1260 }
1261 
Clone(SfxItemPool *) const1262 SvxFormatSplitItem* SvxFormatSplitItem::Clone( SfxItemPool * ) const
1263 {
1264     return new SvxFormatSplitItem( *this );
1265 }
1266 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1267 bool SvxFormatSplitItem::GetPresentation
1268 (
1269     SfxItemPresentation /*ePres*/,
1270     MapUnit             /*eCoreUnit*/,
1271     MapUnit             /*ePresUnit*/,
1272     OUString&           rText, const IntlWrapper&
1273 )   const
1274 {
1275     TranslateId pId = RID_SVXITEMS_FMTSPLIT_FALSE;
1276 
1277     if ( GetValue() )
1278         pId = RID_SVXITEMS_FMTSPLIT_TRUE;
1279     rText = EditResId(pId);
1280     return true;
1281 }
1282 
Clone(SfxItemPool *) const1283 SvxPageModelItem* SvxPageModelItem::Clone( SfxItemPool* ) const
1284 {
1285     return new SvxPageModelItem( *this );
1286 }
1287 
QueryValue(css::uno::Any & rVal,sal_uInt8 nMemberId) const1288 bool SvxPageModelItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const
1289 {
1290     nMemberId &= ~CONVERT_TWIPS;
1291 
1292     switch ( nMemberId )
1293     {
1294         case MID_AUTO: rVal <<= bAuto; break;
1295         case MID_NAME: rVal <<= GetValue(); break;
1296         default: OSL_FAIL("Wrong MemberId!"); return false;
1297     }
1298 
1299     return true;
1300 }
1301 
PutValue(const css::uno::Any & rVal,sal_uInt8 nMemberId)1302 bool SvxPageModelItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId )
1303 {
1304     nMemberId &= ~CONVERT_TWIPS;
1305     bool bRet;
1306     OUString aStr;
1307     switch ( nMemberId )
1308     {
1309         case MID_AUTO: bRet = ( rVal >>= bAuto ); break;
1310         case MID_NAME: bRet = ( rVal >>= aStr ); if ( bRet ) SetValue(aStr); break;
1311         default: OSL_FAIL("Wrong MemberId!"); return false;
1312     }
1313 
1314     return bRet;
1315 }
1316 
operator ==(const SfxPoolItem & rAttr) const1317 bool SvxPageModelItem::operator==( const SfxPoolItem& rAttr ) const
1318 {
1319     return SfxStringItem::operator==(rAttr) &&
1320            bAuto == static_cast<const SvxPageModelItem&>( rAttr ).bAuto;
1321 }
1322 
GetPresentation(SfxItemPresentation ePres,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1323 bool SvxPageModelItem::GetPresentation
1324 (
1325     SfxItemPresentation ePres,
1326     MapUnit             /*eCoreUnit*/,
1327     MapUnit             /*ePresUnit*/,
1328     OUString&           rText, const IntlWrapper&
1329 )   const
1330 {
1331     rText.clear();
1332     bool bSet = !GetValue().isEmpty();
1333 
1334     switch ( ePres )
1335     {
1336         case SfxItemPresentation::Nameless:
1337             if ( bSet )
1338                 rText = GetValue();
1339             return true;
1340 
1341         case SfxItemPresentation::Complete:
1342             if ( bSet )
1343             {
1344                 rText = EditResId(RID_SVXITEMS_PAGEMODEL_COMPLETE) + GetValue();
1345             }
1346             return true;
1347         default: ;//prevent warning
1348     }
1349     return false;
1350 }
1351 
1352 
SvxScriptSpaceItem(bool bOn,const sal_uInt16 nId)1353 SvxScriptSpaceItem::SvxScriptSpaceItem( bool bOn, const sal_uInt16 nId )
1354     : SfxBoolItem( nId, bOn )
1355 {
1356 }
1357 
Clone(SfxItemPool *) const1358 SvxScriptSpaceItem* SvxScriptSpaceItem::Clone( SfxItemPool * ) const
1359 {
1360     return new SvxScriptSpaceItem( *this );
1361 }
1362 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1363 bool SvxScriptSpaceItem::GetPresentation(
1364         SfxItemPresentation /*ePres*/,
1365         MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/,
1366         OUString &rText, const IntlWrapper& /*rIntl*/ ) const
1367 {
1368     rText = EditResId( !GetValue()
1369                             ? RID_SVXITEMS_SCRPTSPC_OFF
1370                             : RID_SVXITEMS_SCRPTSPC_ON );
1371     return true;
1372 }
1373 
1374 
SvxHangingPunctuationItem(bool bOn,const sal_uInt16 nId)1375 SvxHangingPunctuationItem::SvxHangingPunctuationItem(
1376                                     bool bOn, const sal_uInt16 nId )
1377     : SfxBoolItem( nId, bOn )
1378 {
1379 }
1380 
Clone(SfxItemPool *) const1381 SvxHangingPunctuationItem* SvxHangingPunctuationItem::Clone( SfxItemPool * ) const
1382 {
1383     return new SvxHangingPunctuationItem( *this );
1384 }
1385 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1386 bool SvxHangingPunctuationItem::GetPresentation(
1387         SfxItemPresentation /*ePres*/,
1388         MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/,
1389         OUString &rText, const IntlWrapper& /*rIntl*/ ) const
1390 {
1391     rText = EditResId( !GetValue()
1392                             ? RID_SVXITEMS_HNGPNCT_OFF
1393                             : RID_SVXITEMS_HNGPNCT_ON );
1394     return true;
1395 }
1396 
1397 
SvxForbiddenRuleItem(bool bOn,const sal_uInt16 nId)1398 SvxForbiddenRuleItem::SvxForbiddenRuleItem(
1399                                     bool bOn, const sal_uInt16 nId )
1400     : SfxBoolItem( nId, bOn )
1401 {
1402 }
1403 
Clone(SfxItemPool *) const1404 SvxForbiddenRuleItem* SvxForbiddenRuleItem::Clone( SfxItemPool * ) const
1405 {
1406     return new SvxForbiddenRuleItem( *this );
1407 }
1408 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1409 bool SvxForbiddenRuleItem::GetPresentation(
1410         SfxItemPresentation /*ePres*/,
1411         MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/,
1412         OUString &rText, const IntlWrapper& /*rIntl*/ ) const
1413 {
1414     rText = EditResId( !GetValue()
1415                             ? RID_SVXITEMS_FORBIDDEN_RULE_OFF
1416                             : RID_SVXITEMS_FORBIDDEN_RULE_ON );
1417     return true;
1418 }
1419 
1420 /*************************************************************************
1421 |*    class SvxParaVertAlignItem
1422 *************************************************************************/
1423 
SvxParaVertAlignItem(Align nValue,TypedWhichId<SvxParaVertAlignItem> nW)1424 SvxParaVertAlignItem::SvxParaVertAlignItem( Align nValue,
1425     TypedWhichId<SvxParaVertAlignItem> nW )
1426     : SfxUInt16Item( nW, static_cast<sal_uInt16>(nValue) )
1427 {
1428 }
1429 
Clone(SfxItemPool *) const1430 SvxParaVertAlignItem* SvxParaVertAlignItem::Clone( SfxItemPool* ) const
1431 {
1432     return new SvxParaVertAlignItem( *this );
1433 }
1434 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1435 bool SvxParaVertAlignItem::GetPresentation(
1436         SfxItemPresentation /*ePres*/,
1437         MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/,
1438         OUString &rText, const IntlWrapper& ) const
1439 {
1440     TranslateId pTmp;
1441     switch( GetValue() )
1442     {
1443         case Align::Automatic: pTmp = RID_SVXITEMS_PARAVERTALIGN_AUTO; break;
1444         case Align::Top:       pTmp = RID_SVXITEMS_PARAVERTALIGN_TOP; break;
1445         case Align::Center:    pTmp = RID_SVXITEMS_PARAVERTALIGN_CENTER; break;
1446         case Align::Bottom:    pTmp = RID_SVXITEMS_PARAVERTALIGN_BOTTOM; break;
1447         default:    pTmp = RID_SVXITEMS_PARAVERTALIGN_BASELINE; break;
1448     }
1449     rText = EditResId(pTmp);
1450     return true;
1451 }
1452 
QueryValue(css::uno::Any & rVal,sal_uInt8) const1453 bool SvxParaVertAlignItem::QueryValue( css::uno::Any& rVal,
1454                                            sal_uInt8 /*nMemberId*/ ) const
1455 {
1456     rVal <<= static_cast<sal_Int16>(GetValue());
1457     return true;
1458 }
1459 
PutValue(const css::uno::Any & rVal,sal_uInt8)1460 bool SvxParaVertAlignItem::PutValue( const css::uno::Any& rVal,
1461                                          sal_uInt8 /*nMemberId*/ )
1462 {
1463     sal_Int16 nVal = sal_Int16();
1464     if((rVal >>= nVal) && nVal >=0 && nVal <= sal_uInt16(Align::Bottom) )
1465     {
1466         SetValue( static_cast<Align>(nVal) );
1467         return true;
1468     }
1469     else
1470         return false;
1471 }
1472 
SvxParaGridItem(bool bOn,const sal_uInt16 nId)1473 SvxParaGridItem::SvxParaGridItem( bool bOn, const sal_uInt16 nId )
1474     : SfxBoolItem( nId, bOn )
1475 {
1476 }
1477 
Clone(SfxItemPool *) const1478 SvxParaGridItem* SvxParaGridItem::Clone( SfxItemPool * ) const
1479 {
1480     return new SvxParaGridItem( *this );
1481 }
1482 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const1483 bool SvxParaGridItem::GetPresentation(
1484         SfxItemPresentation /*ePres*/,
1485         MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/,
1486         OUString &rText, const IntlWrapper& /*rIntl*/ ) const
1487 {
1488     rText = GetValue() ?
1489             EditResId( RID_SVXITEMS_PARASNAPTOGRID_ON ) :
1490             EditResId( RID_SVXITEMS_PARASNAPTOGRID_OFF );
1491 
1492     return true;
1493 }
1494 
1495 
1496 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1497