Use o3tl::convert in Math
[LibreOffice.git] / editeng / source / items / frmitems.cxx
blob45ac886d5c506fe454d5513e366650cded903225
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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 #include <unotools/securityoptions.hxx>
77 #include <boost/property_tree/ptree.hpp>
79 using namespace ::editeng;
80 using namespace ::com::sun::star;
81 using namespace ::com::sun::star::drawing;
82 using namespace ::com::sun::star::table::BorderLineStyle;
85 SfxPoolItem* SvxPaperBinItem::CreateDefault() { return new SvxPaperBinItem(0);}
86 SfxPoolItem* SvxSizeItem::CreateDefault() { return new SvxSizeItem(0);}
87 SfxPoolItem* SvxLRSpaceItem::CreateDefault() { return new SvxLRSpaceItem(0);}
88 SfxPoolItem* SvxULSpaceItem::CreateDefault() { return new SvxULSpaceItem(0);}
89 SfxPoolItem* SvxProtectItem::CreateDefault() { return new SvxProtectItem(0);}
90 SfxPoolItem* SvxBrushItem::CreateDefault() { return new SvxBrushItem(0);}
91 SfxPoolItem* SvxShadowItem::CreateDefault() { return new SvxShadowItem(0);}
92 SfxPoolItem* SvxBoxItem::CreateDefault() { return new SvxBoxItem(0);}
93 SfxPoolItem* SvxBoxInfoItem::CreateDefault() { return new SvxBoxInfoItem(0);}
94 SfxPoolItem* SvxFormatBreakItem::CreateDefault() { return new SvxFormatBreakItem(SvxBreak::NONE, 0);}
95 SfxPoolItem* SvxFormatKeepItem::CreateDefault() { return new SvxFormatKeepItem(false, 0);}
96 SfxPoolItem* SvxLineItem::CreateDefault() { return new SvxLineItem(0);}
98 SvxPaperBinItem* SvxPaperBinItem::Clone( SfxItemPool* ) const
100 return new SvxPaperBinItem( *this );
103 bool SvxPaperBinItem::GetPresentation
105 SfxItemPresentation ePres,
106 MapUnit /*eCoreUnit*/,
107 MapUnit /*ePresUnit*/,
108 OUString& rText, const IntlWrapper&
109 ) const
111 switch ( ePres )
113 case SfxItemPresentation::Nameless:
114 rText = OUString::number( GetValue() );
115 return true;
117 case SfxItemPresentation::Complete:
119 sal_uInt8 nValue = GetValue();
121 if ( PAPERBIN_PRINTER_SETTINGS == nValue )
122 rText = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS);
123 else
125 rText = EditResId(RID_SVXSTR_PAPERBIN) + " " + OUString::number( nValue );
127 return true;
129 //no break necessary
130 default: ; //prevent warning
133 return false;
137 SvxSizeItem::SvxSizeItem( const sal_uInt16 nId, const Size& rSize ) :
139 SfxPoolItem( nId ),
141 m_aSize( rSize )
146 bool SvxSizeItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
148 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
149 nMemberId &= ~CONVERT_TWIPS;
151 awt::Size aTmp(m_aSize.Width(), m_aSize.Height());
152 if( bConvert )
154 aTmp.Height = convertTwipToMm100(aTmp.Height);
155 aTmp.Width = convertTwipToMm100(aTmp.Width);
158 switch( nMemberId )
160 case MID_SIZE_SIZE: rVal <<= aTmp; break;
161 case MID_SIZE_WIDTH: rVal <<= aTmp.Width; break;
162 case MID_SIZE_HEIGHT: rVal <<= aTmp.Height; break;
163 default: OSL_FAIL("Wrong MemberId!"); return false;
166 return true;
170 bool SvxSizeItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
172 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
173 nMemberId &= ~CONVERT_TWIPS;
175 switch( nMemberId )
177 case MID_SIZE_SIZE:
179 awt::Size aTmp;
180 if( rVal >>= aTmp )
182 if(bConvert)
184 aTmp.Height = o3tl::toTwips(aTmp.Height, o3tl::Length::mm100);
185 aTmp.Width = o3tl::toTwips(aTmp.Width, o3tl::Length::mm100);
187 m_aSize = Size( aTmp.Width, aTmp.Height );
189 else
191 return false;
194 break;
195 case MID_SIZE_WIDTH:
197 sal_Int32 nVal = 0;
198 if(!(rVal >>= nVal ))
199 return false;
201 m_aSize.setWidth( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal );
203 break;
204 case MID_SIZE_HEIGHT:
206 sal_Int32 nVal = 0;
207 if(!(rVal >>= nVal))
208 return true;
210 m_aSize.setHeight( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal );
212 break;
213 default: OSL_FAIL("Wrong MemberId!");
214 return false;
216 return true;
220 SvxSizeItem::SvxSizeItem( const sal_uInt16 nId ) :
222 SfxPoolItem( nId )
227 bool SvxSizeItem::operator==( const SfxPoolItem& rAttr ) const
229 assert(SfxPoolItem::operator==(rAttr));
231 return ( m_aSize == static_cast<const SvxSizeItem&>( rAttr ).GetSize() );
234 SvxSizeItem* SvxSizeItem::Clone( SfxItemPool* ) const
236 return new SvxSizeItem( *this );
239 bool SvxSizeItem::GetPresentation
241 SfxItemPresentation ePres,
242 MapUnit eCoreUnit,
243 MapUnit ePresUnit,
244 OUString& rText, const IntlWrapper& rIntl
245 ) const
247 OUString cpDelimTmp(cpDelim);
248 switch ( ePres )
250 case SfxItemPresentation::Nameless:
251 rText = GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) +
252 cpDelimTmp +
253 GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl );
254 return true;
256 case SfxItemPresentation::Complete:
257 rText = EditResId(RID_SVXITEMS_SIZE_WIDTH) +
258 GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) +
259 " " + EditResId(GetMetricId(ePresUnit)) +
260 cpDelimTmp +
261 EditResId(RID_SVXITEMS_SIZE_HEIGHT) +
262 GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl ) +
263 " " + EditResId(GetMetricId(ePresUnit));
264 return true;
265 // no break necessary
266 default: ; // prevent warning
269 return false;
273 void SvxSizeItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
275 m_aSize.setWidth( BigInt::Scale( m_aSize.Width(), nMult, nDiv ) );
276 m_aSize.setHeight( BigInt::Scale( m_aSize.Height(), nMult, nDiv ) );
280 bool SvxSizeItem::HasMetrics() const
282 return true;
286 SvxLRSpaceItem::SvxLRSpaceItem( const sal_uInt16 nId ) :
288 SfxPoolItem( nId ),
290 nTxtLeft ( 0 ),
291 nLeftMargin ( 0 ),
292 nRightMargin ( 0 ),
293 m_nGutterMargin(0),
294 m_nRightGutterMargin(0),
295 nPropFirstLineOffset( 100 ),
296 nPropLeftMargin( 100 ),
297 nPropRightMargin( 100 ),
298 nFirstLineOffset ( 0 ),
299 bAutoFirst ( false ),
300 bExplicitZeroMarginValRight(false),
301 bExplicitZeroMarginValLeft(false)
306 SvxLRSpaceItem::SvxLRSpaceItem( const tools::Long nLeft, const tools::Long nRight,
307 const tools::Long nTLeft, const short nOfset,
308 const sal_uInt16 nId )
309 : SfxPoolItem( nId ),
311 nTxtLeft ( nTLeft ),
312 nLeftMargin ( nLeft ),
313 nRightMargin ( nRight ),
314 m_nGutterMargin(0),
315 m_nRightGutterMargin(0),
316 nPropFirstLineOffset( 100 ),
317 nPropLeftMargin( 100 ),
318 nPropRightMargin( 100 ),
319 nFirstLineOffset ( nOfset ),
320 bAutoFirst ( false ),
321 bExplicitZeroMarginValRight(false),
322 bExplicitZeroMarginValLeft(false)
327 bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
329 bool bRet = true;
330 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
331 nMemberId &= ~CONVERT_TWIPS;
332 switch( nMemberId )
334 // now all signed
335 case 0:
337 css::frame::status::LeftRightMarginScale aLRSpace;
338 aLRSpace.Left = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin);
339 aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft);
340 aLRSpace.Right = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin);
341 aLRSpace.ScaleLeft = static_cast<sal_Int16>(nPropLeftMargin);
342 aLRSpace.ScaleRight = static_cast<sal_Int16>(nPropRightMargin);
343 aLRSpace.FirstLine = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOffset) : nFirstLineOffset);
344 aLRSpace.ScaleFirstLine = static_cast<sal_Int16>(nPropFirstLineOffset);
345 aLRSpace.AutoFirstLine = IsAutoFirst();
346 rVal <<= aLRSpace;
347 break;
349 case MID_L_MARGIN:
350 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin);
351 break;
353 case MID_TXT_LMARGIN :
354 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft);
355 break;
356 case MID_R_MARGIN:
357 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin);
358 break;
359 case MID_L_REL_MARGIN:
360 rVal <<= static_cast<sal_Int16>(nPropLeftMargin);
361 break;
362 case MID_R_REL_MARGIN:
363 rVal <<= static_cast<sal_Int16>(nPropRightMargin);
364 break;
366 case MID_FIRST_LINE_INDENT:
367 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOffset) : nFirstLineOffset);
368 break;
370 case MID_FIRST_LINE_REL_INDENT:
371 rVal <<= static_cast<sal_Int16>(nPropFirstLineOffset);
372 break;
374 case MID_FIRST_AUTO:
375 rVal <<= IsAutoFirst();
376 break;
378 case MID_GUTTER_MARGIN:
379 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nGutterMargin)
380 : m_nGutterMargin);
381 break;
383 default:
384 bRet = false;
385 // 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?
386 OSL_FAIL("unknown MemberId");
388 return bRet;
392 bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
394 bool bConvert = 0 != (nMemberId&CONVERT_TWIPS);
395 nMemberId &= ~CONVERT_TWIPS;
396 sal_Int32 nVal = 0;
397 if( nMemberId != 0 && nMemberId != MID_FIRST_AUTO &&
398 nMemberId != MID_L_REL_MARGIN && nMemberId != MID_R_REL_MARGIN)
399 if(!(rVal >>= nVal))
400 return false;
402 switch( nMemberId )
404 case 0:
406 css::frame::status::LeftRightMarginScale aLRSpace;
407 if(!(rVal >>= aLRSpace))
408 return false;
410 SetLeft( bConvert ? o3tl::toTwips(aLRSpace.Left, o3tl::Length::mm100) : aLRSpace.Left );
411 SetTextLeft( bConvert ? o3tl::toTwips(aLRSpace.TextLeft, o3tl::Length::mm100) : aLRSpace.TextLeft );
412 SetRight(bConvert ? o3tl::toTwips(aLRSpace.Right, o3tl::Length::mm100) : aLRSpace.Right);
413 nPropLeftMargin = aLRSpace.ScaleLeft;
414 nPropRightMargin = aLRSpace.ScaleRight;
415 SetTextFirstLineOffset(bConvert ? o3tl::toTwips(aLRSpace.FirstLine, o3tl::Length::mm100) : aLRSpace.FirstLine);
416 SetPropTextFirstLineOffset ( aLRSpace.ScaleFirstLine );
417 SetAutoFirst( aLRSpace.AutoFirstLine );
418 break;
420 case MID_L_MARGIN:
421 SetLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal );
422 break;
424 case MID_TXT_LMARGIN :
425 SetTextLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal );
426 break;
428 case MID_R_MARGIN:
429 SetRight(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal);
430 break;
431 case MID_L_REL_MARGIN:
432 case MID_R_REL_MARGIN:
434 sal_Int32 nRel = 0;
435 if((rVal >>= nRel) && nRel >= 0 && nRel < SAL_MAX_UINT16)
437 if(MID_L_REL_MARGIN== nMemberId)
438 nPropLeftMargin = static_cast<sal_uInt16>(nRel);
439 else
440 nPropRightMargin = static_cast<sal_uInt16>(nRel);
442 else
443 return false;
445 break;
446 case MID_FIRST_LINE_INDENT :
447 SetTextFirstLineOffset(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal);
448 break;
450 case MID_FIRST_LINE_REL_INDENT:
451 SetPropTextFirstLineOffset ( nVal );
452 break;
454 case MID_FIRST_AUTO:
455 SetAutoFirst( Any2Bool(rVal) );
456 break;
458 case MID_GUTTER_MARGIN:
459 SetGutterMargin(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal);
460 break;
462 default:
463 OSL_FAIL("unknown MemberId");
464 return false;
466 return true;
470 /// Adapt nLeftMargin and nTxtLeft.
471 void SvxLRSpaceItem::AdjustLeft()
473 if ( 0 > nFirstLineOffset )
474 nLeftMargin = nTxtLeft + nFirstLineOffset;
475 else
476 nLeftMargin = nTxtLeft;
480 bool SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const
482 assert(SfxPoolItem::operator==(rAttr));
484 const SvxLRSpaceItem& rOther = static_cast<const SvxLRSpaceItem&>(rAttr);
486 return (
487 nFirstLineOffset == rOther.GetTextFirstLineOffset() &&
488 nTxtLeft == rOther.GetTextLeft() &&
489 m_nGutterMargin == rOther.GetGutterMargin() &&
490 m_nRightGutterMargin == rOther.GetRightGutterMargin() &&
491 nLeftMargin == rOther.GetLeft() &&
492 nRightMargin == rOther.GetRight() &&
493 nPropFirstLineOffset == rOther.GetPropTextFirstLineOffset() &&
494 nPropLeftMargin == rOther.GetPropLeft() &&
495 nPropRightMargin == rOther.GetPropRight() &&
496 bAutoFirst == rOther.IsAutoFirst() &&
497 bExplicitZeroMarginValRight == rOther.IsExplicitZeroMarginValRight() &&
498 bExplicitZeroMarginValLeft == rOther.IsExplicitZeroMarginValLeft() );
501 SvxLRSpaceItem* SvxLRSpaceItem::Clone( SfxItemPool* ) const
503 return new SvxLRSpaceItem( *this );
506 bool SvxLRSpaceItem::GetPresentation
508 SfxItemPresentation ePres,
509 MapUnit eCoreUnit,
510 MapUnit ePresUnit,
511 OUString& rText, const IntlWrapper& rIntl
512 ) const
514 switch ( ePres )
516 case SfxItemPresentation::Nameless:
518 if ( 100 != nPropLeftMargin )
520 rText = unicode::formatPercent(nPropLeftMargin,
521 Application::GetSettings().GetUILanguageTag());
523 else
524 rText = GetMetricText( nLeftMargin,
525 eCoreUnit, ePresUnit, &rIntl );
526 rText += cpDelim;
527 if ( 100 != nPropFirstLineOffset )
529 rText += unicode::formatPercent(nPropFirstLineOffset,
530 Application::GetSettings().GetUILanguageTag());
532 else
533 rText += GetMetricText( static_cast<tools::Long>(nFirstLineOffset),
534 eCoreUnit, ePresUnit, &rIntl );
535 rText += cpDelim;
536 if ( 100 != nRightMargin )
538 rText += unicode::formatPercent(nRightMargin,
539 Application::GetSettings().GetUILanguageTag());
541 else
542 rText += GetMetricText( nRightMargin,
543 eCoreUnit, ePresUnit, &rIntl );
544 return true;
546 case SfxItemPresentation::Complete:
548 rText = EditResId(RID_SVXITEMS_LRSPACE_LEFT);
549 if ( 100 != nPropLeftMargin )
550 rText += unicode::formatPercent(nPropLeftMargin,
551 Application::GetSettings().GetUILanguageTag());
552 else
554 rText += GetMetricText( nLeftMargin, eCoreUnit, ePresUnit, &rIntl ) +
555 " " + EditResId(GetMetricId(ePresUnit));
557 rText += cpDelim;
558 if ( 100 != nPropFirstLineOffset || nFirstLineOffset )
560 rText += EditResId(RID_SVXITEMS_LRSPACE_FLINE);
561 if ( 100 != nPropFirstLineOffset )
562 rText += unicode::formatPercent(nPropFirstLineOffset,
563 Application::GetSettings().GetUILanguageTag());
564 else
566 rText += GetMetricText( static_cast<tools::Long>(nFirstLineOffset),
567 eCoreUnit, ePresUnit, &rIntl ) +
568 " " + EditResId(GetMetricId(ePresUnit));
570 rText += cpDelim;
572 rText += EditResId(RID_SVXITEMS_LRSPACE_RIGHT);
573 if ( 100 != nPropRightMargin )
574 rText += unicode::formatPercent(nPropRightMargin,
575 Application::GetSettings().GetUILanguageTag());
576 else
578 rText += GetMetricText( nRightMargin,
579 eCoreUnit, ePresUnit, &rIntl ) +
580 " " + EditResId(GetMetricId(ePresUnit));
582 return true;
584 default: ; // prevent warning
586 return false;
590 void SvxLRSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
592 nFirstLineOffset = static_cast<short>(BigInt::Scale( nFirstLineOffset, nMult, nDiv ));
593 nTxtLeft = BigInt::Scale( nTxtLeft, nMult, nDiv );
594 nLeftMargin = BigInt::Scale( nLeftMargin, nMult, nDiv );
595 nRightMargin = BigInt::Scale( nRightMargin, nMult, nDiv );
599 bool SvxLRSpaceItem::HasMetrics() const
601 return true;
605 void SvxLRSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const
607 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxLRSpaceItem"));
608 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
609 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nFirstLineOffset"), BAD_CAST(OString::number(nFirstLineOffset).getStr()));
610 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nTxtLeft"), BAD_CAST(OString::number(nTxtLeft).getStr()));
611 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeftMargin"), BAD_CAST(OString::number(nLeftMargin).getStr()));
612 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRightMargin"), BAD_CAST(OString::number(nRightMargin).getStr()));
613 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nGutterMargin"),
614 BAD_CAST(OString::number(m_nGutterMargin).getStr()));
615 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightGutterMargin"),
616 BAD_CAST(OString::number(m_nRightGutterMargin).getStr()));
617 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropFirstLineOffset"), BAD_CAST(OString::number(nPropFirstLineOffset).getStr()));
618 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLeftMargin"), BAD_CAST(OString::number(nPropLeftMargin).getStr()));
619 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropRightMargin"), BAD_CAST(OString::number(nPropRightMargin).getStr()));
620 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAutoFirst"), BAD_CAST(OString::number(int(bAutoFirst)).getStr()));
621 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValRight"), BAD_CAST(OString::number(int(bExplicitZeroMarginValRight)).getStr()));
622 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValLeft"), BAD_CAST(OString::number(int(bExplicitZeroMarginValLeft)).getStr()));
623 (void)xmlTextWriterEndElement(pWriter);
627 boost::property_tree::ptree SvxLRSpaceItem::dumpAsJSON() const
629 boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
631 boost::property_tree::ptree aState;
633 MapUnit eTargetUnit = MapUnit::MapInch;
635 OUString sLeft = GetMetricText(GetLeft(),
636 MapUnit::MapTwip, eTargetUnit, nullptr);
638 OUString sRight = GetMetricText(GetRight(),
639 MapUnit::MapTwip, eTargetUnit, nullptr);
641 OUString sFirstline = GetMetricText(GetTextFirstLineOffset(),
642 MapUnit::MapTwip, eTargetUnit, nullptr);
644 aState.put("left", sLeft);
645 aState.put("right", sRight);
646 aState.put("firstline", sFirstline);
647 aState.put("unit", "inch");
649 aTree.push_back(std::make_pair("state", aState));
651 return aTree;
655 SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nId )
656 : SfxPoolItem(nId)
657 , nUpper(0)
658 , nLower(0)
659 , bContext(false)
660 , nPropUpper(100)
661 , nPropLower(100)
666 SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nUp, const sal_uInt16 nLow,
667 const sal_uInt16 nId )
668 : SfxPoolItem(nId)
669 , nUpper(nUp)
670 , nLower(nLow)
671 , bContext(false)
672 , nPropUpper(100)
673 , nPropLower(100)
678 bool SvxULSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
680 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
681 nMemberId &= ~CONVERT_TWIPS;
682 switch( nMemberId )
684 // now all signed
685 case 0:
687 css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
688 aUpperLowerMarginScale.Upper = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper);
689 aUpperLowerMarginScale.Lower = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nPropUpper);
690 aUpperLowerMarginScale.ScaleUpper = static_cast<sal_Int16>(nPropUpper);
691 aUpperLowerMarginScale.ScaleLower = static_cast<sal_Int16>(nPropLower);
692 rVal <<= aUpperLowerMarginScale;
693 break;
695 case MID_UP_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper); break;
696 case MID_LO_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nLower); break;
697 case MID_CTX_MARGIN: rVal <<= bContext; break;
698 case MID_UP_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropUpper); break;
699 case MID_LO_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropLower); break;
701 return true;
705 bool SvxULSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
707 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
708 nMemberId &= ~CONVERT_TWIPS;
709 sal_Int32 nVal = 0;
710 bool bVal = false;
711 switch( nMemberId )
713 case 0:
715 css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale;
716 if ( !(rVal >>= aUpperLowerMarginScale ))
717 return false;
719 SetUpper(bConvert ? o3tl::toTwips(aUpperLowerMarginScale.Upper, o3tl::Length::mm100) : aUpperLowerMarginScale.Upper);
720 SetLower(bConvert ? o3tl::toTwips(aUpperLowerMarginScale.Lower, o3tl::Length::mm100) : aUpperLowerMarginScale.Lower);
721 if( aUpperLowerMarginScale.ScaleUpper > 1 )
722 nPropUpper = aUpperLowerMarginScale.ScaleUpper;
723 if( aUpperLowerMarginScale.ScaleLower > 1 )
724 nPropUpper = aUpperLowerMarginScale.ScaleLower;
727 break;
728 case MID_UP_MARGIN :
729 if(!(rVal >>= nVal))
730 return false;
731 SetUpper(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal);
732 break;
733 case MID_LO_MARGIN :
734 if(!(rVal >>= nVal) || nVal < 0)
735 return false;
736 SetLower(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal);
737 break;
738 case MID_CTX_MARGIN :
739 if (!(rVal >>= bVal))
740 return false;
741 SetContextValue(bVal);
742 break;
743 case MID_UP_REL_MARGIN:
744 case MID_LO_REL_MARGIN:
746 sal_Int32 nRel = 0;
747 if((rVal >>= nRel) && nRel > 1 )
749 if(MID_UP_REL_MARGIN == nMemberId)
750 nPropUpper = static_cast<sal_uInt16>(nRel);
751 else
752 nPropLower = static_cast<sal_uInt16>(nRel);
754 else
755 return false;
757 break;
759 default:
760 OSL_FAIL("unknown MemberId");
761 return false;
763 return true;
767 bool SvxULSpaceItem::operator==( const SfxPoolItem& rAttr ) const
769 assert(SfxPoolItem::operator==(rAttr));
771 const SvxULSpaceItem& rSpaceItem = static_cast<const SvxULSpaceItem&>( rAttr );
772 return ( nUpper == rSpaceItem.nUpper &&
773 nLower == rSpaceItem.nLower &&
774 bContext == rSpaceItem.bContext &&
775 nPropUpper == rSpaceItem.nPropUpper &&
776 nPropLower == rSpaceItem.nPropLower );
779 SvxULSpaceItem* SvxULSpaceItem::Clone( SfxItemPool* ) const
781 return new SvxULSpaceItem( *this );
784 bool SvxULSpaceItem::GetPresentation
786 SfxItemPresentation ePres,
787 MapUnit eCoreUnit,
788 MapUnit ePresUnit,
789 OUString& rText,
790 const IntlWrapper& rIntl
791 ) const
793 switch ( ePres )
795 case SfxItemPresentation::Nameless:
797 if ( 100 != nPropUpper )
799 rText = unicode::formatPercent(nPropUpper,
800 Application::GetSettings().GetUILanguageTag());
802 else
803 rText = GetMetricText( static_cast<tools::Long>(nUpper), eCoreUnit, ePresUnit, &rIntl );
804 rText += cpDelim;
805 if ( 100 != nPropLower )
807 rText += unicode::formatPercent(nPropLower,
808 Application::GetSettings().GetUILanguageTag());
810 else
811 rText += GetMetricText( static_cast<tools::Long>(nLower), eCoreUnit, ePresUnit, &rIntl );
812 return true;
814 case SfxItemPresentation::Complete:
816 rText = EditResId(RID_SVXITEMS_ULSPACE_UPPER);
817 if ( 100 != nPropUpper )
819 rText += unicode::formatPercent(nPropUpper,
820 Application::GetSettings().GetUILanguageTag());
822 else
824 rText += GetMetricText( static_cast<tools::Long>(nUpper), eCoreUnit, ePresUnit, &rIntl ) +
825 " " + EditResId(GetMetricId(ePresUnit));
827 rText += cpDelim + EditResId(RID_SVXITEMS_ULSPACE_LOWER);
828 if ( 100 != nPropLower )
830 rText += unicode::formatPercent(nPropLower,
831 Application::GetSettings().GetUILanguageTag());
833 else
835 rText += GetMetricText( static_cast<tools::Long>(nLower), eCoreUnit, ePresUnit, &rIntl ) +
836 " " + EditResId(GetMetricId(ePresUnit));
838 return true;
840 default: ; // prevent warning
842 return false;
846 void SvxULSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
848 nUpper = static_cast<sal_uInt16>(BigInt::Scale( nUpper, nMult, nDiv ));
849 nLower = static_cast<sal_uInt16>(BigInt::Scale( nLower, nMult, nDiv ));
853 bool SvxULSpaceItem::HasMetrics() const
855 return true;
859 void SvxULSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const
861 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxULSpaceItem"));
862 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
863 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(nUpper).getStr()));
864 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(nLower).getStr()));
865 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContext"), BAD_CAST(OString::boolean(bContext).getStr()));
866 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropUpper"), BAD_CAST(OString::number(nPropUpper).getStr()));
867 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLower"), BAD_CAST(OString::number(nPropLower).getStr()));
868 (void)xmlTextWriterEndElement(pWriter);
871 boost::property_tree::ptree SvxULSpaceItem::dumpAsJSON() const
873 boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
875 boost::property_tree::ptree aState;
877 MapUnit eTargetUnit = MapUnit::MapInch;
879 OUString sUpper = GetMetricText(GetUpper(),
880 MapUnit::MapTwip, eTargetUnit, nullptr);
882 OUString sLower = GetMetricText(GetLower(),
883 MapUnit::MapTwip, eTargetUnit, nullptr);
885 aState.put("upper", sUpper);
886 aState.put("lower", sLower);
887 aState.put("unit", "inch");
889 aTree.push_back(std::make_pair("state", aState));
891 return aTree;
894 SvxPrintItem* SvxPrintItem::Clone( SfxItemPool* ) const
896 return new SvxPrintItem( *this );
899 bool SvxPrintItem::GetPresentation
901 SfxItemPresentation /*ePres*/,
902 MapUnit /*eCoreUnit*/,
903 MapUnit /*ePresUnit*/,
904 OUString& rText, const IntlWrapper&
905 ) const
907 TranslateId pId = RID_SVXITEMS_PRINT_FALSE;
909 if ( GetValue() )
910 pId = RID_SVXITEMS_PRINT_TRUE;
911 rText = EditResId(pId);
912 return true;
915 SvxOpaqueItem* SvxOpaqueItem::Clone( SfxItemPool* ) const
917 return new SvxOpaqueItem( *this );
920 bool SvxOpaqueItem::GetPresentation
922 SfxItemPresentation /*ePres*/,
923 MapUnit /*eCoreUnit*/,
924 MapUnit /*ePresUnit*/,
925 OUString& rText, const IntlWrapper&
926 ) const
928 TranslateId pId = RID_SVXITEMS_OPAQUE_FALSE;
930 if ( GetValue() )
931 pId = RID_SVXITEMS_OPAQUE_TRUE;
932 rText = EditResId(pId);
933 return true;
937 bool SvxProtectItem::operator==( const SfxPoolItem& rAttr ) const
939 assert(SfxPoolItem::operator==(rAttr));
941 const SvxProtectItem& rItem = static_cast<const SvxProtectItem&>(rAttr);
942 return ( bCntnt == rItem.bCntnt &&
943 bSize == rItem.bSize &&
944 bPos == rItem.bPos );
948 bool SvxProtectItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
950 nMemberId &= ~CONVERT_TWIPS;
951 bool bValue;
952 switch(nMemberId)
954 case MID_PROTECT_CONTENT : bValue = bCntnt; break;
955 case MID_PROTECT_SIZE : bValue = bSize; break;
956 case MID_PROTECT_POSITION: bValue = bPos; break;
957 default:
958 OSL_FAIL("Wrong MemberId");
959 return false;
962 rVal <<= bValue;
963 return true;
967 bool SvxProtectItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
969 nMemberId &= ~CONVERT_TWIPS;
970 bool bVal( Any2Bool(rVal) );
971 switch(nMemberId)
973 case MID_PROTECT_CONTENT : bCntnt = bVal; break;
974 case MID_PROTECT_SIZE : bSize = bVal; break;
975 case MID_PROTECT_POSITION: bPos = bVal; break;
976 default:
977 OSL_FAIL("Wrong MemberId");
978 return false;
980 return true;
983 SvxProtectItem* SvxProtectItem::Clone( SfxItemPool* ) const
985 return new SvxProtectItem( *this );
988 bool SvxProtectItem::GetPresentation
990 SfxItemPresentation /*ePres*/,
991 MapUnit /*eCoreUnit*/,
992 MapUnit /*ePresUnit*/,
993 OUString& rText, const IntlWrapper&
994 ) const
996 TranslateId pId = RID_SVXITEMS_PROT_CONTENT_FALSE;
998 if ( bCntnt )
999 pId = RID_SVXITEMS_PROT_CONTENT_TRUE;
1000 rText = EditResId(pId) + cpDelim;
1001 pId = RID_SVXITEMS_PROT_SIZE_FALSE;
1003 if ( bSize )
1004 pId = RID_SVXITEMS_PROT_SIZE_TRUE;
1005 rText += EditResId(pId) + cpDelim;
1006 pId = RID_SVXITEMS_PROT_POS_FALSE;
1008 if ( bPos )
1009 pId = RID_SVXITEMS_PROT_POS_TRUE;
1010 rText += EditResId(pId);
1011 return true;
1015 void SvxProtectItem::dumpAsXml(xmlTextWriterPtr pWriter) const
1017 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxProtectItem"));
1018 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1019 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("content"), BAD_CAST(OString::boolean(bCntnt).getStr()));
1020 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(OString::boolean(bSize).getStr()));
1021 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("position"), BAD_CAST(OString::boolean(bPos).getStr()));
1022 (void)xmlTextWriterEndElement(pWriter);
1026 SvxShadowItem::SvxShadowItem( const sal_uInt16 nId,
1027 const Color *pColor, const sal_uInt16 nW,
1028 const SvxShadowLocation eLoc ) :
1029 SfxEnumItemInterface( nId ),
1030 aShadowColor(COL_GRAY),
1031 nWidth ( nW ),
1032 eLocation ( eLoc )
1034 if ( pColor )
1035 aShadowColor = *pColor;
1039 bool SvxShadowItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1041 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1042 nMemberId &= ~CONVERT_TWIPS;
1044 table::ShadowFormat aShadow;
1045 table::ShadowLocation eSet = table::ShadowLocation_NONE;
1046 switch( eLocation )
1048 case SvxShadowLocation::TopLeft : eSet = table::ShadowLocation_TOP_LEFT ; break;
1049 case SvxShadowLocation::TopRight : eSet = table::ShadowLocation_TOP_RIGHT ; break;
1050 case SvxShadowLocation::BottomLeft : eSet = table::ShadowLocation_BOTTOM_LEFT ; break;
1051 case SvxShadowLocation::BottomRight: eSet = table::ShadowLocation_BOTTOM_RIGHT; break;
1052 default: ; // prevent warning
1054 aShadow.Location = eSet;
1055 aShadow.ShadowWidth = bConvert ? convertTwipToMm100(nWidth) : nWidth;
1056 aShadow.IsTransparent = aShadowColor.IsTransparent();
1057 aShadow.Color = sal_Int32(aShadowColor);
1059 sal_Int8 nTransparence = rtl::math::round((float(255 - aShadowColor.GetAlpha()) * 100) / 255);
1061 switch ( nMemberId )
1063 case MID_LOCATION: rVal <<= aShadow.Location; break;
1064 case MID_WIDTH: rVal <<= aShadow.ShadowWidth; break;
1065 case MID_TRANSPARENT: rVal <<= aShadow.IsTransparent; break;
1066 case MID_BG_COLOR: rVal <<= aShadow.Color; break;
1067 case 0: rVal <<= aShadow; break;
1068 case MID_SHADOW_TRANSPARENCE: rVal <<= nTransparence; break;
1069 default: OSL_FAIL("Wrong MemberId!"); return false;
1072 return true;
1075 bool SvxShadowItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1077 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1078 nMemberId &= ~CONVERT_TWIPS;
1080 table::ShadowFormat aShadow;
1081 uno::Any aAny;
1082 bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aShadow );
1083 switch ( nMemberId )
1085 case MID_LOCATION:
1087 bRet = (rVal >>= aShadow.Location);
1088 if ( !bRet )
1090 sal_Int16 nVal = 0;
1091 bRet = (rVal >>= nVal);
1092 aShadow.Location = static_cast<table::ShadowLocation>(nVal);
1095 break;
1098 case MID_WIDTH: rVal >>= aShadow.ShadowWidth; break;
1099 case MID_TRANSPARENT: rVal >>= aShadow.IsTransparent; break;
1100 case MID_BG_COLOR: rVal >>= aShadow.Color; break;
1101 case 0: rVal >>= aShadow; break;
1102 case MID_SHADOW_TRANSPARENCE:
1104 sal_Int32 nTransparence = 0;
1105 if ((rVal >>= nTransparence) && !o3tl::checked_multiply<sal_Int32>(nTransparence, 255, nTransparence))
1107 Color aColor(ColorTransparency, aShadow.Color);
1108 aColor.SetAlpha(255 - rtl::math::round(float(nTransparence) / 100));
1109 aShadow.Color = sal_Int32(aColor);
1111 break;
1113 default: OSL_FAIL("Wrong MemberId!"); return false;
1116 if ( bRet )
1118 switch( aShadow.Location )
1120 case table::ShadowLocation_NONE : eLocation = SvxShadowLocation::NONE; break;
1121 case table::ShadowLocation_TOP_LEFT : eLocation = SvxShadowLocation::TopLeft; break;
1122 case table::ShadowLocation_TOP_RIGHT : eLocation = SvxShadowLocation::TopRight; break;
1123 case table::ShadowLocation_BOTTOM_LEFT : eLocation = SvxShadowLocation::BottomLeft ; break;
1124 case table::ShadowLocation_BOTTOM_RIGHT: eLocation = SvxShadowLocation::BottomRight; break;
1125 default: ; // prevent warning
1128 nWidth = bConvert ? o3tl::toTwips(aShadow.ShadowWidth, o3tl::Length::mm100) : aShadow.ShadowWidth;
1129 Color aSet(ColorTransparency, aShadow.Color);
1130 aShadowColor = aSet;
1133 return bRet;
1137 bool SvxShadowItem::operator==( const SfxPoolItem& rAttr ) const
1139 assert(SfxPoolItem::operator==(rAttr));
1141 const SvxShadowItem& rItem = static_cast<const SvxShadowItem&>(rAttr);
1142 return ( ( aShadowColor == rItem.aShadowColor ) &&
1143 ( nWidth == rItem.GetWidth() ) &&
1144 ( eLocation == rItem.GetLocation() ) );
1147 SvxShadowItem* SvxShadowItem::Clone( SfxItemPool* ) const
1149 return new SvxShadowItem( *this );
1152 sal_uInt16 SvxShadowItem::CalcShadowSpace( SvxShadowItemSide nShadow ) const
1154 sal_uInt16 nSpace = 0;
1156 switch ( nShadow )
1158 case SvxShadowItemSide::TOP:
1159 if ( eLocation == SvxShadowLocation::TopLeft ||
1160 eLocation == SvxShadowLocation::TopRight )
1161 nSpace = nWidth;
1162 break;
1164 case SvxShadowItemSide::BOTTOM:
1165 if ( eLocation == SvxShadowLocation::BottomLeft ||
1166 eLocation == SvxShadowLocation::BottomRight )
1167 nSpace = nWidth;
1168 break;
1170 case SvxShadowItemSide::LEFT:
1171 if ( eLocation == SvxShadowLocation::TopLeft ||
1172 eLocation == SvxShadowLocation::BottomLeft )
1173 nSpace = nWidth;
1174 break;
1176 case SvxShadowItemSide::RIGHT:
1177 if ( eLocation == SvxShadowLocation::TopRight ||
1178 eLocation == SvxShadowLocation::BottomRight )
1179 nSpace = nWidth;
1180 break;
1182 default:
1183 OSL_FAIL( "wrong shadow" );
1185 return nSpace;
1188 static TranslateId RID_SVXITEMS_SHADOW[] =
1190 RID_SVXITEMS_SHADOW_NONE,
1191 RID_SVXITEMS_SHADOW_TOPLEFT,
1192 RID_SVXITEMS_SHADOW_TOPRIGHT,
1193 RID_SVXITEMS_SHADOW_BOTTOMLEFT,
1194 RID_SVXITEMS_SHADOW_BOTTOMRIGHT
1197 bool SvxShadowItem::GetPresentation
1199 SfxItemPresentation ePres,
1200 MapUnit eCoreUnit,
1201 MapUnit ePresUnit,
1202 OUString& rText, const IntlWrapper& rIntl
1203 ) const
1205 switch ( ePres )
1207 case SfxItemPresentation::Nameless:
1209 rText = ::GetColorString( aShadowColor ) + cpDelim;
1210 TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE;
1212 if ( aShadowColor.IsTransparent() )
1213 pId = RID_SVXITEMS_TRANSPARENT_TRUE;
1214 rText += EditResId(pId) +
1215 cpDelim +
1216 GetMetricText( static_cast<tools::Long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) +
1217 cpDelim +
1218 EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]);
1219 return true;
1221 case SfxItemPresentation::Complete:
1223 rText = EditResId(RID_SVXITEMS_SHADOW_COMPLETE) +
1224 ::GetColorString( aShadowColor ) +
1225 cpDelim;
1227 TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE;
1228 if ( aShadowColor.IsTransparent() )
1229 pId = RID_SVXITEMS_TRANSPARENT_TRUE;
1230 rText += EditResId(pId) +
1231 cpDelim +
1232 GetMetricText( static_cast<tools::Long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) +
1233 " " + EditResId(GetMetricId(ePresUnit)) +
1234 cpDelim +
1235 EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]);
1236 return true;
1238 default: ; // prevent warning
1240 return false;
1244 void SvxShadowItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
1246 nWidth = static_cast<sal_uInt16>(BigInt::Scale( nWidth, nMult, nDiv ));
1250 bool SvxShadowItem::HasMetrics() const
1252 return true;
1256 sal_uInt16 SvxShadowItem::GetValueCount() const
1258 return sal_uInt16(SvxShadowLocation::End); // SvxShadowLocation::BottomRight + 1
1261 sal_uInt16 SvxShadowItem::GetEnumValue() const
1263 return static_cast<sal_uInt16>(GetLocation());
1267 void SvxShadowItem::SetEnumValue( sal_uInt16 nVal )
1269 SetLocation( static_cast<SvxShadowLocation>(nVal) );
1272 void SvxShadowItem::dumpAsXml(xmlTextWriterPtr pWriter) const
1274 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxShadowItem"));
1275 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
1276 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aShadowColor"), BAD_CAST(aShadowColor.AsRGBHexString().toUtf8().getStr()));
1277 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(nWidth).getStr()));
1278 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLocation"), BAD_CAST(OString::number(static_cast<int>(eLocation)).getStr()));
1279 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]).toUtf8().getStr()));
1280 (void)xmlTextWriterEndElement(pWriter);
1283 // class SvxBoxItem ------------------------------------------------------
1285 SvxBoxItem::SvxBoxItem( const SvxBoxItem& rCpy ) :
1287 SfxPoolItem ( rCpy ),
1288 pTop ( rCpy.pTop ? new SvxBorderLine( *rCpy.pTop ) : nullptr ),
1289 pBottom ( rCpy.pBottom ? new SvxBorderLine( *rCpy.pBottom ) : nullptr ),
1290 pLeft ( rCpy.pLeft ? new SvxBorderLine( *rCpy.pLeft ) : nullptr ),
1291 pRight ( rCpy.pRight ? new SvxBorderLine( *rCpy.pRight ) : nullptr ),
1292 nTopDist ( rCpy.nTopDist ),
1293 nBottomDist ( rCpy.nBottomDist ),
1294 nLeftDist ( rCpy.nLeftDist ),
1295 nRightDist ( rCpy.nRightDist ),
1296 bRemoveAdjCellBorder ( rCpy.bRemoveAdjCellBorder )
1301 SvxBoxItem::SvxBoxItem( const sal_uInt16 nId ) :
1302 SfxPoolItem( nId ),
1303 nTopDist ( 0 ),
1304 nBottomDist ( 0 ),
1305 nLeftDist ( 0 ),
1306 nRightDist ( 0 ),
1307 bRemoveAdjCellBorder ( false )
1312 SvxBoxItem::~SvxBoxItem()
1317 boost::property_tree::ptree SvxBoxItem::dumpAsJSON() const
1319 boost::property_tree::ptree aTree;
1321 boost::property_tree::ptree aState;
1322 aState.put("top", GetTop() && !GetTop()->isEmpty());
1323 aState.put("bottom", GetBottom() && !GetBottom()->isEmpty());
1324 aState.put("left", GetLeft() && !GetLeft()->isEmpty());
1325 aState.put("right", GetRight() && !GetRight()->isEmpty());
1327 aTree.push_back(std::make_pair("state", aState));
1328 aTree.put("commandName", ".uno:BorderOuter");
1330 return aTree;
1334 static bool CmpBrdLn( const std::unique_ptr<SvxBorderLine> & pBrd1, const SvxBorderLine* pBrd2 )
1336 if( pBrd1.get() == pBrd2 )
1337 return true;
1338 if( pBrd1 == nullptr || pBrd2 == nullptr)
1339 return false;
1340 return *pBrd1 == *pBrd2;
1344 bool SvxBoxItem::operator==( const SfxPoolItem& rAttr ) const
1346 assert(SfxPoolItem::operator==(rAttr));
1348 const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(rAttr);
1349 return (
1350 ( nTopDist == rBoxItem.nTopDist ) &&
1351 ( nBottomDist == rBoxItem.nBottomDist ) &&
1352 ( nLeftDist == rBoxItem.nLeftDist ) &&
1353 ( nRightDist == rBoxItem.nRightDist ) &&
1354 ( bRemoveAdjCellBorder == rBoxItem.bRemoveAdjCellBorder ) &&
1355 CmpBrdLn( pTop, rBoxItem.GetTop() ) &&
1356 CmpBrdLn( pBottom, rBoxItem.GetBottom() ) &&
1357 CmpBrdLn( pLeft, rBoxItem.GetLeft() ) &&
1358 CmpBrdLn( pRight, rBoxItem.GetRight() ) );
1362 table::BorderLine2 SvxBoxItem::SvxLineToLine(const SvxBorderLine* pLine, bool bConvert)
1364 table::BorderLine2 aLine;
1365 if(pLine)
1367 aLine.Color = sal_Int32(pLine->GetColor());
1368 aLine.InnerLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetInWidth() ): pLine->GetInWidth() );
1369 aLine.OuterLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetOutWidth()): pLine->GetOutWidth() );
1370 aLine.LineDistance = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetDistance()): pLine->GetDistance() );
1371 aLine.LineStyle = sal_Int16(pLine->GetBorderLineStyle());
1372 aLine.LineWidth = sal_uInt32( bConvert ? convertTwipToMm100( pLine->GetWidth( ) ) : pLine->GetWidth( ) );
1374 else
1375 aLine.Color = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance = 0;
1376 return aLine;
1379 bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
1381 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1382 table::BorderLine2 aRetLine;
1383 sal_uInt16 nDist = 0;
1384 bool bDistMember = false;
1385 nMemberId &= ~CONVERT_TWIPS;
1386 switch(nMemberId)
1388 case 0:
1390 // 4 Borders and 5 distances
1391 uno::Sequence< uno::Any > aSeq{
1392 uno::Any(SvxBoxItem::SvxLineToLine(GetLeft(), bConvert)),
1393 uno::Any(SvxBoxItem::SvxLineToLine(GetRight(), bConvert)),
1394 uno::Any(SvxBoxItem::SvxLineToLine(GetBottom(), bConvert)),
1395 uno::Any(SvxBoxItem::SvxLineToLine(GetTop(), bConvert)),
1396 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( GetSmallestDistance()) : GetSmallestDistance())),
1397 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nTopDist ) : nTopDist )),
1398 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nBottomDist ) : nBottomDist )),
1399 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nLeftDist ) : nLeftDist )),
1400 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nRightDist ) : nRightDist ))
1402 rVal <<= aSeq;
1403 return true;
1405 case MID_LEFT_BORDER:
1406 case LEFT_BORDER:
1407 aRetLine = SvxBoxItem::SvxLineToLine(GetLeft(), bConvert);
1408 break;
1409 case MID_RIGHT_BORDER:
1410 case RIGHT_BORDER:
1411 aRetLine = SvxBoxItem::SvxLineToLine(GetRight(), bConvert);
1412 break;
1413 case MID_BOTTOM_BORDER:
1414 case BOTTOM_BORDER:
1415 aRetLine = SvxBoxItem::SvxLineToLine(GetBottom(), bConvert);
1416 break;
1417 case MID_TOP_BORDER:
1418 case TOP_BORDER:
1419 aRetLine = SvxBoxItem::SvxLineToLine(GetTop(), bConvert);
1420 break;
1421 case BORDER_DISTANCE:
1422 nDist = GetSmallestDistance();
1423 bDistMember = true;
1424 break;
1425 case TOP_BORDER_DISTANCE:
1426 nDist = nTopDist;
1427 bDistMember = true;
1428 break;
1429 case BOTTOM_BORDER_DISTANCE:
1430 nDist = nBottomDist;
1431 bDistMember = true;
1432 break;
1433 case LEFT_BORDER_DISTANCE:
1434 nDist = nLeftDist;
1435 bDistMember = true;
1436 break;
1437 case RIGHT_BORDER_DISTANCE:
1438 nDist = nRightDist;
1439 bDistMember = true;
1440 break;
1441 case LINE_STYLE:
1442 case LINE_WIDTH:
1443 // it doesn't make sense to return a value for these since it's
1444 // probably ambiguous
1445 return true;
1448 if( bDistMember )
1449 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nDist) : nDist);
1450 else
1451 rVal <<= aRetLine;
1453 return true;
1456 namespace
1459 bool
1460 lcl_lineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert, bool bGuessWidth)
1462 rSvxLine.SetColor( Color(ColorTransparency, rLine.Color));
1463 if ( bGuessWidth )
1465 rSvxLine.GuessLinesWidths( rSvxLine.GetBorderLineStyle(),
1466 bConvert ? o3tl::toTwips(rLine.OuterLineWidth, o3tl::Length::mm100) : rLine.OuterLineWidth,
1467 bConvert ? o3tl::toTwips(rLine.InnerLineWidth, o3tl::Length::mm100) : rLine.InnerLineWidth,
1468 bConvert ? o3tl::toTwips(rLine.LineDistance, o3tl::Length::mm100) : rLine.LineDistance );
1471 bool bRet = !rSvxLine.isEmpty();
1472 return bRet;
1478 bool SvxBoxItem::LineToSvxLine(const css::table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert)
1480 return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, true);
1483 bool
1484 SvxBoxItem::LineToSvxLine(const css::table::BorderLine2& rLine, SvxBorderLine& rSvxLine, bool bConvert)
1486 SvxBorderLineStyle const nStyle =
1487 (rLine.LineStyle < 0 || BORDER_LINE_STYLE_MAX < rLine.LineStyle)
1488 ? SvxBorderLineStyle::SOLID // default
1489 : static_cast<SvxBorderLineStyle>(rLine.LineStyle);
1491 rSvxLine.SetBorderLineStyle( nStyle );
1493 bool bGuessWidth = true;
1494 if ( rLine.LineWidth )
1496 rSvxLine.SetWidth( bConvert? o3tl::toTwips(rLine.LineWidth, o3tl::Length::mm100) : rLine.LineWidth );
1497 // fdo#46112: double does not necessarily mean symmetric
1498 // for backwards compatibility
1499 bGuessWidth = (SvxBorderLineStyle::DOUBLE == nStyle || SvxBorderLineStyle::DOUBLE_THIN == nStyle) &&
1500 (rLine.InnerLineWidth > 0) && (rLine.OuterLineWidth > 0);
1503 return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, bGuessWidth);
1507 namespace
1510 bool
1511 lcl_extractBorderLine(const uno::Any& rAny, table::BorderLine2& rLine)
1513 if (rAny >>= rLine)
1514 return true;
1516 table::BorderLine aBorderLine;
1517 if (rAny >>= aBorderLine)
1519 rLine.Color = aBorderLine.Color;
1520 rLine.InnerLineWidth = aBorderLine.InnerLineWidth;
1521 rLine.OuterLineWidth = aBorderLine.OuterLineWidth;
1522 rLine.LineDistance = aBorderLine.LineDistance;
1523 rLine.LineStyle = table::BorderLineStyle::SOLID;
1524 return true;
1527 return false;
1530 template<typename Item, typename Line>
1531 bool
1532 lcl_setLine(const uno::Any& rAny, Item& rItem, Line nLine, const bool bConvert)
1534 bool bDone = false;
1535 table::BorderLine2 aBorderLine;
1536 if (lcl_extractBorderLine(rAny, aBorderLine))
1538 SvxBorderLine aLine;
1539 bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
1540 rItem.SetLine( bSet ? &aLine : nullptr, nLine);
1541 bDone = true;
1543 return bDone;
1548 bool SvxBoxItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
1550 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
1551 SvxBoxItemLine nLine = SvxBoxItemLine::TOP;
1552 bool bDistMember = false;
1553 nMemberId &= ~CONVERT_TWIPS;
1554 switch(nMemberId)
1556 case 0:
1558 uno::Sequence< uno::Any > aSeq;
1559 if (( rVal >>= aSeq ) && ( aSeq.getLength() == 9 ))
1561 // 4 Borders and 5 distances
1562 const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP };
1563 for (int n(0); n != SAL_N_ELEMENTS(aBorders); ++n)
1565 if (!lcl_setLine(aSeq[n], *this, aBorders[n], bConvert))
1566 return false;
1569 // WTH are the borders and the distances saved in different order?
1570 SvxBoxItemLine const nLines[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT };
1571 for ( sal_Int32 n = 4; n < 9; n++ )
1573 sal_Int32 nDist = 0;
1574 if ( aSeq[n] >>= nDist )
1576 if( bConvert )
1577 nDist = o3tl::toTwips(nDist, o3tl::Length::mm100);
1578 if ( n == 4 )
1579 SetAllDistances(nDist);
1580 else
1581 SetDistance( nDist, nLines[n-5] );
1583 else
1584 return false;
1587 return true;
1589 else
1590 return false;
1592 case LEFT_BORDER_DISTANCE:
1593 bDistMember = true;
1594 [[fallthrough]];
1595 case LEFT_BORDER:
1596 case MID_LEFT_BORDER:
1597 nLine = SvxBoxItemLine::LEFT;
1598 break;
1599 case RIGHT_BORDER_DISTANCE:
1600 bDistMember = true;
1601 [[fallthrough]];
1602 case RIGHT_BORDER:
1603 case MID_RIGHT_BORDER:
1604 nLine = SvxBoxItemLine::RIGHT;
1605 break;
1606 case BOTTOM_BORDER_DISTANCE:
1607 bDistMember = true;
1608 [[fallthrough]];
1609 case BOTTOM_BORDER:
1610 case MID_BOTTOM_BORDER:
1611 nLine = SvxBoxItemLine::BOTTOM;
1612 break;
1613 case TOP_BORDER_DISTANCE:
1614 bDistMember = true;
1615 [[fallthrough]];
1616 case TOP_BORDER:
1617 case MID_TOP_BORDER:
1618 nLine = SvxBoxItemLine::TOP;
1619 break;
1620 case LINE_STYLE:
1622 drawing::LineStyle eDrawingStyle;
1623 rVal >>= eDrawingStyle;
1624 SvxBorderLineStyle eBorderStyle = SvxBorderLineStyle::NONE;
1625 switch ( eDrawingStyle )
1627 default:
1628 case drawing::LineStyle_NONE:
1629 break;
1630 case drawing::LineStyle_SOLID:
1631 eBorderStyle = SvxBorderLineStyle::SOLID;
1632 break;
1633 case drawing::LineStyle_DASH:
1634 eBorderStyle = SvxBorderLineStyle::DASHED;
1635 break;
1638 // Set the line style on all borders
1639 for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() )
1641 editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) );
1642 if( pLine )
1643 pLine->SetBorderLineStyle( eBorderStyle );
1645 return true;
1647 break;
1648 case LINE_WIDTH:
1650 // Set the line width on all borders
1651 tools::Long nWidth(0);
1652 rVal >>= nWidth;
1653 if( bConvert )
1654 nWidth = o3tl::toTwips(nWidth, o3tl::Length::mm100);
1656 // Set the line Width on all borders
1657 for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() )
1659 editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) );
1660 if( pLine )
1661 pLine->SetWidth( nWidth );
1664 return true;
1667 if( bDistMember || nMemberId == BORDER_DISTANCE )
1669 sal_Int32 nDist = 0;
1670 if(!(rVal >>= nDist))
1671 return false;
1673 if(nDist >= 0)
1675 if( bConvert )
1676 nDist = o3tl::toTwips(nDist, o3tl::Length::mm100);
1677 if( nMemberId == BORDER_DISTANCE )
1678 SetAllDistances(nDist);
1679 else
1680 SetDistance( nDist, nLine );
1683 else
1685 SvxBorderLine aLine;
1686 if( !rVal.hasValue() )
1687 return false;
1689 table::BorderLine2 aBorderLine;
1690 if( lcl_extractBorderLine(rVal, aBorderLine) )
1692 // usual struct
1694 else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
1696 // serialization for basic macro recording
1697 uno::Reference < script::XTypeConverter > xConverter
1698 ( script::Converter::create(::comphelper::getProcessComponentContext()) );
1699 uno::Sequence < uno::Any > aSeq;
1700 uno::Any aNew;
1701 try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); }
1702 catch (const uno::Exception&) {}
1704 aNew >>= aSeq;
1705 if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6)
1707 sal_Int32 nVal = 0;
1708 if ( aSeq[0] >>= nVal )
1709 aBorderLine.Color = nVal;
1710 if ( aSeq[1] >>= nVal )
1711 aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal);
1712 if ( aSeq[2] >>= nVal )
1713 aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal);
1714 if ( aSeq[3] >>= nVal )
1715 aBorderLine.LineDistance = static_cast<sal_Int16>(nVal);
1716 if (aSeq.getLength() >= 5) // fdo#40874 added fields
1718 if (aSeq[4] >>= nVal)
1720 aBorderLine.LineStyle = nVal;
1722 if (aSeq.getLength() >= 6)
1724 if (aSeq[5] >>= nVal)
1726 aBorderLine.LineWidth = nVal;
1731 else
1732 return false;
1734 else
1735 return false;
1737 bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
1738 SetLine(bSet ? &aLine : nullptr, nLine);
1741 return true;
1744 SvxBoxItem* SvxBoxItem::Clone( SfxItemPool* ) const
1746 return new SvxBoxItem( *this );
1749 bool SvxBoxItem::GetPresentation
1751 SfxItemPresentation ePres,
1752 MapUnit eCoreUnit,
1753 MapUnit ePresUnit,
1754 OUString& rText, const IntlWrapper& rIntl
1755 ) const
1757 OUString cpDelimTmp(cpDelim);
1758 switch ( ePres )
1760 case SfxItemPresentation::Nameless:
1762 rText.clear();
1764 if ( pTop )
1766 rText = pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1768 if( !(pTop && pBottom && pLeft && pRight &&
1769 *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) )
1771 if ( pBottom )
1773 rText += pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1775 if ( pLeft )
1777 rText += pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1779 if ( pRight )
1781 rText += pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp;
1784 rText += GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit, ePresUnit, &rIntl );
1785 if( nTopDist != nBottomDist || nTopDist != nLeftDist ||
1786 nTopDist != nRightDist )
1788 rText += cpDelimTmp +
1789 GetMetricText( static_cast<tools::Long>(nBottomDist), eCoreUnit,
1790 ePresUnit, &rIntl ) +
1791 cpDelimTmp +
1792 GetMetricText( static_cast<tools::Long>(nLeftDist), eCoreUnit, ePresUnit, &rIntl ) +
1793 cpDelimTmp +
1794 GetMetricText( static_cast<tools::Long>(nRightDist), eCoreUnit,
1795 ePresUnit, &rIntl );
1797 return true;
1799 case SfxItemPresentation::Complete:
1801 if( !(pTop || pBottom || pLeft || pRight) )
1803 rText = EditResId(RID_SVXITEMS_BORDER_NONE) + cpDelimTmp;
1805 else
1807 rText = EditResId(RID_SVXITEMS_BORDER_COMPLETE);
1808 if( pTop && pBottom && pLeft && pRight &&
1809 *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight )
1811 rText += pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + cpDelimTmp;
1813 else
1815 if ( pTop )
1817 rText += EditResId(RID_SVXITEMS_BORDER_TOP) +
1818 pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1819 cpDelimTmp;
1821 if ( pBottom )
1823 rText += EditResId(RID_SVXITEMS_BORDER_BOTTOM) +
1824 pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1825 cpDelimTmp;
1827 if ( pLeft )
1829 rText += EditResId(RID_SVXITEMS_BORDER_LEFT) +
1830 pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1831 cpDelimTmp;
1833 if ( pRight )
1835 rText += EditResId(RID_SVXITEMS_BORDER_RIGHT) +
1836 pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) +
1837 cpDelimTmp;
1842 rText += EditResId(RID_SVXITEMS_BORDER_DISTANCE);
1843 if( nTopDist == nBottomDist && nTopDist == nLeftDist &&
1844 nTopDist == nRightDist )
1846 rText += GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit,
1847 ePresUnit, &rIntl ) +
1848 " " + EditResId(GetMetricId(ePresUnit));
1850 else
1852 rText += EditResId(RID_SVXITEMS_BORDER_TOP) +
1853 GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit,
1854 ePresUnit, &rIntl ) +
1855 " " + EditResId(GetMetricId(ePresUnit)) +
1856 cpDelimTmp +
1857 EditResId(RID_SVXITEMS_BORDER_BOTTOM) +
1858 GetMetricText( static_cast<tools::Long>(nBottomDist), eCoreUnit,
1859 ePresUnit, &rIntl ) +
1860 " " + EditResId(GetMetricId(ePresUnit)) +
1861 cpDelimTmp +
1862 EditResId(RID_SVXITEMS_BORDER_LEFT) +
1863 GetMetricText( static_cast<tools::Long>(nLeftDist), eCoreUnit,
1864 ePresUnit, &rIntl ) +
1865 " " + EditResId(GetMetricId(ePresUnit)) +
1866 cpDelimTmp +
1867 EditResId(RID_SVXITEMS_BORDER_RIGHT) +
1868 GetMetricText( static_cast<tools::Long>(nRightDist), eCoreUnit,
1869 ePresUnit, &rIntl ) +
1870 " " + EditResId(GetMetricId(ePresUnit));
1872 return true;
1874 default: ; // prevent warning
1876 return false;
1880 void SvxBoxItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
1882 if ( pTop ) pTop->ScaleMetrics( nMult, nDiv );
1883 if ( pBottom ) pBottom->ScaleMetrics( nMult, nDiv );
1884 if ( pLeft ) pLeft->ScaleMetrics( nMult, nDiv );
1885 if ( pRight ) pRight->ScaleMetrics( nMult, nDiv );
1886 nTopDist = static_cast<sal_uInt16>(BigInt::Scale( nTopDist, nMult, nDiv ));
1887 nBottomDist = static_cast<sal_uInt16>(BigInt::Scale( nBottomDist, nMult, nDiv ));
1888 nLeftDist = static_cast<sal_uInt16>(BigInt::Scale( nLeftDist, nMult, nDiv ));
1889 nRightDist = static_cast<sal_uInt16>(BigInt::Scale( nRightDist, nMult, nDiv ));
1893 bool SvxBoxItem::HasMetrics() const
1895 return true;
1899 const SvxBorderLine *SvxBoxItem::GetLine( SvxBoxItemLine nLine ) const
1901 const SvxBorderLine *pRet = nullptr;
1903 switch ( nLine )
1905 case SvxBoxItemLine::TOP:
1906 pRet = pTop.get();
1907 break;
1908 case SvxBoxItemLine::BOTTOM:
1909 pRet = pBottom.get();
1910 break;
1911 case SvxBoxItemLine::LEFT:
1912 pRet = pLeft.get();
1913 break;
1914 case SvxBoxItemLine::RIGHT:
1915 pRet = pRight.get();
1916 break;
1917 default:
1918 OSL_FAIL( "wrong line" );
1919 break;
1922 return pRet;
1926 void SvxBoxItem::SetLine( const SvxBorderLine* pNew, SvxBoxItemLine nLine )
1928 std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr );
1930 switch ( nLine )
1932 case SvxBoxItemLine::TOP:
1933 pTop = std::move( pTmp );
1934 break;
1935 case SvxBoxItemLine::BOTTOM:
1936 pBottom = std::move( pTmp );
1937 break;
1938 case SvxBoxItemLine::LEFT:
1939 pLeft = std::move( pTmp );
1940 break;
1941 case SvxBoxItemLine::RIGHT:
1942 pRight = std::move( pTmp );
1943 break;
1944 default:
1945 OSL_FAIL( "wrong line" );
1950 sal_uInt16 SvxBoxItem::GetSmallestDistance() const
1952 // The smallest distance that is not 0 will be returned.
1953 sal_uInt16 nDist = nTopDist;
1954 if( nBottomDist && (!nDist || nBottomDist < nDist) )
1955 nDist = nBottomDist;
1956 if( nLeftDist && (!nDist || nLeftDist < nDist) )
1957 nDist = nLeftDist;
1958 if( nRightDist && (!nDist || nRightDist < nDist) )
1959 nDist = nRightDist;
1961 return nDist;
1965 sal_uInt16 SvxBoxItem::GetDistance( SvxBoxItemLine nLine ) const
1967 sal_uInt16 nDist = 0;
1968 switch ( nLine )
1970 case SvxBoxItemLine::TOP:
1971 nDist = nTopDist;
1972 break;
1973 case SvxBoxItemLine::BOTTOM:
1974 nDist = nBottomDist;
1975 break;
1976 case SvxBoxItemLine::LEFT:
1977 nDist = nLeftDist;
1978 break;
1979 case SvxBoxItemLine::RIGHT:
1980 nDist = nRightDist;
1981 break;
1982 default:
1983 OSL_FAIL( "wrong line" );
1986 return nDist;
1990 void SvxBoxItem::SetDistance( sal_uInt16 nNew, SvxBoxItemLine nLine )
1992 switch ( nLine )
1994 case SvxBoxItemLine::TOP:
1995 nTopDist = nNew;
1996 break;
1997 case SvxBoxItemLine::BOTTOM:
1998 nBottomDist = nNew;
1999 break;
2000 case SvxBoxItemLine::LEFT:
2001 nLeftDist = nNew;
2002 break;
2003 case SvxBoxItemLine::RIGHT:
2004 nRightDist = nNew;
2005 break;
2006 default:
2007 OSL_FAIL( "wrong line" );
2011 sal_uInt16 SvxBoxItem::CalcLineWidth( SvxBoxItemLine nLine ) const
2013 SvxBorderLine* pTmp = nullptr;
2014 sal_uInt16 nWidth = 0;
2015 switch ( nLine )
2017 case SvxBoxItemLine::TOP:
2018 pTmp = pTop.get();
2019 break;
2020 case SvxBoxItemLine::BOTTOM:
2021 pTmp = pBottom.get();
2022 break;
2023 case SvxBoxItemLine::LEFT:
2024 pTmp = pLeft.get();
2025 break;
2026 case SvxBoxItemLine::RIGHT:
2027 pTmp = pRight.get();
2028 break;
2029 default:
2030 OSL_FAIL( "wrong line" );
2033 if( pTmp )
2034 nWidth = pTmp->GetScaledWidth();
2036 return nWidth;
2039 sal_uInt16 SvxBoxItem::CalcLineSpace( SvxBoxItemLine nLine, bool bEvenIfNoLine ) const
2041 SvxBorderLine* pTmp = nullptr;
2042 sal_uInt16 nDist = 0;
2043 switch ( nLine )
2045 case SvxBoxItemLine::TOP:
2046 pTmp = pTop.get();
2047 nDist = nTopDist;
2048 break;
2049 case SvxBoxItemLine::BOTTOM:
2050 pTmp = pBottom.get();
2051 nDist = nBottomDist;
2052 break;
2053 case SvxBoxItemLine::LEFT:
2054 pTmp = pLeft.get();
2055 nDist = nLeftDist;
2056 break;
2057 case SvxBoxItemLine::RIGHT:
2058 pTmp = pRight.get();
2059 nDist = nRightDist;
2060 break;
2061 default:
2062 OSL_FAIL( "wrong line" );
2065 if( pTmp )
2067 nDist = nDist + pTmp->GetScaledWidth();
2069 else if( !bEvenIfNoLine )
2070 nDist = 0;
2071 return nDist;
2074 bool SvxBoxItem::HasBorder( bool bTreatPaddingAsBorder ) const
2076 return CalcLineSpace( SvxBoxItemLine::BOTTOM, bTreatPaddingAsBorder )
2077 || CalcLineSpace( SvxBoxItemLine::RIGHT, bTreatPaddingAsBorder )
2078 || CalcLineSpace( SvxBoxItemLine::TOP, bTreatPaddingAsBorder )
2079 || CalcLineSpace( SvxBoxItemLine::LEFT, bTreatPaddingAsBorder );
2082 // class SvxBoxInfoItem --------------------------------------------------
2084 SvxBoxInfoItem::SvxBoxInfoItem( const sal_uInt16 nId ) :
2085 SfxPoolItem( nId ),
2086 mbEnableHor( false ),
2087 mbEnableVer( false ),
2088 nDefDist( 0 )
2090 bDist = bMinDist = false;
2091 ResetFlags();
2095 SvxBoxInfoItem::SvxBoxInfoItem( const SvxBoxInfoItem& rCpy ) :
2096 SfxPoolItem( rCpy ),
2097 pHori( rCpy.pHori ? new SvxBorderLine( *rCpy.pHori ) : nullptr ),
2098 pVert( rCpy.pVert ? new SvxBorderLine( *rCpy.pVert ) : nullptr ),
2099 mbEnableHor( rCpy.mbEnableHor ),
2100 mbEnableVer( rCpy.mbEnableVer ),
2101 bDist( rCpy.bDist ),
2102 bMinDist ( rCpy.bMinDist ),
2103 nValidFlags( rCpy.nValidFlags ),
2104 nDefDist( rCpy.nDefDist )
2108 SvxBoxInfoItem::~SvxBoxInfoItem()
2113 boost::property_tree::ptree SvxBoxInfoItem::dumpAsJSON() const
2115 boost::property_tree::ptree aTree;
2117 boost::property_tree::ptree aState;
2118 aState.put("vertical", GetVert() && !GetVert()->isEmpty());
2119 aState.put("horizontal", GetHori() && !GetHori()->isEmpty());
2121 aTree.push_back(std::make_pair("state", aState));
2122 aTree.put("commandName", ".uno:BorderInner");
2124 return aTree;
2128 bool SvxBoxInfoItem::operator==( const SfxPoolItem& rAttr ) const
2130 assert(SfxPoolItem::operator==(rAttr));
2132 const SvxBoxInfoItem& rBoxInfo = static_cast<const SvxBoxInfoItem&>(rAttr);
2134 return ( mbEnableHor == rBoxInfo.mbEnableHor
2135 && mbEnableVer == rBoxInfo.mbEnableVer
2136 && bDist == rBoxInfo.IsDist()
2137 && bMinDist == rBoxInfo.IsMinDist()
2138 && nValidFlags == rBoxInfo.nValidFlags
2139 && nDefDist == rBoxInfo.GetDefDist()
2140 && CmpBrdLn( pHori, rBoxInfo.GetHori() )
2141 && CmpBrdLn( pVert, rBoxInfo.GetVert() )
2146 void SvxBoxInfoItem::SetLine( const SvxBorderLine* pNew, SvxBoxInfoItemLine nLine )
2148 std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr );
2150 if ( SvxBoxInfoItemLine::HORI == nLine )
2152 pHori = std::move(pTmp);
2154 else if ( SvxBoxInfoItemLine::VERT == nLine )
2156 pVert = std::move(pTmp);
2158 else
2160 OSL_FAIL( "wrong line" );
2164 SvxBoxInfoItem* SvxBoxInfoItem::Clone( SfxItemPool* ) const
2166 return new SvxBoxInfoItem( *this );
2169 bool SvxBoxInfoItem::GetPresentation
2171 SfxItemPresentation /*ePres*/,
2172 MapUnit /*eCoreUnit*/,
2173 MapUnit /*ePresUnit*/,
2174 OUString& rText, const IntlWrapper&
2175 ) const
2177 rText.clear();
2178 return false;
2182 void SvxBoxInfoItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
2184 if ( pHori ) pHori->ScaleMetrics( nMult, nDiv );
2185 if ( pVert ) pVert->ScaleMetrics( nMult, nDiv );
2186 nDefDist = static_cast<sal_uInt16>(BigInt::Scale( nDefDist, nMult, nDiv ));
2190 bool SvxBoxInfoItem::HasMetrics() const
2192 return true;
2196 void SvxBoxInfoItem::ResetFlags()
2198 nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(0x7F); // all valid except Disable
2201 bool SvxBoxInfoItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2203 bool bConvert = 0 != (nMemberId & CONVERT_TWIPS);
2204 table::BorderLine2 aRetLine;
2205 sal_Int16 nVal=0;
2206 bool bIntMember = false;
2207 nMemberId &= ~CONVERT_TWIPS;
2208 switch(nMemberId)
2210 case 0:
2212 // 2 BorderLines, flags, valid flags and distance
2213 if ( IsTable() )
2214 nVal |= 0x01;
2215 if ( IsDist() )
2216 nVal |= 0x02;
2217 if ( IsMinDist() )
2218 nVal |= 0x04;
2219 css::uno::Sequence< css::uno::Any > aSeq{
2220 uno::Any(SvxBoxItem::SvxLineToLine( pHori.get(), bConvert)),
2221 uno::Any(SvxBoxItem::SvxLineToLine( pVert.get(), bConvert)),
2222 uno::Any(nVal),
2223 uno::Any(static_cast<sal_Int16>(nValidFlags)),
2224 uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist()))
2226 rVal <<= aSeq;
2227 return true;
2230 case MID_HORIZONTAL:
2231 aRetLine = SvxBoxItem::SvxLineToLine( pHori.get(), bConvert);
2232 break;
2233 case MID_VERTICAL:
2234 aRetLine = SvxBoxItem::SvxLineToLine( pVert.get(), bConvert);
2235 break;
2236 case MID_FLAGS:
2237 bIntMember = true;
2238 if ( IsTable() )
2239 nVal |= 0x01;
2240 if ( IsDist() )
2241 nVal |= 0x02;
2242 if ( IsMinDist() )
2243 nVal |= 0x04;
2244 rVal <<= nVal;
2245 break;
2246 case MID_VALIDFLAGS:
2247 bIntMember = true;
2248 rVal <<= static_cast<sal_Int16>(nValidFlags);
2249 break;
2250 case MID_DISTANCE:
2251 bIntMember = true;
2252 rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist());
2253 break;
2254 default: OSL_FAIL("Wrong MemberId!"); return false;
2257 if( !bIntMember )
2258 rVal <<= aRetLine;
2260 return true;
2264 bool SvxBoxInfoItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2266 bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
2267 nMemberId &= ~CONVERT_TWIPS;
2268 bool bRet;
2269 switch(nMemberId)
2271 case 0:
2273 css::uno::Sequence< css::uno::Any > aSeq;
2274 if (( rVal >>= aSeq ) && ( aSeq.getLength() == 5 ))
2276 // 2 BorderLines, flags, valid flags and distance
2277 if (!lcl_setLine(aSeq[0], *this, SvxBoxInfoItemLine::HORI, bConvert))
2278 return false;
2279 if (!lcl_setLine(aSeq[1], *this, SvxBoxInfoItemLine::VERT, bConvert))
2280 return false;
2282 sal_Int16 nFlags( 0 );
2283 sal_Int32 nVal( 0 );
2284 if ( aSeq[2] >>= nFlags )
2286 SetTable ( ( nFlags & 0x01 ) != 0 );
2287 SetDist ( ( nFlags & 0x02 ) != 0 );
2288 SetMinDist( ( nFlags & 0x04 ) != 0 );
2290 else
2291 return false;
2292 if ( aSeq[3] >>= nFlags )
2293 nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags);
2294 else
2295 return false;
2296 if (( aSeq[4] >>= nVal ) && ( nVal >= 0 ))
2298 if( bConvert )
2299 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
2300 SetDefDist( nVal );
2303 return true;
2306 case MID_HORIZONTAL:
2307 case MID_VERTICAL:
2309 if( !rVal.hasValue() )
2310 return false;
2312 table::BorderLine2 aBorderLine;
2313 if( lcl_extractBorderLine(rVal, aBorderLine) )
2315 // usual struct
2317 else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE )
2319 // serialization for basic macro recording
2320 uno::Reference < script::XTypeConverter > xConverter( script::Converter::create(::comphelper::getProcessComponentContext()) );
2321 uno::Any aNew;
2322 uno::Sequence < uno::Any > aSeq;
2323 try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); }
2324 catch (const uno::Exception&) {}
2326 if ((aNew >>= aSeq) &&
2327 aSeq.getLength() >= 4 && aSeq.getLength() <= 6)
2329 sal_Int32 nVal = 0;
2330 if ( aSeq[0] >>= nVal )
2331 aBorderLine.Color = nVal;
2332 if ( aSeq[1] >>= nVal )
2333 aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal);
2334 if ( aSeq[2] >>= nVal )
2335 aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal);
2336 if ( aSeq[3] >>= nVal )
2337 aBorderLine.LineDistance = static_cast<sal_Int16>(nVal);
2338 if (aSeq.getLength() >= 5) // fdo#40874 added fields
2340 if (aSeq[4] >>= nVal)
2342 aBorderLine.LineStyle = nVal;
2344 if (aSeq.getLength() >= 6)
2346 if (aSeq[5] >>= nVal)
2348 aBorderLine.LineWidth = nVal;
2353 else
2354 return false;
2356 else if (rVal.getValueType() == cppu::UnoType<css::uno::Sequence < sal_Int16 >>::get() )
2358 // serialization for basic macro recording
2359 css::uno::Sequence < sal_Int16 > aSeq;
2360 rVal >>= aSeq;
2361 if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6)
2363 aBorderLine.Color = aSeq[0];
2364 aBorderLine.InnerLineWidth = aSeq[1];
2365 aBorderLine.OuterLineWidth = aSeq[2];
2366 aBorderLine.LineDistance = aSeq[3];
2367 if (aSeq.getLength() >= 5) // fdo#40874 added fields
2369 aBorderLine.LineStyle = aSeq[4];
2370 if (aSeq.getLength() >= 6)
2372 aBorderLine.LineWidth = aSeq[5];
2376 else
2377 return false;
2379 else
2380 return false;
2382 SvxBorderLine aLine;
2383 bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert);
2384 if ( bSet )
2385 SetLine( &aLine, nMemberId == MID_HORIZONTAL ? SvxBoxInfoItemLine::HORI : SvxBoxInfoItemLine::VERT );
2386 break;
2388 case MID_FLAGS:
2390 sal_Int16 nFlags = sal_Int16();
2391 bRet = (rVal >>= nFlags);
2392 if ( bRet )
2394 SetTable ( ( nFlags & 0x01 ) != 0 );
2395 SetDist ( ( nFlags & 0x02 ) != 0 );
2396 SetMinDist( ( nFlags & 0x04 ) != 0 );
2399 break;
2401 case MID_VALIDFLAGS:
2403 sal_Int16 nFlags = sal_Int16();
2404 bRet = (rVal >>= nFlags);
2405 if ( bRet )
2406 nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags);
2407 break;
2409 case MID_DISTANCE:
2411 sal_Int32 nVal = 0;
2412 bRet = (rVal >>= nVal);
2413 if ( bRet && nVal>=0 )
2415 if( bConvert )
2416 nVal = o3tl::toTwips(nVal, o3tl::Length::mm100);
2417 SetDefDist( static_cast<sal_uInt16>(nVal) );
2419 break;
2421 default: OSL_FAIL("Wrong MemberId!"); return false;
2424 return true;
2428 namespace editeng
2431 void BorderDistanceFromWord(bool bFromEdge, sal_Int32& nMargin, sal_Int32& nBorderDistance,
2432 sal_Int32 nBorderWidth)
2434 // See https://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder
2436 sal_Int32 nNewMargin = nMargin;
2437 sal_Int32 nNewBorderDistance = nBorderDistance;
2439 if (bFromEdge)
2441 nNewMargin = nBorderDistance;
2442 nNewBorderDistance = nMargin - nBorderDistance - nBorderWidth;
2444 else
2446 nNewMargin -= nBorderDistance + nBorderWidth;
2449 // Ensure correct distance from page edge to text in cases not supported by us:
2450 // when border is outside entire page area (!bFromEdge && BorderDistance > Margin),
2451 // and when border is inside page body area (bFromEdge && BorderDistance > Margin)
2452 if (nNewMargin < 0)
2454 nNewMargin = 0;
2455 nNewBorderDistance = std::max<sal_Int32>(nMargin - nBorderWidth, 0);
2457 else if (nNewBorderDistance < 0)
2459 nNewMargin = std::max<sal_Int32>(nMargin - nBorderWidth, 0);
2460 nNewBorderDistance = 0;
2463 nMargin = nNewMargin;
2464 nBorderDistance = nNewBorderDistance;
2467 // Heuristics to decide if we need to use "from edge" offset of borders
2469 // There are two cases when we can safely use "from text" or "from edge" offset without distorting
2470 // border position (modulo rounding errors):
2471 // 1. When distance of all borders from text is no greater than 31 pt, we use "from text"
2472 // 2. Otherwise, if distance of all borders from edge is no greater than 31 pt, we use "from edge"
2473 // In all other cases, the position of borders would be distorted on export, because Word doesn't
2474 // support the offset of >31 pts (https://msdn.microsoft.com/en-us/library/ff533820), and we need
2475 // to decide which type of offset would provide less wrong result (i.e., the result would look
2476 // closer to original). Here, we just check sum of distances from text to borders, and if it is
2477 // less than sum of distances from borders to edges. The alternative would be to compare total areas
2478 // between text-and-borders and between borders-and-edges (taking into account different lengths of
2479 // borders, and visual impact of that).
2480 void BorderDistancesToWord(const SvxBoxItem& rBox, const WordPageMargins& rMargins,
2481 WordBorderDistances& rDistances)
2483 // Use signed sal_Int32 that can hold sal_uInt16, to prevent overflow at subtraction below
2484 const sal_Int32 nT = rBox.GetDistance(SvxBoxItemLine::TOP);
2485 const sal_Int32 nL = rBox.GetDistance(SvxBoxItemLine::LEFT);
2486 const sal_Int32 nB = rBox.GetDistance(SvxBoxItemLine::BOTTOM);
2487 const sal_Int32 nR = rBox.GetDistance(SvxBoxItemLine::RIGHT);
2489 // Only take into account existing borders
2490 const SvxBorderLine* pLnT = rBox.GetLine(SvxBoxItemLine::TOP);
2491 const SvxBorderLine* pLnL = rBox.GetLine(SvxBoxItemLine::LEFT);
2492 const SvxBorderLine* pLnB = rBox.GetLine(SvxBoxItemLine::BOTTOM);
2493 const SvxBorderLine* pLnR = rBox.GetLine(SvxBoxItemLine::RIGHT);
2495 // We need to take border widths into account
2496 const tools::Long nWidthT = pLnT ? pLnT->GetScaledWidth() : 0;
2497 const tools::Long nWidthL = pLnL ? pLnL->GetScaledWidth() : 0;
2498 const tools::Long nWidthB = pLnB ? pLnB->GetScaledWidth() : 0;
2499 const tools::Long nWidthR = pLnR ? pLnR->GetScaledWidth() : 0;
2501 // Resulting distances from text to borders
2502 const sal_Int32 nT2BT = pLnT ? nT : 0;
2503 const sal_Int32 nT2BL = pLnL ? nL : 0;
2504 const sal_Int32 nT2BB = pLnB ? nB : 0;
2505 const sal_Int32 nT2BR = pLnR ? nR : 0;
2507 // Resulting distances from edge to borders
2508 const sal_Int32 nE2BT = pLnT ? std::max<sal_Int32>(rMargins.nTop - nT - nWidthT, 0) : 0;
2509 const sal_Int32 nE2BL = pLnL ? std::max<sal_Int32>(rMargins.nLeft - nL - nWidthL, 0) : 0;
2510 const sal_Int32 nE2BB = pLnB ? std::max<sal_Int32>(rMargins.nBottom - nB - nWidthB, 0) : 0;
2511 const sal_Int32 nE2BR = pLnR ? std::max<sal_Int32>(rMargins.nRight - nR - nWidthR, 0) : 0;
2513 const sal_Int32 n32pt = 32 * 20;
2514 // 1. If all borders are in range of 31 pts from text
2515 if (nT2BT < n32pt && nT2BL < n32pt && nT2BB < n32pt && nT2BR < n32pt)
2517 rDistances.bFromEdge = false;
2519 else
2521 // 2. If all borders are in range of 31 pts from edge
2522 if (nE2BT < n32pt && nE2BL < n32pt && nE2BB < n32pt && nE2BR < n32pt)
2524 rDistances.bFromEdge = true;
2526 else
2528 // Let's try to guess which would be the best approximation
2529 rDistances.bFromEdge =
2530 (nT2BT + nT2BL + nT2BB + nT2BR) > (nE2BT + nE2BL + nE2BB + nE2BR);
2534 if (rDistances.bFromEdge)
2536 rDistances.nTop = sal::static_int_cast<sal_uInt16>(nE2BT);
2537 rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nE2BL);
2538 rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nE2BB);
2539 rDistances.nRight = sal::static_int_cast<sal_uInt16>(nE2BR);
2541 else
2543 rDistances.nTop = sal::static_int_cast<sal_uInt16>(nT2BT);
2544 rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nT2BL);
2545 rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nT2BB);
2546 rDistances.nRight = sal::static_int_cast<sal_uInt16>(nT2BR);
2552 // class SvxFormatBreakItem -------------------------------------------------
2554 bool SvxFormatBreakItem::operator==( const SfxPoolItem& rAttr ) const
2556 assert(SfxPoolItem::operator==(rAttr));
2558 return GetValue() == static_cast<const SvxFormatBreakItem&>( rAttr ).GetValue();
2562 bool SvxFormatBreakItem::GetPresentation
2564 SfxItemPresentation /*ePres*/,
2565 MapUnit /*eCoreUnit*/,
2566 MapUnit /*ePresUnit*/,
2567 OUString& rText, const IntlWrapper&
2568 ) const
2570 rText = GetValueTextByPos( GetEnumValue() );
2571 return true;
2574 OUString SvxFormatBreakItem::GetValueTextByPos( sal_uInt16 nPos )
2576 static TranslateId RID_SVXITEMS_BREAK[] =
2578 RID_SVXITEMS_BREAK_NONE,
2579 RID_SVXITEMS_BREAK_COLUMN_BEFORE,
2580 RID_SVXITEMS_BREAK_COLUMN_AFTER,
2581 RID_SVXITEMS_BREAK_COLUMN_BOTH,
2582 RID_SVXITEMS_BREAK_PAGE_BEFORE,
2583 RID_SVXITEMS_BREAK_PAGE_AFTER,
2584 RID_SVXITEMS_BREAK_PAGE_BOTH
2586 static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_BREAK) == size_t(SvxBreak::End), "unexpected size");
2587 assert(nPos < sal_uInt16(SvxBreak::End) && "enum overflow!");
2588 return EditResId(RID_SVXITEMS_BREAK[nPos]);
2591 bool SvxFormatBreakItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const
2593 style::BreakType eBreak = style::BreakType_NONE;
2594 switch ( GetBreak() )
2596 case SvxBreak::ColumnBefore: eBreak = style::BreakType_COLUMN_BEFORE; break;
2597 case SvxBreak::ColumnAfter: eBreak = style::BreakType_COLUMN_AFTER ; break;
2598 case SvxBreak::ColumnBoth: eBreak = style::BreakType_COLUMN_BOTH ; break;
2599 case SvxBreak::PageBefore: eBreak = style::BreakType_PAGE_BEFORE ; break;
2600 case SvxBreak::PageAfter: eBreak = style::BreakType_PAGE_AFTER ; break;
2601 case SvxBreak::PageBoth: eBreak = style::BreakType_PAGE_BOTH ; break;
2602 default: ; // prevent warning
2604 rVal <<= eBreak;
2605 return true;
2608 bool SvxFormatBreakItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
2610 style::BreakType nBreak;
2612 if(!(rVal >>= nBreak))
2614 sal_Int32 nValue = 0;
2615 if(!(rVal >>= nValue))
2616 return false;
2618 nBreak = static_cast<style::BreakType>(nValue);
2621 SvxBreak eBreak = SvxBreak::NONE;
2622 switch( nBreak )
2624 case style::BreakType_COLUMN_BEFORE: eBreak = SvxBreak::ColumnBefore; break;
2625 case style::BreakType_COLUMN_AFTER: eBreak = SvxBreak::ColumnAfter; break;
2626 case style::BreakType_COLUMN_BOTH: eBreak = SvxBreak::ColumnBoth; break;
2627 case style::BreakType_PAGE_BEFORE: eBreak = SvxBreak::PageBefore; break;
2628 case style::BreakType_PAGE_AFTER: eBreak = SvxBreak::PageAfter; break;
2629 case style::BreakType_PAGE_BOTH: eBreak = SvxBreak::PageBoth; break;
2630 default: ; // prevent warning
2632 SetValue(eBreak);
2634 return true;
2637 SvxFormatBreakItem* SvxFormatBreakItem::Clone( SfxItemPool* ) const
2639 return new SvxFormatBreakItem( *this );
2642 sal_uInt16 SvxFormatBreakItem::GetValueCount() const
2644 return sal_uInt16(SvxBreak::End); // SvxBreak::PageBoth + 1
2647 SvxFormatKeepItem* SvxFormatKeepItem::Clone( SfxItemPool* ) const
2649 return new SvxFormatKeepItem( *this );
2652 bool SvxFormatKeepItem::GetPresentation
2654 SfxItemPresentation /*ePres*/,
2655 MapUnit /*eCoreUnit*/,
2656 MapUnit /*ePresUnit*/,
2657 OUString& rText, const IntlWrapper&
2658 ) const
2660 TranslateId pId = RID_SVXITEMS_FMTKEEP_FALSE;
2662 if ( GetValue() )
2663 pId = RID_SVXITEMS_FMTKEEP_TRUE;
2664 rText = EditResId(pId);
2665 return true;
2668 void SvxFormatKeepItem::dumpAsXml(xmlTextWriterPtr pWriter) const
2670 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFormatKeepItem"));
2672 SfxBoolItem::dumpAsXml(pWriter);
2674 (void)xmlTextWriterEndElement(pWriter);
2677 SvxLineItem::SvxLineItem( const sal_uInt16 nId ) :
2678 SfxPoolItem ( nId )
2683 SvxLineItem::SvxLineItem( const SvxLineItem& rCpy ) :
2684 SfxPoolItem ( rCpy ),
2685 pLine(rCpy.pLine ? new SvxBorderLine( *rCpy.pLine ) : nullptr)
2690 SvxLineItem::~SvxLineItem()
2695 bool SvxLineItem::operator==( const SfxPoolItem& rAttr ) const
2697 assert(SfxPoolItem::operator==(rAttr));
2699 return CmpBrdLn( pLine, static_cast<const SvxLineItem&>(rAttr).GetLine() );
2702 SvxLineItem* SvxLineItem::Clone( SfxItemPool* ) const
2704 return new SvxLineItem( *this );
2707 bool SvxLineItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemId ) const
2709 bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
2710 nMemId &= ~CONVERT_TWIPS;
2711 if ( nMemId == 0 )
2713 rVal <<= SvxBoxItem::SvxLineToLine(pLine.get(), bConvert);
2714 return true;
2716 else if ( pLine )
2718 switch ( nMemId )
2720 case MID_FG_COLOR: rVal <<= pLine->GetColor(); break;
2721 case MID_OUTER_WIDTH: rVal <<= sal_Int32(pLine->GetOutWidth()); break;
2722 case MID_INNER_WIDTH: rVal <<= sal_Int32(pLine->GetInWidth( )); break;
2723 case MID_DISTANCE: rVal <<= sal_Int32(pLine->GetDistance()); break;
2724 default:
2725 OSL_FAIL( "Wrong MemberId" );
2726 return false;
2730 return true;
2734 bool SvxLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemId )
2736 bool bConvert = 0!=(nMemId&CONVERT_TWIPS);
2737 nMemId &= ~CONVERT_TWIPS;
2738 sal_Int32 nVal = 0;
2739 if ( nMemId == 0 )
2741 table::BorderLine2 aLine;
2742 if ( lcl_extractBorderLine(rVal, aLine) )
2744 if ( !pLine )
2745 pLine.reset( new SvxBorderLine );
2746 if( !SvxBoxItem::LineToSvxLine(aLine, *pLine, bConvert) )
2747 pLine.reset();
2748 return true;
2750 return false;
2752 else if ( rVal >>= nVal )
2754 if ( !pLine )
2755 pLine.reset( new SvxBorderLine );
2757 switch ( nMemId )
2759 case MID_FG_COLOR: pLine->SetColor( Color(ColorTransparency, nVal) ); break;
2760 case MID_LINE_STYLE:
2761 pLine->SetBorderLineStyle(static_cast<SvxBorderLineStyle>(nVal));
2762 break;
2763 default:
2764 OSL_FAIL( "Wrong MemberId" );
2765 return false;
2768 return true;
2771 return false;
2775 bool SvxLineItem::GetPresentation
2777 SfxItemPresentation ePres,
2778 MapUnit eCoreUnit,
2779 MapUnit ePresUnit,
2780 OUString& rText, const IntlWrapper& rIntl
2781 ) const
2783 rText.clear();
2785 if ( pLine )
2786 rText = pLine->GetValueString( eCoreUnit, ePresUnit, &rIntl,
2787 (SfxItemPresentation::Complete == ePres) );
2788 return true;
2792 void SvxLineItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv )
2794 if ( pLine ) pLine->ScaleMetrics( nMult, nDiv );
2798 bool SvxLineItem::HasMetrics() const
2800 return true;
2804 void SvxLineItem::SetLine( const SvxBorderLine* pNew )
2806 pLine.reset( pNew ? new SvxBorderLine( *pNew ) : nullptr );
2809 SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich)
2810 : SfxPoolItem(_nWhich)
2811 , aColor(COL_TRANSPARENT)
2812 , aFilterColor(COL_TRANSPARENT)
2813 , nShadingValue(ShadingPattern::CLEAR)
2814 , nGraphicTransparency(0)
2815 , eGraphicPos(GPOS_NONE)
2816 , bLoadAgain(true)
2820 SvxBrushItem::SvxBrushItem(const Color& rColor, sal_uInt16 _nWhich)
2821 : SfxPoolItem(_nWhich)
2822 , aColor(rColor)
2823 , aFilterColor(COL_TRANSPARENT)
2824 , nShadingValue(ShadingPattern::CLEAR)
2825 , nGraphicTransparency(0)
2826 , eGraphicPos(GPOS_NONE)
2827 , bLoadAgain(true)
2831 SvxBrushItem::SvxBrushItem(const Graphic& rGraphic, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2832 : SfxPoolItem(_nWhich)
2833 , aColor(COL_TRANSPARENT)
2834 , aFilterColor(COL_TRANSPARENT)
2835 , nShadingValue(ShadingPattern::CLEAR)
2836 , xGraphicObject(new GraphicObject(rGraphic))
2837 , nGraphicTransparency(0)
2838 , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2839 , bLoadAgain(true)
2841 DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2844 SvxBrushItem::SvxBrushItem(const GraphicObject& rGraphicObj, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2845 : SfxPoolItem(_nWhich)
2846 , aColor(COL_TRANSPARENT)
2847 , aFilterColor(COL_TRANSPARENT)
2848 , nShadingValue(ShadingPattern::CLEAR)
2849 , xGraphicObject(new GraphicObject(rGraphicObj))
2850 , nGraphicTransparency(0)
2851 , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2852 , bLoadAgain(true)
2854 DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2857 SvxBrushItem::SvxBrushItem(const OUString& rLink, const OUString& rFilter,
2858 SvxGraphicPosition ePos, sal_uInt16 _nWhich)
2859 : SfxPoolItem(_nWhich)
2860 , aColor(COL_TRANSPARENT)
2861 , aFilterColor(COL_TRANSPARENT)
2862 , nShadingValue(ShadingPattern::CLEAR)
2863 , nGraphicTransparency(0)
2864 , maStrLink(rLink)
2865 , maStrFilter(rFilter)
2866 , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM)
2867 , bLoadAgain(true)
2869 DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" );
2872 SvxBrushItem::SvxBrushItem(const SvxBrushItem& rItem)
2873 : SfxPoolItem(rItem)
2874 , aColor(rItem.aColor)
2875 , aFilterColor(rItem.aFilterColor)
2876 , nShadingValue(rItem.nShadingValue)
2877 , xGraphicObject(rItem.xGraphicObject ? new GraphicObject(*rItem.xGraphicObject) : nullptr)
2878 , nGraphicTransparency(rItem.nGraphicTransparency)
2879 , maStrLink(rItem.maStrLink)
2880 , maStrFilter(rItem.maStrFilter)
2881 , eGraphicPos(rItem.eGraphicPos)
2882 , bLoadAgain(rItem.bLoadAgain)
2886 SvxBrushItem::SvxBrushItem(SvxBrushItem&& rItem)
2887 : SfxPoolItem(std::move(rItem))
2888 , aColor(std::move(rItem.aColor))
2889 , aFilterColor(std::move(rItem.aFilterColor))
2890 , nShadingValue(std::move(rItem.nShadingValue))
2891 , xGraphicObject(std::move(rItem.xGraphicObject))
2892 , nGraphicTransparency(std::move(rItem.nGraphicTransparency))
2893 , maStrLink(std::move(rItem.maStrLink))
2894 , maStrFilter(std::move(rItem.maStrFilter))
2895 , eGraphicPos(std::move(rItem.eGraphicPos))
2896 , bLoadAgain(std::move(rItem.bLoadAgain))
2900 SvxBrushItem::~SvxBrushItem()
2904 bool SvxBrushItem::isUsed() const
2906 if (GPOS_NONE != GetGraphicPos())
2908 // graphic used
2909 return true;
2911 else if (!GetColor().IsFullyTransparent())
2913 // color used
2914 return true;
2917 return false;
2921 static sal_Int8 lcl_PercentToTransparency(tools::Long nPercent)
2923 // 0xff must not be returned!
2924 return sal_Int8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0);
2928 sal_Int8 SvxBrushItem::TransparencyToPercent(sal_Int32 nTrans)
2930 return static_cast<sal_Int8>((nTrans * 100 + 127) / 254);
2934 bool SvxBrushItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
2936 nMemberId &= ~CONVERT_TWIPS;
2937 switch( nMemberId)
2939 case MID_BACK_COLOR:
2940 rVal <<= aColor;
2941 break;
2942 case MID_BACK_COLOR_R_G_B:
2943 rVal <<= aColor.GetRGBColor();
2944 break;
2945 case MID_BACK_COLOR_TRANSPARENCY:
2946 rVal <<= SvxBrushItem::TransparencyToPercent(255 - aColor.GetAlpha());
2947 break;
2948 case MID_GRAPHIC_POSITION:
2949 rVal <<= static_cast<style::GraphicLocation>(static_cast<sal_Int16>(eGraphicPos));
2950 break;
2952 case MID_GRAPHIC_TRANSPARENT:
2953 rVal <<= ( aColor.GetAlpha() == 0 );
2954 break;
2956 case MID_GRAPHIC_URL:
2957 case MID_GRAPHIC:
2959 uno::Reference<graphic::XGraphic> xGraphic;
2960 if (!maStrLink.isEmpty())
2962 Graphic aGraphic(vcl::graphic::loadFromURL(maStrLink));
2963 xGraphic = aGraphic.GetXGraphic();
2965 else if (xGraphicObject)
2967 xGraphic = xGraphicObject->GetGraphic().GetXGraphic();
2969 rVal <<= xGraphic;
2971 break;
2973 case MID_GRAPHIC_FILTER:
2975 rVal <<= maStrFilter;
2977 break;
2979 case MID_GRAPHIC_TRANSPARENCY:
2980 rVal <<= nGraphicTransparency;
2981 break;
2983 case MID_SHADING_VALUE:
2985 rVal <<= nShadingValue;
2987 break;
2990 return true;
2994 bool SvxBrushItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
2996 nMemberId &= ~CONVERT_TWIPS;
2997 switch( nMemberId)
2999 case MID_BACK_COLOR:
3000 case MID_BACK_COLOR_R_G_B:
3002 Color aNewCol;
3003 if ( !( rVal >>= aNewCol ) )
3004 return false;
3005 if(MID_BACK_COLOR_R_G_B == nMemberId)
3007 aNewCol.SetAlpha(aColor.GetAlpha());
3009 aColor = aNewCol;
3011 break;
3012 case MID_BACK_COLOR_TRANSPARENCY:
3014 sal_Int32 nTrans = 0;
3015 if ( !( rVal >>= nTrans ) || nTrans < 0 || nTrans > 100 )
3016 return false;
3017 aColor.SetAlpha(255 - lcl_PercentToTransparency(nTrans));
3019 break;
3021 case MID_GRAPHIC_POSITION:
3023 style::GraphicLocation eLocation;
3024 if ( !( rVal>>=eLocation ) )
3026 sal_Int32 nValue = 0;
3027 if ( !( rVal >>= nValue ) )
3028 return false;
3029 eLocation = static_cast<style::GraphicLocation>(nValue);
3031 SetGraphicPos( static_cast<SvxGraphicPosition>(static_cast<sal_uInt16>(eLocation)) );
3033 break;
3035 case MID_GRAPHIC_TRANSPARENT:
3036 aColor.SetAlpha( Any2Bool( rVal ) ? 0 : 255 );
3037 break;
3039 case MID_GRAPHIC_URL:
3040 case MID_GRAPHIC:
3042 Graphic aGraphic;
3044 if (rVal.getValueType() == ::cppu::UnoType<OUString>::get())
3046 OUString aURL = rVal.get<OUString>();
3047 aGraphic = vcl::graphic::loadFromURL(aURL);
3049 else if (rVal.getValueType() == cppu::UnoType<graphic::XGraphic>::get())
3051 auto xGraphic = rVal.get<uno::Reference<graphic::XGraphic>>();
3052 aGraphic = Graphic(xGraphic);
3055 if (!aGraphic.IsNone())
3057 maStrLink.clear();
3059 std::unique_ptr<GraphicObject> xOldGrfObj(std::move(xGraphicObject));
3060 xGraphicObject.reset(new GraphicObject(aGraphic));
3061 ApplyGraphicTransparency_Impl();
3062 xOldGrfObj.reset();
3064 if (!aGraphic.IsNone() && eGraphicPos == GPOS_NONE)
3066 eGraphicPos = GPOS_MM;
3068 else if (aGraphic.IsNone())
3070 eGraphicPos = GPOS_NONE;
3074 break;
3076 case MID_GRAPHIC_FILTER:
3078 if( rVal.getValueType() == ::cppu::UnoType<OUString>::get() )
3080 OUString sLink;
3081 rVal >>= sLink;
3082 SetGraphicFilter( sLink );
3085 break;
3086 case MID_GRAPHIC_TRANSPARENCY :
3088 sal_Int32 nTmp = 0;
3089 rVal >>= nTmp;
3090 if(nTmp >= 0 && nTmp <= 100)
3092 nGraphicTransparency = sal_Int8(nTmp);
3093 if (xGraphicObject)
3094 ApplyGraphicTransparency_Impl();
3097 break;
3099 case MID_SHADING_VALUE:
3101 sal_Int32 nVal = 0;
3102 if (!(rVal >>= nVal))
3103 return false;
3105 nShadingValue = nVal;
3107 break;
3110 return true;
3114 bool SvxBrushItem::GetPresentation
3116 SfxItemPresentation /*ePres*/,
3117 MapUnit /*eCoreUnit*/,
3118 MapUnit /*ePresUnit*/,
3119 OUString& rText, const IntlWrapper&
3120 ) const
3122 if ( GPOS_NONE == eGraphicPos )
3124 rText = ::GetColorString( aColor ) + cpDelim;
3125 TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE;
3127 if ( aColor.IsTransparent() )
3128 pId = RID_SVXITEMS_TRANSPARENT_TRUE;
3129 rText += EditResId(pId);
3131 else
3133 rText = EditResId(RID_SVXITEMS_GRAPHIC);
3136 return true;
3139 bool SvxBrushItem::operator==( const SfxPoolItem& rAttr ) const
3141 assert(SfxPoolItem::operator==(rAttr));
3143 const SvxBrushItem& rCmp = static_cast<const SvxBrushItem&>(rAttr);
3144 bool bEqual = ( aColor == rCmp.aColor && aFilterColor == rCmp.aFilterColor &&
3145 eGraphicPos == rCmp.eGraphicPos && nGraphicTransparency == rCmp.nGraphicTransparency);
3147 if ( bEqual )
3149 if ( GPOS_NONE != eGraphicPos )
3151 bEqual = maStrLink == rCmp.maStrLink;
3153 if ( bEqual )
3155 bEqual = maStrFilter == rCmp.maStrFilter;
3158 if ( bEqual )
3160 if (!rCmp.xGraphicObject)
3161 bEqual = !xGraphicObject;
3162 else
3163 bEqual = xGraphicObject &&
3164 (*xGraphicObject == *rCmp.xGraphicObject);
3168 if (bEqual)
3170 bEqual = nShadingValue == rCmp.nShadingValue;
3174 return bEqual;
3177 SvxBrushItem* SvxBrushItem::Clone( SfxItemPool* ) const
3179 return new SvxBrushItem( *this );
3182 const GraphicObject* SvxBrushItem::GetGraphicObject(OUString const & referer) const
3184 if (bLoadAgain && !maStrLink.isEmpty() && !xGraphicObject)
3185 // when graphics already loaded, use as a cache
3187 if (SvtSecurityOptions::isUntrustedReferer(referer)) {
3188 return nullptr;
3191 // tdf#94088 prepare graphic and state
3192 Graphic aGraphic;
3193 bool bGraphicLoaded = false;
3195 // try to create stream directly from given URL
3196 std::unique_ptr<SvStream> xStream(utl::UcbStreamHelper::CreateStream(maStrLink, StreamMode::STD_READ));
3197 // tdf#94088 if we have a stream, try to load it directly as graphic
3198 if (xStream && !xStream->GetError())
3200 if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, maStrLink, *xStream,
3201 GRFILTER_FORMAT_DONTKNOW, nullptr, GraphicFilterImportFlags::DontSetLogsizeForJpeg))
3203 bGraphicLoaded = true;
3207 // tdf#94088 if no succeeded, try if the string (which is not empty) contains
3208 // a 'data:' scheme url and try to load that (embedded graphics)
3209 if(!bGraphicLoaded)
3211 INetURLObject aGraphicURL( maStrLink );
3213 if( INetProtocol::Data == aGraphicURL.GetProtocol() )
3215 std::unique_ptr<SvMemoryStream> const xMemStream(aGraphicURL.getData());
3216 if (xMemStream)
3218 if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, "", *xMemStream))
3220 bGraphicLoaded = true;
3222 // tdf#94088 delete the no longer needed data scheme URL which
3223 // is potentially pretty // large, containing a base64 encoded copy of the graphic
3224 const_cast< SvxBrushItem* >(this)->maStrLink.clear();
3230 // tdf#94088 when we got a graphic, set it
3231 if(bGraphicLoaded && GraphicType::NONE != aGraphic.GetType())
3233 xGraphicObject.reset(new GraphicObject);
3234 xGraphicObject->SetGraphic(aGraphic);
3235 const_cast < SvxBrushItem*> (this)->ApplyGraphicTransparency_Impl();
3237 else
3239 bLoadAgain = false;
3243 return xGraphicObject.get();
3246 void SvxBrushItem::setGraphicTransparency(sal_Int8 nNew)
3248 if (nNew != nGraphicTransparency)
3250 nGraphicTransparency = nNew;
3251 ApplyGraphicTransparency_Impl();
3255 const Graphic* SvxBrushItem::GetGraphic(OUString const & referer) const
3257 const GraphicObject* pGrafObj = GetGraphicObject(referer);
3258 return( pGrafObj ? &( pGrafObj->GetGraphic() ) : nullptr );
3261 void SvxBrushItem::SetGraphicPos( SvxGraphicPosition eNew )
3263 eGraphicPos = eNew;
3265 if ( GPOS_NONE == eGraphicPos )
3267 xGraphicObject.reset();
3268 maStrLink.clear();
3269 maStrFilter.clear();
3271 else
3273 if (!xGraphicObject && maStrLink.isEmpty())
3275 xGraphicObject.reset(new GraphicObject); // Creating a dummy
3280 void SvxBrushItem::SetGraphic( const Graphic& rNew )
3282 if ( maStrLink.isEmpty() )
3284 if (xGraphicObject)
3285 xGraphicObject->SetGraphic(rNew);
3286 else
3287 xGraphicObject.reset(new GraphicObject(rNew));
3289 ApplyGraphicTransparency_Impl();
3291 if ( GPOS_NONE == eGraphicPos )
3292 eGraphicPos = GPOS_MM; // None would be brush, then Default: middle
3294 else
3296 OSL_FAIL( "SetGraphic() on linked graphic! :-/" );
3300 void SvxBrushItem::SetGraphicObject( const GraphicObject& rNewObj )
3302 if ( maStrLink.isEmpty() )
3304 if (xGraphicObject)
3305 *xGraphicObject = rNewObj;
3306 else
3307 xGraphicObject.reset(new GraphicObject(rNewObj));
3309 ApplyGraphicTransparency_Impl();
3311 if ( GPOS_NONE == eGraphicPos )
3312 eGraphicPos = GPOS_MM; // None would be brush, then Default: middle
3314 else
3316 OSL_FAIL( "SetGraphic() on linked graphic! :-/" );
3320 void SvxBrushItem::SetGraphicLink( const OUString& rNew )
3322 if ( rNew.isEmpty() )
3323 maStrLink.clear();
3324 else
3326 maStrLink = rNew;
3327 xGraphicObject.reset();
3331 void SvxBrushItem::SetGraphicFilter( const OUString& rNew )
3333 maStrFilter = rNew;
3336 void SvxBrushItem::ApplyGraphicTransparency_Impl()
3338 DBG_ASSERT(xGraphicObject, "no GraphicObject available" );
3339 if (xGraphicObject)
3341 GraphicAttr aAttr(xGraphicObject->GetAttr());
3342 aAttr.SetAlpha(255 - lcl_PercentToTransparency(
3343 nGraphicTransparency));
3344 xGraphicObject->SetAttr(aAttr);
3348 void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) const
3350 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBrushItem"));
3351 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
3352 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"), BAD_CAST(aColor.AsRGBHexString().toUtf8().getStr()));
3353 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filtercolor"), BAD_CAST(aFilterColor.AsRGBHexString().toUtf8().getStr()));
3354 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("shadingValue"), BAD_CAST(OString::number(nShadingValue).getStr()));
3355 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("link"), BAD_CAST(maStrLink.toUtf8().getStr()));
3356 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filter"), BAD_CAST(maStrFilter.toUtf8().getStr()));
3357 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("graphicPos"), BAD_CAST(OString::number(eGraphicPos).getStr()));
3358 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("loadAgain"), BAD_CAST(OString::boolean(bLoadAgain).getStr()));
3359 (void)xmlTextWriterEndElement(pWriter);
3363 SvxFrameDirectionItem::SvxFrameDirectionItem( SvxFrameDirection nValue ,
3364 sal_uInt16 _nWhich )
3365 : SfxEnumItem<SvxFrameDirection>( _nWhich, nValue )
3370 SvxFrameDirectionItem::~SvxFrameDirectionItem()
3374 SvxFrameDirectionItem* SvxFrameDirectionItem::Clone( SfxItemPool * ) const
3376 return new SvxFrameDirectionItem( *this );
3379 TranslateId getFrmDirResId(size_t nIndex)
3381 TranslateId const RID_SVXITEMS_FRMDIR[] =
3383 RID_SVXITEMS_FRMDIR_HORI_LEFT_TOP,
3384 RID_SVXITEMS_FRMDIR_HORI_RIGHT_TOP,
3385 RID_SVXITEMS_FRMDIR_VERT_TOP_RIGHT,
3386 RID_SVXITEMS_FRMDIR_VERT_TOP_LEFT,
3387 RID_SVXITEMS_FRMDIR_ENVIRONMENT,
3388 RID_SVXITEMS_FRMDIR_VERT_BOT_LEFT
3390 return RID_SVXITEMS_FRMDIR[nIndex];
3393 bool SvxFrameDirectionItem::GetPresentation(
3394 SfxItemPresentation /*ePres*/,
3395 MapUnit /*eCoreUnit*/,
3396 MapUnit /*ePresUnit*/,
3397 OUString& rText, const IntlWrapper&) const
3399 rText = EditResId(getFrmDirResId(GetEnumValue()));
3400 return true;
3403 bool SvxFrameDirectionItem::PutValue( const css::uno::Any& rVal,
3404 sal_uInt8 )
3406 sal_Int16 nVal = sal_Int16();
3407 bool bRet = ( rVal >>= nVal );
3408 if( bRet )
3410 // translate WritingDirection2 constants into SvxFrameDirection
3411 switch( nVal )
3413 case text::WritingMode2::LR_TB:
3414 SetValue( SvxFrameDirection::Horizontal_LR_TB );
3415 break;
3416 case text::WritingMode2::RL_TB:
3417 SetValue( SvxFrameDirection::Horizontal_RL_TB );
3418 break;
3419 case text::WritingMode2::TB_RL:
3420 SetValue( SvxFrameDirection::Vertical_RL_TB );
3421 break;
3422 case text::WritingMode2::TB_LR:
3423 SetValue( SvxFrameDirection::Vertical_LR_TB );
3424 break;
3425 case text::WritingMode2::BT_LR:
3426 SetValue( SvxFrameDirection::Vertical_LR_BT );
3427 break;
3428 case text::WritingMode2::PAGE:
3429 SetValue( SvxFrameDirection::Environment );
3430 break;
3431 default:
3432 bRet = false;
3433 break;
3437 return bRet;
3441 bool SvxFrameDirectionItem::QueryValue( css::uno::Any& rVal,
3442 sal_uInt8 ) const
3444 // translate SvxFrameDirection into WritingDirection2
3445 sal_Int16 nVal;
3446 bool bRet = true;
3447 switch( GetValue() )
3449 case SvxFrameDirection::Horizontal_LR_TB:
3450 nVal = text::WritingMode2::LR_TB;
3451 break;
3452 case SvxFrameDirection::Horizontal_RL_TB:
3453 nVal = text::WritingMode2::RL_TB;
3454 break;
3455 case SvxFrameDirection::Vertical_RL_TB:
3456 nVal = text::WritingMode2::TB_RL;
3457 break;
3458 case SvxFrameDirection::Vertical_LR_TB:
3459 nVal = text::WritingMode2::TB_LR;
3460 break;
3461 case SvxFrameDirection::Vertical_LR_BT:
3462 nVal = text::WritingMode2::BT_LR;
3463 break;
3464 case SvxFrameDirection::Environment:
3465 nVal = text::WritingMode2::PAGE;
3466 break;
3467 default:
3468 OSL_FAIL("Unknown SvxFrameDirection value!");
3469 bRet = false;
3470 break;
3473 // return value + error state
3474 if( bRet )
3476 rVal <<= nVal;
3478 return bRet;
3481 void SvxFrameDirectionItem::dumpAsXml(xmlTextWriterPtr pWriter) const
3483 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFrameDirectionItem"));
3484 (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nWhich"),
3485 BAD_CAST(OString::number(Which()).getStr()));
3486 (void)xmlTextWriterWriteAttribute(
3487 pWriter, BAD_CAST("m_nValue"),
3488 BAD_CAST(OString::number(static_cast<sal_Int16>(GetValue())).getStr()));
3489 (void)xmlTextWriterEndElement(pWriter);
3492 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */