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