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 <memory>
21 #include <com/sun/star/uno/Any.hxx>
22 #include <com/sun/star/drawing/LineStyle.hpp>
23 #include <com/sun/star/script/Converter.hpp>
24 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
25 #include <com/sun/star/table/ShadowLocation.hpp>
26 #include <com/sun/star/table/TableBorder.hpp>
27 #include <com/sun/star/table/ShadowFormat.hpp>
28 #include <com/sun/star/table/CellRangeAddress.hpp>
29 #include <com/sun/star/table/CellContentType.hpp>
30 #include <com/sun/star/table/TableOrientation.hpp>
31 #include <com/sun/star/util/SortField.hpp>
32 #include <com/sun/star/util/SortFieldType.hpp>
33 #include <com/sun/star/table/BorderLine2.hpp>
34 #include <com/sun/star/table/BorderLineStyle.hpp>
35 #include <com/sun/star/table/CellOrientation.hpp>
36 #include <com/sun/star/table/CellAddress.hpp>
37 #include <com/sun/star/style/PageStyleLayout.hpp>
38 #include <com/sun/star/style/BreakType.hpp>
39 #include <com/sun/star/style/GraphicLocation.hpp>
40 #include <com/sun/star/awt/Rectangle.hpp>
41 #include <com/sun/star/awt/Selection.hpp>
42 #include <com/sun/star/awt/Size.hpp>
43 #include <com/sun/star/text/WritingMode2.hpp>
44 #include <com/sun/star/frame/status/UpperLowerMarginScale.hpp>
45 #include <com/sun/star/frame/status/LeftRightMarginScale.hpp>
46 #include <com/sun/star/drawing/ShadingPattern.hpp>
47 #include <com/sun/star/graphic/XGraphic.hpp>
48 
49 #include <osl/diagnose.h>
50 #include <sal/log.hxx>
51 #include <i18nutil/unicode.hxx>
52 #include <unotools/ucbstreamhelper.hxx>
53 #include <limits.h>
54 #include <comphelper/processfactory.hxx>
55 #include <vcl/GraphicObject.hxx>
56 #include <tools/urlobj.hxx>
57 #include <comphelper/fileformat.h>
58 #include <svl/memberid.h>
59 #include <svtools/borderhelper.hxx>
60 #include <rtl/ustring.hxx>
61 #include <rtl/ustrbuf.hxx>
62 #include <tools/mapunit.hxx>
63 #include <vcl/graphicfilter.hxx>
64 #include <vcl/settings.hxx>
65 #include <vcl/svapp.hxx>
66 #include <editeng/editids.hrc>
67 #include <editeng/editrids.hrc>
68 #include <editeng/pbinitem.hxx>
69 #include <editeng/sizeitem.hxx>
70 #include <editeng/lrspitem.hxx>
71 #include <editeng/ulspitem.hxx>
72 #include <editeng/prntitem.hxx>
73 #include <editeng/opaqitem.hxx>
74 #include <editeng/protitem.hxx>
75 #include <editeng/shaditem.hxx>
76 #include <editeng/borderline.hxx>
77 #include <editeng/boxitem.hxx>
78 #include <editeng/formatbreakitem.hxx>
79 #include <editeng/keepitem.hxx>
80 #include <editeng/lineitem.hxx>
81 #include <editeng/brushitem.hxx>
82 #include <editeng/frmdiritem.hxx>
83 #include <editeng/itemtype.hxx>
84 #include <editeng/eerdll.hxx>
85 #include <editeng/unoprnms.hxx>
86 #include <editeng/memberids.h>
87 #include <editeng/editerr.hxx>
88 #include <libxml/xmlwriter.h>
89 #include <o3tl/enumrange.hxx>
90 #include <o3tl/safeint.hxx>
91 #include <vcl/GraphicLoader.hxx>
92 
93 using namespace ::editeng;
94 using namespace ::com::sun::star;
95 using namespace ::com::sun::star::drawing;
96 using namespace ::com::sun::star::table::BorderLineStyle;
97 
98 
CreateDefault()99 SfxPoolItem* SvxPaperBinItem::CreateDefault() { return new  SvxPaperBinItem(0);}
CreateDefault()100 SfxPoolItem* SvxSizeItem::CreateDefault() { return new  SvxSizeItem(0);}
CreateDefault()101 SfxPoolItem* SvxLRSpaceItem::CreateDefault() { return new  SvxLRSpaceItem(0);}
CreateDefault()102 SfxPoolItem* SvxULSpaceItem::CreateDefault() { return new  SvxULSpaceItem(0);}
CreateDefault()103 SfxPoolItem* SvxProtectItem::CreateDefault() { return new  SvxProtectItem(0);}
CreateDefault()104 SfxPoolItem* SvxBrushItem::CreateDefault() { return new  SvxBrushItem(0);}
CreateDefault()105 SfxPoolItem* SvxShadowItem::CreateDefault() { return new  SvxShadowItem(0);}
CreateDefault()106 SfxPoolItem* SvxBoxItem::CreateDefault() { return new  SvxBoxItem(0);}
CreateDefault()107 SfxPoolItem* SvxBoxInfoItem::CreateDefault() { return new  SvxBoxInfoItem(0);}
CreateDefault()108 SfxPoolItem* SvxFormatBreakItem::CreateDefault() { return new  SvxFormatBreakItem(SvxBreak::NONE, 0);}
CreateDefault()109 SfxPoolItem* SvxFormatKeepItem::CreateDefault() { return new  SvxFormatKeepItem(false, 0);}
CreateDefault()110 SfxPoolItem* SvxLineItem::CreateDefault() { return new  SvxLineItem(0);}
111 
112 
Clone(SfxItemPool *) const113 SfxPoolItem* SvxPaperBinItem::Clone( SfxItemPool* ) const
114 {
115     return new SvxPaperBinItem( *this );
116 }
117 
118 
GetPresentation(SfxItemPresentation ePres,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const119 bool SvxPaperBinItem::GetPresentation
120 (
121     SfxItemPresentation ePres,
122     MapUnit             /*eCoreUnit*/,
123     MapUnit             /*ePresUnit*/,
124     OUString&           rText, const IntlWrapper&
125 )   const
126 {
127     switch ( ePres )
128     {
129         case SfxItemPresentation::Nameless:
130             rText = OUString::number( GetValue() );
131             return true;
132 
133         case SfxItemPresentation::Complete:
134         {
135             sal_uInt8 nValue = GetValue();
136 
137             if ( PAPERBIN_PRINTER_SETTINGS == nValue )
138                 rText = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS);
139             else
140             {
141                 rText = EditResId(RID_SVXSTR_PAPERBIN) + " " + OUString::number( nValue );
142             }
143             return true;
144         }
145         //no break necessary
146         default: ; //prevent warning
147     }
148 
149     return false;
150 }
151 
152 
SvxSizeItem(const sal_uInt16 nId,const Size & rSize)153 SvxSizeItem::SvxSizeItem( const sal_uInt16 nId, const Size& rSize ) :
154 
155     SfxPoolItem( nId ),
156 
157     m_aSize( rSize )
158 {
159 }
160 
161 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const162 bool SvxSizeItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
163 {
164     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
165     nMemberId &= ~CONVERT_TWIPS;
166 
167     awt::Size aTmp(m_aSize.Width(), m_aSize.Height());
168     if( bConvert )
169     {
170         aTmp.Height = convertTwipToMm100(aTmp.Height);
171         aTmp.Width = convertTwipToMm100(aTmp.Width);
172     }
173 
174     switch( nMemberId )
175     {
176         case MID_SIZE_SIZE:  rVal <<= aTmp; break;
177         case MID_SIZE_WIDTH: rVal <<= aTmp.Width; break;
178         case MID_SIZE_HEIGHT: rVal <<= aTmp.Height;  break;
179         default: OSL_FAIL("Wrong MemberId!"); return false;
180     }
181 
182     return true;
183 }
184 
185 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)186 bool SvxSizeItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
187 {
188     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
189     nMemberId &= ~CONVERT_TWIPS;
190 
191     switch( nMemberId )
192     {
193         case MID_SIZE_SIZE:
194         {
195             awt::Size aTmp;
196             if( rVal >>= aTmp )
197             {
198                 if(bConvert)
199                 {
200                     aTmp.Height = convertMm100ToTwip(aTmp.Height);
201                     aTmp.Width = convertMm100ToTwip(aTmp.Width);
202                 }
203                 m_aSize = Size( aTmp.Width, aTmp.Height );
204             }
205             else
206             {
207                 return false;
208             }
209         }
210         break;
211         case MID_SIZE_WIDTH:
212         {
213             sal_Int32 nVal = 0;
214             if(!(rVal >>= nVal ))
215                 return false;
216 
217             m_aSize.setWidth( bConvert ? convertMm100ToTwip(nVal) : nVal );
218         }
219         break;
220         case MID_SIZE_HEIGHT:
221         {
222             sal_Int32 nVal = 0;
223             if(!(rVal >>= nVal))
224                 return true;
225 
226             m_aSize.setHeight( bConvert ? convertMm100ToTwip(nVal) : nVal );
227         }
228         break;
229         default: OSL_FAIL("Wrong MemberId!");
230             return false;
231     }
232     return true;
233 }
234 
235 
SvxSizeItem(const sal_uInt16 nId)236 SvxSizeItem::SvxSizeItem( const sal_uInt16 nId ) :
237 
238     SfxPoolItem( nId )
239 {
240 }
241 
242 
operator ==(const SfxPoolItem & rAttr) const243 bool SvxSizeItem::operator==( const SfxPoolItem& rAttr ) const
244 {
245     assert(SfxPoolItem::operator==(rAttr));
246 
247     return ( m_aSize == static_cast<const SvxSizeItem&>( rAttr ).GetSize() );
248 }
249 
250 
Clone(SfxItemPool *) const251 SfxPoolItem* SvxSizeItem::Clone( SfxItemPool* ) const
252 {
253     return new SvxSizeItem( *this );
254 }
255 
256 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const257 bool SvxSizeItem::GetPresentation
258 (
259     SfxItemPresentation ePres,
260     MapUnit             eCoreUnit,
261     MapUnit             ePresUnit,
262     OUString&           rText, const IntlWrapper& rIntl
263 )   const
264 {
265     OUString cpDelimTmp(cpDelim);
266     switch ( ePres )
267     {
268         case SfxItemPresentation::Nameless:
269             rText = GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) +
270                     cpDelimTmp +
271                     GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl );
272             return true;
273 
274         case SfxItemPresentation::Complete:
275             rText = EditResId(RID_SVXITEMS_SIZE_WIDTH) +
276                     GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) +
277                     " " + EditResId(GetMetricId(ePresUnit)) +
278                     cpDelimTmp +
279                     EditResId(RID_SVXITEMS_SIZE_HEIGHT) +
280                     GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl ) +
281                     " " + EditResId(GetMetricId(ePresUnit));
282             return true;
283         // no break necessary
284         default: ; // prevent warning
285 
286     }
287     return false;
288 }
289 
290 
ScaleMetrics(long nMult,long nDiv)291 void SvxSizeItem::ScaleMetrics( long nMult, long nDiv )
292 {
293     m_aSize.setWidth( Scale( m_aSize.Width(), nMult, nDiv ) );
294     m_aSize.setHeight( Scale( m_aSize.Height(), nMult, nDiv ) );
295 }
296 
297 
HasMetrics() const298 bool SvxSizeItem::HasMetrics() const
299 {
300     return true;
301 }
302 
303 
SvxLRSpaceItem(const sal_uInt16 nId)304 SvxLRSpaceItem::SvxLRSpaceItem( const sal_uInt16 nId ) :
305 
306     SfxPoolItem( nId ),
307 
308     nTxtLeft        ( 0 ),
309     nLeftMargin     ( 0 ),
310     nRightMargin    ( 0 ),
311     nPropFirstLineOfst( 100 ),
312     nPropLeftMargin( 100 ),
313     nPropRightMargin( 100 ),
314     nFirstLineOfst  ( 0 ),
315     bAutoFirst      ( false ),
316     bExplicitZeroMarginValRight(false),
317     bExplicitZeroMarginValLeft(false)
318 {
319 }
320 
321 
SvxLRSpaceItem(const long nLeft,const long nRight,const long nTLeft,const short nOfset,const sal_uInt16 nId)322 SvxLRSpaceItem::SvxLRSpaceItem( const long nLeft, const long nRight,
323                                 const long nTLeft, const short nOfset,
324                                 const sal_uInt16 nId )
325 :   SfxPoolItem( nId ),
326 
327     nTxtLeft        ( nTLeft ),
328     nLeftMargin     ( nLeft ),
329     nRightMargin    ( nRight ),
330     nPropFirstLineOfst( 100 ),
331     nPropLeftMargin( 100 ),
332     nPropRightMargin( 100 ),
333     nFirstLineOfst  ( nOfset ),
334     bAutoFirst      ( false ),
335     bExplicitZeroMarginValRight(false),
336     bExplicitZeroMarginValLeft(false)
337 {
338 }
339 
340 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const341 bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
342 {
343     bool bRet = true;
344     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
345     nMemberId &= ~CONVERT_TWIPS;
346     switch( nMemberId )
347     {
348         // now all signed
349         case 0:
350         {
351             css::frame::status::LeftRightMarginScale aLRSpace;
352             aLRSpace.Left = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin);
353             aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft);
354             aLRSpace.Right = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin);
355             aLRSpace.ScaleLeft = static_cast<sal_Int16>(nPropLeftMargin);
356             aLRSpace.ScaleRight = static_cast<sal_Int16>(nPropRightMargin);
357             aLRSpace.FirstLine = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOfst) : nFirstLineOfst);
358             aLRSpace.ScaleFirstLine = static_cast<sal_Int16>(nPropFirstLineOfst);
359             aLRSpace.AutoFirstLine = IsAutoFirst();
360             rVal <<= aLRSpace;
361             break;
362         }
363         case MID_L_MARGIN:
364             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin);
365             break;
366 
367         case MID_TXT_LMARGIN :
368             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft);
369         break;
370         case MID_R_MARGIN:
371             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin);
372             break;
373         case MID_L_REL_MARGIN:
374             rVal <<= static_cast<sal_Int16>(nPropLeftMargin);
375         break;
376         case MID_R_REL_MARGIN:
377             rVal <<= static_cast<sal_Int16>(nPropRightMargin);
378         break;
379 
380         case MID_FIRST_LINE_INDENT:
381             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOfst) : nFirstLineOfst);
382             break;
383 
384         case MID_FIRST_LINE_REL_INDENT:
385             rVal <<= static_cast<sal_Int16>(nPropFirstLineOfst);
386             break;
387 
388         case MID_FIRST_AUTO:
389             rVal <<= IsAutoFirst();
390             break;
391 
392         default:
393             bRet = false;
394             // SfxDispatchController_Impl::StateChanged calls this with hardcoded 0 triggering this; there used to be a MID_LR_MARGIN 0 but what type would it have?
395             OSL_FAIL("unknown MemberId");
396     }
397     return bRet;
398 }
399 
400 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)401 bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
402 {
403     bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
404     nMemberId &= ~CONVERT_TWIPS;
405     sal_Int32 nVal = 0;
406     if( nMemberId != 0 && nMemberId != MID_FIRST_AUTO &&
407             nMemberId != MID_L_REL_MARGIN && nMemberId != MID_R_REL_MARGIN)
408         if(!(rVal >>= nVal))
409             return false;
410 
411     switch( nMemberId )
412     {
413         case 0:
414         {
415             css::frame::status::LeftRightMarginScale aLRSpace;
416             if(!(rVal >>= aLRSpace))
417                 return false;
418 
419             SetLeft( bConvert ? convertMm100ToTwip(aLRSpace.Left) : aLRSpace.Left );
420             SetTextLeft( bConvert ? convertMm100ToTwip(aLRSpace.TextLeft) : aLRSpace.TextLeft );
421             SetRight(bConvert ? convertMm100ToTwip(aLRSpace.Right) : aLRSpace.Right);
422             nPropLeftMargin = aLRSpace.ScaleLeft;
423             nPropRightMargin = aLRSpace.ScaleRight;
424             SetTextFirstLineOfst(static_cast<short>(bConvert ?  convertMm100ToTwip(aLRSpace.FirstLine) : aLRSpace.FirstLine));
425             SetPropTextFirstLineOfst ( static_cast<sal_uInt16>(aLRSpace.ScaleFirstLine) );
426             SetAutoFirst( aLRSpace.AutoFirstLine );
427             break;
428         }
429         case MID_L_MARGIN:
430             SetLeft( bConvert ? convertMm100ToTwip(nVal) : nVal );
431             break;
432 
433         case MID_TXT_LMARGIN :
434             SetTextLeft( bConvert ? convertMm100ToTwip(nVal) : nVal );
435         break;
436 
437         case MID_R_MARGIN:
438             SetRight(bConvert ? convertMm100ToTwip(nVal) : nVal);
439             break;
440         case MID_L_REL_MARGIN:
441         case MID_R_REL_MARGIN:
442         {
443             sal_Int32 nRel = 0;
444             if((rVal >>= nRel) && nRel >= 0 && nRel < SAL_MAX_UINT16)
445             {
446                 if(MID_L_REL_MARGIN== nMemberId)
447                     nPropLeftMargin = static_cast<sal_uInt16>(nRel);
448                 else
449                     nPropRightMargin = static_cast<sal_uInt16>(nRel);
450             }
451             else
452                 return false;
453         }
454         break;
455         case MID_FIRST_LINE_INDENT     :
456             SetTextFirstLineOfst(static_cast<short>(bConvert ?  convertMm100ToTwip(nVal) : nVal));
457             break;
458 
459         case MID_FIRST_LINE_REL_INDENT:
460             SetPropTextFirstLineOfst ( static_cast<sal_uInt16>(nVal) );
461             break;
462 
463         case MID_FIRST_AUTO:
464             SetAutoFirst( Any2Bool(rVal) );
465             break;
466 
467         default:
468             OSL_FAIL("unknown MemberId");
469             return false;
470     }
471     return true;
472 }
473 
474 
475 /// Adapt nLeftMargin and nTxtLeft.
AdjustLeft()476 void SvxLRSpaceItem::AdjustLeft()
477 {
478     if ( 0 > nFirstLineOfst )
479         nLeftMargin = nTxtLeft + nFirstLineOfst;
480     else
481         nLeftMargin = nTxtLeft;
482 }
483 
484 
operator ==(const SfxPoolItem & rAttr) const485 bool SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const
486 {
487     assert(SfxPoolItem::operator==(rAttr));
488 
489     const SvxLRSpaceItem& rOther = static_cast<const SvxLRSpaceItem&>(rAttr);
490 
491     return (
492         nFirstLineOfst == rOther.GetTextFirstLineOfst() &&
493         nTxtLeft == rOther.GetTextLeft() &&
494         nLeftMargin == rOther.GetLeft()  &&
495         nRightMargin == rOther.GetRight() &&
496         nPropFirstLineOfst == rOther.GetPropTextFirstLineOfst() &&
497         nPropLeftMargin == rOther.GetPropLeft()  &&
498         nPropRightMargin == rOther.GetPropRight() &&
499         bAutoFirst == rOther.IsAutoFirst() &&
500         bExplicitZeroMarginValRight == rOther.IsExplicitZeroMarginValRight() &&
501         bExplicitZeroMarginValLeft == rOther.IsExplicitZeroMarginValLeft() );
502 }
503 
504 
Clone(SfxItemPool *) const505 SfxPoolItem* SvxLRSpaceItem::Clone( SfxItemPool* ) const
506 {
507     return new SvxLRSpaceItem( *this );
508 }
509 
510 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const511 bool SvxLRSpaceItem::GetPresentation
512 (
513     SfxItemPresentation ePres,
514     MapUnit             eCoreUnit,
515     MapUnit             ePresUnit,
516     OUString&           rText, const IntlWrapper& rIntl
517 )   const
518 {
519     switch ( ePres )
520     {
521         case SfxItemPresentation::Nameless:
522         {
523             if ( 100 != nPropLeftMargin )
524             {
525                 rText = unicode::formatPercent(nPropLeftMargin,
526                     Application::GetSettings().GetUILanguageTag());
527             }
528             else
529                 rText = GetMetricText( nLeftMargin,
530                                        eCoreUnit, ePresUnit, &rIntl );
531             rText += OUString(cpDelim);
532             if ( 100 != nPropFirstLineOfst )
533             {
534                 rText += unicode::formatPercent(nPropFirstLineOfst,
535                     Application::GetSettings().GetUILanguageTag());
536             }
537             else
538                 rText += GetMetricText( static_cast<long>(nFirstLineOfst),
539                                         eCoreUnit, ePresUnit, &rIntl );
540             rText += OUString(cpDelim);
541             if ( 100 != nRightMargin )
542             {
543                 rText += unicode::formatPercent(nRightMargin,
544                     Application::GetSettings().GetUILanguageTag());
545             }
546             else
547                 rText += GetMetricText( nRightMargin,
548                                         eCoreUnit, ePresUnit, &rIntl );
549             return true;
550         }
551         case SfxItemPresentation::Complete:
552         {
553             rText = EditResId(RID_SVXITEMS_LRSPACE_LEFT);
554             if ( 100 != nPropLeftMargin )
555                 rText += unicode::formatPercent(nPropLeftMargin,
556                     Application::GetSettings().GetUILanguageTag());
557             else
558             {
559                 rText += GetMetricText( nLeftMargin, eCoreUnit, ePresUnit, &rIntl ) +
560                         " " + EditResId(GetMetricId(ePresUnit));
561             }
562             rText += OUString(cpDelim);
563             if ( 100 != nPropFirstLineOfst || nFirstLineOfst )
564             {
565                 rText += EditResId(RID_SVXITEMS_LRSPACE_FLINE);
566                 if ( 100 != nPropFirstLineOfst )
567                     rText += unicode::formatPercent(nPropFirstLineOfst,
568                                 Application::GetSettings().GetUILanguageTag());
569                 else
570                 {
571                     rText += GetMetricText( static_cast<long>(nFirstLineOfst),
572                                             eCoreUnit, ePresUnit, &rIntl ) +
573                             " " + EditResId(GetMetricId(ePresUnit));
574                 }
575                 rText += OUString(cpDelim);
576             }
577             rText += EditResId(RID_SVXITEMS_LRSPACE_RIGHT);
578             if ( 100 != nPropRightMargin )
579                 rText += unicode::formatPercent(nPropRightMargin,
580                     Application::GetSettings().GetUILanguageTag());
581             else
582             {
583                 rText += GetMetricText( nRightMargin,
584                                        eCoreUnit, ePresUnit, &rIntl ) +
585                         " " + EditResId(GetMetricId(ePresUnit));
586             }
587             return true;
588         }
589         default: ; // prevent warning
590     }
591     return false;
592 }
593 
594 
ScaleMetrics(long nMult,long nDiv)595 void SvxLRSpaceItem::ScaleMetrics( long nMult, long nDiv )
596 {
597     nFirstLineOfst = static_cast<short>(Scale( nFirstLineOfst, nMult, nDiv ));
598     nTxtLeft = Scale( nTxtLeft, nMult, nDiv );
599     nLeftMargin = Scale( nLeftMargin, nMult, nDiv );
600     nRightMargin = Scale( nRightMargin, nMult, nDiv );
601 }
602 
603 
HasMetrics() const604 bool SvxLRSpaceItem::HasMetrics() const
605 {
606     return true;
607 }
608 
609 
dumpAsXml(xmlTextWriterPtr pWriter) const610 void SvxLRSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const
611 {
612     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxLRSpaceItem"));
613     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
614     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nFirstLineOfst"), BAD_CAST(OString::number(nFirstLineOfst).getStr()));
615     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nTxtLeft"), BAD_CAST(OString::number(nTxtLeft).getStr()));
616     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeftMargin"), BAD_CAST(OString::number(nLeftMargin).getStr()));
617     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRightMargin"), BAD_CAST(OString::number(nRightMargin).getStr()));
618     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropFirstLineOfst"), BAD_CAST(OString::number(nPropFirstLineOfst).getStr()));
619     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLeftMargin"), BAD_CAST(OString::number(nPropLeftMargin).getStr()));
620     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropRightMargin"), BAD_CAST(OString::number(nPropRightMargin).getStr()));
621     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAutoFirst"), BAD_CAST(OString::number(int(bAutoFirst)).getStr()));
622     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValRight"), BAD_CAST(OString::number(int(bExplicitZeroMarginValRight)).getStr()));
623     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValLeft"), BAD_CAST(OString::number(int(bExplicitZeroMarginValLeft)).getStr()));
624     xmlTextWriterEndElement(pWriter);
625 }
626 
627 
SvxULSpaceItem(const sal_uInt16 nId)628 SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nId )
629     : SfxPoolItem(nId)
630     , nUpper(0)
631     , nLower(0)
632     , bContext(false)
633     , nPropUpper(100)
634     , nPropLower(100)
635 {
636 }
637 
638 
SvxULSpaceItem(const sal_uInt16 nUp,const sal_uInt16 nLow,const sal_uInt16 nId)639 SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nUp, const sal_uInt16 nLow,
640                                 const sal_uInt16 nId )
641     : SfxPoolItem(nId)
642     , nUpper(nUp)
643     , nLower(nLow)
644     , bContext(false)
645     , nPropUpper(100)
646     , nPropLower(100)
647 {
648 }
649 
650 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const651 bool SvxULSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
652 {
653     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
654     nMemberId &= ~CONVERT_TWIPS;
655     switch( nMemberId )
656     {
657         // now all signed
658         case 0:
659         {
660             css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
661             aUpperLowerMarginScale.Upper = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper);
662             aUpperLowerMarginScale.Lower = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nPropUpper);
663             aUpperLowerMarginScale.ScaleUpper = static_cast<sal_Int16>(nPropUpper);
664             aUpperLowerMarginScale.ScaleLower = static_cast<sal_Int16>(nPropLower);
665             rVal <<= aUpperLowerMarginScale;
666             break;
667         }
668         case MID_UP_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper); break;
669         case MID_LO_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nLower); break;
670         case MID_CTX_MARGIN: rVal <<= bContext; break;
671         case MID_UP_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropUpper); break;
672         case MID_LO_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropLower); break;
673     }
674     return true;
675 }
676 
677 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)678 bool SvxULSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
679 {
680     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
681     nMemberId &= ~CONVERT_TWIPS;
682     sal_Int32 nVal = 0;
683     bool bVal = false;
684     switch( nMemberId )
685     {
686         case 0:
687         {
688             css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
689             if ( !(rVal >>= aUpperLowerMarginScale ))
690                 return false;
691             {
692                 SetUpper(static_cast<sal_uInt16>(bConvert ? convertMm100ToTwip( aUpperLowerMarginScale.Upper ) : aUpperLowerMarginScale.Upper));
693                 SetLower(static_cast<sal_uInt16>(bConvert ? convertMm100ToTwip( aUpperLowerMarginScale.Lower ) : aUpperLowerMarginScale.Lower));
694                 if( aUpperLowerMarginScale.ScaleUpper > 1 )
695                     nPropUpper = aUpperLowerMarginScale.ScaleUpper;
696                 if( aUpperLowerMarginScale.ScaleLower > 1 )
697                     nPropUpper = aUpperLowerMarginScale.ScaleLower;
698             }
699         }
700         break;
701         case MID_UP_MARGIN :
702             if(!(rVal >>= nVal) || nVal < 0)
703                 return false;
704             SetUpper(static_cast<sal_uInt16>(bConvert ? convertMm100ToTwip(nVal) : nVal));
705             break;
706         case MID_LO_MARGIN :
707             if(!(rVal >>= nVal) || nVal < 0)
708                 return false;
709             SetLower(static_cast<sal_uInt16>(bConvert ? convertMm100ToTwip(nVal) : nVal));
710             break;
711         case MID_CTX_MARGIN :
712             if (!(rVal >>= bVal))
713                 return false;
714             SetContextValue(bVal);
715             break;
716         case MID_UP_REL_MARGIN:
717         case MID_LO_REL_MARGIN:
718         {
719             sal_Int32 nRel = 0;
720             if((rVal >>= nRel) && nRel > 1 )
721             {
722                 if(MID_UP_REL_MARGIN == nMemberId)
723                     nPropUpper = static_cast<sal_uInt16>(nRel);
724                 else
725                     nPropLower = static_cast<sal_uInt16>(nRel);
726             }
727             else
728                 return false;
729         }
730         break;
731 
732         default:
733             OSL_FAIL("unknown MemberId");
734             return false;
735     }
736     return true;
737 }
738 
739 
operator ==(const SfxPoolItem & rAttr) const740 bool SvxULSpaceItem::operator==( const SfxPoolItem& rAttr ) const
741 {
742     assert(SfxPoolItem::operator==(rAttr));
743 
744     const SvxULSpaceItem& rSpaceItem = static_cast<const SvxULSpaceItem&>( rAttr );
745     return ( nUpper == rSpaceItem.nUpper &&
746              nLower == rSpaceItem.nLower &&
747              bContext == rSpaceItem.bContext &&
748              nPropUpper == rSpaceItem.nPropUpper &&
749              nPropLower == rSpaceItem.nPropLower );
750 }
751 
752 
Clone(SfxItemPool *) const753 SfxPoolItem* SvxULSpaceItem::Clone( SfxItemPool* ) const
754 {
755     return new SvxULSpaceItem( *this );
756 }
757 
758 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const759 bool SvxULSpaceItem::GetPresentation
760 (
761     SfxItemPresentation ePres,
762     MapUnit             eCoreUnit,
763     MapUnit             ePresUnit,
764     OUString&           rText,
765     const IntlWrapper&  rIntl
766 )   const
767 {
768     switch ( ePres )
769     {
770         case SfxItemPresentation::Nameless:
771         {
772             if ( 100 != nPropUpper )
773             {
774                 rText = unicode::formatPercent(nPropUpper,
775                     Application::GetSettings().GetUILanguageTag());
776             }
777             else
778                 rText = GetMetricText( static_cast<long>(nUpper), eCoreUnit, ePresUnit, &rIntl );
779             rText += OUString(cpDelim);
780             if ( 100 != nPropLower )
781             {
782                 rText += unicode::formatPercent(nPropLower,
783                     Application::GetSettings().GetUILanguageTag());
784             }
785             else
786                 rText += GetMetricText( static_cast<long>(nLower), eCoreUnit, ePresUnit, &rIntl );
787             return true;
788         }
789         case SfxItemPresentation::Complete:
790         {
791             rText = EditResId(RID_SVXITEMS_ULSPACE_UPPER);
792             if ( 100 != nPropUpper )
793             {
794                 rText += unicode::formatPercent(nPropUpper,
795                     Application::GetSettings().GetUILanguageTag());
796             }
797             else
798             {
799                 rText += GetMetricText( static_cast<long>(nUpper), eCoreUnit, ePresUnit, &rIntl ) +
800                         " " + EditResId(GetMetricId(ePresUnit));
801             }
802             rText += cpDelim + EditResId(RID_SVXITEMS_ULSPACE_LOWER);
803             if ( 100 != nPropLower )
804             {
805                 rText += unicode::formatPercent(nPropLower,
806                     Application::GetSettings().GetUILanguageTag());
807             }
808             else
809             {
810                 rText += GetMetricText( static_cast<long>(nLower), eCoreUnit, ePresUnit, &rIntl ) +
811                         " " + EditResId(GetMetricId(ePresUnit));
812             }
813             return true;
814         }
815         default: ; // prevent warning
816     }
817     return false;
818 }
819 
820 
ScaleMetrics(long nMult,long nDiv)821 void SvxULSpaceItem::ScaleMetrics( long nMult, long nDiv )
822 {
823     nUpper = static_cast<sal_uInt16>(Scale( nUpper, nMult, nDiv ));
824     nLower = static_cast<sal_uInt16>(Scale( nLower, nMult, nDiv ));
825 }
826 
827 
HasMetrics() const828 bool SvxULSpaceItem::HasMetrics() const
829 {
830     return true;
831 }
832 
833 
dumpAsXml(xmlTextWriterPtr pWriter) const834 void SvxULSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const
835 {
836     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxULSpaceItem"));
837     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
838     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(nUpper).getStr()));
839     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(nLower).getStr()));
840     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContext"), BAD_CAST(OString::boolean(bContext).getStr()));
841     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropUpper"), BAD_CAST(OString::number(nPropUpper).getStr()));
842     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLower"), BAD_CAST(OString::number(nPropLower).getStr()));
843     xmlTextWriterEndElement(pWriter);
844 }
845 
846 
Clone(SfxItemPool *) const847 SfxPoolItem* SvxPrintItem::Clone( SfxItemPool* ) const
848 {
849     return new SvxPrintItem( *this );
850 }
851 
852 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const853 bool SvxPrintItem::GetPresentation
854 (
855     SfxItemPresentation /*ePres*/,
856     MapUnit             /*eCoreUnit*/,
857     MapUnit             /*ePresUnit*/,
858     OUString&           rText, const IntlWrapper&
859 )   const
860 {
861     const char* pId = RID_SVXITEMS_PRINT_FALSE;
862 
863     if ( GetValue() )
864         pId = RID_SVXITEMS_PRINT_TRUE;
865     rText = EditResId(pId);
866     return true;
867 }
868 
869 
Clone(SfxItemPool *) const870 SfxPoolItem* SvxOpaqueItem::Clone( SfxItemPool* ) const
871 {
872     return new SvxOpaqueItem( *this );
873 }
874 
875 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const876 bool SvxOpaqueItem::GetPresentation
877 (
878     SfxItemPresentation /*ePres*/,
879     MapUnit             /*eCoreUnit*/,
880     MapUnit             /*ePresUnit*/,
881     OUString&           rText, const IntlWrapper&
882 )   const
883 {
884     const char* pId = RID_SVXITEMS_OPAQUE_FALSE;
885 
886     if ( GetValue() )
887         pId = RID_SVXITEMS_OPAQUE_TRUE;
888     rText = EditResId(pId);
889     return true;
890 }
891 
892 
operator ==(const SfxPoolItem & rAttr) const893 bool SvxProtectItem::operator==( const SfxPoolItem& rAttr ) const
894 {
895     assert(SfxPoolItem::operator==(rAttr));
896 
897     const SvxProtectItem& rItem = static_cast<const SvxProtectItem&>(rAttr);
898     return ( bCntnt == rItem.bCntnt &&
899              bSize  == rItem.bSize  &&
900              bPos   == rItem.bPos );
901 }
902 
903 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const904 bool SvxProtectItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
905 {
906     nMemberId &= ~CONVERT_TWIPS;
907     bool bValue;
908     switch(nMemberId)
909     {
910         case MID_PROTECT_CONTENT :  bValue = bCntnt; break;
911         case MID_PROTECT_SIZE    :  bValue = bSize; break;
912         case MID_PROTECT_POSITION:  bValue = bPos; break;
913         default:
914             OSL_FAIL("Wrong MemberId");
915             return false;
916     }
917 
918     rVal <<= bValue;
919     return true;
920 }
921 
922 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)923 bool SvxProtectItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
924 {
925     nMemberId &= ~CONVERT_TWIPS;
926     bool bVal( Any2Bool(rVal) );
927     switch(nMemberId)
928     {
929         case MID_PROTECT_CONTENT :  bCntnt = bVal;  break;
930         case MID_PROTECT_SIZE    :  bSize  = bVal;  break;
931         case MID_PROTECT_POSITION:  bPos   = bVal;  break;
932         default:
933             OSL_FAIL("Wrong MemberId");
934             return false;
935     }
936     return true;
937 }
938 
939 
Clone(SfxItemPool *) const940 SfxPoolItem* SvxProtectItem::Clone( SfxItemPool* ) const
941 {
942     return new SvxProtectItem( *this );
943 }
944 
945 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const946 bool SvxProtectItem::GetPresentation
947 (
948     SfxItemPresentation /*ePres*/,
949     MapUnit             /*eCoreUnit*/,
950     MapUnit             /*ePresUnit*/,
951     OUString&           rText, const IntlWrapper&
952 )   const
953 {
954     const char* pId = RID_SVXITEMS_PROT_CONTENT_FALSE;
955 
956     if ( bCntnt )
957         pId = RID_SVXITEMS_PROT_CONTENT_TRUE;
958     rText = EditResId(pId) + cpDelim;
959     pId = RID_SVXITEMS_PROT_SIZE_FALSE;
960 
961     if ( bSize )
962         pId = RID_SVXITEMS_PROT_SIZE_TRUE;
963     rText += EditResId(pId) + cpDelim;
964     pId = RID_SVXITEMS_PROT_POS_FALSE;
965 
966     if ( bPos )
967         pId = RID_SVXITEMS_PROT_POS_TRUE;
968     rText += EditResId(pId);
969     return true;
970 }
971 
972 
dumpAsXml(xmlTextWriterPtr pWriter) const973 void SvxProtectItem::dumpAsXml(xmlTextWriterPtr pWriter) const
974 {
975     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxProtectItem"));
976     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
977     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("content"), BAD_CAST(OString::boolean(bCntnt).getStr()));
978     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(OString::boolean(bSize).getStr()));
979     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("position"), BAD_CAST(OString::boolean(bPos).getStr()));
980     xmlTextWriterEndElement(pWriter);
981 }
982 
983 
SvxShadowItem(const sal_uInt16 nId,const Color * pColor,const sal_uInt16 nW,const SvxShadowLocation eLoc)984 SvxShadowItem::SvxShadowItem( const sal_uInt16 nId,
985                  const Color *pColor, const sal_uInt16 nW,
986                  const SvxShadowLocation eLoc ) :
987     SfxEnumItemInterface( nId ),
988     aShadowColor(COL_GRAY),
989     nWidth      ( nW ),
990     eLocation   ( eLoc )
991 {
992     if ( pColor )
993         aShadowColor = *pColor;
994 }
995 
996 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const997 bool SvxShadowItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
998 {
999     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1000     nMemberId &= ~CONVERT_TWIPS;
1001 
1002     table::ShadowFormat aShadow;
1003     table::ShadowLocation eSet = table::ShadowLocation_NONE;
1004     switch( eLocation )
1005     {
1006         case SvxShadowLocation::TopLeft    : eSet = table::ShadowLocation_TOP_LEFT    ; break;
1007         case SvxShadowLocation::TopRight   : eSet = table::ShadowLocation_TOP_RIGHT   ; break;
1008         case SvxShadowLocation::BottomLeft : eSet = table::ShadowLocation_BOTTOM_LEFT ; break;
1009         case SvxShadowLocation::BottomRight: eSet = table::ShadowLocation_BOTTOM_RIGHT; break;
1010         default: ; // prevent warning
1011     }
1012     aShadow.Location = eSet;
1013     aShadow.ShadowWidth =   bConvert ? convertTwipToMm100(nWidth) : nWidth;
1014     aShadow.IsTransparent = aShadowColor.GetTransparency() > 0;
1015     aShadow.Color = sal_Int32(aShadowColor);
1016 
1017     sal_Int8 nTransparence = rtl::math::round(float(aShadowColor.GetTransparency() * 100) / 255);
1018 
1019     switch ( nMemberId )
1020     {
1021         case MID_LOCATION: rVal <<= aShadow.Location; break;
1022         case MID_WIDTH: rVal <<= aShadow.ShadowWidth; break;
1023         case MID_TRANSPARENT: rVal <<= aShadow.IsTransparent; break;
1024         case MID_BG_COLOR: rVal <<= aShadow.Color; break;
1025         case 0: rVal <<= aShadow; break;
1026         case MID_SHADOW_TRANSPARENCE: rVal <<= nTransparence; break;
1027         default: OSL_FAIL("Wrong MemberId!"); return false;
1028     }
1029 
1030     return true;
1031 }
1032 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1033 bool SvxShadowItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1034 {
1035     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1036     nMemberId &= ~CONVERT_TWIPS;
1037 
1038     table::ShadowFormat aShadow;
1039     uno::Any aAny;
1040     bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aShadow );
1041     switch ( nMemberId )
1042     {
1043         case MID_LOCATION:
1044         {
1045             bRet = (rVal >>= aShadow.Location);
1046             if ( !bRet )
1047             {
1048                 sal_Int16 nVal = 0;
1049                 bRet = (rVal >>= nVal);
1050                 aShadow.Location = static_cast<table::ShadowLocation>(nVal);
1051             }
1052 
1053             break;
1054         }
1055 
1056         case MID_WIDTH: rVal >>= aShadow.ShadowWidth; break;
1057         case MID_TRANSPARENT: rVal >>= aShadow.IsTransparent; break;
1058         case MID_BG_COLOR: rVal >>= aShadow.Color; break;
1059         case 0: rVal >>= aShadow; break;
1060         case MID_SHADOW_TRANSPARENCE:
1061         {
1062             sal_Int32 nTransparence = 0;
1063             if ((rVal >>= nTransparence) && !o3tl::checked_multiply<sal_Int32>(nTransparence, 255, nTransparence))
1064             {
1065                 Color aColor(aShadow.Color);
1066                 aColor.SetTransparency(rtl::math::round(float(nTransparence) / 100));
1067                 aShadow.Color = sal_Int32(aColor);
1068             }
1069             break;
1070         }
1071         default: OSL_FAIL("Wrong MemberId!"); return false;
1072     }
1073 
1074     if ( bRet )
1075     {
1076 //      SvxShadowLocation eSet = SvxShadowLocation::NONE;
1077         switch( aShadow.Location )
1078         {
1079             case table::ShadowLocation_TOP_LEFT    : eLocation = SvxShadowLocation::TopLeft; break;
1080             case table::ShadowLocation_TOP_RIGHT   : eLocation = SvxShadowLocation::TopRight; break;
1081             case table::ShadowLocation_BOTTOM_LEFT : eLocation = SvxShadowLocation::BottomLeft ; break;
1082             case table::ShadowLocation_BOTTOM_RIGHT: eLocation = SvxShadowLocation::BottomRight; break;
1083             default: ; // prevent warning
1084         }
1085 
1086         nWidth = bConvert ? convertMm100ToTwip(aShadow.ShadowWidth) : aShadow.ShadowWidth;
1087         Color aSet(aShadow.Color);
1088         aShadowColor = aSet;
1089     }
1090 
1091     return bRet;
1092 }
1093 
1094 
operator ==(const SfxPoolItem & rAttr) const1095 bool SvxShadowItem::operator==( const SfxPoolItem& rAttr ) const
1096 {
1097     assert(SfxPoolItem::operator==(rAttr));
1098 
1099     const SvxShadowItem& rItem = static_cast<const SvxShadowItem&>(rAttr);
1100     return ( ( aShadowColor == rItem.aShadowColor ) &&
1101              ( nWidth    == rItem.GetWidth() ) &&
1102              ( eLocation == rItem.GetLocation() ) );
1103 }
1104 
1105 
Clone(SfxItemPool *) const1106 SfxPoolItem* SvxShadowItem::Clone( SfxItemPool* ) const
1107 {
1108     return new SvxShadowItem( *this );
1109 }
1110 
1111 
CalcShadowSpace(SvxShadowItemSide nShadow) const1112 sal_uInt16 SvxShadowItem::CalcShadowSpace( SvxShadowItemSide nShadow ) const
1113 {
1114     sal_uInt16 nSpace = 0;
1115 
1116     switch ( nShadow )
1117     {
1118         case SvxShadowItemSide::TOP:
1119             if ( eLocation == SvxShadowLocation::TopLeft ||
1120                  eLocation == SvxShadowLocation::TopRight  )
1121                 nSpace = nWidth;
1122             break;
1123 
1124         case SvxShadowItemSide::BOTTOM:
1125             if ( eLocation == SvxShadowLocation::BottomLeft ||
1126                  eLocation == SvxShadowLocation::BottomRight  )
1127                 nSpace = nWidth;
1128             break;
1129 
1130         case SvxShadowItemSide::LEFT:
1131             if ( eLocation == SvxShadowLocation::TopLeft ||
1132                  eLocation == SvxShadowLocation::BottomLeft )
1133                 nSpace = nWidth;
1134             break;
1135 
1136         case SvxShadowItemSide::RIGHT:
1137             if ( eLocation == SvxShadowLocation::TopRight ||
1138                  eLocation == SvxShadowLocation::BottomRight )
1139                 nSpace = nWidth;
1140             break;
1141 
1142         default:
1143             OSL_FAIL( "wrong shadow" );
1144     }
1145     return nSpace;
1146 }
1147 
1148 static const char* RID_SVXITEMS_SHADOW[] =
1149 {
1150     RID_SVXITEMS_SHADOW_NONE,
1151     RID_SVXITEMS_SHADOW_TOPLEFT,
1152     RID_SVXITEMS_SHADOW_TOPRIGHT,
1153     RID_SVXITEMS_SHADOW_BOTTOMLEFT,
1154     RID_SVXITEMS_SHADOW_BOTTOMRIGHT
1155 };
1156 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const1157 bool SvxShadowItem::GetPresentation
1158 (
1159     SfxItemPresentation ePres,
1160     MapUnit             eCoreUnit,
1161     MapUnit             ePresUnit,
1162     OUString&           rText, const IntlWrapper& rIntl
1163 )   const
1164 {
1165     switch ( ePres )
1166     {
1167         case SfxItemPresentation::Nameless:
1168         {
1169             rText = ::GetColorString( aShadowColor ) + cpDelim;
1170             const char* pId = RID_SVXITEMS_TRANSPARENT_FALSE;
1171 
1172             if ( aShadowColor.GetTransparency() )
1173                 pId = RID_SVXITEMS_TRANSPARENT_TRUE;
1174             rText += EditResId(pId) +
1175                     cpDelim +
1176                     GetMetricText( static_cast<long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) +
1177                     cpDelim +
1178                     EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]);
1179             return true;
1180         }
1181         case SfxItemPresentation::Complete:
1182         {
1183             rText = EditResId(RID_SVXITEMS_SHADOW_COMPLETE) +
1184                     ::GetColorString( aShadowColor ) +
1185                     cpDelim;
1186 
1187             const char* pId = RID_SVXITEMS_TRANSPARENT_FALSE;
1188             if ( aShadowColor.GetTransparency() )
1189                 pId = RID_SVXITEMS_TRANSPARENT_TRUE;
1190             rText += EditResId(pId) +
1191                     cpDelim +
1192                     GetMetricText( static_cast<long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) +
1193                     " " + EditResId(GetMetricId(ePresUnit)) +
1194                     cpDelim +
1195                     EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]);
1196             return true;
1197         }
1198         default: ; // prevent warning
1199     }
1200     return false;
1201 }
1202 
1203 
ScaleMetrics(long nMult,long nDiv)1204 void SvxShadowItem::ScaleMetrics( long nMult, long nDiv )
1205 {
1206     nWidth = static_cast<sal_uInt16>(Scale( nWidth, nMult, nDiv ));
1207 }
1208 
1209 
HasMetrics() const1210 bool SvxShadowItem::HasMetrics() const
1211 {
1212     return true;
1213 }
1214 
1215 
GetValueCount() const1216 sal_uInt16 SvxShadowItem::GetValueCount() const
1217 {
1218     return sal_uInt16(SvxShadowLocation::End);  // SvxShadowLocation::BottomRight + 1
1219 }
1220 
GetEnumValue() const1221 sal_uInt16 SvxShadowItem::GetEnumValue() const
1222 {
1223     return static_cast<sal_uInt16>(GetLocation());
1224 }
1225 
1226 
SetEnumValue(sal_uInt16 nVal)1227 void SvxShadowItem::SetEnumValue( sal_uInt16 nVal )
1228 {
1229     SetLocation( static_cast<SvxShadowLocation>(nVal) );
1230 }
1231 
dumpAsXml(xmlTextWriterPtr pWriter) const1232 void SvxShadowItem::dumpAsXml(xmlTextWriterPtr pWriter) const
1233 {
1234     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxShadowItem"));
1235     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1236     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aShadowColor"), BAD_CAST(aShadowColor.AsRGBHexString().toUtf8().getStr()));
1237     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(nWidth).getStr()));
1238     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLocation"), BAD_CAST(OString::number(static_cast<int>(eLocation)).getStr()));
1239     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]).toUtf8().getStr()));
1240     xmlTextWriterEndElement(pWriter);
1241 }
1242 
1243 // class SvxBoxItem ------------------------------------------------------
1244 
SvxBoxItem(const SvxBoxItem & rCpy)1245 SvxBoxItem::SvxBoxItem( const SvxBoxItem& rCpy ) :
1246 
1247     SfxPoolItem ( rCpy ),
1248     pTop        ( rCpy.pTop     ? new SvxBorderLine( *rCpy.pTop )    : nullptr ),
1249     pBottom     ( rCpy.pBottom  ? new SvxBorderLine( *rCpy.pBottom ) : nullptr ),
1250     pLeft       ( rCpy.pLeft    ? new SvxBorderLine( *rCpy.pLeft )   : nullptr ),
1251     pRight      ( rCpy.pRight   ? new SvxBorderLine( *rCpy.pRight )  : nullptr ),
1252     nTopDist    ( rCpy.nTopDist ),
1253     nBottomDist ( rCpy.nBottomDist ),
1254     nLeftDist   ( rCpy.nLeftDist ),
1255     nRightDist  ( rCpy.nRightDist ),
1256     bRemoveAdjCellBorder ( rCpy.bRemoveAdjCellBorder )
1257 {
1258 }
1259 
1260 
SvxBoxItem(const sal_uInt16 nId)1261 SvxBoxItem::SvxBoxItem( const sal_uInt16 nId ) :
1262     SfxPoolItem( nId ),
1263     nTopDist    ( 0 ),
1264     nBottomDist ( 0 ),
1265     nLeftDist   ( 0 ),
1266     nRightDist  ( 0 ),
1267     bRemoveAdjCellBorder ( false )
1268 {
1269 }
1270 
1271 
~SvxBoxItem()1272 SvxBoxItem::~SvxBoxItem()
1273 {
1274 }
1275 
1276 
CmpBrdLn(const std::unique_ptr<SvxBorderLine> & pBrd1,const SvxBorderLine * pBrd2)1277 static bool CmpBrdLn( const std::unique_ptr<SvxBorderLine> & pBrd1, const SvxBorderLine* pBrd2 )
1278 {
1279     if( pBrd1.get() == pBrd2 )
1280         return true;
1281     if( pBrd1 == nullptr || pBrd2 == nullptr)
1282         return false;
1283     return *pBrd1 == *pBrd2;
1284 }
1285 
1286 
operator ==(const SfxPoolItem & rAttr) const1287 bool SvxBoxItem::operator==( const SfxPoolItem& rAttr ) const
1288 {
1289     assert(SfxPoolItem::operator==(rAttr));
1290 
1291     const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(rAttr);
1292     return (
1293         ( nTopDist == rBoxItem.nTopDist ) &&
1294         ( nBottomDist == rBoxItem.nBottomDist )   &&
1295         ( nLeftDist == rBoxItem.nLeftDist )   &&
1296         ( nRightDist == rBoxItem.nRightDist ) &&
1297         ( bRemoveAdjCellBorder == rBoxItem.bRemoveAdjCellBorder ) &&
1298         CmpBrdLn( pTop, rBoxItem.GetTop() )           &&
1299         CmpBrdLn( pBottom, rBoxItem.GetBottom() )     &&
1300         CmpBrdLn( pLeft, rBoxItem.GetLeft() )         &&
1301         CmpBrdLn( pRight, rBoxItem.GetRight() ) );
1302 }
1303 
1304 
SvxLineToLine(const SvxBorderLine * pLine,bool bConvert)1305 table::BorderLine2 SvxBoxItem::SvxLineToLine(const SvxBorderLine* pLine, bool bConvert)
1306 {
1307     table::BorderLine2 aLine;
1308     if(pLine)
1309     {
1310         aLine.Color          = sal_Int32(pLine->GetColor());
1311         aLine.InnerLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetInWidth() ): pLine->GetInWidth() );
1312         aLine.OuterLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetOutWidth()): pLine->GetOutWidth() );
1313         aLine.LineDistance   = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetDistance()): pLine->GetDistance() );
1314         aLine.LineStyle      = sal_Int16(pLine->GetBorderLineStyle());
1315         aLine.LineWidth      = sal_uInt32( bConvert ? convertTwipToMm100( pLine->GetWidth( ) ) : pLine->GetWidth( ) );
1316     }
1317     else
1318         aLine.Color          = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance  = 0;
1319     return aLine;
1320 }
1321 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const1322 bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1323 {
1324     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1325     table::BorderLine2 aRetLine;
1326     sal_uInt16 nDist = 0;
1327     bool bDistMember = false;
1328     nMemberId &= ~CONVERT_TWIPS;
1329     switch(nMemberId)
1330     {
1331         case 0:
1332         {
1333             // 4 Borders and 5 distances
1334             uno::Sequence< uno::Any > aSeq( 9 );
1335             aSeq[0] <<= SvxBoxItem::SvxLineToLine(GetLeft(), bConvert);
1336             aSeq[1] <<= SvxBoxItem::SvxLineToLine(GetRight(), bConvert);
1337             aSeq[2] <<= SvxBoxItem::SvxLineToLine(GetBottom(), bConvert);
1338             aSeq[3] <<= SvxBoxItem::SvxLineToLine(GetTop(), bConvert);
1339             aSeq[4] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100( GetSmallestDistance()) : GetSmallestDistance());
1340             aSeq[5] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nTopDist ) : nTopDist );
1341             aSeq[6] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nBottomDist ) : nBottomDist );
1342             aSeq[7] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nLeftDist ) : nLeftDist );
1343             aSeq[8] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nRightDist ) : nRightDist );
1344             rVal <<= aSeq;
1345             return true;
1346         }
1347         case MID_LEFT_BORDER:
1348         case LEFT_BORDER:
1349             aRetLine = SvxBoxItem::SvxLineToLine(GetLeft(), bConvert);
1350             break;
1351         case MID_RIGHT_BORDER:
1352         case RIGHT_BORDER:
1353             aRetLine = SvxBoxItem::SvxLineToLine(GetRight(), bConvert);
1354             break;
1355         case MID_BOTTOM_BORDER:
1356         case BOTTOM_BORDER:
1357             aRetLine = SvxBoxItem::SvxLineToLine(GetBottom(), bConvert);
1358             break;
1359         case MID_TOP_BORDER:
1360         case TOP_BORDER:
1361             aRetLine = SvxBoxItem::SvxLineToLine(GetTop(), bConvert);
1362             break;
1363         case BORDER_DISTANCE:
1364             nDist = GetSmallestDistance();
1365             bDistMember = true;
1366             break;
1367         case TOP_BORDER_DISTANCE:
1368             nDist = nTopDist;
1369             bDistMember = true;
1370             break;
1371         case BOTTOM_BORDER_DISTANCE:
1372             nDist = nBottomDist;
1373             bDistMember = true;
1374             break;
1375         case LEFT_BORDER_DISTANCE:
1376             nDist = nLeftDist;
1377             bDistMember = true;
1378             break;
1379         case RIGHT_BORDER_DISTANCE:
1380             nDist = nRightDist;
1381             bDistMember = true;
1382             break;
1383         case LINE_STYLE:
1384         case LINE_WIDTH:
1385             // it doesn't make sense to return a value for these since it's
1386             // probably ambiguous
1387             return true;
1388             break;
1389     }
1390 
1391     if( bDistMember )
1392         rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nDist) : nDist);
1393     else
1394         rVal <<= aRetLine;
1395 
1396     return true;
1397 }
1398 
1399 namespace
1400 {
1401 
1402 bool
lcl_lineToSvxLine(const table::BorderLine & rLine,SvxBorderLine & rSvxLine,bool bConvert,bool bGuessWidth)1403 lcl_lineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert, bool bGuessWidth)
1404 {
1405     rSvxLine.SetColor( Color(rLine.Color));
1406     if ( bGuessWidth )
1407     {
1408         rSvxLine.GuessLinesWidths( rSvxLine.GetBorderLineStyle(),
1409                 sal_uInt16( bConvert ? convertMm100ToTwip(rLine.OuterLineWidth) : rLine.OuterLineWidth  ),
1410                 sal_uInt16( bConvert ? convertMm100ToTwip(rLine.InnerLineWidth) : rLine.InnerLineWidth  ),
1411                 sal_uInt16( bConvert ? convertMm100ToTwip(rLine.LineDistance )  : rLine.LineDistance  ));
1412     }
1413 
1414     bool bRet = !rSvxLine.isEmpty();
1415     return bRet;
1416 }
1417 
1418 }
1419 
1420 
LineToSvxLine(const css::table::BorderLine & rLine,SvxBorderLine & rSvxLine,bool bConvert)1421 bool SvxBoxItem::LineToSvxLine(const css::table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert)
1422 {
1423     return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, true);
1424 }
1425 
1426 bool
LineToSvxLine(const css::table::BorderLine2 & rLine,SvxBorderLine & rSvxLine,bool bConvert)1427 SvxBoxItem::LineToSvxLine(const css::table::BorderLine2& rLine, SvxBorderLine& rSvxLine, bool bConvert)
1428 {
1429     SvxBorderLineStyle const nStyle =
1430         (rLine.LineStyle < 0 || BORDER_LINE_STYLE_MAX < rLine.LineStyle)
1431         ? SvxBorderLineStyle::SOLID     // default
1432         : static_cast<SvxBorderLineStyle>(rLine.LineStyle);
1433 
1434     rSvxLine.SetBorderLineStyle( nStyle );
1435 
1436     bool bGuessWidth = true;
1437     if ( rLine.LineWidth )
1438     {
1439         rSvxLine.SetWidth( bConvert? convertMm100ToTwip( rLine.LineWidth ) : rLine.LineWidth );
1440         // fdo#46112: double does not necessarily mean symmetric
1441         // for backwards compatibility
1442         bGuessWidth = (SvxBorderLineStyle::DOUBLE == nStyle || SvxBorderLineStyle::DOUBLE_THIN == nStyle) &&
1443             (rLine.InnerLineWidth > 0) && (rLine.OuterLineWidth > 0);
1444     }
1445 
1446     return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, bGuessWidth);
1447 }
1448 
1449 
1450 namespace
1451 {
1452 
1453 bool
lcl_extractBorderLine(const uno::Any & rAny,table::BorderLine2 & rLine)1454 lcl_extractBorderLine(const uno::Any& rAny, table::BorderLine2& rLine)
1455 {
1456     if (rAny >>= rLine)
1457         return true;
1458 
1459     table::BorderLine aBorderLine;
1460     if (rAny >>= aBorderLine)
1461     {
1462         rLine.Color = aBorderLine.Color;
1463         rLine.InnerLineWidth = aBorderLine.InnerLineWidth;
1464         rLine.OuterLineWidth = aBorderLine.OuterLineWidth;
1465         rLine.LineDistance = aBorderLine.LineDistance;
1466         rLine.LineStyle = table::BorderLineStyle::SOLID;
1467         return true;
1468     }
1469 
1470     return false;
1471 }
1472 
1473 template<typename Item, typename Line>
1474 bool
lcl_setLine(const uno::Any & rAny,Item & rItem,Line nLine,const bool bConvert)1475 lcl_setLine(const uno::Any& rAny, Item& rItem, Line nLine, const bool bConvert)
1476 {
1477     bool bDone = false;
1478     table::BorderLine2 aBorderLine;
1479     if (lcl_extractBorderLine(rAny, aBorderLine))
1480     {
1481         SvxBorderLine aLine;
1482         bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
1483         rItem.SetLine( bSet ? &aLine : nullptr, nLine);
1484         bDone = true;
1485     }
1486     return bDone;
1487 }
1488 
1489 }
1490 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)1491 bool SvxBoxItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1492 {
1493     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1494     SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
1495     bool bDistMember = false;
1496     nMemberId &= ~CONVERT_TWIPS;
1497     switch(nMemberId)
1498     {
1499         case 0:
1500         {
1501             uno::Sequence< uno::Any > aSeq;
1502             if (( rVal >>= aSeq ) && ( aSeq.getLength() == 9 ))
1503             {
1504                 // 4 Borders and 5 distances
1505                 const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP };
1506                 for (int n(0); n != SAL_N_ELEMENTS(aBorders); ++n)
1507                 {
1508                     if (!lcl_setLine(aSeq[n], *this, aBorders[n], bConvert))
1509                         return false;
1510                 }
1511 
1512                 // WTH are the borders and the distances saved in different order?
1513                 SvxBoxItemLine const nLines[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT };
1514                 for ( sal_Int32 n = 4; n < 9; n++ )
1515                 {
1516                     sal_Int32 nDist = 0;
1517                     if ( aSeq[n] >>= nDist )
1518                     {
1519                         if( bConvert )
1520                             nDist = convertMm100ToTwip(nDist);
1521                         if ( n == 4 )
1522                             SetAllDistances(sal_uInt16(nDist));
1523                         else
1524                             SetDistance( sal_uInt16( nDist ), nLines[n-5] );
1525                     }
1526                     else
1527                         return false;
1528                 }
1529 
1530                 return true;
1531             }
1532             else
1533                 return false;
1534         }
1535         case LEFT_BORDER_DISTANCE:
1536             bDistMember = true;
1537             [[fallthrough]];
1538         case LEFT_BORDER:
1539         case MID_LEFT_BORDER:
1540             nLine = SvxBoxItemLine::LEFT;
1541             break;
1542         case RIGHT_BORDER_DISTANCE:
1543             bDistMember = true;
1544             [[fallthrough]];
1545         case RIGHT_BORDER:
1546         case MID_RIGHT_BORDER:
1547             nLine = SvxBoxItemLine::RIGHT;
1548             break;
1549         case BOTTOM_BORDER_DISTANCE:
1550             bDistMember = true;
1551             [[fallthrough]];
1552         case BOTTOM_BORDER:
1553         case MID_BOTTOM_BORDER:
1554             nLine = SvxBoxItemLine::BOTTOM;
1555             break;
1556         case TOP_BORDER_DISTANCE:
1557             bDistMember = true;
1558             [[fallthrough]];
1559         case TOP_BORDER:
1560         case MID_TOP_BORDER:
1561             nLine = SvxBoxItemLine::TOP;
1562             break;
1563         case LINE_STYLE:
1564             {
1565                 drawing::LineStyle eDrawingStyle;
1566                 rVal >>= eDrawingStyle;
1567                 SvxBorderLineStyle eBorderStyle = SvxBorderLineStyle::NONE;
1568                 switch ( eDrawingStyle )
1569                 {
1570                     default:
1571                     case drawing::LineStyle_NONE:
1572                         break;
1573                     case drawing::LineStyle_SOLID:
1574                         eBorderStyle = SvxBorderLineStyle::SOLID;
1575                         break;
1576                     case drawing::LineStyle_DASH:
1577                         eBorderStyle = SvxBorderLineStyle::DASHED;
1578                         break;
1579                 }
1580 
1581                 // Set the line style on all borders
1582                 for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() )
1583                 {
1584                     editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) );
1585                     if( pLine )
1586                         pLine->SetBorderLineStyle( eBorderStyle );
1587                 }
1588                 return true;
1589             }
1590             break;
1591         case LINE_WIDTH:
1592             {
1593                 // Set the line width on all borders
1594                 long nWidth(0);
1595                 rVal >>= nWidth;
1596                 if( bConvert )
1597                     nWidth = convertMm100ToTwip( nWidth );
1598 
1599                 // Set the line Width on all borders
1600                 for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() )
1601                 {
1602                     editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) );
1603                     if( pLine )
1604                         pLine->SetWidth( nWidth );
1605                 }
1606             }
1607             return true;
1608     }
1609 
1610     if( bDistMember || nMemberId == BORDER_DISTANCE )
1611     {
1612         sal_Int32 nDist = 0;
1613         if(!(rVal >>= nDist))
1614             return false;
1615 
1616         if(nDist >= 0)
1617         {
1618             if( bConvert )
1619                 nDist = convertMm100ToTwip(nDist);
1620             if( nMemberId == BORDER_DISTANCE )
1621                 SetAllDistances(sal_uInt16(nDist));
1622             else
1623                 SetDistance( sal_uInt16( nDist ), nLine );
1624         }
1625     }
1626     else
1627     {
1628         SvxBorderLine aLine;
1629         if( !rVal.hasValue() )
1630             return false;
1631 
1632         table::BorderLine2 aBorderLine;
1633         if( lcl_extractBorderLine(rVal, aBorderLine) )
1634         {
1635             // usual struct
1636         }
1637         else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1638         {
1639             // serialization for basic macro recording
1640             uno::Reference < script::XTypeConverter > xConverter
1641                     ( script::Converter::create(::comphelper::getProcessComponentContext()) );
1642             uno::Sequence < uno::Any > aSeq;
1643             uno::Any aNew;
1644             try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); }
1645             catch (const uno::Exception&) {}
1646 
1647             aNew >>= aSeq;
1648             if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6)
1649             {
1650                 sal_Int32 nVal = 0;
1651                 if ( aSeq[0] >>= nVal )
1652                     aBorderLine.Color = nVal;
1653                 if ( aSeq[1] >>= nVal )
1654                     aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal);
1655                 if ( aSeq[2] >>= nVal )
1656                     aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal);
1657                 if ( aSeq[3] >>= nVal )
1658                     aBorderLine.LineDistance = static_cast<sal_Int16>(nVal);
1659                 if (aSeq.getLength() >= 5) // fdo#40874 added fields
1660                 {
1661                     if (aSeq[4] >>= nVal)
1662                     {
1663                         aBorderLine.LineStyle = nVal;
1664                     }
1665                     if (aSeq.getLength() >= 6)
1666                     {
1667                         if (aSeq[5] >>= nVal)
1668                         {
1669                             aBorderLine.LineWidth = nVal;
1670                         }
1671                     }
1672                 }
1673             }
1674             else
1675                 return false;
1676         }
1677         else
1678             return false;
1679 
1680         bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
1681         SetLine(bSet ? &aLine : nullptr, nLine);
1682     }
1683 
1684     return true;
1685 }
1686 
1687 
Clone(SfxItemPool *) const1688 SfxPoolItem* SvxBoxItem::Clone( SfxItemPool* ) const
1689 {
1690     return new SvxBoxItem( *this );
1691 }
1692 
1693 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const1694 bool SvxBoxItem::GetPresentation
1695 (
1696     SfxItemPresentation ePres,
1697     MapUnit             eCoreUnit,
1698     MapUnit             ePresUnit,
1699     OUString&           rText, const IntlWrapper& rIntl
1700 )   const
1701 {
1702     OUString cpDelimTmp(cpDelim);
1703     switch ( ePres )
1704     {
1705         case SfxItemPresentation::Nameless:
1706         {
1707             rText.clear();
1708 
1709             if ( pTop )
1710             {
1711                 rText = pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1712             }
1713             if( !(pTop && pBottom && pLeft && pRight &&
1714                   *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) )
1715             {
1716                 if ( pBottom )
1717                 {
1718                     rText += pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1719                 }
1720                 if ( pLeft )
1721                 {
1722                     rText += pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1723                 }
1724                 if ( pRight )
1725                 {
1726                     rText += pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1727                 }
1728             }
1729             rText += GetMetricText( static_cast<long>(nTopDist), eCoreUnit, ePresUnit, &rIntl );
1730             if( nTopDist != nBottomDist || nTopDist != nLeftDist ||
1731                 nTopDist != nRightDist )
1732             {
1733                 rText += cpDelimTmp +
1734                         GetMetricText( static_cast<long>(nBottomDist), eCoreUnit,
1735                                         ePresUnit, &rIntl ) +
1736                         cpDelimTmp +
1737                         GetMetricText( static_cast<long>(nLeftDist), eCoreUnit, ePresUnit, &rIntl ) +
1738                         cpDelimTmp +
1739                         GetMetricText( static_cast<long>(nRightDist), eCoreUnit,
1740                                         ePresUnit, &rIntl );
1741             }
1742             return true;
1743         }
1744         case SfxItemPresentation::Complete:
1745         {
1746             if( !(pTop || pBottom || pLeft || pRight) )
1747             {
1748                 rText = EditResId(RID_SVXITEMS_BORDER_NONE) + cpDelimTmp;
1749             }
1750             else
1751             {
1752                 rText = EditResId(RID_SVXITEMS_BORDER_COMPLETE);
1753                 if( pTop && pBottom && pLeft && pRight &&
1754                     *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight )
1755                 {
1756                     rText += pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + cpDelimTmp;
1757                 }
1758                 else
1759                 {
1760                     if ( pTop )
1761                     {
1762                         rText += EditResId(RID_SVXITEMS_BORDER_TOP) +
1763                                 pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1764                                 cpDelimTmp;
1765                     }
1766                     if ( pBottom )
1767                     {
1768                         rText += EditResId(RID_SVXITEMS_BORDER_BOTTOM) +
1769                                 pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1770                                 cpDelimTmp;
1771                     }
1772                     if ( pLeft )
1773                     {
1774                         rText += EditResId(RID_SVXITEMS_BORDER_LEFT) +
1775                                 pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1776                                 cpDelimTmp;
1777                     }
1778                     if ( pRight )
1779                     {
1780                         rText += EditResId(RID_SVXITEMS_BORDER_RIGHT) +
1781                                 pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1782                                 cpDelimTmp;
1783                     }
1784                 }
1785             }
1786 
1787             rText += EditResId(RID_SVXITEMS_BORDER_DISTANCE);
1788             if( nTopDist == nBottomDist && nTopDist == nLeftDist &&
1789                 nTopDist == nRightDist )
1790             {
1791                 rText += GetMetricText( static_cast<long>(nTopDist), eCoreUnit,
1792                                             ePresUnit, &rIntl ) +
1793                         " " + EditResId(GetMetricId(ePresUnit));
1794             }
1795             else
1796             {
1797                 rText += EditResId(RID_SVXITEMS_BORDER_TOP) +
1798                         GetMetricText( static_cast<long>(nTopDist), eCoreUnit,
1799                                         ePresUnit, &rIntl ) +
1800                         " " + EditResId(GetMetricId(ePresUnit)) +
1801                         cpDelimTmp +
1802                         EditResId(RID_SVXITEMS_BORDER_BOTTOM) +
1803                         GetMetricText( static_cast<long>(nBottomDist), eCoreUnit,
1804                                         ePresUnit, &rIntl ) +
1805                         " " + EditResId(GetMetricId(ePresUnit)) +
1806                         cpDelimTmp +
1807                         EditResId(RID_SVXITEMS_BORDER_LEFT) +
1808                         GetMetricText( static_cast<long>(nLeftDist), eCoreUnit,
1809                                         ePresUnit, &rIntl ) +
1810                         " " + EditResId(GetMetricId(ePresUnit)) +
1811                         cpDelimTmp +
1812                         EditResId(RID_SVXITEMS_BORDER_RIGHT) +
1813                         GetMetricText( static_cast<long>(nRightDist), eCoreUnit,
1814                                         ePresUnit, &rIntl ) +
1815                         " " + EditResId(GetMetricId(ePresUnit));
1816             }
1817             return true;
1818         }
1819         default: ; // prevent warning
1820     }
1821     return false;
1822 }
1823 
1824 
ScaleMetrics(long nMult,long nDiv)1825 void SvxBoxItem::ScaleMetrics( long nMult, long nDiv )
1826 {
1827     if ( pTop )     pTop->ScaleMetrics( nMult, nDiv );
1828     if ( pBottom )  pBottom->ScaleMetrics( nMult, nDiv );
1829     if ( pLeft )    pLeft->ScaleMetrics( nMult, nDiv );
1830     if ( pRight )   pRight->ScaleMetrics( nMult, nDiv );
1831     nTopDist = static_cast<sal_uInt16>(Scale( nTopDist, nMult, nDiv ));
1832     nBottomDist = static_cast<sal_uInt16>(Scale( nBottomDist, nMult, nDiv ));
1833     nLeftDist = static_cast<sal_uInt16>(Scale( nLeftDist, nMult, nDiv ));
1834     nRightDist = static_cast<sal_uInt16>(Scale( nRightDist, nMult, nDiv ));
1835 }
1836 
1837 
HasMetrics() const1838 bool SvxBoxItem::HasMetrics() const
1839 {
1840     return true;
1841 }
1842 
1843 
GetLine(SvxBoxItemLine nLine) const1844 const SvxBorderLine *SvxBoxItem::GetLine( SvxBoxItemLine nLine ) const
1845 {
1846     const SvxBorderLine *pRet = nullptr;
1847 
1848     switch ( nLine )
1849     {
1850         case SvxBoxItemLine::TOP:
1851             pRet = pTop.get();
1852             break;
1853         case SvxBoxItemLine::BOTTOM:
1854             pRet = pBottom.get();
1855             break;
1856         case SvxBoxItemLine::LEFT:
1857             pRet = pLeft.get();
1858             break;
1859         case SvxBoxItemLine::RIGHT:
1860             pRet = pRight.get();
1861             break;
1862         default:
1863             OSL_FAIL( "wrong line" );
1864             break;
1865     }
1866 
1867     return pRet;
1868 }
1869 
1870 
SetLine(const SvxBorderLine * pNew,SvxBoxItemLine nLine)1871 void SvxBoxItem::SetLine( const SvxBorderLine* pNew, SvxBoxItemLine nLine )
1872 {
1873     std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr );
1874 
1875     switch ( nLine )
1876     {
1877         case SvxBoxItemLine::TOP:
1878             pTop = std::move( pTmp );
1879             break;
1880         case SvxBoxItemLine::BOTTOM:
1881             pBottom = std::move( pTmp );
1882             break;
1883         case SvxBoxItemLine::LEFT:
1884             pLeft = std::move( pTmp );
1885             break;
1886         case SvxBoxItemLine::RIGHT:
1887             pRight = std::move( pTmp );
1888             break;
1889         default:
1890             OSL_FAIL( "wrong line" );
1891     }
1892 }
1893 
1894 
GetSmallestDistance() const1895 sal_uInt16 SvxBoxItem::GetSmallestDistance() const
1896 {
1897     // The smallest distance that is not 0 will be returned.
1898     sal_uInt16 nDist = nTopDist;
1899     if( nBottomDist && (!nDist || nBottomDist < nDist) )
1900         nDist = nBottomDist;
1901     if( nLeftDist && (!nDist || nLeftDist < nDist) )
1902         nDist = nLeftDist;
1903     if( nRightDist && (!nDist || nRightDist < nDist) )
1904         nDist = nRightDist;
1905 
1906     return nDist;
1907 }
1908 
1909 
GetDistance(SvxBoxItemLine nLine) const1910 sal_uInt16 SvxBoxItem::GetDistance( SvxBoxItemLine nLine ) const
1911 {
1912     sal_uInt16 nDist = 0;
1913     switch ( nLine )
1914     {
1915         case SvxBoxItemLine::TOP:
1916             nDist = nTopDist;
1917             break;
1918         case SvxBoxItemLine::BOTTOM:
1919             nDist = nBottomDist;
1920             break;
1921         case SvxBoxItemLine::LEFT:
1922             nDist = nLeftDist;
1923             break;
1924         case SvxBoxItemLine::RIGHT:
1925             nDist = nRightDist;
1926             break;
1927         default:
1928             OSL_FAIL( "wrong line" );
1929     }
1930 
1931     return nDist;
1932 }
1933 
1934 
SetDistance(sal_uInt16 nNew,SvxBoxItemLine nLine)1935 void SvxBoxItem::SetDistance( sal_uInt16 nNew, SvxBoxItemLine nLine )
1936 {
1937     switch ( nLine )
1938     {
1939         case SvxBoxItemLine::TOP:
1940             nTopDist = nNew;
1941             break;
1942         case SvxBoxItemLine::BOTTOM:
1943             nBottomDist = nNew;
1944             break;
1945         case SvxBoxItemLine::LEFT:
1946             nLeftDist = nNew;
1947             break;
1948         case SvxBoxItemLine::RIGHT:
1949             nRightDist = nNew;
1950             break;
1951         default:
1952             OSL_FAIL( "wrong line" );
1953     }
1954 }
1955 
CalcLineWidth(SvxBoxItemLine nLine) const1956 sal_uInt16 SvxBoxItem::CalcLineWidth( SvxBoxItemLine nLine ) const
1957 {
1958     SvxBorderLine* pTmp = nullptr;
1959     sal_uInt16 nWidth = 0;
1960     switch ( nLine )
1961     {
1962     case SvxBoxItemLine::TOP:
1963         pTmp = pTop.get();
1964         break;
1965     case SvxBoxItemLine::BOTTOM:
1966         pTmp = pBottom.get();
1967         break;
1968     case SvxBoxItemLine::LEFT:
1969         pTmp = pLeft.get();
1970         break;
1971     case SvxBoxItemLine::RIGHT:
1972         pTmp = pRight.get();
1973         break;
1974     default:
1975         OSL_FAIL( "wrong line" );
1976     }
1977 
1978     if( pTmp )
1979         nWidth = pTmp->GetScaledWidth();
1980 
1981     return nWidth;
1982 }
1983 
CalcLineSpace(SvxBoxItemLine nLine,bool bEvenIfNoLine) const1984 sal_uInt16 SvxBoxItem::CalcLineSpace( SvxBoxItemLine nLine, bool bEvenIfNoLine ) const
1985 {
1986     SvxBorderLine* pTmp = nullptr;
1987     sal_uInt16 nDist = 0;
1988     switch ( nLine )
1989     {
1990     case SvxBoxItemLine::TOP:
1991         pTmp = pTop.get();
1992         nDist = nTopDist;
1993         break;
1994     case SvxBoxItemLine::BOTTOM:
1995         pTmp = pBottom.get();
1996         nDist = nBottomDist;
1997         break;
1998     case SvxBoxItemLine::LEFT:
1999         pTmp = pLeft.get();
2000         nDist = nLeftDist;
2001         break;
2002     case SvxBoxItemLine::RIGHT:
2003         pTmp = pRight.get();
2004         nDist = nRightDist;
2005         break;
2006     default:
2007         OSL_FAIL( "wrong line" );
2008     }
2009 
2010     if( pTmp )
2011     {
2012         nDist = nDist + pTmp->GetScaledWidth();
2013     }
2014     else if( !bEvenIfNoLine )
2015         nDist = 0;
2016     return nDist;
2017 }
2018 
HasBorder(bool bTreatPaddingAsBorder) const2019 bool SvxBoxItem::HasBorder( bool bTreatPaddingAsBorder ) const
2020 {
2021     return  CalcLineSpace( SvxBoxItemLine::BOTTOM,   bTreatPaddingAsBorder )
2022             || CalcLineSpace( SvxBoxItemLine::RIGHT, bTreatPaddingAsBorder )
2023             || CalcLineSpace( SvxBoxItemLine::TOP,   bTreatPaddingAsBorder )
2024             || CalcLineSpace( SvxBoxItemLine::LEFT,  bTreatPaddingAsBorder );
2025 }
2026 
2027 // class SvxBoxInfoItem --------------------------------------------------
2028 
SvxBoxInfoItem(const sal_uInt16 nId)2029 SvxBoxInfoItem::SvxBoxInfoItem( const sal_uInt16 nId ) :
2030     SfxPoolItem( nId ),
2031     mbEnableHor( false ),
2032     mbEnableVer( false ),
2033     nDefDist( 0 )
2034 {
2035     bDist = bMinDist = false;
2036     ResetFlags();
2037 }
2038 
2039 
SvxBoxInfoItem(const SvxBoxInfoItem & rCpy)2040 SvxBoxInfoItem::SvxBoxInfoItem( const SvxBoxInfoItem& rCpy ) :
2041     SfxPoolItem( rCpy ),
2042     pHori( rCpy.pHori ? new SvxBorderLine( *rCpy.pHori ) : nullptr ),
2043     pVert( rCpy.pVert ? new SvxBorderLine( *rCpy.pVert ) : nullptr ),
2044     mbEnableHor( rCpy.mbEnableHor ),
2045     mbEnableVer( rCpy.mbEnableVer ),
2046     bDist( rCpy.bDist ),
2047     bMinDist ( rCpy.bMinDist ),
2048     nValidFlags( rCpy.nValidFlags ),
2049     nDefDist( rCpy.nDefDist )
2050 {
2051 }
2052 
~SvxBoxInfoItem()2053 SvxBoxInfoItem::~SvxBoxInfoItem()
2054 {
2055 }
2056 
operator ==(const SfxPoolItem & rAttr) const2057 bool SvxBoxInfoItem::operator==( const SfxPoolItem& rAttr ) const
2058 {
2059     assert(SfxPoolItem::operator==(rAttr));
2060 
2061     const SvxBoxInfoItem& rBoxInfo = static_cast<const SvxBoxInfoItem&>(rAttr);
2062 
2063     return (   mbEnableHor               == rBoxInfo.mbEnableHor
2064             && mbEnableVer               == rBoxInfo.mbEnableVer
2065             && bDist                     == rBoxInfo.IsDist()
2066             && bMinDist                  == rBoxInfo.IsMinDist()
2067             && nValidFlags               == rBoxInfo.nValidFlags
2068             && nDefDist                  == rBoxInfo.GetDefDist()
2069             && CmpBrdLn( pHori, rBoxInfo.GetHori() )
2070             && CmpBrdLn( pVert, rBoxInfo.GetVert() )
2071            );
2072 }
2073 
2074 
SetLine(const SvxBorderLine * pNew,SvxBoxInfoItemLine nLine)2075 void SvxBoxInfoItem::SetLine( const SvxBorderLine* pNew, SvxBoxInfoItemLine nLine )
2076 {
2077     std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr );
2078 
2079     if ( SvxBoxInfoItemLine::HORI == nLine )
2080     {
2081         pHori = std::move(pTmp);
2082     }
2083     else if ( SvxBoxInfoItemLine::VERT == nLine )
2084     {
2085         pVert = std::move(pTmp);
2086     }
2087     else
2088     {
2089         OSL_FAIL( "wrong line" );
2090     }
2091 }
2092 
2093 
Clone(SfxItemPool *) const2094 SfxPoolItem* SvxBoxInfoItem::Clone( SfxItemPool* ) const
2095 {
2096     return new SvxBoxInfoItem( *this );
2097 }
2098 
2099 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const2100 bool SvxBoxInfoItem::GetPresentation
2101 (
2102     SfxItemPresentation /*ePres*/,
2103     MapUnit             /*eCoreUnit*/,
2104     MapUnit             /*ePresUnit*/,
2105     OUString&           rText, const IntlWrapper&
2106 )   const
2107 {
2108     rText.clear();
2109     return false;
2110 }
2111 
2112 
ScaleMetrics(long nMult,long nDiv)2113 void SvxBoxInfoItem::ScaleMetrics( long nMult, long nDiv )
2114 {
2115     if ( pHori ) pHori->ScaleMetrics( nMult, nDiv );
2116     if ( pVert ) pVert->ScaleMetrics( nMult, nDiv );
2117     nDefDist = static_cast<sal_uInt16>(Scale( nDefDist, nMult, nDiv ));
2118 }
2119 
2120 
HasMetrics() const2121 bool SvxBoxInfoItem::HasMetrics() const
2122 {
2123     return true;
2124 }
2125 
2126 
ResetFlags()2127 void SvxBoxInfoItem::ResetFlags()
2128 {
2129     nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(0x7F); // all valid except Disable
2130 }
2131 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2132 bool SvxBoxInfoItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2133 {
2134     bool bConvert = 0 != (nMemberId & CONVERT_TWIPS);
2135     table::BorderLine2 aRetLine;
2136     sal_Int16 nVal=0;
2137     bool bIntMember = false;
2138     nMemberId &= ~CONVERT_TWIPS;
2139     switch(nMemberId)
2140     {
2141         case 0:
2142         {
2143             // 2 BorderLines, flags, valid flags and distance
2144             css::uno::Sequence< css::uno::Any > aSeq( 5 );
2145             aSeq[0] <<= SvxBoxItem::SvxLineToLine( pHori.get(), bConvert);
2146             aSeq[1] <<= SvxBoxItem::SvxLineToLine( pVert.get(), bConvert);
2147             if ( IsTable() )
2148                 nVal |= 0x01;
2149             if ( IsDist() )
2150                 nVal |= 0x02;
2151             if ( IsMinDist() )
2152                 nVal |= 0x04;
2153             aSeq[2] <<= nVal;
2154             aSeq[3] <<= static_cast<sal_Int16>(nValidFlags);
2155             aSeq[4] <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist());
2156             rVal <<= aSeq;
2157             return true;
2158         }
2159 
2160         case MID_HORIZONTAL:
2161             aRetLine = SvxBoxItem::SvxLineToLine( pHori.get(), bConvert);
2162             break;
2163         case MID_VERTICAL:
2164             aRetLine = SvxBoxItem::SvxLineToLine( pVert.get(), bConvert);
2165             break;
2166         case MID_FLAGS:
2167             bIntMember = true;
2168             if ( IsTable() )
2169                 nVal |= 0x01;
2170             if ( IsDist() )
2171                 nVal |= 0x02;
2172             if ( IsMinDist() )
2173                 nVal |= 0x04;
2174             rVal <<= nVal;
2175             break;
2176         case MID_VALIDFLAGS:
2177             bIntMember = true;
2178             rVal <<= static_cast<sal_Int16>(nValidFlags);
2179             break;
2180         case MID_DISTANCE:
2181             bIntMember = true;
2182             rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist());
2183             break;
2184         default: OSL_FAIL("Wrong MemberId!"); return false;
2185     }
2186 
2187     if( !bIntMember )
2188         rVal <<= aRetLine;
2189 
2190     return true;
2191 }
2192 
2193 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2194 bool SvxBoxInfoItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2195 {
2196     bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
2197     nMemberId &= ~CONVERT_TWIPS;
2198     bool bRet;
2199     switch(nMemberId)
2200     {
2201         case 0:
2202         {
2203             css::uno::Sequence< css::uno::Any > aSeq;
2204             if (( rVal >>= aSeq ) && ( aSeq.getLength() == 5 ))
2205             {
2206                 // 2 BorderLines, flags, valid flags and distance
2207                 if (!lcl_setLine(aSeq[0], *this, SvxBoxInfoItemLine::HORI, bConvert))
2208                     return false;
2209                 if (!lcl_setLine(aSeq[1], *this, SvxBoxInfoItemLine::VERT, bConvert))
2210                     return false;
2211 
2212                 sal_Int16 nFlags( 0 );
2213                 sal_Int32 nVal( 0 );
2214                 if ( aSeq[2] >>= nFlags )
2215                 {
2216                     SetTable  ( ( nFlags & 0x01 ) != 0 );
2217                     SetDist   ( ( nFlags & 0x02 ) != 0 );
2218                     SetMinDist( ( nFlags & 0x04 ) != 0 );
2219                 }
2220                 else
2221                     return false;
2222                 if ( aSeq[3] >>= nFlags )
2223                     nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags);
2224                 else
2225                     return false;
2226                 if (( aSeq[4] >>= nVal ) && ( nVal >= 0 ))
2227                 {
2228                     if( bConvert )
2229                         nVal = convertMm100ToTwip(nVal);
2230                     SetDefDist( static_cast<sal_uInt16>(nVal) );
2231                 }
2232             }
2233             return true;
2234         }
2235 
2236         case MID_HORIZONTAL:
2237         case MID_VERTICAL:
2238         {
2239             if( !rVal.hasValue() )
2240                 return false;
2241 
2242             table::BorderLine2 aBorderLine;
2243             if( lcl_extractBorderLine(rVal, aBorderLine) )
2244             {
2245                 // usual struct
2246             }
2247             else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
2248             {
2249                 // serialization for basic macro recording
2250                 uno::Reference < script::XTypeConverter > xConverter( script::Converter::create(::comphelper::getProcessComponentContext()) );
2251                 uno::Any aNew;
2252                 uno::Sequence < uno::Any > aSeq;
2253                 try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); }
2254                 catch (const uno::Exception&) {}
2255 
2256                 if ((aNew >>= aSeq) &&
2257                     aSeq.getLength() >= 4  && aSeq.getLength() <= 6)
2258                 {
2259                     sal_Int32 nVal = 0;
2260                     if ( aSeq[0] >>= nVal )
2261                         aBorderLine.Color = nVal;
2262                     if ( aSeq[1] >>= nVal )
2263                         aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal);
2264                     if ( aSeq[2] >>= nVal )
2265                         aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal);
2266                     if ( aSeq[3] >>= nVal )
2267                         aBorderLine.LineDistance = static_cast<sal_Int16>(nVal);
2268                     if (aSeq.getLength() >= 5) // fdo#40874 added fields
2269                     {
2270                         if (aSeq[4] >>= nVal)
2271                         {
2272                             aBorderLine.LineStyle = nVal;
2273                         }
2274                         if (aSeq.getLength() >= 6)
2275                         {
2276                             if (aSeq[5] >>= nVal)
2277                             {
2278                                 aBorderLine.LineWidth = nVal;
2279                             }
2280                         }
2281                     }
2282                 }
2283                 else
2284                     return false;
2285             }
2286             else if (rVal.getValueType() == cppu::UnoType<css::uno::Sequence < sal_Int16 >>::get() )
2287             {
2288                 // serialization for basic macro recording
2289                 css::uno::Sequence < sal_Int16 > aSeq;
2290                 rVal >>= aSeq;
2291                 if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6)
2292                 {
2293                     aBorderLine.Color = aSeq[0];
2294                     aBorderLine.InnerLineWidth = aSeq[1];
2295                     aBorderLine.OuterLineWidth = aSeq[2];
2296                     aBorderLine.LineDistance = aSeq[3];
2297                     if (aSeq.getLength() >= 5) // fdo#40874 added fields
2298                     {
2299                         aBorderLine.LineStyle = aSeq[4];
2300                         if (aSeq.getLength() >= 6)
2301                         {
2302                             aBorderLine.LineWidth = aSeq[5];
2303                         }
2304                     }
2305                 }
2306                 else
2307                     return false;
2308             }
2309             else
2310                 return false;
2311 
2312             SvxBorderLine aLine;
2313             bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
2314             if ( bSet )
2315                 SetLine( &aLine, nMemberId == MID_HORIZONTAL ? SvxBoxInfoItemLine::HORI : SvxBoxInfoItemLine::VERT );
2316             break;
2317         }
2318         case MID_FLAGS:
2319         {
2320             sal_Int16 nFlags = sal_Int16();
2321             bRet = (rVal >>= nFlags);
2322             if ( bRet )
2323             {
2324                 SetTable  ( ( nFlags & 0x01 ) != 0 );
2325                 SetDist   ( ( nFlags & 0x02 ) != 0 );
2326                 SetMinDist( ( nFlags & 0x04 ) != 0 );
2327             }
2328 
2329             break;
2330         }
2331         case MID_VALIDFLAGS:
2332         {
2333             sal_Int16 nFlags = sal_Int16();
2334             bRet = (rVal >>= nFlags);
2335             if ( bRet )
2336                 nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags);
2337             break;
2338         }
2339         case MID_DISTANCE:
2340         {
2341             sal_Int32 nVal = 0;
2342             bRet = (rVal >>= nVal);
2343             if ( bRet && nVal>=0 )
2344             {
2345                 if( bConvert )
2346                     nVal = convertMm100ToTwip(nVal);
2347                 SetDefDist( static_cast<sal_uInt16>(nVal) );
2348             }
2349             break;
2350         }
2351         default: OSL_FAIL("Wrong MemberId!"); return false;
2352     }
2353 
2354     return true;
2355 }
2356 
2357 
2358 namespace editeng
2359 {
2360 
BorderDistanceFromWord(bool bFromEdge,sal_Int32 & nMargin,sal_Int32 & nBorderDistance,sal_Int32 nBorderWidth)2361 void BorderDistanceFromWord(bool bFromEdge, sal_Int32& nMargin, sal_Int32& nBorderDistance,
2362     sal_Int32 nBorderWidth)
2363 {
2364     // See https://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
2365 
2366     sal_Int32 nNewMargin = nMargin;
2367     sal_Int32 nNewBorderDistance = nBorderDistance;
2368 
2369     if (bFromEdge)
2370     {
2371         nNewMargin = nBorderDistance;
2372         nNewBorderDistance = nMargin - nBorderDistance - nBorderWidth;
2373     }
2374     else
2375     {
2376         nNewMargin -= nBorderDistance + nBorderWidth;
2377     }
2378 
2379     // Ensure correct distance from page edge to text in cases not supported by us:
2380     // when border is outside entire page area (!bFromEdge && BorderDistance > Margin),
2381     // and when border is inside page body area (bFromEdge && BorderDistance > Margin)
2382     if (nNewMargin < 0)
2383     {
2384         nNewMargin = 0;
2385         nNewBorderDistance = std::max<sal_Int32>(nMargin - nBorderWidth, 0);
2386     }
2387     else if (nNewBorderDistance < 0)
2388     {
2389         nNewMargin = std::max<sal_Int32>(nMargin - nBorderWidth, 0);
2390         nNewBorderDistance = 0;
2391     }
2392 
2393     nMargin = nNewMargin;
2394     nBorderDistance = nNewBorderDistance;
2395 }
2396 
2397 // Heuristics to decide if we need to use "from edge" offset of borders
2398 //
2399 // There are two cases when we can safely use "from text" or "from edge" offset without distorting
2400 // border position (modulo rounding errors):
2401 // 1. When distance of all borders from text is no greater than 31 pt, we use "from text"
2402 // 2. Otherwise, if distance of all borders from edge is no greater than 31 pt, we use "from edge"
2403 // In all other cases, the position of borders would be distorted on export, because Word doesn't
2404 // support the offset of >31 pts (https://msdn.microsoft.com/en-us/library/ff533820), and we need
2405 // to decide which type of offset would provide less wrong result (i.e., the result would look
2406 // closer to original). Here, we just check sum of distances from text to borders, and if it is
2407 // less than sum of distances from borders to edges. The alternative would be to compare total areas
2408 // between text-and-borders and between borders-and-edges (taking into account different lengths of
2409 // borders, and visual impact of that).
BorderDistancesToWord(const SvxBoxItem & rBox,const WordPageMargins & rMargins,WordBorderDistances & rDistances)2410 void BorderDistancesToWord(const SvxBoxItem& rBox, const WordPageMargins& rMargins,
2411     WordBorderDistances& rDistances)
2412 {
2413     // Use signed sal_Int32 that can hold sal_uInt16, to prevent overflow at subtraction below
2414     const sal_Int32 nT = rBox.GetDistance(SvxBoxItemLine::TOP);
2415     const sal_Int32 nL = rBox.GetDistance(SvxBoxItemLine::LEFT);
2416     const sal_Int32 nB = rBox.GetDistance(SvxBoxItemLine::BOTTOM);
2417     const sal_Int32 nR = rBox.GetDistance(SvxBoxItemLine::RIGHT);
2418 
2419     // Only take into account existing borders
2420     const SvxBorderLine* pLnT = rBox.GetLine(SvxBoxItemLine::TOP);
2421     const SvxBorderLine* pLnL = rBox.GetLine(SvxBoxItemLine::LEFT);
2422     const SvxBorderLine* pLnB = rBox.GetLine(SvxBoxItemLine::BOTTOM);
2423     const SvxBorderLine* pLnR = rBox.GetLine(SvxBoxItemLine::RIGHT);
2424 
2425     // We need to take border widths into account
2426     const long nWidthT = pLnT ? pLnT->GetScaledWidth() : 0;
2427     const long nWidthL = pLnL ? pLnL->GetScaledWidth() : 0;
2428     const long nWidthB = pLnB ? pLnB->GetScaledWidth() : 0;
2429     const long nWidthR = pLnR ? pLnR->GetScaledWidth() : 0;
2430 
2431     // Resulting distances from text to borders
2432     const sal_Int32 nT2BT = pLnT ? nT : 0;
2433     const sal_Int32 nT2BL = pLnL ? nL : 0;
2434     const sal_Int32 nT2BB = pLnB ? nB : 0;
2435     const sal_Int32 nT2BR = pLnR ? nR : 0;
2436 
2437     // Resulting distances from edge to borders
2438     const sal_Int32 nE2BT = pLnT ? std::max<sal_Int32>(rMargins.nTop - nT - nWidthT, 0) : 0;
2439     const sal_Int32 nE2BL = pLnL ? std::max<sal_Int32>(rMargins.nLeft - nL - nWidthL, 0) : 0;
2440     const sal_Int32 nE2BB = pLnB ? std::max<sal_Int32>(rMargins.nBottom - nB - nWidthB, 0) : 0;
2441     const sal_Int32 nE2BR = pLnR ? std::max<sal_Int32>(rMargins.nRight - nR - nWidthR, 0) : 0;
2442 
2443     const sal_Int32 n32pt = 32 * 20;
2444     // 1. If all borders are in range of 31 pts from text
2445     if (nT2BT < n32pt && nT2BL < n32pt && nT2BB < n32pt && nT2BR < n32pt)
2446     {
2447         rDistances.bFromEdge = false;
2448     }
2449     else
2450     {
2451         // 2. If all borders are in range of 31 pts from edge
2452         if (nE2BT < n32pt && nE2BL < n32pt && nE2BB < n32pt && nE2BR < n32pt)
2453         {
2454             rDistances.bFromEdge = true;
2455         }
2456         else
2457         {
2458             // Let's try to guess which would be the best approximation
2459             rDistances.bFromEdge =
2460                 (nT2BT + nT2BL + nT2BB + nT2BR) > (nE2BT + nE2BL + nE2BB + nE2BR);
2461         }
2462     }
2463 
2464     if (rDistances.bFromEdge)
2465     {
2466         rDistances.nTop = sal::static_int_cast<sal_uInt16>(nE2BT);
2467         rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nE2BL);
2468         rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nE2BB);
2469         rDistances.nRight = sal::static_int_cast<sal_uInt16>(nE2BR);
2470     }
2471     else
2472     {
2473         rDistances.nTop = sal::static_int_cast<sal_uInt16>(nT2BT);
2474         rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nT2BL);
2475         rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nT2BB);
2476         rDistances.nRight = sal::static_int_cast<sal_uInt16>(nT2BR);
2477     }
2478 }
2479 
2480 }
2481 
2482 // class SvxFormatBreakItem -------------------------------------------------
2483 
operator ==(const SfxPoolItem & rAttr) const2484 bool SvxFormatBreakItem::operator==( const SfxPoolItem& rAttr ) const
2485 {
2486     assert(SfxPoolItem::operator==(rAttr));
2487 
2488     return GetValue() == static_cast<const SvxFormatBreakItem&>( rAttr ).GetValue();
2489 }
2490 
2491 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const2492 bool SvxFormatBreakItem::GetPresentation
2493 (
2494     SfxItemPresentation /*ePres*/,
2495     MapUnit             /*eCoreUnit*/,
2496     MapUnit             /*ePresUnit*/,
2497     OUString&           rText, const IntlWrapper&
2498 )   const
2499 {
2500     rText = GetValueTextByPos( GetEnumValue() );
2501     return true;
2502 }
2503 
GetValueTextByPos(sal_uInt16 nPos)2504 OUString SvxFormatBreakItem::GetValueTextByPos( sal_uInt16 nPos )
2505 {
2506     static const char* RID_SVXITEMS_BREAK[] =
2507     {
2508         RID_SVXITEMS_BREAK_NONE,
2509         RID_SVXITEMS_BREAK_COLUMN_BEFORE,
2510         RID_SVXITEMS_BREAK_COLUMN_AFTER,
2511         RID_SVXITEMS_BREAK_COLUMN_BOTH,
2512         RID_SVXITEMS_BREAK_PAGE_BEFORE,
2513         RID_SVXITEMS_BREAK_PAGE_AFTER,
2514         RID_SVXITEMS_BREAK_PAGE_BOTH
2515     };
2516     static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_BREAK) == size_t(SvxBreak::End), "unexpected size");
2517     assert(nPos < sal_uInt16(SvxBreak::End) && "enum overflow!");
2518     return EditResId(RID_SVXITEMS_BREAK[nPos]);
2519 }
2520 
QueryValue(uno::Any & rVal,sal_uInt8) const2521 bool SvxFormatBreakItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const
2522 {
2523     style::BreakType eBreak = style::BreakType_NONE;
2524     switch ( GetBreak() )
2525     {
2526         case SvxBreak::ColumnBefore:   eBreak = style::BreakType_COLUMN_BEFORE; break;
2527         case SvxBreak::ColumnAfter:    eBreak = style::BreakType_COLUMN_AFTER ; break;
2528         case SvxBreak::ColumnBoth:     eBreak = style::BreakType_COLUMN_BOTH  ; break;
2529         case SvxBreak::PageBefore:     eBreak = style::BreakType_PAGE_BEFORE  ; break;
2530         case SvxBreak::PageAfter:      eBreak = style::BreakType_PAGE_AFTER   ; break;
2531         case SvxBreak::PageBoth:       eBreak = style::BreakType_PAGE_BOTH    ; break;
2532         default: ; // prevent warning
2533     }
2534     rVal <<= eBreak;
2535     return true;
2536 }
2537 
PutValue(const uno::Any & rVal,sal_uInt8)2538 bool SvxFormatBreakItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
2539 {
2540     style::BreakType nBreak;
2541 
2542     if(!(rVal >>= nBreak))
2543     {
2544         sal_Int32 nValue = 0;
2545         if(!(rVal >>= nValue))
2546             return false;
2547 
2548         nBreak = static_cast<style::BreakType>(nValue);
2549     }
2550 
2551     SvxBreak eBreak = SvxBreak::NONE;
2552     switch( nBreak )
2553     {
2554         case style::BreakType_COLUMN_BEFORE:    eBreak = SvxBreak::ColumnBefore; break;
2555         case style::BreakType_COLUMN_AFTER: eBreak = SvxBreak::ColumnAfter;  break;
2556         case style::BreakType_COLUMN_BOTH:      eBreak = SvxBreak::ColumnBoth;   break;
2557         case style::BreakType_PAGE_BEFORE:      eBreak = SvxBreak::PageBefore;   break;
2558         case style::BreakType_PAGE_AFTER:       eBreak = SvxBreak::PageAfter;    break;
2559         case style::BreakType_PAGE_BOTH:        eBreak = SvxBreak::PageBoth;     break;
2560         default: ; // prevent warning
2561     }
2562     SetValue(eBreak);
2563 
2564     return true;
2565 }
2566 
2567 
Clone(SfxItemPool *) const2568 SfxPoolItem* SvxFormatBreakItem::Clone( SfxItemPool* ) const
2569 {
2570     return new SvxFormatBreakItem( *this );
2571 }
2572 
2573 
GetValueCount() const2574 sal_uInt16 SvxFormatBreakItem::GetValueCount() const
2575 {
2576     return sal_uInt16(SvxBreak::End);   // SvxBreak::PageBoth + 1
2577 }
2578 
2579 
Clone(SfxItemPool *) const2580 SfxPoolItem* SvxFormatKeepItem::Clone( SfxItemPool* ) const
2581 {
2582     return new SvxFormatKeepItem( *this );
2583 }
2584 
2585 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const2586 bool SvxFormatKeepItem::GetPresentation
2587 (
2588     SfxItemPresentation /*ePres*/,
2589     MapUnit             /*eCoreUnit*/,
2590     MapUnit             /*ePresUnit*/,
2591     OUString&           rText, const IntlWrapper&
2592     ) const
2593 {
2594     const char* pId = RID_SVXITEMS_FMTKEEP_FALSE;
2595 
2596     if ( GetValue() )
2597         pId = RID_SVXITEMS_FMTKEEP_TRUE;
2598     rText = EditResId(pId);
2599     return true;
2600 }
2601 
2602 
SvxLineItem(const sal_uInt16 nId)2603 SvxLineItem::SvxLineItem( const sal_uInt16 nId ) :
2604     SfxPoolItem ( nId )
2605 {
2606 }
2607 
2608 
SvxLineItem(const SvxLineItem & rCpy)2609 SvxLineItem::SvxLineItem( const SvxLineItem& rCpy ) :
2610     SfxPoolItem ( rCpy ),
2611     pLine(rCpy.pLine ? new SvxBorderLine( *rCpy.pLine ) : nullptr)
2612 {
2613 }
2614 
2615 
~SvxLineItem()2616 SvxLineItem::~SvxLineItem()
2617 {
2618 }
2619 
2620 
operator ==(const SfxPoolItem & rAttr) const2621 bool SvxLineItem::operator==( const SfxPoolItem& rAttr ) const
2622 {
2623     assert(SfxPoolItem::operator==(rAttr));
2624 
2625     return CmpBrdLn( pLine, static_cast<const SvxLineItem&>(rAttr).GetLine() );
2626 }
2627 
2628 
Clone(SfxItemPool *) const2629 SfxPoolItem* SvxLineItem::Clone( SfxItemPool* ) const
2630 {
2631     return new SvxLineItem( *this );
2632 }
2633 
2634 
QueryValue(uno::Any & rVal,sal_uInt8 nMemId) const2635 bool SvxLineItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemId ) const
2636 {
2637     bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
2638     nMemId &= ~CONVERT_TWIPS;
2639     if ( nMemId == 0 )
2640     {
2641         rVal <<= SvxBoxItem::SvxLineToLine(pLine.get(), bConvert);
2642         return true;
2643     }
2644     else if ( pLine )
2645     {
2646         switch ( nMemId )
2647         {
2648             case MID_FG_COLOR:      rVal <<= pLine->GetColor(); break;
2649             case MID_OUTER_WIDTH:   rVal <<= sal_Int32(pLine->GetOutWidth());   break;
2650             case MID_INNER_WIDTH:   rVal <<= sal_Int32(pLine->GetInWidth( ));   break;
2651             case MID_DISTANCE:      rVal <<= sal_Int32(pLine->GetDistance());   break;
2652             default:
2653                 OSL_FAIL( "Wrong MemberId" );
2654                 return false;
2655         }
2656     }
2657 
2658     return true;
2659 }
2660 
2661 
PutValue(const uno::Any & rVal,sal_uInt8 nMemId)2662 bool SvxLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemId )
2663 {
2664     bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
2665     nMemId &= ~CONVERT_TWIPS;
2666     sal_Int32 nVal = 0;
2667     if ( nMemId == 0 )
2668     {
2669         table::BorderLine2 aLine;
2670         if ( lcl_extractBorderLine(rVal, aLine) )
2671         {
2672             if ( !pLine )
2673                 pLine.reset( new SvxBorderLine );
2674             if( !SvxBoxItem::LineToSvxLine(aLine, *pLine, bConvert) )
2675                 pLine.reset();
2676             return true;
2677         }
2678         return false;
2679     }
2680     else if ( rVal >>= nVal )
2681     {
2682         if ( !pLine )
2683             pLine.reset( new SvxBorderLine );
2684 
2685         switch ( nMemId )
2686         {
2687             case MID_FG_COLOR:      pLine->SetColor( Color(nVal) ); break;
2688             case MID_LINE_STYLE:
2689                 pLine->SetBorderLineStyle(static_cast<SvxBorderLineStyle>(nVal));
2690             break;
2691             default:
2692                 OSL_FAIL( "Wrong MemberId" );
2693                 return false;
2694         }
2695 
2696         return true;
2697     }
2698 
2699     return false;
2700 }
2701 
2702 
GetPresentation(SfxItemPresentation ePres,MapUnit eCoreUnit,MapUnit ePresUnit,OUString & rText,const IntlWrapper & rIntl) const2703 bool SvxLineItem::GetPresentation
2704 (
2705     SfxItemPresentation ePres,
2706     MapUnit             eCoreUnit,
2707     MapUnit             ePresUnit,
2708     OUString&           rText, const IntlWrapper& rIntl
2709 )   const
2710 {
2711     rText.clear();
2712 
2713     if ( pLine )
2714         rText = pLine->GetValueString( eCoreUnit, ePresUnit, &rIntl,
2715             (SfxItemPresentation::Complete == ePres) );
2716     return true;
2717 }
2718 
2719 
ScaleMetrics(long nMult,long nDiv)2720 void SvxLineItem::ScaleMetrics( long nMult, long nDiv )
2721 {
2722     if ( pLine ) pLine->ScaleMetrics( nMult, nDiv );
2723 }
2724 
2725 
HasMetrics() const2726 bool SvxLineItem::HasMetrics() const
2727 {
2728     return true;
2729 }
2730 
2731 
SetLine(const SvxBorderLine * pNew)2732 void SvxLineItem::SetLine( const SvxBorderLine* pNew )
2733 {
2734     pLine.reset( pNew ? new SvxBorderLine( *pNew ) : nullptr );
2735 }
2736 
SvxBrushItem(sal_uInt16 _nWhich)2737 SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich)
2738     : SfxPoolItem(_nWhich)
2739     , aColor(COL_TRANSPARENT)
2740     , nShadingValue(ShadingPattern::CLEAR)
2741     , nGraphicTransparency(0)
2742     , eGraphicPos(GPOS_NONE)
2743     , bLoadAgain(true)
2744 {
2745 }
2746 
SvxBrushItem(const Color & rColor,sal_uInt16 _nWhich)2747 SvxBrushItem::SvxBrushItem(const Color& rColor, sal_uInt16 _nWhich)
2748     : SfxPoolItem(_nWhich)
2749     , aColor(rColor)
2750     , nShadingValue(ShadingPattern::CLEAR)
2751     , nGraphicTransparency(0)
2752     , eGraphicPos(GPOS_NONE)
2753     , bLoadAgain(true)
2754 {
2755 }
2756 
SvxBrushItem(const Graphic & rGraphic,SvxGraphicPosition ePos,sal_uInt16 _nWhich)2757 SvxBrushItem::SvxBrushItem(const Graphic& rGraphic, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2758     : SfxPoolItem(_nWhich)
2759     , aColor(COL_TRANSPARENT)
2760     , nShadingValue(ShadingPattern::CLEAR)
2761     , xGraphicObject(new GraphicObject(rGraphic))
2762     , nGraphicTransparency(0)
2763     , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2764     , bLoadAgain(true)
2765 {
2766     DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2767 }
2768 
SvxBrushItem(const GraphicObject & rGraphicObj,SvxGraphicPosition ePos,sal_uInt16 _nWhich)2769 SvxBrushItem::SvxBrushItem(const GraphicObject& rGraphicObj, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2770     : SfxPoolItem(_nWhich)
2771     , aColor(COL_TRANSPARENT)
2772     , nShadingValue(ShadingPattern::CLEAR)
2773     , xGraphicObject(new GraphicObject(rGraphicObj))
2774     , nGraphicTransparency(0)
2775     , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2776     , bLoadAgain(true)
2777 {
2778     DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2779 }
2780 
SvxBrushItem(const OUString & rLink,const OUString & rFilter,SvxGraphicPosition ePos,sal_uInt16 _nWhich)2781 SvxBrushItem::SvxBrushItem(const OUString& rLink, const OUString& rFilter,
2782                            SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2783     : SfxPoolItem(_nWhich)
2784     , aColor(COL_TRANSPARENT)
2785     , nShadingValue(ShadingPattern::CLEAR)
2786     , nGraphicTransparency(0)
2787     , maStrLink(rLink)
2788     , maStrFilter(rFilter)
2789     , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2790     , bLoadAgain(true)
2791 {
2792     DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2793 }
2794 
SvxBrushItem(const SvxBrushItem & rItem)2795 SvxBrushItem::SvxBrushItem(const SvxBrushItem& rItem)
2796     : SfxPoolItem(rItem)
2797     , aColor(rItem.aColor)
2798     , nShadingValue(rItem.nShadingValue)
2799     , xGraphicObject(rItem.xGraphicObject ? new GraphicObject(*rItem.xGraphicObject) : nullptr)
2800     , nGraphicTransparency(rItem.nGraphicTransparency)
2801     , maStrLink(rItem.maStrLink)
2802     , maStrFilter(rItem.maStrFilter)
2803     , eGraphicPos(rItem.eGraphicPos)
2804     , bLoadAgain(rItem.bLoadAgain)
2805 {
2806 }
2807 
SvxBrushItem(SvxBrushItem && rItem)2808 SvxBrushItem::SvxBrushItem(SvxBrushItem&& rItem)
2809     : SfxPoolItem(std::move(rItem))
2810     , aColor(std::move(rItem.aColor))
2811     , nShadingValue(std::move(rItem.nShadingValue))
2812     , xGraphicObject(std::move(rItem.xGraphicObject))
2813     , nGraphicTransparency(std::move(rItem.nGraphicTransparency))
2814     , maStrLink(std::move(rItem.maStrLink))
2815     , maStrFilter(std::move(rItem.maStrFilter))
2816     , eGraphicPos(std::move(rItem.eGraphicPos))
2817     , bLoadAgain(std::move(rItem.bLoadAgain))
2818 {
2819 }
2820 
~SvxBrushItem()2821 SvxBrushItem::~SvxBrushItem()
2822 {
2823 }
2824 
isUsed() const2825 bool SvxBrushItem::isUsed() const
2826 {
2827     if (GPOS_NONE != GetGraphicPos())
2828     {
2829         // graphic used
2830         return true;
2831     }
2832     else if (0xff != GetColor().GetTransparency())
2833     {
2834         // color used
2835         return true;
2836     }
2837 
2838     return false;
2839 }
2840 
2841 
lcl_PercentToTransparency(long nPercent)2842 static sal_Int8 lcl_PercentToTransparency(long nPercent)
2843 {
2844     // 0xff must not be returned!
2845     return sal_Int8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0);
2846 }
2847 
2848 
TransparencyToPercent(sal_Int32 nTrans)2849 sal_Int8 SvxBrushItem::TransparencyToPercent(sal_Int32 nTrans)
2850 {
2851     return static_cast<sal_Int8>((nTrans * 100 + 127) / 254);
2852 }
2853 
2854 
QueryValue(uno::Any & rVal,sal_uInt8 nMemberId) const2855 bool SvxBrushItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2856 {
2857     nMemberId &= ~CONVERT_TWIPS;
2858     switch( nMemberId)
2859     {
2860         case MID_BACK_COLOR:
2861             rVal <<= aColor;
2862         break;
2863         case MID_BACK_COLOR_R_G_B:
2864             rVal <<= aColor.GetRGBColor();
2865         break;
2866         case MID_BACK_COLOR_TRANSPARENCY:
2867             rVal <<= SvxBrushItem::TransparencyToPercent(aColor.GetTransparency());
2868         break;
2869         case MID_GRAPHIC_POSITION:
2870             rVal <<= static_cast<style::GraphicLocation>(static_cast<sal_Int16>(eGraphicPos));
2871         break;
2872 
2873         case MID_GRAPHIC_TRANSPARENT:
2874             rVal <<= ( aColor.GetTransparency() == 0xff );
2875         break;
2876 
2877         case MID_GRAPHIC_URL:
2878         {
2879             SAL_INFO("editeng.items", "Getting GraphicURL property is not supported");
2880             return false;
2881         }
2882         break;
2883         case MID_GRAPHIC:
2884         {
2885             uno::Reference<graphic::XGraphic> xGraphic;
2886             if (!maStrLink.isEmpty())
2887             {
2888                 Graphic aGraphic(vcl::graphic::loadFromURL(maStrLink));
2889                 xGraphic = aGraphic.GetXGraphic();
2890             }
2891             else if (xGraphicObject)
2892             {
2893                 xGraphic = xGraphicObject->GetGraphic().GetXGraphic();
2894             }
2895             rVal <<= xGraphic;
2896         }
2897         break;
2898 
2899         case MID_GRAPHIC_FILTER:
2900         {
2901             rVal <<= maStrFilter;
2902         }
2903         break;
2904 
2905         case MID_GRAPHIC_TRANSPARENCY:
2906             rVal <<= nGraphicTransparency;
2907         break;
2908 
2909         case MID_SHADING_VALUE:
2910         {
2911             rVal <<= nShadingValue;
2912         }
2913         break;
2914     }
2915 
2916     return true;
2917 }
2918 
2919 
PutValue(const uno::Any & rVal,sal_uInt8 nMemberId)2920 bool SvxBrushItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2921 {
2922     nMemberId &= ~CONVERT_TWIPS;
2923     switch( nMemberId)
2924     {
2925         case MID_BACK_COLOR:
2926         case MID_BACK_COLOR_R_G_B:
2927         {
2928             Color aNewCol;
2929             if ( !( rVal >>= aNewCol ) )
2930                 return false;
2931             if(MID_BACK_COLOR_R_G_B == nMemberId)
2932             {
2933                 aNewCol.SetTransparency(aColor.GetTransparency());
2934             }
2935             aColor = aNewCol;
2936         }
2937         break;
2938         case MID_BACK_COLOR_TRANSPARENCY:
2939         {
2940             sal_Int32 nTrans = 0;
2941             if ( !( rVal >>= nTrans ) || nTrans < 0 || nTrans > 100 )
2942                 return false;
2943             aColor.SetTransparency(lcl_PercentToTransparency(nTrans));
2944         }
2945         break;
2946 
2947         case MID_GRAPHIC_POSITION:
2948         {
2949             style::GraphicLocation eLocation;
2950             if ( !( rVal>>=eLocation ) )
2951             {
2952                 sal_Int32 nValue = 0;
2953                 if ( !( rVal >>= nValue ) )
2954                     return false;
2955                 eLocation = static_cast<style::GraphicLocation>(nValue);
2956             }
2957             SetGraphicPos( static_cast<SvxGraphicPosition>(static_cast<sal_uInt16>(eLocation)) );
2958         }
2959         break;
2960 
2961         case MID_GRAPHIC_TRANSPARENT:
2962             aColor.SetTransparency( Any2Bool( rVal ) ? 0xff : 0 );
2963         break;
2964 
2965         case MID_GRAPHIC_URL:
2966         case MID_GRAPHIC:
2967         {
2968             Graphic aGraphic;
2969 
2970             if (rVal.getValueType() == ::cppu::UnoType<OUString>::get())
2971             {
2972                 OUString aURL = rVal.get<OUString>();
2973                 aGraphic = vcl::graphic::loadFromURL(aURL);
2974             }
2975             else if (rVal.getValueType() == cppu::UnoType<graphic::XGraphic>::get())
2976             {
2977                 auto xGraphic = rVal.get<uno::Reference<graphic::XGraphic>>();
2978                 aGraphic = Graphic(xGraphic);
2979             }
2980 
2981             if (!aGraphic.IsNone())
2982             {
2983                 maStrLink.clear();
2984 
2985                 std::unique_ptr<GraphicObject> xOldGrfObj(std::move(xGraphicObject));
2986                 xGraphicObject.reset(new GraphicObject(aGraphic));
2987                 ApplyGraphicTransparency_Impl();
2988                 xOldGrfObj.reset();
2989 
2990                 if (!aGraphic.IsNone() && eGraphicPos == GPOS_NONE)
2991                 {
2992                     eGraphicPos = GPOS_MM;
2993                 }
2994                 else if (aGraphic.IsNone())
2995                 {
2996                     eGraphicPos = GPOS_NONE;
2997                 }
2998             }
2999         }
3000         break;
3001 
3002         case MID_GRAPHIC_FILTER:
3003         {
3004             if( rVal.getValueType() == ::cppu::UnoType<OUString>::get() )
3005             {
3006                 OUString sLink;
3007                 rVal >>= sLink;
3008                 SetGraphicFilter( sLink );
3009             }
3010         }
3011         break;
3012         case MID_GRAPHIC_TRANSPARENCY :
3013         {
3014             sal_Int32 nTmp = 0;
3015             rVal >>= nTmp;
3016             if(nTmp >= 0 && nTmp <= 100)
3017             {
3018                 nGraphicTransparency = sal_Int8(nTmp);
3019                 if (xGraphicObject)
3020                     ApplyGraphicTransparency_Impl();
3021             }
3022         }
3023         break;
3024 
3025         case MID_SHADING_VALUE:
3026         {
3027             sal_Int32 nVal = 0;
3028             if (!(rVal >>= nVal))
3029                 return false;
3030 
3031             nShadingValue = nVal;
3032         }
3033         break;
3034     }
3035 
3036     return true;
3037 }
3038 
3039 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const3040 bool SvxBrushItem::GetPresentation
3041 (
3042     SfxItemPresentation /*ePres*/,
3043     MapUnit             /*eCoreUnit*/,
3044     MapUnit             /*ePresUnit*/,
3045     OUString&           rText, const IntlWrapper&
3046     ) const
3047 {
3048     if ( GPOS_NONE  == eGraphicPos )
3049     {
3050         rText = ::GetColorString( aColor ) + cpDelim;
3051         const char* pId = RID_SVXITEMS_TRANSPARENT_FALSE;
3052 
3053         if ( aColor.GetTransparency() )
3054             pId = RID_SVXITEMS_TRANSPARENT_TRUE;
3055         rText += EditResId(pId);
3056     }
3057     else
3058     {
3059         rText = EditResId(RID_SVXITEMS_GRAPHIC);
3060     }
3061 
3062     return true;
3063 }
3064 
operator ==(const SfxPoolItem & rAttr) const3065 bool SvxBrushItem::operator==( const SfxPoolItem& rAttr ) const
3066 {
3067     assert(SfxPoolItem::operator==(rAttr));
3068 
3069     const SvxBrushItem& rCmp = static_cast<const SvxBrushItem&>(rAttr);
3070     bool bEqual = ( aColor == rCmp.aColor && eGraphicPos == rCmp.eGraphicPos &&
3071         nGraphicTransparency == rCmp.nGraphicTransparency);
3072 
3073     if ( bEqual )
3074     {
3075         if ( GPOS_NONE != eGraphicPos )
3076         {
3077             bEqual = maStrLink == rCmp.maStrLink;
3078 
3079             if ( bEqual )
3080             {
3081                 bEqual = maStrFilter == rCmp.maStrFilter;
3082             }
3083 
3084             if ( bEqual )
3085             {
3086                 if (!rCmp.xGraphicObject)
3087                     bEqual = !xGraphicObject;
3088                 else
3089                     bEqual = xGraphicObject &&
3090                              (*xGraphicObject == *rCmp.xGraphicObject);
3091             }
3092         }
3093 
3094         if (bEqual)
3095         {
3096             bEqual = nShadingValue == rCmp.nShadingValue;
3097         }
3098     }
3099 
3100     return bEqual;
3101 }
3102 
3103 
Clone(SfxItemPool *) const3104 SfxPoolItem* SvxBrushItem::Clone( SfxItemPool* ) const
3105 {
3106     return new SvxBrushItem( *this );
3107 }
3108 
3109 
GetGraphicObject(OUString const & referer) const3110 const GraphicObject* SvxBrushItem::GetGraphicObject(OUString const & referer) const
3111 {
3112     if (bLoadAgain && !maStrLink.isEmpty() && !xGraphicObject)
3113     // when graphics already loaded, use as a cache
3114     {
3115         if (maSecOptions.isUntrustedReferer(referer)) {
3116             return nullptr;
3117         }
3118 
3119         // tdf#94088 prepare graphic and state
3120         Graphic aGraphic;
3121         bool bGraphicLoaded = false;
3122 
3123         // try to create stream directly from given URL
3124         std::unique_ptr<SvStream> xStream(utl::UcbStreamHelper::CreateStream(maStrLink, StreamMode::STD_READ));
3125         // tdf#94088 if we have a stream, try to load it directly as graphic
3126         if (xStream && !xStream->GetError())
3127         {
3128             if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, maStrLink, *xStream,
3129                 GRFILTER_FORMAT_DONTKNOW, nullptr, GraphicFilterImportFlags::DontSetLogsizeForJpeg))
3130             {
3131                 bGraphicLoaded = true;
3132             }
3133         }
3134 
3135         // tdf#94088 if no succeeded, try if the string (which is not empty) contains
3136         // a 'data:' scheme url and try to load that (embedded graphics)
3137         if(!bGraphicLoaded)
3138         {
3139             INetURLObject aGraphicURL( maStrLink );
3140 
3141             if( INetProtocol::Data == aGraphicURL.GetProtocol() )
3142             {
3143                 std::unique_ptr<SvMemoryStream> const xMemStream(aGraphicURL.getData());
3144                 if (xMemStream)
3145                 {
3146                     if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, "", *xMemStream))
3147                     {
3148                         bGraphicLoaded = true;
3149 
3150                         // tdf#94088 delete the no longer needed data scheme URL which
3151                         // is potentially pretty // large, containing a base64 encoded copy of the graphic
3152                         const_cast< SvxBrushItem* >(this)->maStrLink.clear();
3153                     }
3154                 }
3155             }
3156         }
3157 
3158         // tdf#94088 when we got a graphic, set it
3159         if(bGraphicLoaded && GraphicType::NONE != aGraphic.GetType())
3160         {
3161             xGraphicObject.reset(new GraphicObject);
3162             xGraphicObject->SetGraphic(aGraphic);
3163             const_cast < SvxBrushItem*> (this)->ApplyGraphicTransparency_Impl();
3164         }
3165         else
3166         {
3167             bLoadAgain = false;
3168         }
3169     }
3170 
3171     return xGraphicObject.get();
3172 }
3173 
setGraphicTransparency(sal_Int8 nNew)3174 void SvxBrushItem::setGraphicTransparency(sal_Int8 nNew)
3175 {
3176     if (nNew != nGraphicTransparency)
3177     {
3178         nGraphicTransparency = nNew;
3179         ApplyGraphicTransparency_Impl();
3180     }
3181 }
3182 
GetGraphic(OUString const & referer) const3183 const Graphic* SvxBrushItem::GetGraphic(OUString const & referer) const
3184 {
3185     const GraphicObject* pGrafObj = GetGraphicObject(referer);
3186     return( pGrafObj ? &( pGrafObj->GetGraphic() ) : nullptr );
3187 }
3188 
SetGraphicPos(SvxGraphicPosition eNew)3189 void SvxBrushItem::SetGraphicPos( SvxGraphicPosition eNew )
3190 {
3191     eGraphicPos = eNew;
3192 
3193     if ( GPOS_NONE == eGraphicPos )
3194     {
3195         xGraphicObject.reset();
3196         maStrLink.clear();
3197         maStrFilter.clear();
3198     }
3199     else
3200     {
3201         if (!xGraphicObject && maStrLink.isEmpty())
3202         {
3203             xGraphicObject.reset(new GraphicObject); // Creating a dummy
3204         }
3205     }
3206 }
3207 
SetGraphic(const Graphic & rNew)3208 void SvxBrushItem::SetGraphic( const Graphic& rNew )
3209 {
3210     if ( maStrLink.isEmpty() )
3211     {
3212         if (xGraphicObject)
3213             xGraphicObject->SetGraphic(rNew);
3214         else
3215             xGraphicObject.reset(new GraphicObject(rNew));
3216 
3217         ApplyGraphicTransparency_Impl();
3218 
3219         if ( GPOS_NONE == eGraphicPos )
3220             eGraphicPos = GPOS_MM; // None would be brush, then Default: middle
3221     }
3222     else
3223     {
3224         OSL_FAIL( "SetGraphic() on linked graphic! :-/" );
3225     }
3226 }
3227 
SetGraphicObject(const GraphicObject & rNewObj)3228 void SvxBrushItem::SetGraphicObject( const GraphicObject& rNewObj )
3229 {
3230     if ( maStrLink.isEmpty() )
3231     {
3232         if (xGraphicObject)
3233             *xGraphicObject = rNewObj;
3234         else
3235             xGraphicObject.reset(new GraphicObject(rNewObj));
3236 
3237         ApplyGraphicTransparency_Impl();
3238 
3239         if ( GPOS_NONE == eGraphicPos )
3240             eGraphicPos = GPOS_MM; // None would be brush, then Default: middle
3241     }
3242     else
3243     {
3244         OSL_FAIL( "SetGraphic() on linked graphic! :-/" );
3245     }
3246 }
3247 
SetGraphicLink(const OUString & rNew)3248 void SvxBrushItem::SetGraphicLink( const OUString& rNew )
3249 {
3250     if ( rNew.isEmpty() )
3251         maStrLink.clear();
3252     else
3253     {
3254         maStrLink = rNew;
3255         xGraphicObject.reset();
3256     }
3257 }
3258 
SetGraphicFilter(const OUString & rNew)3259 void SvxBrushItem::SetGraphicFilter( const OUString& rNew )
3260 {
3261     maStrFilter = rNew;
3262 }
3263 
ApplyGraphicTransparency_Impl()3264 void SvxBrushItem::ApplyGraphicTransparency_Impl()
3265 {
3266     DBG_ASSERT(xGraphicObject, "no GraphicObject available" );
3267     if (xGraphicObject)
3268     {
3269         GraphicAttr aAttr(xGraphicObject->GetAttr());
3270         aAttr.SetTransparency(lcl_PercentToTransparency(
3271                             nGraphicTransparency));
3272         xGraphicObject->SetAttr(aAttr);
3273     }
3274 }
3275 
dumpAsXml(xmlTextWriterPtr pWriter) const3276 void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) const
3277 {
3278     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBrushItem"));
3279     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
3280     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"), BAD_CAST(aColor.AsRGBHexString().toUtf8().getStr()));
3281     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("shadingValue"), BAD_CAST(OString::number(nShadingValue).getStr()));
3282     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("link"), BAD_CAST(maStrLink.toUtf8().getStr()));
3283     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filter"), BAD_CAST(maStrFilter.toUtf8().getStr()));
3284     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("graphicPos"), BAD_CAST(OString::number(eGraphicPos).getStr()));
3285     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("loadAgain"), BAD_CAST(OString::boolean(bLoadAgain).getStr()));
3286     xmlTextWriterEndElement(pWriter);
3287 }
3288 
3289 
SvxFrameDirectionItem(SvxFrameDirection nValue,sal_uInt16 _nWhich)3290 SvxFrameDirectionItem::SvxFrameDirectionItem( SvxFrameDirection nValue ,
3291                                             sal_uInt16 _nWhich )
3292     : SfxEnumItem<SvxFrameDirection>( _nWhich, nValue )
3293 {
3294 }
3295 
3296 
~SvxFrameDirectionItem()3297 SvxFrameDirectionItem::~SvxFrameDirectionItem()
3298 {
3299 }
3300 
3301 
Clone(SfxItemPool *) const3302 SfxPoolItem* SvxFrameDirectionItem::Clone( SfxItemPool * ) const
3303 {
3304     return new SvxFrameDirectionItem( *this );
3305 }
3306 
3307 
getFrmDirResId(size_t nIndex)3308 const char* getFrmDirResId(size_t nIndex)
3309 {
3310     const char* const RID_SVXITEMS_FRMDIR[] =
3311     {
3312         RID_SVXITEMS_FRMDIR_HORI_LEFT_TOP,
3313         RID_SVXITEMS_FRMDIR_HORI_RIGHT_TOP,
3314         RID_SVXITEMS_FRMDIR_VERT_TOP_RIGHT,
3315         RID_SVXITEMS_FRMDIR_VERT_TOP_LEFT,
3316         RID_SVXITEMS_FRMDIR_ENVIRONMENT,
3317         RID_SVXITEMS_FRMDIR_VERT_BOT_LEFT
3318     };
3319     return RID_SVXITEMS_FRMDIR[nIndex];
3320 }
3321 
GetPresentation(SfxItemPresentation,MapUnit,MapUnit,OUString & rText,const IntlWrapper &) const3322 bool SvxFrameDirectionItem::GetPresentation(
3323     SfxItemPresentation /*ePres*/,
3324     MapUnit             /*eCoreUnit*/,
3325     MapUnit             /*ePresUnit*/,
3326     OUString&           rText, const IntlWrapper&) const
3327 {
3328     rText = EditResId(getFrmDirResId(GetEnumValue()));
3329     return true;
3330 }
3331 
PutValue(const css::uno::Any & rVal,sal_uInt8)3332 bool SvxFrameDirectionItem::PutValue( const css::uno::Any& rVal,
3333                                              sal_uInt8 )
3334 {
3335     sal_Int16 nVal = sal_Int16();
3336     bool bRet = ( rVal >>= nVal );
3337     if( bRet )
3338     {
3339         // translate WritingDirection2 constants into SvxFrameDirection
3340         switch( nVal )
3341         {
3342             case text::WritingMode2::LR_TB:
3343                 SetValue( SvxFrameDirection::Horizontal_LR_TB );
3344                 break;
3345             case text::WritingMode2::RL_TB:
3346                 SetValue( SvxFrameDirection::Horizontal_RL_TB );
3347                 break;
3348             case text::WritingMode2::TB_RL:
3349                 SetValue( SvxFrameDirection::Vertical_RL_TB );
3350                 break;
3351             case text::WritingMode2::TB_LR:
3352                 SetValue( SvxFrameDirection::Vertical_LR_TB );
3353                 break;
3354             case text::WritingMode2::BT_LR:
3355                 SetValue( SvxFrameDirection::Vertical_LR_BT );
3356                 break;
3357             case text::WritingMode2::PAGE:
3358                 SetValue( SvxFrameDirection::Environment );
3359                 break;
3360             default:
3361                 bRet = false;
3362                 break;
3363         }
3364     }
3365 
3366     return bRet;
3367 }
3368 
3369 
QueryValue(css::uno::Any & rVal,sal_uInt8) const3370 bool SvxFrameDirectionItem::QueryValue( css::uno::Any& rVal,
3371                                             sal_uInt8 ) const
3372 {
3373     // translate SvxFrameDirection into WritingDirection2
3374     sal_Int16 nVal;
3375     bool bRet = true;
3376     switch( GetValue() )
3377     {
3378         case SvxFrameDirection::Horizontal_LR_TB:
3379             nVal = text::WritingMode2::LR_TB;
3380             break;
3381         case SvxFrameDirection::Horizontal_RL_TB:
3382             nVal = text::WritingMode2::RL_TB;
3383             break;
3384         case SvxFrameDirection::Vertical_RL_TB:
3385             nVal = text::WritingMode2::TB_RL;
3386             break;
3387         case SvxFrameDirection::Vertical_LR_TB:
3388             nVal = text::WritingMode2::TB_LR;
3389             break;
3390         case SvxFrameDirection::Vertical_LR_BT:
3391             nVal = text::WritingMode2::BT_LR;
3392             break;
3393         case SvxFrameDirection::Environment:
3394             nVal = text::WritingMode2::PAGE;
3395             break;
3396         default:
3397             OSL_FAIL("Unknown SvxFrameDirection value!");
3398             bRet = false;
3399             break;
3400     }
3401 
3402     // return value + error state
3403     if( bRet )
3404     {
3405         rVal <<= nVal;
3406     }
3407     return bRet;
3408 }
3409 
dumpAsXml(xmlTextWriterPtr pWriter) const3410 void SvxFrameDirectionItem::dumpAsXml(xmlTextWriterPtr pWriter) const
3411 {
3412     xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFrameDirectionItem"));
3413     xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nWhich"),
3414                                 BAD_CAST(OString::number(Which()).getStr()));
3415     xmlTextWriterWriteAttribute(
3416         pWriter, BAD_CAST("m_nValue"),
3417         BAD_CAST(OString::number(static_cast<sal_Int16>(GetValue())).getStr()));
3418     xmlTextWriterEndElement(pWriter);
3419 }
3420 
3421 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
3422