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