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 <hintids.hxx> 21 22 #include <svl/whiter.hxx> 23 #include <svl/stritem.hxx> 24 #include <svl/ctloptions.hxx> 25 #include <swmodule.hxx> 26 #include <sfx2/bindings.hxx> 27 #include <sfx2/request.hxx> 28 #include <sfx2/viewfrm.hxx> 29 #include <editeng/fhgtitem.hxx> 30 #include <editeng/adjustitem.hxx> 31 #include <editeng/lspcitem.hxx> 32 #include <editeng/lrspitem.hxx> 33 #include <editeng/udlnitem.hxx> 34 #include <editeng/escapementitem.hxx> 35 #include <sfx2/htmlmode.hxx> 36 #include <editeng/scripttypeitem.hxx> 37 #include <editeng/frmdiritem.hxx> 38 #include <editeng/cmapitem.hxx> 39 #include <paratr.hxx> 40 41 #include <fmtinfmt.hxx> 42 #include <wrtsh.hxx> 43 #include <view.hxx> 44 #include <viewopt.hxx> 45 #include <uitool.hxx> 46 #include <textsh.hxx> 47 #include <swundo.hxx> 48 #include <fmtcol.hxx> 49 50 #include <cmdid.h> 51 #include <globals.h> 52 #include <SwStyleNameMapper.hxx> 53 #include <swabstdlg.hxx> 54 #include <memory> 55 56 const sal_uInt32 nFontInc = 40; // 2pt 57 const sal_uInt32 nFontMaxSz = 19998; // 999.9pt 58 59 void SwTextShell::ExecCharAttr(SfxRequest &rReq) 60 { 61 SwWrtShell &rSh = GetShell(); 62 const SfxItemSet *pArgs = rReq.GetArgs(); 63 int eState = STATE_TOGGLE; 64 sal_uInt16 nWhich = rReq.GetSlot(); 65 66 if(pArgs ) 67 { 68 const SfxPoolItem* pItem; 69 pArgs->GetItemState(nWhich, false, &pItem); 70 eState = static_cast<const SfxBoolItem &>( pArgs-> 71 Get( nWhich )).GetValue() ? STATE_ON : STATE_OFF; 72 } 73 74 SfxItemSet aSet( GetPool(), svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END-1>{} ); 75 if (STATE_TOGGLE == eState) 76 rSh.GetCurAttr( aSet ); 77 78 switch ( nWhich ) 79 { 80 case FN_SET_SUB_SCRIPT: 81 case FN_SET_SUPER_SCRIPT: 82 { 83 SvxEscapement eEscape = SvxEscapement::Subscript; 84 switch (eState) 85 { 86 case STATE_TOGGLE: 87 { 88 short nTmpEsc = aSet.Get( RES_CHRATR_ESCAPEMENT ).GetEsc(); 89 eEscape = nWhich == FN_SET_SUPER_SCRIPT ? 90 SvxEscapement::Superscript: 91 SvxEscapement::Subscript; 92 if( (nWhich == FN_SET_SUB_SCRIPT && nTmpEsc < 0) || 93 (nWhich == FN_SET_SUPER_SCRIPT && nTmpEsc > 0) ) 94 eEscape = SvxEscapement::Off; 95 96 SfxBindings& rBind = GetView().GetViewFrame()->GetBindings(); 97 if( nWhich == FN_SET_SUB_SCRIPT ) 98 rBind.SetState( SfxBoolItem( FN_SET_SUPER_SCRIPT, 99 false ) ); 100 else 101 rBind.SetState( SfxBoolItem( FN_SET_SUB_SCRIPT, 102 false ) ); 103 104 } 105 break; 106 case STATE_ON: 107 eEscape = nWhich == FN_SET_SUPER_SCRIPT ? 108 SvxEscapement::Superscript: 109 SvxEscapement::Subscript; 110 break; 111 case STATE_OFF: 112 eEscape = SvxEscapement::Off; 113 break; 114 } 115 SvxEscapementItem aEscape( eEscape, RES_CHRATR_ESCAPEMENT ); 116 if(eEscape == SvxEscapement::Superscript) 117 aEscape.GetEsc() = DFLT_ESC_AUTO_SUPER; 118 else if(eEscape == SvxEscapement::Subscript) 119 aEscape.GetEsc() = DFLT_ESC_AUTO_SUB; 120 rSh.SetAttrItem( aEscape ); 121 rReq.AppendItem( aEscape ); 122 rReq.Done(); 123 } 124 break; 125 126 case FN_SET_SMALL_CAPS: 127 { 128 SvxCaseMap eCaseMap = SvxCaseMap::SmallCaps; 129 switch (eState) 130 { 131 case STATE_TOGGLE: 132 { 133 SvxCaseMap eTmpCaseMap = aSet.Get(RES_CHRATR_CASEMAP).GetCaseMap(); 134 if (eTmpCaseMap == SvxCaseMap::SmallCaps) 135 eCaseMap = SvxCaseMap::NotMapped; 136 } 137 break; 138 case STATE_ON: 139 // Nothing to do, already set. 140 break; 141 case STATE_OFF: 142 eCaseMap = SvxCaseMap::NotMapped; 143 break; 144 } 145 SvxCaseMapItem aCaseMap(eCaseMap, RES_CHRATR_CASEMAP); 146 rSh.SetAttrItem(aCaseMap); 147 rReq.AppendItem(aCaseMap); 148 rReq.Done(); 149 } 150 break; 151 152 case FN_UPDATE_STYLE_BY_EXAMPLE: 153 rSh.QuickUpdateStyle(); 154 rReq.Done(); 155 break; 156 157 case SID_ULINE_VAL_NONE: 158 { 159 SvxUnderlineItem aUnderline(LINESTYLE_NONE, RES_CHRATR_UNDERLINE ); 160 rSh.SetAttrItem( aUnderline ); 161 rReq.AppendItem( aUnderline ); 162 rReq.Done(); 163 break; 164 } 165 166 case SID_ULINE_VAL_SINGLE: 167 case SID_ULINE_VAL_DOUBLE: 168 case SID_ULINE_VAL_DOTTED: 169 { 170 FontLineStyle eOld = aSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle(); 171 FontLineStyle eNew = eOld; 172 173 switch (nWhich) 174 { 175 case SID_ULINE_VAL_SINGLE: 176 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE; 177 break; 178 case SID_ULINE_VAL_DOUBLE: 179 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE; 180 break; 181 case SID_ULINE_VAL_DOTTED: 182 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED; 183 break; 184 } 185 186 SvxUnderlineItem aUnderline(eNew, RES_CHRATR_UNDERLINE ); 187 rSh.SetAttrItem( aUnderline ); 188 rReq.AppendItem( aUnderline ); 189 rReq.Done(); 190 } 191 break; 192 case FN_REMOVE_DIRECT_CHAR_FORMATS: 193 if( !rSh.HasReadonlySel() && rSh.IsEndPara()) 194 rSh.DontExpandFormat(); 195 break; 196 default: 197 OSL_FAIL("wrong dispatcher"); 198 return; 199 } 200 } 201 202 void SwTextShell::ExecCharAttrArgs(SfxRequest &rReq) 203 { 204 sal_uInt16 nSlot = rReq.GetSlot(); 205 const SfxItemSet* pArgs = rReq.GetArgs(); 206 bool bArgs = pArgs != nullptr && pArgs->Count() > 0; 207 SwWrtShell& rWrtSh = GetShell(); 208 SwTextFormatColl* pColl = nullptr; 209 210 // Is only set if the whole paragraph is selected and AutoUpdateFormat is set. 211 if (rWrtSh.HasSelection() && rWrtSh.IsSelFullPara()) 212 { 213 pColl = rWrtSh.GetCurTextFormatColl(); 214 if ( pColl && !pColl->IsAutoUpdateFormat() ) 215 pColl = nullptr; 216 } 217 SfxItemPool& rPool = GetPool(); 218 sal_uInt16 nWhich = rPool.GetWhich( nSlot ); 219 switch (nSlot) 220 { 221 case FN_TXTATR_INET: 222 // Special treatment of the PoolId of the SwFormatInetFormat 223 if(bArgs) 224 { 225 const SfxPoolItem& rItem = pArgs->Get( nWhich ); 226 227 SwFormatINetFormat aINetFormat( static_cast<const SwFormatINetFormat&>(rItem) ); 228 if ( USHRT_MAX == aINetFormat.GetVisitedFormatId() ) 229 { 230 OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected visited character format ID at hyperlink attribute" ); 231 aINetFormat.SetVisitedFormatAndId( 232 aINetFormat.GetVisitedFormat(), 233 SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetVisitedFormat(), SwGetPoolIdFromName::ChrFmt ) ); 234 } 235 if ( USHRT_MAX == aINetFormat.GetINetFormatId() ) 236 { 237 OSL_ENSURE( false, "<SwTextShell::ExecCharAttrArgs(..)> - unexpected unvisited character format ID at hyperlink attribute" ); 238 aINetFormat.SetINetFormatAndId( 239 aINetFormat.GetINetFormat(), 240 SwStyleNameMapper::GetPoolIdFromUIName( aINetFormat.GetINetFormat(), SwGetPoolIdFromName::ChrFmt ) ); 241 } 242 243 if ( pColl ) 244 pColl->SetFormatAttr( aINetFormat ); 245 else 246 rWrtSh.SetAttrItem( aINetFormat ); 247 rReq.Done(); 248 } 249 break; 250 251 case FN_GROW_FONT_SIZE: 252 case FN_SHRINK_FONT_SIZE: 253 { 254 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool ); 255 rWrtSh.GetCurAttr( aSetItem.GetItemSet() ); 256 SfxItemSet aAttrSet( rPool, aSetItem.GetItemSet().GetRanges() ); 257 258 SvtScriptType nScriptTypes = rWrtSh.GetScriptType(); 259 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( 260 aSetItem.GetItemOfScript( nScriptTypes ) ) ); 261 std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> vItems; 262 // simple case where selected text has one size and 263 // (tdf#124919) selection is not multiple table cells 264 if (pSize && !rWrtSh.IsTableMode()) 265 { 266 // must create new one, otherwise document is without pam 267 SwPaM* pPaM = rWrtSh.GetCursor(); 268 vItems.emplace_back( pSize, std::make_unique<SwPaM>( *(pPaM->GetMark()), *(pPaM->GetPoint())) ); 269 } 270 else 271 vItems = rWrtSh.GetItemWithPaM( RES_CHRATR_FONTSIZE ); 272 273 rWrtSh.StartUndo( SwUndoId::INSATTR ); 274 for( std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >& iPair : vItems ) 275 { 276 std::unique_ptr<SwPaM> pPaM = std::move(iPair.second); 277 const SfxPoolItem* pItem = iPair.first; 278 aSetItem.GetItemSet().ClearItem(); 279 rWrtSh.GetPaMAttr( pPaM.get(), aSetItem.GetItemSet() ); 280 aAttrSet.SetRanges( aSetItem.GetItemSet().GetRanges() ); 281 282 pSize = static_cast<const SvxFontHeightItem*>( pItem ); 283 if (pSize) 284 { 285 SvxFontHeightItem aSize(*pSize); 286 287 sal_uInt32 nSize = aSize.GetHeight(); 288 289 if ( nSlot == FN_GROW_FONT_SIZE && ( nSize += nFontInc ) > nFontMaxSz ) 290 nSize = nFontMaxSz; 291 else if ( nSlot == FN_SHRINK_FONT_SIZE && ( nSize -= nFontInc ) < nFontInc ) 292 nSize = nFontInc; 293 294 aSize.SetHeight( nSize ); 295 aSetItem.PutItemForScriptType( nScriptTypes, aSize ); 296 aAttrSet.Put( aSetItem.GetItemSet() ); 297 if( pColl ) 298 pColl->SetFormatAttr( aAttrSet ); 299 else 300 rWrtSh.SetAttrSet( aAttrSet, SetAttrMode::DEFAULT, pPaM.get() ); 301 } 302 } 303 rWrtSh.EndUndo( SwUndoId::INSATTR ); 304 rReq.Done(); 305 } 306 break; 307 308 default: 309 OSL_FAIL("wrong dispatcher"); 310 return; 311 } 312 } 313 314 void SwTextShell::ExecParaAttr(SfxRequest &rReq) 315 { 316 SvxAdjust eAdjst; 317 sal_uInt16 ePropL; 318 const SfxItemSet* pArgs = rReq.GetArgs(); 319 320 // Get both attributes immediately isn't more expensive!! 321 SfxItemSet aSet( GetPool(), 322 svl::Items<RES_PARATR_LINESPACING, RES_PARATR_ADJUST, 323 RES_FRAMEDIR, RES_FRAMEDIR>{} ); 324 325 sal_uInt16 nSlot = rReq.GetSlot(); 326 switch (nSlot) 327 { 328 case SID_ATTR_PARA_ADJUST: 329 { 330 if( pArgs && SfxItemState::SET == pArgs->GetItemState(RES_PARATR_ADJUST) ) 331 { 332 const SvxAdjustItem& rAdj = pArgs->Get(RES_PARATR_ADJUST); 333 SvxAdjustItem aAdj( rAdj.GetAdjust(), RES_PARATR_ADJUST ); 334 if ( rAdj.GetAdjust() == SvxAdjust::Block ) 335 { 336 aAdj.SetLastBlock( rAdj.GetLastBlock() ); 337 aAdj.SetOneWord( rAdj.GetOneWord() ); 338 } 339 340 aSet.Put(aAdj); 341 } 342 } 343 break; 344 case SID_ATTR_PARA_ADJUST_LEFT: eAdjst = SvxAdjust::Left; goto SET_ADJUST; 345 case SID_ATTR_PARA_ADJUST_RIGHT: eAdjst = SvxAdjust::Right; goto SET_ADJUST; 346 case SID_ATTR_PARA_ADJUST_CENTER: eAdjst = SvxAdjust::Center; goto SET_ADJUST; 347 case SID_ATTR_PARA_ADJUST_BLOCK: eAdjst = SvxAdjust::Block; goto SET_ADJUST; 348 SET_ADJUST: 349 { 350 aSet.Put(SvxAdjustItem(eAdjst,RES_PARATR_ADJUST)); 351 rReq.AppendItem( SfxBoolItem( GetPool().GetWhich(nSlot), true ) ); 352 } 353 break; 354 355 case SID_ATTR_PARA_LINESPACE: 356 if(pArgs && SfxItemState::SET == pArgs->GetItemState( GetPool().GetWhich(nSlot) )) 357 { 358 SvxLineSpacingItem aLineSpace = static_cast<const SvxLineSpacingItem&>( pArgs->Get( 359 GetPool().GetWhich(nSlot))); 360 aSet.Put( aLineSpace ); 361 } 362 break; 363 case SID_ATTR_PARA_LINESPACE_10: ePropL = 100; goto SET_LINESPACE; 364 case SID_ATTR_PARA_LINESPACE_15: ePropL = 150; goto SET_LINESPACE; 365 case SID_ATTR_PARA_LINESPACE_20: ePropL = 200; goto SET_LINESPACE; 366 367 SET_LINESPACE: 368 { 369 370 SvxLineSpacingItem aLineSpacing(ePropL, RES_PARATR_LINESPACING ); 371 aLineSpacing.SetLineSpaceRule( SvxLineSpaceRule::Auto ); 372 if( 100 == ePropL ) 373 aLineSpacing.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off ); 374 else 375 aLineSpacing.SetPropLineSpace(ePropL); 376 aSet.Put( aLineSpacing ); 377 } 378 break; 379 380 case SID_ATTR_PARA_LEFT_TO_RIGHT : 381 case SID_ATTR_PARA_RIGHT_TO_LEFT : 382 { 383 SfxItemSet aAdjustSet( GetPool(), 384 svl::Items<RES_PARATR_ADJUST, RES_PARATR_ADJUST>{} ); 385 GetShell().GetCurAttr(aAdjustSet); 386 bool bChgAdjust = false; 387 SfxItemState eAdjustState = aAdjustSet.GetItemState(RES_PARATR_ADJUST, false); 388 if(eAdjustState >= SfxItemState::DEFAULT) 389 { 390 SvxAdjust eAdjust = 391 aAdjustSet.Get(RES_PARATR_ADJUST).GetAdjust(); 392 bChgAdjust = (SvxAdjust::Left == eAdjust && SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot) || 393 (SvxAdjust::Right == eAdjust && SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot); 394 } 395 else 396 bChgAdjust = true; 397 398 SvxFrameDirection eFrameDirection = 399 (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ? 400 SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB; 401 aSet.Put( SvxFrameDirectionItem( eFrameDirection, RES_FRAMEDIR ) ); 402 403 if (bChgAdjust) 404 { 405 SvxAdjust eAdjust = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot) ? 406 SvxAdjust::Left : SvxAdjust::Right; 407 SvxAdjustItem aAdjust( eAdjust, RES_PARATR_ADJUST ); 408 aSet.Put( aAdjust ); 409 aAdjust.SetWhich(SID_ATTR_PARA_ADJUST); 410 GetView().GetViewFrame()->GetBindings().SetState( aAdjust ); 411 // Toggle numbering alignment 412 const SwNumRule* pCurRule = GetShell().GetNumRuleAtCurrCursorPos(); 413 if( pCurRule ) 414 { 415 SvxNumRule aRule = pCurRule->MakeSvxNumRule(); 416 417 for(sal_uInt16 i = 0; i < aRule.GetLevelCount(); i++) 418 { 419 SvxNumberFormat aFormat(aRule.GetLevel(i)); 420 if(SvxAdjust::Left == aFormat.GetNumAdjust()) 421 aFormat.SetNumAdjust( SvxAdjust::Right ); 422 423 else if(SvxAdjust::Right == aFormat.GetNumAdjust()) 424 aFormat.SetNumAdjust( SvxAdjust::Left ); 425 426 aRule.SetLevel(i, aFormat, aRule.Get(i) != nullptr); 427 } 428 SwNumRule aSetRule( pCurRule->GetName(), 429 pCurRule->Get( 0 ).GetPositionAndSpaceMode() ); 430 aSetRule.SetSvxRule( aRule, GetShell().GetDoc()); 431 aSetRule.SetAutoRule( true ); 432 // no start or continuation of a list - list style is only changed 433 GetShell().SetCurNumRule( aSetRule, false ); 434 } 435 } 436 } 437 break; 438 439 default: 440 OSL_FAIL("wrong dispatcher"); 441 return; 442 } 443 SwWrtShell& rWrtSh = GetShell(); 444 SwTextFormatColl* pColl = rWrtSh.GetCurTextFormatColl(); 445 if(pColl && pColl->IsAutoUpdateFormat()) 446 { 447 rWrtSh.AutoUpdatePara(pColl, aSet); 448 } 449 else 450 rWrtSh.SetAttrSet( aSet, SetAttrMode::DEFAULT, nullptr, true); 451 rReq.Done(); 452 } 453 454 void SwTextShell::ExecParaAttrArgs(SfxRequest &rReq) 455 { 456 SwWrtShell &rSh = GetShell(); 457 const SfxItemSet *pArgs = rReq.GetArgs(); 458 const SfxPoolItem *pItem = nullptr; 459 460 sal_uInt16 nSlot = rReq.GetSlot(); 461 if(pArgs) 462 pArgs->GetItemState(GetPool().GetWhich(nSlot), false, &pItem); 463 switch ( nSlot ) 464 { 465 case FN_DROP_CHAR_STYLE_NAME: 466 if( pItem ) 467 { 468 OUString sCharStyleName = static_cast<const SfxStringItem*>(pItem)->GetValue(); 469 SfxItemSet aSet(GetPool(), svl::Items<RES_PARATR_DROP, RES_PARATR_DROP>{}); 470 rSh.GetCurAttr(aSet); 471 SwFormatDrop aDropItem(aSet.Get(RES_PARATR_DROP)); 472 SwCharFormat* pFormat = nullptr; 473 if(!sCharStyleName.isEmpty()) 474 pFormat = rSh.FindCharFormatByName( sCharStyleName ); 475 aDropItem.SetCharFormat( pFormat ); 476 aSet.Put(aDropItem); 477 rSh.SetAttrSet(aSet); 478 } 479 break; 480 case FN_FORMAT_DROPCAPS: 481 { 482 if(pItem) 483 { 484 rSh.SetAttrItem(*pItem); 485 rReq.Done(); 486 } 487 else 488 { 489 SfxItemSet aSet(GetPool(), svl::Items<RES_PARATR_DROP, RES_PARATR_DROP, 490 HINT_END, HINT_END>{}); 491 rSh.GetCurAttr(aSet); 492 SwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create(); 493 ScopedVclPtr<SfxAbstractDialog> pDlg(pFact->CreateSwDropCapsDialog(GetView().GetFrameWeld(), aSet)); 494 if (pDlg->Execute() == RET_OK) 495 { 496 rSh.StartAction(); 497 rSh.StartUndo( SwUndoId::START ); 498 if ( SfxItemState::SET == aSet.GetItemState(HINT_END,false,&pItem) ) 499 { 500 if ( !static_cast<const SfxStringItem*>(pItem)->GetValue().isEmpty() ) 501 rSh.ReplaceDropText(static_cast<const SfxStringItem*>(pItem)->GetValue()); 502 } 503 rSh.SetAttrSet(*pDlg->GetOutputItemSet()); 504 rSh.EndUndo( SwUndoId::END ); 505 rSh.EndAction(); 506 rReq.Done(*pDlg->GetOutputItemSet()); 507 } 508 } 509 } 510 break; 511 case SID_ATTR_PARA_PAGEBREAK: 512 if(pItem) 513 { 514 rSh.SetAttrItem( *pItem ); 515 rReq.Done(); 516 } 517 break; 518 case SID_ATTR_PARA_MODEL: 519 { 520 if(pItem) 521 { 522 SfxItemSet aCoreSet( GetPool(), 523 svl::Items<RES_PAGEDESC, RES_PAGEDESC, 524 SID_ATTR_PARA_MODEL, SID_ATTR_PARA_MODEL>{}); 525 aCoreSet.Put(*pItem); 526 SfxToSwPageDescAttr( rSh, aCoreSet); 527 rSh.SetAttrSet(aCoreSet); 528 rReq.Done(); 529 } 530 } 531 break; 532 533 default: 534 OSL_FAIL("wrong dispatcher"); 535 return; 536 } 537 } 538 539 void SwTextShell::GetAttrState(SfxItemSet &rSet) 540 { 541 SwWrtShell &rSh = GetShell(); 542 SfxItemPool& rPool = GetPool(); 543 SfxItemSet aCoreSet(rPool, aTextFormatCollSetRange); 544 // Request *all* text attributes from the core. 545 // fdo#78737: this is called from SvxRuler, which requires the list indents! 546 rSh.GetCurAttr(aCoreSet, /* bMergeIndentValuesOfNumRule = */ true); 547 548 SfxWhichIter aIter(rSet); 549 sal_uInt16 nSlot = aIter.FirstWhich(); 550 bool bFlag = false; 551 SfxBoolItem aFlagItem; 552 const SfxPoolItem* pItem = nullptr; 553 SvxAdjust eAdjust = SvxAdjust::Left; 554 bool bAdjustGood = false; 555 SfxItemState eState = aCoreSet.GetItemState(RES_PARATR_ADJUST, false, &pItem); 556 557 if( SfxItemState::DEFAULT == eState ) 558 pItem = &rPool.GetDefaultItem(RES_PARATR_ADJUST); 559 if( SfxItemState::DEFAULT <= eState ) 560 { 561 eAdjust = static_cast<const SvxAdjustItem* >( pItem)->GetAdjust(); 562 bAdjustGood = true; 563 } 564 565 short nEsc = 0; 566 eState = aCoreSet.GetItemState(RES_CHRATR_ESCAPEMENT, false, &pItem); 567 if( SfxItemState::DEFAULT == eState ) 568 pItem = &rPool.GetDefaultItem(RES_CHRATR_ESCAPEMENT); 569 if( eState >= SfxItemState::DEFAULT ) 570 nEsc = static_cast<const SvxEscapementItem* >(pItem)->GetEsc(); 571 572 sal_uInt16 nLineSpace = 0; 573 eState = aCoreSet.GetItemState(RES_PARATR_LINESPACING, false, &pItem); 574 if( SfxItemState::DEFAULT == eState ) 575 pItem = &rPool.GetDefaultItem(RES_PARATR_LINESPACING); 576 if( SfxItemState::DEFAULT <= eState && 577 static_cast<const SvxLineSpacingItem* >(pItem)->GetLineSpaceRule() == SvxLineSpaceRule::Auto ) 578 { 579 if(SvxInterLineSpaceRule::Off == 580 static_cast<const SvxLineSpacingItem* >(pItem)->GetInterLineSpaceRule()) 581 nLineSpace = 100; 582 else 583 nLineSpace = static_cast<const SvxLineSpacingItem* >(pItem)->GetPropLineSpace(); 584 } 585 586 SvxCaseMap eCaseMap = SvxCaseMap::NotMapped; 587 eState = aCoreSet.GetItemState(RES_CHRATR_CASEMAP, false, &pItem); 588 if (eState == SfxItemState::DEFAULT) 589 pItem = &rPool.GetDefaultItem(RES_CHRATR_CASEMAP); 590 if (eState >= SfxItemState::DEFAULT) 591 eCaseMap = static_cast<const SvxCaseMapItem*>(pItem)->GetCaseMap(); 592 593 while (nSlot) 594 { 595 switch(nSlot) 596 { 597 case FN_SET_SUPER_SCRIPT: 598 bFlag = 0 < nEsc; 599 break; 600 case FN_SET_SUB_SCRIPT: 601 bFlag = 0 > nEsc; 602 break; 603 case FN_SET_SMALL_CAPS: 604 bFlag = eCaseMap == SvxCaseMap::SmallCaps; 605 break; 606 case SID_ATTR_PARA_ADJUST_LEFT: 607 if (!bAdjustGood) 608 { 609 rSet.InvalidateItem( nSlot ); 610 nSlot = 0; 611 } 612 else 613 bFlag = SvxAdjust::Left == eAdjust; 614 break; 615 case SID_ATTR_PARA_ADJUST_RIGHT: 616 if (!bAdjustGood) 617 { 618 rSet.InvalidateItem( nSlot ); 619 nSlot = 0; 620 } 621 else 622 bFlag = SvxAdjust::Right == eAdjust; 623 break; 624 case SID_ATTR_PARA_ADJUST_CENTER: 625 if (!bAdjustGood) 626 { 627 rSet.InvalidateItem( nSlot ); 628 nSlot = 0; 629 } 630 else 631 bFlag = SvxAdjust::Center == eAdjust; 632 break; 633 case SID_ATTR_PARA_ADJUST_BLOCK: 634 { 635 if (!bAdjustGood) 636 { 637 rSet.InvalidateItem( nSlot ); 638 nSlot = 0; 639 } 640 else 641 { 642 bFlag = SvxAdjust::Block == eAdjust; 643 sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell()); 644 if((nHtmlMode & HTMLMODE_ON) && !(nHtmlMode & HTMLMODE_FULL_STYLES )) 645 { 646 rSet.DisableItem( nSlot ); 647 nSlot = 0; 648 } 649 } 650 } 651 break; 652 case SID_ATTR_PARA_LINESPACE_10: 653 bFlag = nLineSpace == 100; 654 break; 655 case SID_ATTR_PARA_LINESPACE_15: 656 bFlag = nLineSpace == 150; 657 break; 658 case SID_ATTR_PARA_LINESPACE_20: 659 bFlag = nLineSpace == 200; 660 break; 661 case FN_GROW_FONT_SIZE: 662 case FN_SHRINK_FONT_SIZE: 663 { 664 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, 665 *rSet.GetPool() ); 666 aSetItem.GetItemSet().Put( aCoreSet, false ); 667 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( 668 aSetItem.GetItemOfScript( rSh.GetScriptType() ) ) ); 669 670 if( pSize ) // selection is of one size 671 { 672 sal_uInt32 nSize = pSize->GetHeight(); 673 if( nSize == nFontMaxSz ) 674 rSet.DisableItem( FN_GROW_FONT_SIZE ); 675 else if( nSize == nFontInc ) 676 rSet.DisableItem( FN_SHRINK_FONT_SIZE ); 677 } 678 else 679 { 680 std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> 681 vFontHeight = rSh.GetItemWithPaM( RES_CHRATR_FONTSIZE ); 682 for ( const std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM>>& aIt : vFontHeight ) 683 { 684 if (!aIt.first) 685 { 686 rSet.DisableItem(FN_GROW_FONT_SIZE); 687 rSet.DisableItem(FN_SHRINK_FONT_SIZE); 688 break; 689 } 690 pSize = static_cast<const SvxFontHeightItem*>( aIt.first ); 691 sal_uInt32 nSize = pSize->GetHeight(); 692 if( nSize == nFontMaxSz ) 693 rSet.DisableItem( FN_GROW_FONT_SIZE ); 694 else if( nSize == nFontInc ) 695 rSet.DisableItem( FN_SHRINK_FONT_SIZE ); 696 } 697 } 698 nSlot = 0; 699 } 700 break; 701 case SID_ULINE_VAL_NONE: 702 case SID_ULINE_VAL_SINGLE: 703 case SID_ULINE_VAL_DOUBLE: 704 case SID_ULINE_VAL_DOTTED: 705 { 706 eState = aCoreSet.GetItemState(RES_CHRATR_UNDERLINE); 707 if( eState >= SfxItemState::DEFAULT ) 708 { 709 FontLineStyle eLineStyle = aCoreSet.Get(RES_CHRATR_UNDERLINE).GetLineStyle(); 710 711 switch (nSlot) 712 { 713 case SID_ULINE_VAL_NONE: 714 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_NONE)); 715 break; 716 case SID_ULINE_VAL_SINGLE: 717 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_SINGLE)); 718 break; 719 case SID_ULINE_VAL_DOUBLE: 720 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOUBLE)); 721 break; 722 case SID_ULINE_VAL_DOTTED: 723 rSet.Put(SfxBoolItem(nSlot, eLineStyle == LINESTYLE_DOTTED)); 724 break; 725 } 726 } 727 else 728 rSet.InvalidateItem(nSlot); 729 nSlot = 0; 730 } 731 break; 732 case SID_ATTR_PARA_ADJUST: 733 if (!bAdjustGood) 734 rSet.InvalidateItem( nSlot ); 735 else 736 rSet.Put(SvxAdjustItem(eAdjust, SID_ATTR_PARA_ADJUST )); 737 nSlot = 0; 738 break; 739 case SID_ATTR_PARA_LRSPACE: 740 case SID_ATTR_PARA_LEFTSPACE: 741 case SID_ATTR_PARA_RIGHTSPACE: 742 case SID_ATTR_PARA_FIRSTLINESPACE: 743 { 744 eState = aCoreSet.GetItemState(RES_LR_SPACE); 745 if( eState >= SfxItemState::DEFAULT ) 746 { 747 SvxLRSpaceItem aLR = aCoreSet.Get( RES_LR_SPACE ); 748 aLR.SetWhich(nSlot); 749 rSet.Put(aLR); 750 } 751 else 752 rSet.InvalidateItem(nSlot); 753 nSlot = 0; 754 } 755 break; 756 757 case SID_ATTR_PARA_LEFT_TO_RIGHT : 758 case SID_ATTR_PARA_RIGHT_TO_LEFT : 759 { 760 if ( !SW_MOD()->GetCTLOptions().IsCTLFontEnabled() ) 761 { 762 rSet.DisableItem( nSlot ); 763 nSlot = 0; 764 } 765 else 766 { 767 // is the item set? 768 sal_uInt16 nHtmlMode = GetHtmlMode(rSh.GetView().GetDocShell()); 769 if((!(nHtmlMode & HTMLMODE_ON) || (0 != (nHtmlMode & HTMLMODE_SOME_STYLES))) && 770 aCoreSet.GetItemState( RES_FRAMEDIR, false ) >= SfxItemState::DEFAULT) 771 { 772 SvxFrameDirection eFrameDir = 773 aCoreSet.Get(RES_FRAMEDIR).GetValue(); 774 if (SvxFrameDirection::Environment == eFrameDir) 775 { 776 eFrameDir = rSh.IsInRightToLeftText() ? 777 SvxFrameDirection::Horizontal_RL_TB : SvxFrameDirection::Horizontal_LR_TB; 778 } 779 bFlag = (SID_ATTR_PARA_LEFT_TO_RIGHT == nSlot && 780 SvxFrameDirection::Horizontal_LR_TB == eFrameDir) || 781 (SID_ATTR_PARA_RIGHT_TO_LEFT == nSlot && 782 SvxFrameDirection::Horizontal_RL_TB == eFrameDir); 783 } 784 else 785 { 786 rSet.InvalidateItem(nSlot); 787 nSlot = 0; 788 } 789 } 790 } 791 break; 792 793 case SID_ATTR_CHAR_LANGUAGE: 794 case SID_ATTR_CHAR_KERNING: 795 case RES_PARATR_DROP: 796 { 797 #if OSL_DEBUG_LEVEL > 1 798 const SfxPoolItem& rItem = aCoreSet.Get(GetPool().GetWhich(nSlot), true); 799 rSet.Put(rItem); 800 #else 801 rSet.Put(aCoreSet.Get( GetPool().GetWhich(nSlot))); 802 #endif 803 nSlot = 0; 804 } 805 break; 806 case SID_ATTR_PARA_MODEL: 807 { 808 SfxItemSet aTemp(GetPool(), 809 svl::Items<RES_PAGEDESC,RES_PAGEDESC, 810 SID_ATTR_PARA_MODEL,SID_ATTR_PARA_MODEL>{}); 811 aTemp.Put(aCoreSet); 812 ::SwToSfxPageDescAttr(aTemp); 813 rSet.Put(aTemp.Get(SID_ATTR_PARA_MODEL)); 814 nSlot = 0; 815 } 816 break; 817 case RES_TXTATR_INETFMT: 818 { 819 SfxItemSet aSet(GetPool(), svl::Items<RES_TXTATR_INETFMT, RES_TXTATR_INETFMT>{}); 820 rSh.GetCurAttr(aSet); 821 const SfxPoolItem& rItem = aSet.Get(RES_TXTATR_INETFMT); 822 rSet.Put(rItem); 823 nSlot = 0; 824 } 825 break; 826 827 default: 828 // Do nothing 829 nSlot = 0; 830 break; 831 832 } 833 if( nSlot ) 834 { 835 aFlagItem.SetWhich( nSlot ); 836 aFlagItem.SetValue( bFlag ); 837 rSet.Put( aFlagItem ); 838 } 839 nSlot = aIter.NextWhich(); 840 } 841 842 rSet.Put(aCoreSet,false); 843 } 844 845 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 846
