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 <com/sun/star/style/XStyleFamiliesSupplier.hpp> 21 #include <com/sun/star/beans/XPropertySet.hpp> 22 #include <com/sun/star/container/XNameAccess.hpp> 23 24 #include <scitems.hxx> 25 #include <editeng/borderline.hxx> 26 27 #include <sfx2/viewfrm.hxx> 28 #include <sfx2/bindings.hxx> 29 #include <sfx2/newstyle.hxx> 30 #include <sfx2/objface.hxx> 31 #include <sfx2/request.hxx> 32 #include <sfx2/sfxdlg.hxx> 33 #include <svl/whiter.hxx> 34 35 #include <svl/stritem.hxx> 36 #include <svl/numformat.hxx> 37 #include <svl/zformat.hxx> 38 #include <svl/languageoptions.hxx> 39 #include <svl/cjkoptions.hxx> 40 #include <svl/ctloptions.hxx> 41 #include <editeng/boxitem.hxx> 42 #include <editeng/langitem.hxx> 43 #include <svx/numinf.hxx> 44 #include <sfx2/dispatch.hxx> 45 #include <sfx2/tplpitem.hxx> 46 #include <editeng/svxenum.hxx> 47 #include <editeng/wghtitem.hxx> 48 #include <editeng/postitem.hxx> 49 #include <editeng/udlnitem.hxx> 50 #include <editeng/lineitem.hxx> 51 #include <editeng/colritem.hxx> 52 #include <editeng/brushitem.hxx> 53 #include <editeng/frmdiritem.hxx> 54 #include <editeng/scripttypeitem.hxx> 55 #include <editeng/shaditem.hxx> 56 #include <editeng/justifyitem.hxx> 57 #include <editeng/fhgtitem.hxx> 58 #include <sal/log.hxx> 59 #include <comphelper/lok.hxx> 60 #include <LibreOfficeKit/LibreOfficeKitEnums.h> 61 62 #include <formatsh.hxx> 63 #include <sc.hrc> 64 #include <globstr.hrc> 65 #include <scresid.hxx> 66 #include <docsh.hxx> 67 #include <patattr.hxx> 68 #include <scmod.hxx> 69 #include <stlpool.hxx> 70 #include <stlsheet.hxx> 71 #include <printfun.hxx> 72 #include <docpool.hxx> 73 #include <tabvwsh.hxx> 74 #include <undostyl.hxx> 75 #include <markdata.hxx> 76 #include <attrib.hxx> 77 78 #define ShellClass_ScFormatShell 79 #define ShellClass_TableFont 80 #define ShellClass_FormatForSelection 81 #include <scslots.hxx> 82 83 #include <scabstdlg.hxx> 84 #include <editeng/fontitem.hxx> 85 #include <sfx2/classificationhelper.hxx> 86 87 #include <memory> 88 89 using namespace ::com::sun::star; 90 91 namespace { 92 93 SvxCellHorJustify lclConvertSlotToHAlign( sal_uInt16 nSlot ) 94 { 95 SvxCellHorJustify eHJustify = SvxCellHorJustify::Standard; 96 switch( nSlot ) 97 { 98 case SID_ALIGN_ANY_HDEFAULT: eHJustify = SvxCellHorJustify::Standard; break; 99 case SID_ALIGN_ANY_LEFT: eHJustify = SvxCellHorJustify::Left; break; 100 case SID_ALIGN_ANY_HCENTER: eHJustify = SvxCellHorJustify::Center; break; 101 case SID_ALIGN_ANY_RIGHT: eHJustify = SvxCellHorJustify::Right; break; 102 case SID_ALIGN_ANY_JUSTIFIED: eHJustify = SvxCellHorJustify::Block; break; 103 default: OSL_FAIL( "lclConvertSlotToHAlign - invalid slot" ); 104 } 105 return eHJustify; 106 } 107 108 SvxCellVerJustify lclConvertSlotToVAlign( sal_uInt16 nSlot ) 109 { 110 SvxCellVerJustify eVJustify = SvxCellVerJustify::Standard; 111 switch( nSlot ) 112 { 113 case SID_ALIGN_ANY_VDEFAULT: eVJustify = SvxCellVerJustify::Standard; break; 114 case SID_ALIGN_ANY_TOP: eVJustify = SvxCellVerJustify::Top; break; 115 case SID_ALIGN_ANY_VCENTER: eVJustify = SvxCellVerJustify::Center; break; 116 case SID_ALIGN_ANY_BOTTOM: eVJustify = SvxCellVerJustify::Bottom; break; 117 default: OSL_FAIL( "lclConvertSlotToVAlign - invalid slot" ); 118 } 119 return eVJustify; 120 } 121 122 } // namespace 123 124 125 SFX_IMPL_INTERFACE(ScFormatShell, SfxShell) 126 127 void ScFormatShell::InitInterface_Impl() 128 { 129 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT, 130 SfxVisibilityFlags::Standard | SfxVisibilityFlags::Server, 131 ToolbarId::Objectbar_Format); 132 } 133 134 ScFormatShell::ScFormatShell(ScViewData& rData) : 135 SfxShell(rData.GetViewShell()), 136 rViewData(rData) 137 { 138 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 139 140 SetPool( &pTabViewShell->GetPool() ); 141 SfxUndoManager* pMgr = rViewData.GetSfxDocShell()->GetUndoManager(); 142 SetUndoManager( pMgr ); 143 if ( !rViewData.GetDocument().IsUndoEnabled() ) 144 { 145 pMgr->SetMaxUndoActionCount( 0 ); 146 } 147 SetName("Format"); 148 } 149 150 ScFormatShell::~ScFormatShell() 151 { 152 } 153 154 void ScFormatShell::GetStyleState( SfxItemSet& rSet ) 155 { 156 ScDocument& rDoc = GetViewData().GetDocument(); 157 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 158 SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool(); 159 160 bool bProtected = false; 161 SCTAB nTabCount = rDoc.GetTableCount(); 162 for (SCTAB i=0; i<nTabCount && !bProtected; i++) 163 if (rDoc.IsTabProtected(i)) // look after protected table 164 bProtected = true; 165 166 SfxWhichIter aIter(rSet); 167 sal_uInt16 nWhich = aIter.FirstWhich(); 168 sal_uInt16 nSlotId = 0; 169 170 while ( nWhich ) 171 { 172 nSlotId = SfxItemPool::IsWhich( nWhich ) 173 ? GetPool().GetSlotId( nWhich ) 174 : nWhich; 175 176 switch ( nSlotId ) 177 { 178 case SID_STYLE_APPLY: 179 if ( !pStylePool ) 180 rSet.DisableItem( nSlotId ); 181 break; 182 183 case SID_STYLE_FAMILY2: // cell style sheets 184 { 185 SfxStyleSheet* pStyleSheet = const_cast<SfxStyleSheet*>( 186 pTabViewShell->GetStyleSheetFromMarked()); 187 188 if ( pStyleSheet ) 189 rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) ); 190 else 191 rSet.Put( SfxTemplateItem( nSlotId, OUString() ) ); 192 } 193 break; 194 195 case SID_STYLE_FAMILY4: // page style sheets 196 { 197 SCTAB nCurTab = GetViewData().GetTabNo(); 198 OUString aPageStyle = rDoc.GetPageStyle( nCurTab ); 199 SfxStyleSheet* pStyleSheet = pStylePool ? static_cast<SfxStyleSheet*>(pStylePool-> 200 Find( aPageStyle, SfxStyleFamily::Page )) : nullptr; 201 202 if ( pStyleSheet ) 203 rSet.Put( SfxTemplateItem( nSlotId, aPageStyle ) ); 204 else 205 rSet.Put( SfxTemplateItem( nSlotId, OUString() ) ); 206 } 207 break; 208 209 case SID_STYLE_WATERCAN: 210 { 211 rSet.Put( SfxBoolItem( nSlotId, SC_MOD()->GetIsWaterCan() ) ); 212 } 213 break; 214 215 case SID_STYLE_UPDATE_BY_EXAMPLE: 216 { 217 std::unique_ptr<SfxPoolItem> pItem; 218 pTabViewShell->GetViewFrame()->GetBindings().QueryState(SID_STYLE_FAMILY, pItem); 219 SfxUInt16Item* pFamilyItem = dynamic_cast<SfxUInt16Item*>(pItem.get()); 220 221 bool bPage = pFamilyItem && SfxStyleFamily::Page == static_cast<SfxStyleFamily>(pFamilyItem->GetValue()); 222 223 if ( bProtected || bPage ) 224 rSet.DisableItem( nSlotId ); 225 } 226 break; 227 228 case SID_STYLE_EDIT: 229 case SID_STYLE_DELETE: 230 case SID_STYLE_HIDE: 231 case SID_STYLE_SHOW: 232 { 233 std::unique_ptr<SfxPoolItem> pItem; 234 pTabViewShell->GetViewFrame()->GetBindings().QueryState(SID_STYLE_FAMILY, pItem); 235 SfxUInt16Item* pFamilyItem = dynamic_cast<SfxUInt16Item*>(pItem.get()); 236 bool bPage = pFamilyItem && SfxStyleFamily::Page == static_cast<SfxStyleFamily>(pFamilyItem->GetValue()); 237 238 if ( bProtected && !bPage ) 239 rSet.DisableItem( nSlotId ); 240 } 241 break; 242 243 default: 244 break; 245 } 246 247 nWhich = aIter.NextWhich(); 248 } 249 } 250 251 void ScFormatShell::ExecuteStyle( SfxRequest& rReq ) 252 { 253 const SfxItemSet* pArgs = rReq.GetArgs(); 254 const sal_uInt16 nSlotId = rReq.GetSlot(); 255 if ( !pArgs && nSlotId != SID_STYLE_NEW_BY_EXAMPLE && nSlotId != SID_STYLE_UPDATE_BY_EXAMPLE ) 256 { 257 // in case of vertical toolbar 258 rViewData.GetDispatcher().Execute( SID_STYLE_DESIGNER, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD ); 259 return; 260 } 261 262 SfxBindings& rBindings = rViewData.GetBindings(); 263 const SCTAB nCurTab = GetViewData().GetTabNo(); 264 ScDocShell* pDocSh = GetViewData().GetDocShell(); 265 ScTabViewShell* pTabViewShell= GetViewData().GetViewShell(); 266 ScDocument& rDoc = pDocSh->GetDocument(); 267 ScMarkData& rMark = GetViewData().GetMarkData(); 268 ScModule* pScMod = SC_MOD(); 269 OUString aRefName; 270 bool bUndo = rDoc.IsUndoEnabled(); 271 SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool(); 272 273 if ( (nSlotId == SID_STYLE_PREVIEW) 274 || (nSlotId == SID_STYLE_END_PREVIEW) ) 275 { 276 if (nSlotId == SID_STYLE_PREVIEW) 277 { 278 SfxStyleFamily eFamily = SfxStyleFamily::Para; 279 const SfxPoolItem* pFamItem; 280 if ( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_FAMILY, true, &pFamItem ) ) 281 eFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pFamItem)->GetValue()); 282 const SfxPoolItem* pNameItem; 283 OUString aStyleName; 284 if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem )) 285 aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue(); 286 if ( eFamily == SfxStyleFamily::Para ) // CellStyles 287 { 288 ScMarkData aFuncMark( rViewData.GetMarkData() ); 289 ScViewUtil::UnmarkFiltered( aFuncMark, rDoc ); 290 aFuncMark.MarkToMulti(); 291 292 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() ) 293 { 294 SCCOL nCol = rViewData.GetCurX(); 295 SCROW nRow = rViewData.GetCurY(); 296 SCTAB nTab = rViewData.GetTabNo(); 297 ScRange aRange( nCol, nRow, nTab ); 298 aFuncMark.SetMarkArea( aRange ); 299 } 300 rDoc.SetPreviewSelection( aFuncMark ); 301 ScStyleSheet* pPreviewStyle = static_cast<ScStyleSheet*>( pStylePool->Find( aStyleName, eFamily ) ); 302 rDoc.SetPreviewCellStyle( pPreviewStyle ); 303 ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aFuncMark ) ); 304 aAttr.SetStyleSheet( pPreviewStyle ); 305 306 SfxItemSet aItemSet( GetPool() ); 307 308 ScPatternAttr aNewAttrs( GetViewData().GetDocument().GetPool() ); 309 SfxItemSet& rNewSet = aNewAttrs.GetItemSet(); 310 rNewSet.Put( aItemSet, false ); 311 312 rDoc.ApplySelectionPattern( aNewAttrs, rDoc.GetPreviewSelection() ); 313 pTabViewShell->UpdateSelectionArea( aFuncMark, &aAttr ); 314 } 315 } 316 else 317 { 318 // No mark at all happens when creating a new document, in which 319 // case the selection pattern obtained would be empty (created of 320 // GetPool()) anyway and nothing needs to be applied. 321 ScMarkData aPreviewMark( rDoc.GetPreviewSelection()); 322 if (aPreviewMark.IsMarked() || aPreviewMark.IsMultiMarked()) 323 { 324 ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aPreviewMark ) ); 325 if ( ScStyleSheet* pPreviewStyle = rDoc.GetPreviewCellStyle() ) 326 aAttr.SetStyleSheet( pPreviewStyle ); 327 rDoc.SetPreviewCellStyle(nullptr); 328 329 SfxItemSet aItemSet( GetPool() ); 330 331 ScPatternAttr aNewAttrs( GetViewData().GetDocument().GetPool() ); 332 SfxItemSet& rNewSet = aNewAttrs.GetItemSet(); 333 rNewSet.Put( aItemSet, false ); 334 rDoc.ApplySelectionPattern( aNewAttrs, aPreviewMark ); 335 pTabViewShell->UpdateSelectionArea( aPreviewMark, &aAttr ); 336 } 337 } 338 } 339 else if ( (nSlotId == SID_STYLE_NEW) 340 || (nSlotId == SID_STYLE_EDIT) 341 || (nSlotId == SID_STYLE_DELETE) 342 || (nSlotId == SID_STYLE_HIDE) 343 || (nSlotId == SID_STYLE_SHOW) 344 || (nSlotId == SID_STYLE_APPLY) 345 || (nSlotId == SID_STYLE_WATERCAN) 346 || (nSlotId == SID_STYLE_FAMILY) 347 || (nSlotId == SID_STYLE_NEW_BY_EXAMPLE) 348 || (nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE) ) 349 { 350 SfxStyleSheetBase* pStyleSheet = nullptr; 351 352 bool bStyleToMarked = false; 353 bool bListAction = false; 354 bool bAddUndo = false; // add ScUndoModifyStyle (style modified) 355 ScStyleSaveData aOldData; // for undo/redo 356 ScStyleSaveData aNewData; 357 358 SfxStyleFamily eFamily = SfxStyleFamily::Para; 359 const SfxPoolItem* pFamItem; 360 if ( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_FAMILY, true, &pFamItem ) ) 361 eFamily = static_cast<SfxStyleFamily>(static_cast<const SfxUInt16Item*>(pFamItem)->GetValue()); 362 else if ( pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_FAMILYNAME, true, &pFamItem ) ) 363 { 364 OUString sFamily = static_cast<const SfxStringItem*>(pFamItem)->GetValue(); 365 if (sFamily == "CellStyles") 366 eFamily = SfxStyleFamily::Para; 367 else if (sFamily == "PageStyles") 368 eFamily = SfxStyleFamily::Page; 369 } 370 371 OUString aStyleName; 372 sal_uInt16 nRetMask = 0xffff; 373 374 switch ( nSlotId ) 375 { 376 case SID_STYLE_NEW: 377 { 378 const SfxPoolItem* pNameItem; 379 if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem )) 380 aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue(); 381 382 const SfxPoolItem* pRefItem=nullptr; 383 if (pArgs && SfxItemState::SET == pArgs->GetItemState( SID_STYLE_REFERENCE, true, &pRefItem )) 384 { 385 if(pRefItem!=nullptr) 386 aRefName = static_cast<const SfxStringItem*>(pRefItem)->GetValue(); 387 } 388 389 pStyleSheet = &(pStylePool->Make( aStyleName, eFamily, 390 SfxStyleSearchBits::UserDefined ) ); 391 392 if (pStyleSheet->HasParentSupport()) 393 pStyleSheet->SetParent(aRefName); 394 } 395 break; 396 397 case SID_STYLE_APPLY: 398 { 399 const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_APPLY_STYLE); 400 const SfxStringItem* pFamilyItem = rReq.GetArg<SfxStringItem>(SID_STYLE_FAMILYNAME); 401 if ( pFamilyItem && pNameItem ) 402 { 403 css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(pDocSh->GetModel(), css::uno::UNO_QUERY); 404 try 405 { 406 css::uno::Reference< css::container::XNameAccess > xStyles; 407 css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies(); 408 xCont->getByName(pFamilyItem->GetValue()) >>= xStyles; 409 css::uno::Reference< css::beans::XPropertySet > xInfo; 410 xStyles->getByName( pNameItem->GetValue() ) >>= xInfo; 411 OUString aUIName; 412 xInfo->getPropertyValue("DisplayName") >>= aUIName; 413 if ( !aUIName.isEmpty() ) 414 rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) ); 415 } 416 catch( css::uno::Exception& ) 417 { 418 } 419 } 420 [[fallthrough]]; 421 } 422 case SID_STYLE_EDIT: 423 case SID_STYLE_DELETE: 424 case SID_STYLE_HIDE: 425 case SID_STYLE_SHOW: 426 case SID_STYLE_NEW_BY_EXAMPLE: 427 { 428 const SfxPoolItem* pNameItem; 429 if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem )) 430 aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue(); 431 else if ( nSlotId == SID_STYLE_NEW_BY_EXAMPLE ) 432 { 433 weld::Window* pDialogParent = rReq.GetFrameWeld(); 434 if (!pDialogParent) 435 pDialogParent = pTabViewShell->GetFrameWeld(); 436 SfxNewStyleDlg aDlg(pDialogParent, *pStylePool, eFamily); 437 if (aDlg.run() != RET_OK) 438 return; 439 aStyleName = aDlg.GetName(); 440 } 441 442 pStyleSheet = pStylePool->Find( aStyleName, eFamily ); 443 444 aOldData.InitFromStyle( pStyleSheet ); 445 } 446 break; 447 448 case SID_STYLE_WATERCAN: 449 { 450 bool bWaterCan = pScMod->GetIsWaterCan(); 451 452 if( !bWaterCan ) 453 { 454 const SfxPoolItem* pItem; 455 456 if ( SfxItemState::SET == 457 pArgs->GetItemState( nSlotId, true, &pItem ) ) 458 { 459 const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem *>( pItem ); 460 if ( pStrItem ) 461 { 462 aStyleName = pStrItem->GetValue(); 463 pStyleSheet = pStylePool->Find( aStyleName, eFamily ); 464 465 if ( pStyleSheet ) 466 { 467 static_cast<ScStyleSheetPool*>(pStylePool)-> 468 SetActualStyleSheet( pStyleSheet ); 469 rReq.Done(); 470 } 471 } 472 } 473 } 474 475 if ( !bWaterCan && pStyleSheet ) 476 { 477 pScMod->SetWaterCan( true ); 478 pTabViewShell->SetActivePointer( PointerStyle::Fill ); 479 rReq.Done(); 480 } 481 else 482 { 483 pScMod->SetWaterCan( false ); 484 pTabViewShell->SetActivePointer( PointerStyle::Arrow ); 485 rReq.Done(); 486 } 487 } 488 break; 489 490 default: 491 break; 492 } 493 494 // set new style for paintbrush format mode 495 if ( nSlotId == SID_STYLE_APPLY && pScMod->GetIsWaterCan() && pStyleSheet ) 496 static_cast<ScStyleSheetPool*>(pStylePool)->SetActualStyleSheet( pStyleSheet ); 497 498 switch ( eFamily ) 499 { 500 case SfxStyleFamily::Para: 501 { 502 switch ( nSlotId ) 503 { 504 case SID_STYLE_DELETE: 505 { 506 if ( pStyleSheet ) 507 { 508 pTabViewShell->RemoveStyleSheetInUse( pStyleSheet ); 509 pStylePool->Remove( pStyleSheet ); 510 pTabViewShell->InvalidateAttribs(); 511 nRetMask = sal_uInt16(true); 512 bAddUndo = true; 513 rReq.Done(); 514 } 515 else 516 nRetMask = sal_uInt16(false); 517 } 518 break; 519 520 case SID_STYLE_HIDE: 521 case SID_STYLE_SHOW: 522 { 523 if ( pStyleSheet ) 524 { 525 pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE ); 526 pTabViewShell->InvalidateAttribs(); 527 rReq.Done(); 528 } 529 else 530 nRetMask = sal_uInt16(false); 531 } 532 break; 533 534 case SID_STYLE_APPLY: 535 { 536 if ( pStyleSheet && !pScMod->GetIsWaterCan() ) 537 { 538 // apply style sheet to document 539 pTabViewShell->SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) ); 540 pTabViewShell->InvalidateAttribs(); 541 rReq.Done(); 542 } 543 } 544 break; 545 546 case SID_STYLE_NEW_BY_EXAMPLE: 547 case SID_STYLE_UPDATE_BY_EXAMPLE: 548 { 549 // create/replace style sheet by attributes 550 // at cursor position: 551 552 const ScPatternAttr* pAttrItem = nullptr; 553 554 // The query if marked, was always wrong here, 555 // so now no more, and just from the cursor. 556 // If attributes are to be removed from the selection, still need to be 557 // cautious not to adopt items from templates 558 // (GetSelectionPattern also collects items from originals) (# 44748 #) 559 SCCOL nCol = rViewData.GetCurX(); 560 SCROW nRow = rViewData.GetCurY(); 561 pAttrItem = rDoc.GetPattern( nCol, nRow, nCurTab ); 562 563 SfxItemSet aAttrSet = pAttrItem->GetItemSet(); 564 aAttrSet.ClearItem( ATTR_MERGE ); 565 aAttrSet.ClearItem( ATTR_MERGE_FLAG ); 566 567 // Do not adopt conditional formatting and validity, 568 // because they can not be edited in the template 569 aAttrSet.ClearItem( ATTR_VALIDDATA ); 570 aAttrSet.ClearItem( ATTR_CONDITIONAL ); 571 572 if ( SID_STYLE_NEW_BY_EXAMPLE == nSlotId ) 573 { 574 if ( bUndo ) 575 { 576 OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE ); 577 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, pTabViewShell->GetViewShellId() ); 578 bListAction = true; 579 } 580 581 bool bConvertBack = false; 582 SfxStyleSheet* pSheetInUse = const_cast<SfxStyleSheet*>( 583 pTabViewShell->GetStyleSheetFromMarked()); 584 585 // when a new style is present and is used in the selection, 586 // then the parent can not be adopted: 587 if ( pStyleSheet && pSheetInUse && pStyleSheet == pSheetInUse ) 588 pSheetInUse = nullptr; 589 590 // if already present, first remove ... 591 if ( pStyleSheet ) 592 { 593 // style pointer to names before erase, 594 // otherwise cells will get invalid pointer 595 //!!! As it happens, a method that does it for a particular style 596 rDoc.StylesToNames(); 597 bConvertBack = true; 598 pStylePool->Remove(pStyleSheet); 599 } 600 601 // ...and create new 602 pStyleSheet = &pStylePool->Make( aStyleName, eFamily, 603 SfxStyleSearchBits::UserDefined ); 604 605 // when a style is present, then this will become 606 // the parent of the new style: 607 if ( pSheetInUse && pStyleSheet->HasParentSupport() ) 608 pStyleSheet->SetParent( pSheetInUse->GetName() ); 609 610 if ( bConvertBack ) 611 // Name to style pointer 612 rDoc.UpdStlShtPtrsFrmNms(); 613 else 614 rDoc.GetPool()->CellStyleCreated( aStyleName, rDoc ); 615 616 // Adopt attribute and use style 617 pStyleSheet->GetItemSet().Put( aAttrSet ); 618 pTabViewShell->UpdateStyleSheetInUse( pStyleSheet ); 619 620 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle 621 // (pStyleSheet pointer is used!) 622 bStyleToMarked = true; 623 } 624 else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE ) 625 { 626 pStyleSheet = const_cast<SfxStyleSheet*>(pTabViewShell->GetStyleSheetFromMarked()); 627 628 if ( pStyleSheet ) 629 { 630 aOldData.InitFromStyle( pStyleSheet ); 631 632 if ( bUndo ) 633 { 634 OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE ); 635 pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, pTabViewShell->GetViewShellId() ); 636 bListAction = true; 637 } 638 639 pStyleSheet->GetItemSet().Put( aAttrSet ); 640 pTabViewShell->UpdateStyleSheetInUse( pStyleSheet ); 641 642 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle 643 // (pStyleSheet pointer is used!) 644 bStyleToMarked = true; 645 } 646 } 647 648 aNewData.InitFromStyle( pStyleSheet ); 649 bAddUndo = true; 650 rReq.Done(); 651 } 652 break; 653 654 default: 655 break; 656 } 657 } // case SfxStyleFamily::Para: 658 break; 659 660 case SfxStyleFamily::Page: 661 { 662 switch ( nSlotId ) 663 { 664 case SID_STYLE_DELETE: 665 { 666 nRetMask = sal_uInt16( nullptr != pStyleSheet ); 667 if ( pStyleSheet ) 668 { 669 if ( rDoc.RemovePageStyleInUse( pStyleSheet->GetName() ) ) 670 { 671 ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(true), nCurTab ).UpdatePages(); 672 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); 673 rBindings.Invalidate( FID_RESET_PRINTZOOM ); 674 } 675 pStylePool->Remove( pStyleSheet ); 676 rBindings.Invalidate( SID_STYLE_FAMILY4 ); 677 pDocSh->SetDocumentModified(); 678 bAddUndo = true; 679 rReq.Done(); 680 } 681 } 682 break; 683 684 case SID_STYLE_HIDE: 685 case SID_STYLE_SHOW: 686 { 687 nRetMask = sal_uInt16( nullptr != pStyleSheet ); 688 if ( pStyleSheet ) 689 { 690 pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE ); 691 rBindings.Invalidate( SID_STYLE_FAMILY4 ); 692 pDocSh->SetDocumentModified(); 693 rReq.Done(); 694 } 695 } 696 break; 697 698 case SID_STYLE_APPLY: 699 { 700 nRetMask = sal_uInt16( nullptr != pStyleSheet ); 701 if ( pStyleSheet && !pScMod->GetIsWaterCan() ) 702 { 703 std::unique_ptr<ScUndoApplyPageStyle> pUndoAction; 704 SCTAB nTabCount = rDoc.GetTableCount(); 705 for (const auto& rTab : rMark) 706 { 707 if (rTab >= nTabCount) 708 break; 709 OUString aOldName = rDoc.GetPageStyle( rTab ); 710 if ( aOldName != aStyleName ) 711 { 712 rDoc.SetPageStyle( rTab, aStyleName ); 713 ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(true), rTab ).UpdatePages(); 714 if( !pUndoAction ) 715 pUndoAction.reset(new ScUndoApplyPageStyle( pDocSh, aStyleName )); 716 pUndoAction->AddSheetAction( rTab, aOldName ); 717 } 718 } 719 if( pUndoAction ) 720 { 721 pDocSh->GetUndoManager()->AddUndoAction( std::move(pUndoAction) ); 722 pDocSh->SetDocumentModified(); 723 rBindings.Invalidate( SID_STYLE_FAMILY4 ); 724 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); 725 rBindings.Invalidate( FID_RESET_PRINTZOOM ); 726 } 727 rReq.Done(); 728 } 729 } 730 break; 731 732 case SID_STYLE_NEW_BY_EXAMPLE: 733 { 734 const OUString& rStrCurStyle = rDoc.GetPageStyle( nCurTab ); 735 736 if ( rStrCurStyle != aStyleName ) 737 { 738 SfxStyleSheetBase* pCurStyle = pStylePool->Find( rStrCurStyle, eFamily ); 739 SfxItemSet aAttrSet = pCurStyle->GetItemSet(); 740 SCTAB nInTab; 741 bool bUsed = rDoc.IsPageStyleInUse( aStyleName, &nInTab ); 742 743 // if already present, first remove... 744 if ( pStyleSheet ) 745 pStylePool->Remove( pStyleSheet ); 746 747 // ...and create new 748 pStyleSheet = &pStylePool->Make( aStyleName, eFamily, 749 SfxStyleSearchBits::UserDefined ); 750 751 // Adopt attribute 752 pStyleSheet->GetItemSet().Put( aAttrSet ); 753 pDocSh->SetDocumentModified(); 754 755 // If being used -> Update 756 if ( bUsed ) 757 ScPrintFunc( pDocSh, pTabViewShell->GetPrinter(true), nInTab ).UpdatePages(); 758 759 aNewData.InitFromStyle( pStyleSheet ); 760 bAddUndo = true; 761 rReq.Done(); 762 nRetMask = sal_uInt16(true); 763 } 764 } 765 break; 766 767 default: 768 break; 769 } // switch ( nSlotId ) 770 } // case SfxStyleFamily::Page: 771 break; 772 773 default: 774 break; 775 } // switch ( eFamily ) 776 777 // create new or process through Dialog: 778 if ( nSlotId == SID_STYLE_NEW || nSlotId == SID_STYLE_EDIT ) 779 { 780 if ( pStyleSheet ) 781 { 782 SfxStyleFamily eFam = pStyleSheet->GetFamily(); 783 ScopedVclPtr<SfxAbstractTabDialog> pDlg; 784 bool bPage = false; 785 786 // Store old Items from the style 787 SfxItemSet aOldSet = pStyleSheet->GetItemSet(); 788 OUString aOldName = pStyleSheet->GetName(); 789 790 switch ( eFam ) 791 { 792 case SfxStyleFamily::Page: 793 bPage = true; 794 break; 795 796 case SfxStyleFamily::Para: 797 default: 798 { 799 SfxItemSet& rSet = pStyleSheet->GetItemSet(); 800 801 const SfxPoolItem* pItem; 802 if ( rSet.GetItemState( ATTR_VALUE_FORMAT, 803 false, &pItem ) == SfxItemState::SET ) 804 { 805 // Produce and format NumberFormat Value from Value and Language 806 sal_uLong nFormat = 807 static_cast<const SfxUInt32Item*>(pItem)->GetValue(); 808 LanguageType eLang = 809 rSet.Get(ATTR_LANGUAGE_FORMAT ).GetLanguage(); 810 sal_uLong nLangFormat = rDoc.GetFormatTable()-> 811 GetFormatForLanguageIfBuiltIn( nFormat, eLang ); 812 if ( nLangFormat != nFormat ) 813 { 814 SfxUInt32Item aNewItem( ATTR_VALUE_FORMAT, nLangFormat ); 815 rSet.Put( aNewItem ); 816 aOldSet.Put( aNewItem ); 817 // Also in aOldSet for comparison after the dialog, 818 // Otherwise might miss a language change 819 } 820 } 821 822 std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem( 823 ScTabViewShell::MakeNumberInfoItem(rDoc, GetViewData())); 824 825 pDocSh->PutItem( *pNumberInfoItem ); 826 bPage = false; 827 828 // Definitely a SvxBoxInfoItem with Table = sal_False in set: 829 // (If there is no item, the dialogue will also delete the 830 // BORDER_OUTER SvxBoxItem from the Template Set) 831 if ( rSet.GetItemState( ATTR_BORDER_INNER, false ) != SfxItemState::SET ) 832 { 833 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER ); 834 aBoxInfoItem.SetTable(false); // no inner lines 835 aBoxInfoItem.SetDist(true); 836 aBoxInfoItem.SetMinDist(false); 837 rSet.Put( aBoxInfoItem ); 838 } 839 } 840 break; 841 } 842 843 pTabViewShell->SetInFormatDialog(true); 844 845 SfxItemSet& rStyleSet = pStyleSheet->GetItemSet(); 846 rStyleSet.MergeRange( XATTR_FILL_FIRST, XATTR_FILL_LAST ); 847 848 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); 849 850 weld::Window* pDialogParent = rReq.GetFrameWeld(); 851 if (!pDialogParent) 852 pDialogParent = pTabViewShell->GetFrameWeld(); 853 pDlg.disposeAndReset(pFact->CreateScStyleDlg(pDialogParent, *pStyleSheet, bPage)); 854 short nResult = pDlg->Execute(); 855 pTabViewShell->SetInFormatDialog(false); 856 857 if ( nResult == RET_OK ) 858 { 859 const SfxItemSet* pOutSet = pDlg->GetOutputItemSet(); 860 861 if ( pOutSet ) 862 { 863 nRetMask = sal_uInt16(pStyleSheet->GetMask()); 864 865 // Attribute comparisons (earlier in ModifyStyleSheet) now here 866 // with the old values (the style is already changed) 867 if ( SfxStyleFamily::Para == eFam ) 868 { 869 SfxItemSet& rNewSet = pStyleSheet->GetItemSet(); 870 bool bNumFormatChanged; 871 if ( ScGlobal::CheckWidthInvalidate( 872 bNumFormatChanged, rNewSet, aOldSet ) ) 873 rDoc.InvalidateTextWidth( nullptr, nullptr, bNumFormatChanged ); 874 875 SCTAB nTabCount = rDoc.GetTableCount(); 876 for (SCTAB nTab=0; nTab<nTabCount; nTab++) 877 rDoc.SetStreamValid(nTab, false); 878 879 sal_uLong nOldFormat = aOldSet.Get( ATTR_VALUE_FORMAT ).GetValue(); 880 sal_uLong nNewFormat = rNewSet.Get( ATTR_VALUE_FORMAT ).GetValue(); 881 if ( nNewFormat != nOldFormat ) 882 { 883 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 884 const SvNumberformat* pOld = pFormatter->GetEntry( nOldFormat ); 885 const SvNumberformat* pNew = pFormatter->GetEntry( nNewFormat ); 886 if ( pOld && pNew && pOld->GetLanguage() != pNew->GetLanguage() ) 887 rNewSet.Put( SvxLanguageItem( 888 pNew->GetLanguage(), ATTR_LANGUAGE_FORMAT ) ); 889 } 890 891 rDoc.GetPool()->CellStyleCreated( pStyleSheet->GetName(), rDoc ); 892 } 893 else 894 { 895 //! Here also queries for Page Styles 896 897 OUString aNewName = pStyleSheet->GetName(); 898 if ( aNewName != aOldName && 899 rDoc.RenamePageStyleInUse( aOldName, aNewName ) ) 900 { 901 rBindings.Invalidate( SID_STATUS_PAGESTYLE ); 902 rBindings.Invalidate( FID_RESET_PRINTZOOM ); 903 } 904 905 rDoc.ModifyStyleSheet( *pStyleSheet, *pOutSet ); 906 rBindings.Invalidate( FID_RESET_PRINTZOOM ); 907 } 908 909 pDocSh->SetDocumentModified(); 910 911 if ( SfxStyleFamily::Para == eFam ) 912 { 913 ScTabViewShell::UpdateNumberFormatter( 914 *( pDocSh->GetItem(SID_ATTR_NUMBERFORMAT_INFO) )); 915 916 pTabViewShell->UpdateStyleSheetInUse( pStyleSheet ); 917 pTabViewShell->InvalidateAttribs(); 918 } 919 920 aNewData.InitFromStyle( pStyleSheet ); 921 bAddUndo = true; 922 } 923 } 924 else 925 { 926 if ( nSlotId == SID_STYLE_NEW ) 927 pStylePool->Remove( pStyleSheet ); 928 else 929 { 930 // If in the meantime something was painted with the 931 // temporary changed item set 932 pDocSh->PostPaintGridAll(); 933 } 934 } 935 } 936 } 937 938 rReq.SetReturnValue( SfxUInt16Item( nSlotId, nRetMask ) ); 939 940 if ( bAddUndo && bUndo) 941 pDocSh->GetUndoManager()->AddUndoAction( 942 std::make_unique<ScUndoModifyStyle>( pDocSh, eFamily, aOldData, aNewData ) ); 943 944 if ( bStyleToMarked ) 945 { 946 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle, 947 // so redo will find the modified style 948 pTabViewShell->SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) ); 949 pTabViewShell->InvalidateAttribs(); 950 } 951 952 if ( bListAction ) 953 pDocSh->GetUndoManager()->LeaveListAction(); 954 } 955 else if (nSlotId == SID_CLASSIFICATION_APPLY) 956 { 957 const SfxPoolItem* pItem = nullptr; 958 if (pArgs && pArgs->GetItemState(nSlotId, false, &pItem) == SfxItemState::SET) 959 { 960 const OUString& rName = static_cast<const SfxStringItem*>(pItem)->GetValue(); 961 SfxClassificationHelper aHelper(pDocSh->getDocProperties()); 962 auto eType = SfxClassificationPolicyType::IntellectualProperty; 963 if (pArgs->GetItemState(SID_TYPE_NAME, false, &pItem) == SfxItemState::SET) 964 { 965 const OUString& rType = static_cast<const SfxStringItem*>(pItem)->GetValue(); 966 eType = SfxClassificationHelper::stringToPolicyType(rType); 967 } 968 aHelper.SetBACName(rName, eType); 969 } 970 else 971 SAL_WARN("sc.ui", "missing parameter for SID_CLASSIFICATION_APPLY"); 972 } 973 else 974 { 975 OSL_FAIL( "Unknown slot (ScViewShell::ExecuteStyle)" ); 976 } 977 } 978 979 void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq ) 980 { 981 ScModule* pScMod = SC_MOD(); 982 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 983 const SfxItemSet* pReqArgs = rReq.GetArgs(); 984 sal_uInt16 nSlot = rReq.GetSlot(); 985 SfxBindings& rBindings = pTabViewShell->GetViewFrame()->GetBindings(); 986 987 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox 988 989 // End input 990 if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) ) 991 { 992 switch ( nSlot ) 993 { 994 case SID_NUMBER_TYPE_FORMAT: 995 case SID_NUMBER_TWODEC: 996 case SID_NUMBER_SCIENTIFIC: 997 case SID_NUMBER_DATE: 998 case SID_NUMBER_CURRENCY: 999 case SID_NUMBER_PERCENT: 1000 case SID_NUMBER_STANDARD: 1001 case SID_NUMBER_FORMAT: 1002 case SID_NUMBER_INCDEC: 1003 case SID_NUMBER_DECDEC: 1004 case SID_NUMBER_THOUSANDS: 1005 case FID_DEFINE_NAME: 1006 case FID_ADD_NAME: 1007 case FID_USE_NAME: 1008 case FID_INSERT_NAME: 1009 case SID_SPELL_DIALOG: 1010 case SID_HANGUL_HANJA_CONVERSION: 1011 1012 pScMod->InputEnterHandler(); 1013 pTabViewShell->UpdateInputHandler(); 1014 break; 1015 1016 default: 1017 break; 1018 } 1019 } 1020 1021 SvNumFormatType nType = GetCurrentNumberFormatType(); 1022 switch ( nSlot ) 1023 { 1024 case SID_NUMBER_TWODEC: 1025 { 1026 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 1027 sal_uInt32 nNumberFormat = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue(); 1028 1029 if ((nType & SvNumFormatType::NUMBER) && nNumberFormat == 4) 1030 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1031 else 1032 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 4 ); 1033 rBindings.Invalidate( nSlot ); 1034 rReq.Done(); 1035 } 1036 break; 1037 case SID_NUMBER_SCIENTIFIC: 1038 if (nType & SvNumFormatType::SCIENTIFIC) 1039 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1040 else 1041 pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC ); 1042 rBindings.Invalidate( nSlot ); 1043 rReq.Done(); 1044 break; 1045 case SID_NUMBER_DATE: 1046 if (nType & SvNumFormatType::DATE) 1047 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1048 else 1049 pTabViewShell->SetNumberFormat( SvNumFormatType::DATE ); 1050 rBindings.Invalidate( nSlot ); 1051 rReq.Done(); 1052 break; 1053 case SID_NUMBER_TIME: 1054 if (nType & SvNumFormatType::TIME) 1055 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1056 else 1057 pTabViewShell->SetNumberFormat( SvNumFormatType::TIME ); 1058 rBindings.Invalidate( nSlot ); 1059 rReq.Done(); 1060 break; 1061 case SID_NUMBER_CURRENCY: 1062 if(pReqArgs) 1063 { 1064 const SfxPoolItem* pItem; 1065 if ( pReqArgs->HasItem( SID_NUMBER_CURRENCY, &pItem ) ) 1066 { 1067 sal_uInt32 nNewFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue(); 1068 ScDocument& rDoc = rViewData.GetDocument(); 1069 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 1070 const SfxItemSet& rOldSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 1071 1072 LanguageType eOldLang = rOldSet.Get( ATTR_LANGUAGE_FORMAT ).GetLanguage(); 1073 sal_uInt32 nOldFormat = rOldSet.Get( ATTR_VALUE_FORMAT ).GetValue(); 1074 1075 if ( nOldFormat != nNewFormat ) 1076 { 1077 const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat ); 1078 ScPatternAttr aNewAttrs( rDoc.GetPool() ); 1079 SfxItemSet& rSet = aNewAttrs.GetItemSet(); 1080 LanguageType eNewLang = pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW; 1081 if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW ) 1082 rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) ); 1083 rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); 1084 pTabViewShell->ApplySelectionPattern( aNewAttrs ); 1085 } 1086 else 1087 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1088 } 1089 } 1090 else 1091 { 1092 if ( nType & SvNumFormatType::CURRENCY ) 1093 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1094 else 1095 pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY ); 1096 } 1097 rBindings.Invalidate( nSlot ); 1098 rReq.Done(); 1099 break; 1100 case SID_NUMBER_PERCENT: 1101 if (nType & SvNumFormatType::PERCENT) 1102 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1103 else 1104 pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT ); 1105 rBindings.Invalidate( nSlot ); 1106 rReq.Done(); 1107 break; 1108 case SID_NUMBER_STANDARD: 1109 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER ); 1110 rReq.Done(); 1111 break; 1112 case SID_NUMBER_INCDEC: 1113 pTabViewShell->ChangeNumFmtDecimals( true ); 1114 rReq.Done(); 1115 break; 1116 case SID_NUMBER_DECDEC: 1117 pTabViewShell->ChangeNumFmtDecimals( false ); 1118 rReq.Done(); 1119 break; 1120 case SID_NUMBER_THOUSANDS: 1121 { 1122 ScDocument& rDoc = rViewData.GetDocument(); 1123 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 1124 bool bThousand(false); 1125 bool bNegRed(false); 1126 sal_uInt16 nPrecision(0); 1127 sal_uInt16 nLeadZeroes(0); 1128 LanguageType eLanguage = ScGlobal::eLnge; 1129 1130 sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat( 1131 rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo()); 1132 const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat); 1133 1134 if (pEntry) 1135 eLanguage = pEntry->GetLanguage(); 1136 1137 pFormatter->GetFormatSpecialInfo(nCurrentNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes); 1138 bThousand = !bThousand; 1139 OUString aCode = pFormatter->GenerateFormat( 1140 nCurrentNumberFormat, 1141 eLanguage, 1142 bThousand, 1143 bNegRed, 1144 nPrecision, 1145 nLeadZeroes); 1146 pTabViewShell->SetNumFmtByStr(aCode); 1147 1148 rBindings.Invalidate(nSlot); 1149 rReq.Done(); 1150 } 1151 break; 1152 case SID_NUMBER_FORMAT: 1153 // symphony version with format interpretation 1154 if(pReqArgs) 1155 { 1156 const SfxPoolItem* pItem; 1157 ScDocument& rDoc = rViewData.GetDocument(); 1158 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 1159 1160 sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat( 1161 rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo()); 1162 const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat); 1163 1164 if(!pEntry) 1165 break; 1166 1167 LanguageType eLanguage = pEntry->GetLanguage(); 1168 SvNumFormatType eType = pEntry->GetMaskedType(); 1169 1170 //Just use eType to judge whether the command is fired for NUMBER/PERCENT/CURRENCY/SCIENTIFIC/FRACTION/TIME 1171 //In sidebar, users can fire SID_NUMBER_FORMAT command by operating the related UI controls before they are disable 1172 if(!(eType == SvNumFormatType::ALL 1173 || eType == SvNumFormatType::NUMBER 1174 || eType == SvNumFormatType::PERCENT 1175 || eType == SvNumFormatType::CURRENCY 1176 || eType == SvNumFormatType::SCIENTIFIC 1177 || eType == SvNumFormatType::TIME 1178 || eType == SvNumFormatType::FRACTION)) 1179 pEntry = nullptr; 1180 1181 if(SfxItemState::SET == pReqArgs->GetItemState(nSlot, true, &pItem) && pEntry) 1182 { 1183 OUString aCode = static_cast<const SfxStringItem*>(pItem)->GetValue(); 1184 sal_uInt16 aLen = aCode.getLength(); 1185 std::unique_ptr<OUString[]> sFormat( new OUString[4] ); 1186 OUStringBuffer sTmpStr; 1187 sal_uInt16 nCount(0); 1188 sal_uInt16 nStrCount(0); 1189 1190 while(nCount < aLen) 1191 { 1192 sal_Unicode cChar = aCode[nCount]; 1193 1194 if(cChar == ',') 1195 { 1196 sFormat[nStrCount] = sTmpStr.makeStringAndClear(); 1197 nStrCount++; 1198 } 1199 else 1200 { 1201 sTmpStr.append(cChar); 1202 } 1203 1204 nCount++; 1205 1206 if(nStrCount > 3) 1207 break; 1208 } 1209 1210 const bool bThousand = static_cast<bool>(sFormat[0].toInt32()); 1211 const bool bNegRed = static_cast<bool>(sFormat[1].toInt32()); 1212 const sal_uInt16 nPrecision = static_cast<sal_uInt16>(sFormat[2].toInt32()); 1213 const sal_uInt16 nLeadZeroes = static_cast<sal_uInt16>(sFormat[3].toInt32()); 1214 1215 aCode = pFormatter->GenerateFormat( 1216 nCurrentNumberFormat,//modify 1217 eLanguage, 1218 bThousand, 1219 bNegRed, 1220 nPrecision, 1221 nLeadZeroes); 1222 pTabViewShell->SetNumFmtByStr(aCode); 1223 } 1224 } 1225 break; 1226 1227 case SID_ATTR_NUMBERFORMAT_VALUE: 1228 if ( pReqArgs ) 1229 { 1230 const SfxPoolItem* pItem; 1231 if ( pReqArgs->GetItemState( ATTR_VALUE_FORMAT, true, &pItem ) == SfxItemState::SET ) 1232 { 1233 // We have to accomplish this using ApplyAttributes() 1234 // because we also need the language information to be 1235 // considered. 1236 const SfxItemSet& rOldSet = 1237 pTabViewShell->GetSelectionPattern()->GetItemSet(); 1238 SfxItemPool* pDocPool = GetViewData().GetDocument().GetPool(); 1239 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *pDocPool ); 1240 aNewSet.Put( *pItem ); 1241 pTabViewShell->ApplyAttributes( &aNewSet, &rOldSet ); 1242 } 1243 } 1244 break; 1245 1246 case SID_NUMBER_TYPE_FORMAT: 1247 if ( pReqArgs ) 1248 { 1249 const SfxPoolItem* pItem; 1250 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) 1251 { 1252 sal_uInt16 nFormat = static_cast<const SfxInt16Item *>(pItem)->GetValue(); 1253 switch(nFormat) 1254 { 1255 case 0: 1256 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER); //Modify 1257 break; 1258 case 1: 1259 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 2 ); //Modify 1260 break; 1261 case 2: 1262 pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT ); 1263 break; 1264 case 3: 1265 pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY ); 1266 break; 1267 case 4: 1268 pTabViewShell->SetNumberFormat( SvNumFormatType::DATE ); 1269 break; 1270 case 5: 1271 pTabViewShell->SetNumberFormat( SvNumFormatType::TIME ); 1272 break; 1273 case 6: 1274 pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC ); 1275 break; 1276 case 7: 1277 pTabViewShell->SetNumberFormat( SvNumFormatType::FRACTION ); 1278 break; 1279 case 8: 1280 pTabViewShell->SetNumberFormat( SvNumFormatType::LOGICAL ); 1281 break; 1282 case 9: 1283 pTabViewShell->SetNumberFormat( SvNumFormatType::TEXT ); 1284 break; 1285 default: 1286 ; 1287 } 1288 rReq.Done(); 1289 } 1290 } 1291 break; 1292 1293 default: 1294 OSL_FAIL("ExecuteEdit: invalid slot"); 1295 break; 1296 } 1297 } 1298 1299 void ScFormatShell::ExecuteAlignment( SfxRequest& rReq ) 1300 { 1301 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 1302 SfxBindings& rBindings = rViewData.GetBindings(); 1303 const SfxItemSet* pSet = rReq.GetArgs(); 1304 sal_uInt16 nSlot = rReq.GetSlot(); 1305 1306 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox 1307 1308 switch( nSlot ) 1309 { 1310 // pseudo slots for Format menu 1311 case SID_ALIGN_ANY_HDEFAULT: 1312 case SID_ALIGN_ANY_LEFT: 1313 case SID_ALIGN_ANY_HCENTER: 1314 case SID_ALIGN_ANY_RIGHT: 1315 case SID_ALIGN_ANY_JUSTIFIED: 1316 pTabViewShell->ApplyAttr( SvxHorJustifyItem( lclConvertSlotToHAlign( nSlot ), ATTR_HOR_JUSTIFY ) ); 1317 break; 1318 case SID_ALIGN_ANY_VDEFAULT: 1319 case SID_ALIGN_ANY_TOP: 1320 case SID_ALIGN_ANY_VCENTER: 1321 case SID_ALIGN_ANY_BOTTOM: 1322 pTabViewShell->ApplyAttr( SvxVerJustifyItem( lclConvertSlotToVAlign( nSlot ), ATTR_VER_JUSTIFY ) ); 1323 break; 1324 1325 default: 1326 if( pSet ) 1327 { 1328 const SfxPoolItem* pItem = nullptr; 1329 if( pSet->GetItemState(GetPool().GetWhich(nSlot), true, &pItem ) == SfxItemState::SET ) 1330 { 1331 1332 switch ( nSlot ) 1333 { 1334 case SID_ATTR_ALIGN_HOR_JUSTIFY: 1335 case SID_ATTR_ALIGN_VER_JUSTIFY: 1336 case SID_ATTR_ALIGN_INDENT: 1337 case SID_ATTR_ALIGN_HYPHENATION: 1338 case SID_ATTR_ALIGN_DEGREES: 1339 case SID_ATTR_ALIGN_LOCKPOS: 1340 case SID_ATTR_ALIGN_MARGIN: 1341 case SID_ATTR_ALIGN_STACKED: 1342 pTabViewShell->ApplyAttr( *pItem ); 1343 break; 1344 1345 case SID_H_ALIGNCELL: 1346 { 1347 SvxCellHorJustify eJust = static_cast<const SvxHorJustifyItem*>(pItem)->GetValue(); 1348 // #i78476# update alignment of text in cell edit mode 1349 pTabViewShell->UpdateInputHandlerCellAdjust( eJust ); 1350 pTabViewShell->ApplyAttr( SvxHorJustifyItem( eJust, ATTR_HOR_JUSTIFY ) ); 1351 } 1352 break; 1353 case SID_V_ALIGNCELL: 1354 pTabViewShell->ApplyAttr( SvxVerJustifyItem( static_cast<const SvxVerJustifyItem*>(pItem)->GetValue(), ATTR_VER_JUSTIFY ) ); 1355 break; 1356 default: 1357 OSL_FAIL( "ExecuteAlignment: invalid slot" ); 1358 return; 1359 } 1360 } 1361 } 1362 } 1363 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT ); 1364 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT ); 1365 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK ); 1366 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER); 1367 rBindings.Invalidate( SID_ALIGNLEFT ); 1368 rBindings.Invalidate( SID_ALIGNRIGHT ); 1369 rBindings.Invalidate( SID_ALIGNCENTERHOR ); 1370 rBindings.Invalidate( SID_ALIGNBLOCK ); 1371 rBindings.Invalidate( SID_ALIGNTOP ); 1372 rBindings.Invalidate( SID_ALIGNBOTTOM ); 1373 rBindings.Invalidate( SID_ALIGNCENTERVER ); 1374 rBindings.Invalidate( SID_V_ALIGNCELL ); 1375 rBindings.Invalidate( SID_H_ALIGNCELL ); 1376 // pseudo slots for Format menu 1377 rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT ); 1378 rBindings.Invalidate( SID_ALIGN_ANY_LEFT ); 1379 rBindings.Invalidate( SID_ALIGN_ANY_HCENTER ); 1380 rBindings.Invalidate( SID_ALIGN_ANY_RIGHT ); 1381 rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED ); 1382 rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT ); 1383 rBindings.Invalidate( SID_ALIGN_ANY_TOP ); 1384 rBindings.Invalidate( SID_ALIGN_ANY_VCENTER ); 1385 rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM ); 1386 rBindings.Update(); 1387 1388 if( ! rReq.IsAPI() ) 1389 rReq.Done(); 1390 } 1391 1392 void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq ) 1393 { 1394 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 1395 SfxBindings& rBindings = rViewData.GetBindings(); 1396 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern(); 1397 const SfxItemSet* pSet = rReq.GetArgs(); 1398 sal_uInt16 nSlot = rReq.GetSlot(); 1399 std::optional<SfxAllItemSet> pNewSet; 1400 1401 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox 1402 1403 if ( (nSlot == SID_ATTR_CHAR_WEIGHT) 1404 ||(nSlot == SID_ATTR_CHAR_POSTURE) 1405 ||(nSlot == SID_ATTR_CHAR_UNDERLINE) 1406 ||(nSlot == SID_ULINE_VAL_NONE) 1407 ||(nSlot == SID_ULINE_VAL_SINGLE) 1408 ||(nSlot == SID_ULINE_VAL_DOUBLE) 1409 ||(nSlot == SID_ULINE_VAL_DOTTED) ) 1410 { 1411 pNewSet.emplace( GetPool() ); 1412 1413 switch ( nSlot ) 1414 { 1415 case SID_ATTR_CHAR_WEIGHT: 1416 { 1417 // #i78017 establish the same behaviour as in Writer 1418 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX; 1419 1420 SfxItemPool& rPool = GetPool(); 1421 SvxScriptSetItem aSetItem( nSlot, rPool ); 1422 if ( pSet ) 1423 aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_WEIGHT ) ); 1424 else 1425 { 1426 // toggle manually 1427 1428 FontWeight eWeight = WEIGHT_BOLD; 1429 SvxScriptSetItem aOldSetItem( nSlot, rPool ); 1430 aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false ); 1431 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript ); 1432 if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() == WEIGHT_BOLD ) 1433 eWeight = WEIGHT_NORMAL; 1434 1435 aSetItem.PutItemForScriptType( nScript, SvxWeightItem( eWeight, ATTR_FONT_WEIGHT ) ); 1436 } 1437 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() ); 1438 pNewSet->Put( aSetItem.GetItemSet(), false ); 1439 } 1440 break; 1441 1442 case SID_ATTR_CHAR_POSTURE: 1443 { 1444 // #i78017 establish the same behaviour as in Writer 1445 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX; 1446 1447 SfxItemPool& rPool = GetPool(); 1448 SvxScriptSetItem aSetItem( nSlot, rPool ); 1449 if ( pSet ) 1450 aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_POSTURE ) ); 1451 else 1452 { 1453 // toggle manually 1454 1455 FontItalic eItalic = ITALIC_NORMAL; 1456 SvxScriptSetItem aOldSetItem( nSlot, rPool ); 1457 aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false ); 1458 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript ); 1459 if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetPosture() == ITALIC_NORMAL ) 1460 eItalic = ITALIC_NONE; 1461 1462 aSetItem.PutItemForScriptType( nScript, SvxPostureItem( eItalic, ATTR_FONT_POSTURE ) ); 1463 } 1464 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() ); 1465 pNewSet->Put( aSetItem.GetItemSet(), false ); 1466 } 1467 break; 1468 1469 case SID_ATTR_CHAR_UNDERLINE: 1470 { 1471 if( pSet ) 1472 { 1473 const SfxPoolItem& rUnderline = pSet->Get( ATTR_FONT_UNDERLINE ); 1474 1475 if( dynamic_cast<const SvxUnderlineItem*>( &rUnderline) != nullptr ) 1476 { 1477 pTabViewShell->ApplyAttr( rUnderline ); 1478 pNewSet->Put( rUnderline,rUnderline.Which() ); 1479 } 1480 else if ( auto pTextLineItem = dynamic_cast<const SvxTextLineItem*>( &rUnderline) ) 1481 { 1482 // #i106580# also allow SvxTextLineItem (base class of SvxUnderlineItem) 1483 SvxUnderlineItem aNewItem( pTextLineItem->GetLineStyle(), pTextLineItem->Which() ); 1484 aNewItem.SetColor( pTextLineItem->GetColor() ); 1485 pTabViewShell->ApplyAttr( aNewItem ); 1486 pNewSet->Put( aNewItem, aNewItem.Which() ); 1487 } 1488 } 1489 else 1490 { 1491 SvxUnderlineItem aUnderline( pAttrs->GetItem( ATTR_FONT_UNDERLINE ) ); 1492 FontLineStyle eUnderline = (LINESTYLE_NONE != aUnderline.GetLineStyle()) 1493 ? LINESTYLE_NONE 1494 : LINESTYLE_SINGLE; 1495 aUnderline.SetLineStyle( eUnderline ); 1496 pTabViewShell->ApplyAttr( aUnderline ); 1497 pNewSet->Put( aUnderline,aUnderline.Which() ); 1498 } 1499 } 1500 break; 1501 1502 case SID_ULINE_VAL_NONE: 1503 pTabViewShell->ApplyAttr( SvxUnderlineItem( LINESTYLE_NONE, ATTR_FONT_UNDERLINE ) ); 1504 break; 1505 case SID_ULINE_VAL_SINGLE: // Toggles 1506 case SID_ULINE_VAL_DOUBLE: 1507 case SID_ULINE_VAL_DOTTED: 1508 { 1509 FontLineStyle eOld = pAttrs->GetItem(ATTR_FONT_UNDERLINE).GetLineStyle(); 1510 FontLineStyle eNew = eOld; 1511 switch (nSlot) 1512 { 1513 case SID_ULINE_VAL_SINGLE: 1514 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE; 1515 break; 1516 case SID_ULINE_VAL_DOUBLE: 1517 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE; 1518 break; 1519 case SID_ULINE_VAL_DOTTED: 1520 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED; 1521 break; 1522 } 1523 pTabViewShell->ApplyAttr( SvxUnderlineItem( eNew, ATTR_FONT_UNDERLINE ) ); 1524 } 1525 break; 1526 1527 default: 1528 break; 1529 } 1530 rBindings.Invalidate( nSlot ); 1531 } 1532 else 1533 { 1534 /* 1535 * "Self-made" functionality of radio buttons 1536 * At the toggle the default state is used, this means 1537 * no button was clicked. 1538 */ 1539 1540 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 1541 const SfxPoolItem* pItem = nullptr; 1542 const SvxHorJustifyItem* pHorJustify = nullptr; 1543 const SvxVerJustifyItem* pVerJustify = nullptr; 1544 SvxCellHorJustify eHorJustify = SvxCellHorJustify::Standard; 1545 SvxCellVerJustify eVerJustify = SvxCellVerJustify::Standard; 1546 1547 if (rAttrSet.GetItemState(ATTR_HOR_JUSTIFY, true,&pItem ) == SfxItemState::SET) 1548 { 1549 pHorJustify = static_cast<const SvxHorJustifyItem*>(pItem); 1550 eHorJustify = pHorJustify->GetValue(); 1551 } 1552 if (rAttrSet.GetItemState(ATTR_VER_JUSTIFY, true,&pItem ) == SfxItemState::SET) 1553 { 1554 pVerJustify = static_cast<const SvxVerJustifyItem*>(pItem); 1555 eVerJustify = pVerJustify->GetValue(); 1556 } 1557 1558 switch ( nSlot ) 1559 { 1560 case SID_ALIGNLEFT: 1561 rReq.SetSlot( SID_H_ALIGNCELL ); 1562 rReq.AppendItem( SvxHorJustifyItem( 1563 !pHorJustify || (eHorJustify != SvxCellHorJustify::Left) ? 1564 SvxCellHorJustify::Left : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) ); 1565 ExecuteSlot( rReq, GetInterface() ); 1566 return; 1567 1568 case SID_ALIGNRIGHT: 1569 rReq.SetSlot( SID_H_ALIGNCELL ); 1570 rReq.AppendItem( SvxHorJustifyItem( 1571 !pHorJustify || (eHorJustify != SvxCellHorJustify::Right) ? 1572 SvxCellHorJustify::Right : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) ); 1573 ExecuteSlot( rReq, GetInterface() ); 1574 return; 1575 1576 case SID_ALIGNCENTERHOR: 1577 rReq.SetSlot( SID_H_ALIGNCELL ); 1578 rReq.AppendItem( SvxHorJustifyItem( 1579 !pHorJustify || (eHorJustify != SvxCellHorJustify::Center) ? 1580 SvxCellHorJustify::Center : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) ); 1581 ExecuteSlot( rReq, GetInterface() ); 1582 return; 1583 1584 case SID_ALIGNBLOCK: 1585 rReq.SetSlot( SID_H_ALIGNCELL ); 1586 rReq.AppendItem( SvxHorJustifyItem( 1587 !pHorJustify || (eHorJustify != SvxCellHorJustify::Block) ? 1588 SvxCellHorJustify::Block : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) ); 1589 ExecuteSlot( rReq, GetInterface() ); 1590 return; 1591 1592 case SID_ALIGNTOP: 1593 rReq.SetSlot( SID_V_ALIGNCELL ); 1594 rReq.AppendItem( SvxVerJustifyItem( 1595 !pVerJustify || (eVerJustify != SvxCellVerJustify::Top) ? 1596 SvxCellVerJustify::Top : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) ); 1597 ExecuteSlot( rReq, GetInterface() ); 1598 return; 1599 1600 case SID_ALIGNBOTTOM: 1601 rReq.SetSlot( SID_V_ALIGNCELL ); 1602 rReq.AppendItem( SvxVerJustifyItem( 1603 !pVerJustify || (eVerJustify != SvxCellVerJustify::Bottom) ? 1604 SvxCellVerJustify::Bottom : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) ); 1605 ExecuteSlot( rReq, GetInterface() ); 1606 return; 1607 1608 case SID_ALIGNCENTERVER: 1609 rReq.SetSlot( SID_V_ALIGNCELL ); 1610 rReq.AppendItem( SvxVerJustifyItem( 1611 !pVerJustify || (eVerJustify != SvxCellVerJustify::Center) ? 1612 SvxCellVerJustify::Center : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) ); 1613 ExecuteSlot( rReq, GetInterface() ); 1614 return; 1615 1616 default: 1617 break; 1618 } 1619 1620 } 1621 1622 rBindings.Update(); 1623 1624 if( pNewSet ) 1625 { 1626 rReq.Done( *pNewSet ); 1627 pNewSet.reset(); 1628 } 1629 else 1630 { 1631 rReq.Done(); 1632 } 1633 1634 } 1635 1636 namespace 1637 { 1638 bool lcl_getColorFromStr(const SfxItemSet *pArgs, Color &rColor) 1639 { 1640 const SfxPoolItem* pColorStringItem = nullptr; 1641 1642 if (pArgs && SfxItemState::SET == pArgs->GetItemState(SID_ATTR_COLOR_STR, false, &pColorStringItem) && pColorStringItem) 1643 { 1644 OUString sColor; 1645 sColor = static_cast<const SfxStringItem*>(pColorStringItem)->GetValue(); 1646 1647 if (sColor == "transparent") 1648 rColor = COL_TRANSPARENT; 1649 else 1650 rColor = Color(ColorTransparency, sColor.toInt32(16)); 1651 return true; 1652 } 1653 return false; 1654 } 1655 } 1656 1657 void ScFormatShell::ExecuteAttr( SfxRequest& rReq ) 1658 { 1659 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 1660 SfxBindings& rBindings = rViewData.GetBindings(); 1661 const SfxItemSet* pNewAttrs = rReq.GetArgs(); 1662 sal_uInt16 nSlot = rReq.GetSlot(); 1663 1664 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox 1665 ScDocument& rDoc = GetViewData().GetDocument(); 1666 if ( !pNewAttrs ) 1667 { 1668 switch ( nSlot ) 1669 { 1670 case SID_GROW_FONT_SIZE: 1671 case SID_SHRINK_FONT_SIZE: 1672 { 1673 SfxItemPool& rPool = GetPool(); 1674 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool ); 1675 aSetItem.GetItemSet().Put( pTabViewShell->GetSelectionPattern()->GetItemSet(), false ); 1676 1677 SvtScriptType nScriptTypes = pTabViewShell->GetSelectionScriptType(); 1678 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( nScriptTypes ) ) ); 1679 1680 if ( pSize ) 1681 { 1682 SvxFontHeightItem aSize( *pSize ); 1683 sal_uInt32 nSize = aSize.GetHeight(); 1684 1685 const sal_uInt32 nFontInc = 40; // 2pt 1686 const sal_uInt32 nFontMaxSz = 19998; // 999.9pt 1687 if ( nSlot == SID_GROW_FONT_SIZE ) 1688 nSize = std::min< sal_uInt32 >( nSize + nFontInc, nFontMaxSz ); 1689 else 1690 nSize = std::max< sal_Int32 >( nSize - nFontInc, nFontInc ); 1691 1692 aSize.SetHeight( nSize ); 1693 aSetItem.PutItemForScriptType( nScriptTypes, aSize ); 1694 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() ); 1695 } 1696 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT ); 1697 } 1698 break; 1699 1700 case SID_ATTR_CHAR_ENDPREVIEW_FONT: 1701 { 1702 rDoc.SetPreviewFont(nullptr); 1703 pTabViewShell->UpdateSelectionArea( rDoc.GetPreviewSelection() ); 1704 break; 1705 } 1706 case SID_ATTR_CHAR_COLOR: 1707 case SID_ATTR_CHAR_FONT: 1708 case SID_ATTR_CHAR_FONTHEIGHT: 1709 pTabViewShell->ExecuteCellFormatDlg(rReq, "font"); // when ToolBar is vertical 1710 break; 1711 1712 case SID_BACKGROUND_COLOR: 1713 { 1714 SvxBrushItem aBrushItem( 1715 pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) ); 1716 aBrushItem.SetColor( COL_TRANSPARENT ); 1717 pTabViewShell->ApplyAttr( aBrushItem, false ); 1718 } 1719 break; 1720 1721 case SID_ATTR_ALIGN_LINEBREAK: // without parameter as toggle 1722 { 1723 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern(); 1724 bool bOld = pAttrs->GetItem(ATTR_LINEBREAK).GetValue(); 1725 ScLineBreakCell aBreakItem(!bOld); 1726 pTabViewShell->ApplyAttr( aBreakItem ); 1727 1728 SfxAllItemSet aNewSet( GetPool() ); 1729 aNewSet.Put( aBreakItem,aBreakItem.Which() ); 1730 rReq.Done( aNewSet ); 1731 1732 rBindings.Invalidate( nSlot ); 1733 } 1734 break; 1735 1736 case SID_SCATTR_CELLPROTECTION: // without parameter as toggle 1737 { 1738 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern(); 1739 bool bProtect = pAttrs->GetItem(ATTR_PROTECTION).GetProtection(); 1740 bool bHideFormula = pAttrs->GetItem(ATTR_PROTECTION).GetHideFormula(); 1741 bool bHideCell = pAttrs->GetItem(ATTR_PROTECTION).GetHideCell(); 1742 bool bHidePrint = pAttrs->GetItem(ATTR_PROTECTION).GetHidePrint(); 1743 1744 ScProtectionAttr aProtectionItem( !bProtect, bHideFormula, bHideCell, bHidePrint ); 1745 pTabViewShell->ApplyAttr( aProtectionItem ); 1746 1747 SfxAllItemSet aNewSet( GetPool() ); 1748 aNewSet.Put( aProtectionItem, aProtectionItem.Which()); 1749 aNewSet.Put( SfxBoolItem( SID_SCATTR_CELLPROTECTION, !bProtect ) ); 1750 rReq.Done( aNewSet ); 1751 1752 rBindings.Invalidate( nSlot ); 1753 } 1754 break; 1755 } 1756 } 1757 else 1758 { 1759 switch ( nSlot ) 1760 { 1761 case SID_ATTR_CHAR_PREVIEW_FONT: 1762 { 1763 SfxItemPool& rPool = GetPool(); 1764 sal_uInt16 nWhich = rPool.GetWhich( nSlot ); 1765 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(pNewAttrs->Get( nWhich )); 1766 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, rPool ); 1767 SvtScriptType nScript = pTabViewShell->GetSelectionScriptType(); 1768 aSetItem.PutItemForScriptType( nScript, rFont ); 1769 1770 ScMarkData aFuncMark( rViewData.GetMarkData() ); 1771 ScViewUtil::UnmarkFiltered( aFuncMark, rDoc ); 1772 rDoc.SetPreviewFont( aSetItem.GetItemSet().Clone() ); 1773 aFuncMark.MarkToMulti(); 1774 1775 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() ) 1776 { 1777 SCCOL nCol = rViewData.GetCurX(); 1778 SCROW nRow = rViewData.GetCurY(); 1779 SCTAB nTab = rViewData.GetTabNo(); 1780 ScRange aRange( nCol, nRow, nTab ); 1781 aFuncMark.SetMarkArea( aRange ); 1782 } 1783 rDoc.SetPreviewSelection( aFuncMark ); 1784 pTabViewShell->UpdateSelectionArea( aFuncMark ); 1785 break; 1786 } 1787 case SID_ATTR_CHAR_OVERLINE: 1788 case SID_ATTR_CHAR_STRIKEOUT: 1789 case SID_ATTR_ALIGN_LINEBREAK: 1790 case SID_ATTR_CHAR_CONTOUR: 1791 case SID_ATTR_CHAR_SHADOWED: 1792 case SID_ATTR_CHAR_RELIEF: 1793 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich( nSlot ) ) ); 1794 rBindings.Invalidate( nSlot ); 1795 rBindings.Update( nSlot ); 1796 break; 1797 case SID_ATTR_CHAR_COLOR: 1798 case SID_SCATTR_PROTECTION : 1799 { 1800 Color aColor; 1801 if (lcl_getColorFromStr(pNewAttrs, aColor)) 1802 { 1803 SvxColorItem aColorItem(pTabViewShell->GetSelectionPattern()-> 1804 GetItem( ATTR_FONT_COLOR ) ); 1805 aColorItem.SetValue(aColor); 1806 pTabViewShell->ApplyAttr(aColorItem, false); 1807 } 1808 else 1809 { 1810 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhich( nSlot) ), false); 1811 } 1812 1813 rBindings.Invalidate( nSlot ); 1814 rBindings.Update( nSlot ); 1815 } 1816 1817 break; 1818 1819 case SID_ATTR_CHAR_FONT: 1820 case SID_ATTR_CHAR_FONTHEIGHT: 1821 { 1822 // #i78017 establish the same behaviour as in Writer 1823 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX; 1824 if (nSlot == SID_ATTR_CHAR_FONT) 1825 nScript = pTabViewShell->GetSelectionScriptType(); 1826 1827 SfxItemPool& rPool = GetPool(); 1828 SvxScriptSetItem aSetItem( nSlot, rPool ); 1829 sal_uInt16 nWhich = rPool.GetWhich( nSlot ); 1830 aSetItem.PutItemForScriptType( nScript, pNewAttrs->Get( nWhich ) ); 1831 1832 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() ); 1833 1834 rBindings.Invalidate( nSlot ); 1835 rBindings.Update( nSlot ); 1836 } 1837 break; 1838 1839 case SID_FRAME_LINESTYLE: 1840 { 1841 // Update default line 1842 const ::editeng::SvxBorderLine* pLine = 1843 pNewAttrs->Get( SID_FRAME_LINESTYLE ). 1844 GetLine(); 1845 1846 if ( pLine ) 1847 { 1848 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine(); 1849 1850 if ( pDefLine ) 1851 { 1852 pDefLine->SetBorderLineStyle( 1853 pLine->GetBorderLineStyle()); 1854 pDefLine->SetWidth( pLine->GetWidth( ) ); 1855 pTabViewShell->SetSelectionFrameLines( pDefLine, false ); 1856 } 1857 else 1858 { 1859 pTabViewShell->SetDefaultFrameLine( pLine ); 1860 pTabViewShell->GetDefaultFrameLine()->SetColor( COL_BLACK ); 1861 pTabViewShell->SetSelectionFrameLines( pLine, false ); 1862 } 1863 } 1864 else 1865 { 1866 Color aColorBlack( COL_BLACK ); 1867 ::editeng::SvxBorderLine aDefLine( &aColorBlack, 20, 1868 SvxBorderLineStyle::SOLID ); 1869 pTabViewShell->SetDefaultFrameLine( &aDefLine ); 1870 pTabViewShell->SetSelectionFrameLines( nullptr, false ); 1871 } 1872 } 1873 break; 1874 1875 case SID_FRAME_LINECOLOR: 1876 { 1877 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine(); 1878 1879 Color aColor; 1880 if (!lcl_getColorFromStr(pNewAttrs, aColor)) 1881 aColor = pNewAttrs->Get( SID_FRAME_LINECOLOR ).GetValue(); 1882 1883 // Update default line 1884 if ( pDefLine ) 1885 { 1886 pDefLine->SetColor( aColor ); 1887 pTabViewShell->SetSelectionFrameLines( pDefLine, true ); 1888 } 1889 else 1890 { 1891 ::editeng::SvxBorderLine aDefLine( &aColor, 20, SvxBorderLineStyle::SOLID ); 1892 pTabViewShell->SetDefaultFrameLine( &aDefLine ); 1893 pTabViewShell->SetSelectionFrameLines( &aDefLine, false ); 1894 } 1895 } 1896 break; 1897 1898 case SID_ATTR_BORDER_OUTER: 1899 case SID_ATTR_BORDER: 1900 { 1901 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine(); 1902 const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern(); 1903 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aOldSet( *rDoc.GetPool() ); 1904 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *rDoc.GetPool() ); 1905 const SfxPoolItem& rBorderAttr = 1906 pOldAttrs->GetItemSet(). 1907 Get( ATTR_BORDER ); 1908 1909 // Evaluate border items from controller: 1910 const SfxPoolItem* pItem = nullptr; 1911 1912 if ( pNewAttrs->GetItemState( ATTR_BORDER, true, &pItem ) 1913 == SfxItemState::SET ) 1914 { 1915 // The SvxFrameToolBoxControl toolbox controller uses a default 1916 // SvxBorderLine (all widths 0) to mark the lines that should be set. 1917 // Macro recording uses a SvxBoxItem with the real values (OutWidth > 0) 1918 // or NULL pointers for no lines. 1919 // -> Substitute existing lines with pDefLine only if widths are 0. 1920 SvxBoxItem aBoxItem ( *static_cast<const SvxBoxItem*>(pItem )); 1921 if ( aBoxItem.GetTop() && aBoxItem.GetTop()->GetOutWidth() == 0 ) 1922 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::TOP ); 1923 if ( aBoxItem.GetBottom() && aBoxItem.GetBottom()->GetOutWidth() == 0 ) 1924 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::BOTTOM ); 1925 if ( aBoxItem.GetLeft() && aBoxItem.GetLeft()->GetOutWidth() == 0 ) 1926 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::LEFT ); 1927 if ( aBoxItem.GetRight() && aBoxItem.GetRight()->GetOutWidth() == 0 ) 1928 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::RIGHT ); 1929 aNewSet.Put( aBoxItem ); 1930 rReq.AppendItem( aBoxItem ); 1931 } 1932 1933 if ( pNewAttrs->GetItemState( ATTR_BORDER_INNER, true, &pItem ) 1934 == SfxItemState::SET ) 1935 { 1936 SvxBoxInfoItem aBoxInfoItem( *static_cast<const SvxBoxInfoItem*>(pItem) ); 1937 if ( aBoxInfoItem.GetHori() && aBoxInfoItem.GetHori()->GetOutWidth() == 0 ) 1938 aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::HORI ); 1939 if ( aBoxInfoItem.GetVert() && aBoxInfoItem.GetVert()->GetOutWidth() == 0 ) 1940 aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::VERT ); 1941 aNewSet.Put( aBoxInfoItem ); 1942 rReq.AppendItem( aBoxInfoItem ); 1943 } 1944 else 1945 { 1946 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER ); 1947 aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::HORI ); 1948 aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::VERT ); 1949 aNewSet.Put( aBoxInfoItem ); 1950 } 1951 1952 aOldSet.Put( rBorderAttr ); 1953 pTabViewShell->ApplyAttributes( &aNewSet, &aOldSet ); 1954 } 1955 break; 1956 1957 case SID_ATTR_BORDER_DIAG_TLBR: 1958 case SID_ATTR_BORDER_DIAG_BLTR: 1959 { 1960 const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern(); 1961 SfxItemSet aOldSet(pOldAttrs->GetItemSet()); 1962 SfxItemSet aNewSet(pOldAttrs->GetItemSet()); 1963 const SfxPoolItem* pItem = nullptr; 1964 1965 if(SID_ATTR_BORDER_DIAG_TLBR == nSlot) 1966 { 1967 if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_TLBR, true, &pItem)) 1968 { 1969 SvxLineItem aItem(ATTR_BORDER_TLBR); 1970 aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_TLBR).GetLine()); 1971 aNewSet.Put(aItem); 1972 rReq.AppendItem(aItem); 1973 pTabViewShell->ApplyAttributes(&aNewSet, &aOldSet); 1974 } 1975 } 1976 else // if( nSlot == SID_ATTR_BORDER_DIAG_BLTR ) 1977 { 1978 if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_BLTR, true, &pItem )) 1979 { 1980 SvxLineItem aItem(ATTR_BORDER_BLTR); 1981 aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_BLTR).GetLine()); 1982 aNewSet.Put(aItem); 1983 rReq.AppendItem(aItem); 1984 pTabViewShell->ApplyAttributes(&aNewSet, &aOldSet); 1985 } 1986 } 1987 1988 rBindings.Invalidate(nSlot); 1989 } 1990 break; 1991 1992 // ATTR_BACKGROUND (=SID_ATTR_BRUSH) has to be set to two IDs: 1993 case SID_BACKGROUND_COLOR: 1994 { 1995 Color aColor; 1996 1997 if (!lcl_getColorFromStr(pNewAttrs, aColor)) 1998 { 1999 const SvxColorItem& rNewColorItem = pNewAttrs->Get( SID_BACKGROUND_COLOR ); 2000 aColor = rNewColorItem.GetValue(); 2001 } 2002 2003 SvxBrushItem aBrushItem( 2004 pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) ); 2005 aBrushItem.SetColor( aColor ); 2006 2007 pTabViewShell->ApplyAttr( aBrushItem, false ); 2008 } 2009 break; 2010 2011 case SID_ATTR_BRUSH: 2012 { 2013 SvxBrushItem aBrushItem( pTabViewShell->GetSelectionPattern()-> 2014 GetItem( ATTR_BACKGROUND ) ); 2015 const SvxBrushItem& rNewBrushItem = static_cast<const SvxBrushItem&>( 2016 pNewAttrs->Get( GetPool().GetWhich(nSlot) ) ); 2017 aBrushItem.SetColor(rNewBrushItem.GetColor()); 2018 pTabViewShell->ApplyAttr( aBrushItem ); 2019 } 2020 break; 2021 2022 case SID_ATTR_BORDER_SHADOW: 2023 { 2024 const SvxShadowItem& rNewShadowItem = 2025 pNewAttrs->Get( ATTR_SHADOW ); 2026 pTabViewShell->ApplyAttr( rNewShadowItem ); 2027 } 2028 break; 2029 2030 default: 2031 break; 2032 } 2033 2034 if( ! rReq.IsAPI() && ! rReq.IsDone() ) 2035 rReq.Done(); 2036 } 2037 } 2038 2039 void ScFormatShell::GetAttrState( SfxItemSet& rSet ) 2040 { 2041 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2042 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 2043 const SvxBrushItem& rBrushItem = rAttrSet.Get( ATTR_BACKGROUND ); 2044 SfxWhichIter aIter( rSet ); 2045 sal_uInt16 nWhich = aIter.FirstWhich(); 2046 2047 rSet.Put( rAttrSet, false ); 2048 2049 // choose font info according to selection script type 2050 SvtScriptType nScript = SvtScriptType::NONE; // GetSelectionScriptType never returns 0 2051 if ( rSet.GetItemState( ATTR_FONT ) != SfxItemState::UNKNOWN ) 2052 { 2053 nScript = pTabViewShell->GetSelectionScriptType(); 2054 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT, nScript ); 2055 } 2056 if ( rSet.GetItemState( ATTR_FONT_HEIGHT ) != SfxItemState::UNKNOWN ) 2057 { 2058 if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType(); 2059 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_HEIGHT, nScript ); 2060 } 2061 2062 while ( nWhich ) 2063 { 2064 switch(nWhich) 2065 { 2066 case SID_BACKGROUND_COLOR: 2067 { 2068 rSet.Put( SvxColorItem( rBrushItem.GetColor(), SID_BACKGROUND_COLOR ) ); 2069 if(SfxItemState::DONTCARE == rAttrSet.GetItemState(ATTR_BACKGROUND)) 2070 { 2071 rSet.InvalidateItem(SID_BACKGROUND_COLOR); 2072 } 2073 } 2074 break; 2075 case SID_FRAME_LINESTYLE: 2076 case SID_FRAME_LINECOLOR: 2077 { 2078 // handled together because both need the cell border information for decisions 2079 Color aCol; 2080 editeng::SvxBorderLine aLine(nullptr,0,SvxBorderLineStyle::SOLID); 2081 bool bCol = false; 2082 bool bColDisable = false, bStyleDisable = false; 2083 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER)); 2084 std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER)); 2085 2086 pTabViewShell->GetSelectionFrame(aBoxItem, aInfoItem); 2087 2088 if( aBoxItem->GetTop() ) 2089 { 2090 bCol = true; 2091 aCol = aBoxItem->GetTop()->GetColor() ; 2092 aLine.SetColor(aCol); 2093 aLine.SetWidth( aBoxItem->GetTop()->GetWidth()); 2094 aLine.SetBorderLineStyle( aBoxItem->GetTop()->GetBorderLineStyle()); 2095 } 2096 2097 if( aBoxItem->GetBottom() ) 2098 { 2099 if(!bCol) 2100 { 2101 bCol = true; 2102 aCol = aBoxItem->GetBottom()->GetColor() ; 2103 aLine.SetColor(aCol); 2104 aLine.SetWidth( aBoxItem->GetBottom()->GetWidth()); 2105 aLine.SetBorderLineStyle( aBoxItem->GetBottom()->GetBorderLineStyle()); 2106 } 2107 else 2108 { 2109 if(aCol != aBoxItem->GetBottom()->GetColor() ) 2110 bColDisable = true; 2111 if( aLine != *aBoxItem->GetBottom() ) 2112 bStyleDisable = true; 2113 } 2114 } 2115 2116 if( aBoxItem->GetLeft() ) 2117 { 2118 if(!bCol) 2119 { 2120 bCol = true; 2121 aCol = aBoxItem->GetLeft()->GetColor() ; 2122 aLine.SetColor(aCol); 2123 aLine.SetWidth( aBoxItem->GetLeft()->GetWidth()); 2124 aLine.SetBorderLineStyle( aBoxItem->GetLeft()->GetBorderLineStyle()); 2125 } 2126 else 2127 { 2128 if(aCol != aBoxItem->GetLeft()->GetColor() ) 2129 bColDisable = true; 2130 if( aLine != *aBoxItem->GetLeft() ) 2131 bStyleDisable = true; 2132 } 2133 } 2134 2135 if( aBoxItem->GetRight() ) 2136 { 2137 if(!bCol) 2138 { 2139 bCol = true; 2140 aCol = aBoxItem->GetRight()->GetColor() ; 2141 aLine.SetColor(aCol); 2142 aLine.SetWidth( aBoxItem->GetRight()->GetWidth()); 2143 aLine.SetBorderLineStyle( aBoxItem->GetRight()->GetBorderLineStyle()); 2144 } 2145 else 2146 { 2147 if(aCol != aBoxItem->GetRight()->GetColor() ) 2148 bColDisable = true; 2149 if( aLine != *aBoxItem->GetRight() ) 2150 bStyleDisable = true; 2151 } 2152 } 2153 2154 if( aInfoItem->GetVert()) 2155 { 2156 if(!bCol) 2157 { 2158 bCol = true; 2159 aCol = aInfoItem->GetVert()->GetColor() ; 2160 aLine.SetColor(aCol); 2161 aLine.SetWidth( aInfoItem->GetVert()->GetWidth()); 2162 aLine.SetBorderLineStyle( aInfoItem->GetVert()->GetBorderLineStyle()); 2163 } 2164 else 2165 { 2166 if(aCol != aInfoItem->GetVert()->GetColor() ) 2167 bColDisable = true; 2168 if( aLine != *aInfoItem->GetVert() ) 2169 bStyleDisable = true; 2170 } 2171 } 2172 2173 if( aInfoItem->GetHori()) 2174 { 2175 if(!bCol) 2176 { 2177 bCol = true; 2178 aCol = aInfoItem->GetHori()->GetColor() ; 2179 aLine.SetColor(aCol); 2180 aLine.SetWidth( aInfoItem->GetHori()->GetWidth()); 2181 aLine.SetBorderLineStyle( aInfoItem->GetHori()->GetBorderLineStyle()); 2182 } 2183 else 2184 { 2185 if(aCol != aInfoItem->GetHori()->GetColor() ) 2186 bColDisable = true; 2187 if( aLine != *aInfoItem->GetHori() ) 2188 bStyleDisable = true; 2189 } 2190 } 2191 2192 if( !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) 2193 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) 2194 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) 2195 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) 2196 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) 2197 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) ) 2198 { 2199 bColDisable = true; 2200 bStyleDisable = true; 2201 } 2202 2203 if(SID_FRAME_LINECOLOR == nWhich) 2204 { 2205 if(bColDisable) // if different lines have different colors 2206 { 2207 aCol = COL_TRANSPARENT; 2208 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) ); 2209 rSet.InvalidateItem(SID_FRAME_LINECOLOR); 2210 } 2211 else if (!bCol) // if no line available 2212 { 2213 aCol = COL_AUTO; 2214 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) ); 2215 } 2216 else 2217 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) ); 2218 } 2219 else // if( nWhich == SID_FRAME_LINESTYLE) 2220 { 2221 if(bStyleDisable) // if have several lines but don't have same style 2222 { 2223 aLine.SetWidth( 1 ); 2224 SvxLineItem aItem(SID_FRAME_LINESTYLE); 2225 aItem.SetLine(&aLine); 2226 rSet.Put( aItem ); 2227 rSet.InvalidateItem(SID_FRAME_LINESTYLE); 2228 } 2229 else // all the lines have same style or no line available, use initial value (0,0,0,0) 2230 { 2231 SvxLineItem aItem(SID_FRAME_LINESTYLE); 2232 aItem.SetLine(&aLine); 2233 rSet.Put( aItem ); 2234 } 2235 } 2236 } 2237 break; 2238 case SID_ATTR_BRUSH: 2239 { 2240 rSet.Put( rBrushItem.CloneSetWhich(GetPool().GetWhich(nWhich)) ); 2241 } 2242 break; 2243 case SID_SCATTR_CELLPROTECTION: 2244 { 2245 bool bProtect = rAttrSet.Get( ATTR_PROTECTION ).GetProtection(); 2246 rSet.Put( SfxBoolItem(SID_SCATTR_CELLPROTECTION, bProtect) ); 2247 } 2248 break; 2249 } 2250 nWhich = aIter.NextWhich(); 2251 } 2252 2253 // stuff for sidebar panels 2254 Invalidate(SID_ATTR_ALIGN_DEGREES); 2255 Invalidate(SID_ATTR_ALIGN_LOCKPOS); 2256 Invalidate(SID_ATTR_ALIGN_STACKED); 2257 } 2258 2259 void ScFormatShell::GetTextAttrState( SfxItemSet& rSet ) 2260 { 2261 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2262 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 2263 rSet.Put( rAttrSet, false ); // Include ItemStates in copy 2264 2265 // choose font info according to selection script type 2266 SvtScriptType nScript = SvtScriptType::NONE; // GetSelectionScriptType never returns 0 2267 if ( rSet.GetItemState( ATTR_FONT_WEIGHT ) != SfxItemState::UNKNOWN ) 2268 { 2269 nScript = pTabViewShell->GetSelectionScriptType(); 2270 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_WEIGHT, nScript ); 2271 } 2272 if ( rSet.GetItemState( ATTR_FONT_POSTURE ) != SfxItemState::UNKNOWN ) 2273 { 2274 if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType(); 2275 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_POSTURE, nScript ); 2276 } 2277 2278 SfxItemState eState; 2279 2280 // own control on radio button functionality: 2281 2282 // underline 2283 2284 eState = rAttrSet.GetItemState( ATTR_FONT_UNDERLINE ); 2285 if ( eState == SfxItemState::DONTCARE ) 2286 { 2287 rSet.InvalidateItem( SID_ULINE_VAL_NONE ); 2288 rSet.InvalidateItem( SID_ULINE_VAL_SINGLE ); 2289 rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE ); 2290 rSet.InvalidateItem( SID_ULINE_VAL_DOTTED ); 2291 } 2292 else 2293 { 2294 FontLineStyle eUnderline = 2295 rAttrSet.Get(ATTR_FONT_UNDERLINE).GetLineStyle(); 2296 rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE, eUnderline == LINESTYLE_SINGLE)); 2297 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE, eUnderline == LINESTYLE_DOUBLE)); 2298 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED, eUnderline == LINESTYLE_DOTTED)); 2299 rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE, eUnderline == LINESTYLE_NONE)); 2300 } 2301 2302 // horizontal alignment 2303 2304 const SvxHorJustifyItem* pHorJustify = nullptr; 2305 const SvxVerJustifyItem* pVerJustify = nullptr; 2306 SvxCellVerJustify eVerJustify = SvxCellVerJustify::Standard; 2307 sal_uInt16 nWhich = 0; 2308 bool bJustifyStd = false; 2309 SfxBoolItem aBoolItem ( 0, true ); 2310 2311 eState = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY, true, 2312 reinterpret_cast<const SfxPoolItem**>(&pHorJustify) ); 2313 switch ( eState ) 2314 { 2315 case SfxItemState::SET: 2316 { 2317 switch ( pHorJustify->GetValue() ) 2318 { 2319 case SvxCellHorJustify::Standard: 2320 break; 2321 2322 case SvxCellHorJustify::Left: 2323 nWhich = SID_ALIGNLEFT; 2324 break; 2325 2326 case SvxCellHorJustify::Right: 2327 nWhich = SID_ALIGNRIGHT; 2328 break; 2329 2330 case SvxCellHorJustify::Center: 2331 nWhich = SID_ALIGNCENTERHOR; 2332 break; 2333 2334 case SvxCellHorJustify::Block: 2335 nWhich = SID_ALIGNBLOCK; 2336 break; 2337 2338 case SvxCellHorJustify::Repeat: 2339 default: 2340 bJustifyStd = true; 2341 break; 2342 } 2343 } 2344 break; 2345 2346 case SfxItemState::DONTCARE: 2347 rSet.InvalidateItem( SID_ALIGNLEFT ); 2348 rSet.InvalidateItem( SID_ALIGNRIGHT ); 2349 rSet.InvalidateItem( SID_ALIGNCENTERHOR ); 2350 rSet.InvalidateItem( SID_ALIGNBLOCK ); 2351 break; 2352 2353 default: 2354 bJustifyStd = true; 2355 break; 2356 } 2357 2358 if ( nWhich ) 2359 { 2360 aBoolItem.SetWhich( nWhich ); 2361 rSet.Put( aBoolItem ); 2362 } 2363 else if ( bJustifyStd ) 2364 { 2365 aBoolItem.SetValue( false ); 2366 aBoolItem.SetWhich( SID_ALIGNLEFT ); rSet.Put( aBoolItem ); 2367 aBoolItem.SetWhich( SID_ALIGNRIGHT ); rSet.Put( aBoolItem ); 2368 aBoolItem.SetWhich( SID_ALIGNCENTERHOR ); rSet.Put( aBoolItem ); 2369 aBoolItem.SetWhich( SID_ALIGNBLOCK ); rSet.Put( aBoolItem ); 2370 bJustifyStd = false; 2371 } 2372 2373 // vertical alignment 2374 2375 nWhich = 0; 2376 aBoolItem.SetValue( true ); 2377 2378 eState = rAttrSet.GetItemState( ATTR_VER_JUSTIFY, true, 2379 reinterpret_cast<const SfxPoolItem**>(&pVerJustify) ); 2380 2381 switch ( eState ) 2382 { 2383 case SfxItemState::SET: 2384 { 2385 eVerJustify = pVerJustify->GetValue(); 2386 2387 switch ( eVerJustify ) 2388 { 2389 case SvxCellVerJustify::Top: 2390 nWhich = SID_ALIGNTOP; 2391 break; 2392 2393 case SvxCellVerJustify::Bottom: 2394 nWhich = SID_ALIGNBOTTOM; 2395 break; 2396 2397 case SvxCellVerJustify::Center: 2398 nWhich = SID_ALIGNCENTERVER; 2399 break; 2400 2401 case SvxCellVerJustify::Standard: 2402 default: 2403 bJustifyStd = true; 2404 break; 2405 } 2406 } 2407 break; 2408 2409 case SfxItemState::DONTCARE: 2410 rSet.InvalidateItem( SID_ALIGNTOP ); 2411 rSet.InvalidateItem( SID_ALIGNBOTTOM ); 2412 rSet.InvalidateItem( SID_ALIGNCENTERVER ); 2413 break; 2414 2415 default: 2416 bJustifyStd = true; 2417 break; 2418 } 2419 2420 if ( nWhich ) 2421 { 2422 aBoolItem.SetWhich( nWhich ); 2423 rSet.Put( aBoolItem ); 2424 } 2425 else if ( bJustifyStd ) 2426 { 2427 aBoolItem.SetValue( false ); 2428 aBoolItem.SetWhich( SID_ALIGNTOP ); rSet.Put( aBoolItem ); 2429 aBoolItem.SetWhich( SID_ALIGNBOTTOM ); rSet.Put( aBoolItem ); 2430 aBoolItem.SetWhich( SID_ALIGNCENTERVER ); rSet.Put( aBoolItem ); 2431 } 2432 } 2433 2434 void ScFormatShell::GetBorderState( SfxItemSet& rSet ) 2435 { 2436 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2437 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER)); 2438 std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER)); 2439 2440 pTabViewShell->GetSelectionFrame( aBoxItem, aInfoItem ); 2441 2442 if ( rSet.GetItemState( ATTR_BORDER ) != SfxItemState::UNKNOWN ) 2443 rSet.Put( *aBoxItem ); 2444 if ( rSet.GetItemState( ATTR_BORDER_INNER ) != SfxItemState::UNKNOWN ) 2445 rSet.Put( *aInfoItem ); 2446 } 2447 2448 void ScFormatShell::GetAlignState( SfxItemSet& rSet ) 2449 { 2450 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2451 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 2452 SfxWhichIter aIter(rSet); 2453 sal_uInt16 nWhich = aIter.FirstWhich(); 2454 2455 SvxCellHorJustify eHAlign = SvxCellHorJustify::Standard; 2456 bool bHasHAlign = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY ) != SfxItemState::DONTCARE; 2457 if( bHasHAlign ) 2458 eHAlign = rAttrSet.Get( ATTR_HOR_JUSTIFY ).GetValue(); 2459 2460 SvxCellVerJustify eVAlign = SvxCellVerJustify::Standard; 2461 bool bHasVAlign = rAttrSet.GetItemState( ATTR_VER_JUSTIFY ) != SfxItemState::DONTCARE; 2462 if( bHasVAlign ) 2463 eVAlign = rAttrSet.Get( ATTR_VER_JUSTIFY ).GetValue(); 2464 2465 while ( nWhich ) 2466 { 2467 switch ( nWhich ) 2468 { 2469 case SID_H_ALIGNCELL: 2470 if ( bHasHAlign ) 2471 rSet.Put( SvxHorJustifyItem( eHAlign, nWhich )); 2472 break; 2473 case SID_V_ALIGNCELL: 2474 if ( bHasVAlign ) 2475 rSet.Put( SvxVerJustifyItem( eVAlign, nWhich )); 2476 break; 2477 2478 // pseudo slots for Format menu 2479 case SID_ALIGN_ANY_HDEFAULT: 2480 case SID_ALIGN_ANY_LEFT: 2481 case SID_ALIGN_ANY_HCENTER: 2482 case SID_ALIGN_ANY_RIGHT: 2483 case SID_ALIGN_ANY_JUSTIFIED: 2484 rSet.Put( SfxBoolItem( nWhich, bHasHAlign && (eHAlign == lclConvertSlotToHAlign( nWhich )) ) ); 2485 break; 2486 case SID_ALIGN_ANY_VDEFAULT: 2487 case SID_ALIGN_ANY_TOP: 2488 case SID_ALIGN_ANY_VCENTER: 2489 case SID_ALIGN_ANY_BOTTOM: 2490 rSet.Put( SfxBoolItem( nWhich, bHasVAlign && (eVAlign == lclConvertSlotToVAlign( nWhich )) ) ); 2491 break; 2492 } 2493 nWhich = aIter.NextWhich(); 2494 } 2495 } 2496 2497 void ScFormatShell::GetNumFormatState( SfxItemSet& rSet ) 2498 { 2499 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2500 ScDocument& rDoc = rViewData.GetDocument(); 2501 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 2502 const SfxItemState eItemState = rAttrSet.GetItemState( ATTR_VALUE_FORMAT ); 2503 sal_uInt32 nNumberFormat = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue(); 2504 SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 2505 // If item state is default or set it 2506 // indicates one number format so we 2507 // don't have to iterate over all 2508 // selected cells' attribute ranges to 2509 // determine selected types. 2510 // Does *NOT* include the 2511 // SvNumFormatType::DEFINED bit. 2512 const SvNumFormatType nType = (eItemState >= SfxItemState::DEFAULT ? pFormatter->GetType( nNumberFormat) : 2513 GetCurrentNumberFormatType()); 2514 NfIndexTableOffset nOffset = pFormatter->GetIndexTableOffset(nNumberFormat); 2515 2516 SfxWhichIter aIter(rSet); 2517 sal_uInt16 nWhich = aIter.FirstWhich(); 2518 2519 while ( nWhich ) 2520 { 2521 switch ( nWhich ) 2522 { 2523 case SID_NUMBER_THOUSANDS: 2524 { 2525 bool bEnable = (SfxItemState::DONTCARE != eItemState); 2526 if (bEnable) 2527 { 2528 bEnable = ((nType != SvNumFormatType::ALL) && (nType & 2529 (SvNumFormatType::NUMBER | 2530 SvNumFormatType::PERCENT | 2531 SvNumFormatType::CURRENCY | 2532 SvNumFormatType::FRACTION))); 2533 if (bEnable) 2534 { 2535 bool bThousand( false ); 2536 bool bNegRed( false ); 2537 sal_uInt16 nPrecision( 0 ); 2538 sal_uInt16 nLeadZeroes( 0 ); 2539 pFormatter->GetFormatSpecialInfo( nNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes); 2540 rSet.Put( SfxBoolItem( nWhich, bThousand)); 2541 } 2542 } 2543 if (!bEnable) 2544 { 2545 rSet.DisableItem( nWhich ); 2546 } 2547 } 2548 break; 2549 case SID_NUMBER_FORMAT: 2550 // symphony version with format interpretation 2551 { 2552 if(SfxItemState::DONTCARE != eItemState) 2553 { 2554 bool bThousand(false); 2555 bool bNegRed(false); 2556 sal_uInt16 nPrecision(0); 2557 sal_uInt16 nLeadZeroes(0); 2558 2559 pFormatter->GetFormatSpecialInfo(nNumberFormat,bThousand, bNegRed, nPrecision, nLeadZeroes); 2560 2561 const SvNumberformat* pFormatEntry = pFormatter->GetEntry( nNumberFormat ); 2562 if (pFormatEntry && (pFormatEntry->GetType() & SvNumFormatType::SCIENTIFIC)) 2563 { 2564 // if scientific, bThousand is used for engineering notation 2565 const sal_uInt16 nIntegerDigits = pFormatEntry->GetFormatIntegerDigits(); 2566 bThousand = nIntegerDigits > 0 && ((nIntegerDigits % 3) == 0); 2567 } 2568 OUString aFormat; 2569 static constexpr OUStringLiteral sBreak = u","; 2570 const OUString sThousand = OUString::number(static_cast<sal_Int32>(bThousand)); 2571 const OUString sNegRed = OUString::number(static_cast<sal_Int32>(bNegRed)); 2572 const OUString sPrecision = OUString::number(nPrecision); 2573 const OUString sLeadZeroes = OUString::number(nLeadZeroes); 2574 2575 aFormat += sThousand + 2576 sBreak + 2577 sNegRed + 2578 sBreak + 2579 sPrecision + 2580 sBreak + 2581 sLeadZeroes + 2582 sBreak; 2583 2584 rSet.Put(SfxStringItem(nWhich, aFormat)); 2585 2586 if (comphelper::LibreOfficeKit::isActive()) 2587 { 2588 OUString sPayload = ".uno:NumberFormat=" + aFormat; 2589 GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, 2590 OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US).getStr()); 2591 } 2592 } 2593 else 2594 { 2595 rSet.InvalidateItem( nWhich ); 2596 } 2597 } 2598 break; 2599 2600 case SID_NUMBER_TYPE_FORMAT: 2601 { 2602 sal_Int16 nFormatCategory = -1; 2603 if ( eItemState >= SfxItemState::DEFAULT ) //Modify for more robust 2604 { 2605 switch(nType) 2606 { 2607 case SvNumFormatType::NUMBER: 2608 // Determine if General format. 2609 if ((nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) 2610 nFormatCategory = 0; 2611 else 2612 nFormatCategory = 1; 2613 break; 2614 case SvNumFormatType::PERCENT: 2615 nFormatCategory = 2; 2616 break; 2617 case SvNumFormatType::CURRENCY: 2618 nFormatCategory = 3; 2619 break; 2620 case SvNumFormatType::DATE: 2621 //Add 2622 case SvNumFormatType::DATETIME: 2623 nFormatCategory = 4; 2624 break; 2625 case SvNumFormatType::TIME: 2626 nFormatCategory = 5; 2627 break; 2628 case SvNumFormatType::SCIENTIFIC: 2629 nFormatCategory = 6; 2630 break; 2631 case SvNumFormatType::FRACTION: 2632 nFormatCategory = 7; 2633 break; 2634 case SvNumFormatType::LOGICAL: 2635 nFormatCategory = 8; 2636 break; 2637 case SvNumFormatType::TEXT: 2638 nFormatCategory = 9; 2639 break; 2640 default: 2641 nFormatCategory = -1; //for more robust 2642 } 2643 if( nFormatCategory == -1 ) 2644 rSet.InvalidateItem( nWhich ); 2645 else 2646 rSet.Put( SfxInt16Item( nWhich, nFormatCategory ) ); 2647 } 2648 else 2649 { 2650 rSet.InvalidateItem( nWhich ); 2651 } 2652 2653 } 2654 break; 2655 case SID_NUMBER_CURRENCY: 2656 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::CURRENCY)) ); 2657 break; 2658 case SID_NUMBER_SCIENTIFIC: 2659 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::SCIENTIFIC)) ); 2660 break; 2661 case SID_NUMBER_DATE: 2662 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::DATE)) ); 2663 break; 2664 case SID_NUMBER_PERCENT: 2665 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::PERCENT)) ); 2666 break; 2667 case SID_NUMBER_TIME: 2668 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::TIME)) ); 2669 break; 2670 case SID_NUMBER_TWODEC: 2671 rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && nOffset == NF_NUMBER_1000DEC2 ) ); 2672 break; 2673 case SID_NUMBER_STANDARD: 2674 rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && (nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) ); 2675 break; 2676 } 2677 nWhich = aIter.NextWhich(); 2678 } 2679 } 2680 2681 void ScFormatShell::ExecuteTextDirection( const SfxRequest& rReq ) 2682 { 2683 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2684 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox 2685 bool bEditMode = false; 2686 if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) ) 2687 { 2688 bEditMode=true; 2689 SC_MOD()->InputEnterHandler(); 2690 pTabViewShell->UpdateInputHandler(); 2691 } 2692 sal_uInt16 nSlot = rReq.GetSlot(); 2693 switch( nSlot ) 2694 { 2695 case SID_TEXTDIRECTION_LEFT_TO_RIGHT: 2696 case SID_TEXTDIRECTION_TOP_TO_BOTTOM: 2697 { 2698 bool bVert = (nSlot == SID_TEXTDIRECTION_TOP_TO_BOTTOM); 2699 ScPatternAttr aAttr( GetViewData().GetDocument().GetPool() ); 2700 SfxItemSet& rItemSet = aAttr.GetItemSet(); 2701 rItemSet.Put( ScVerticalStackCell( bVert ) ); 2702 rItemSet.Put( SfxBoolItem( ATTR_VERTICAL_ASIAN, bVert ) ); 2703 pTabViewShell->ApplySelectionPattern( aAttr ); 2704 pTabViewShell->AdjustBlockHeight(); 2705 } 2706 break; 2707 2708 case SID_ATTR_PARA_LEFT_TO_RIGHT: 2709 case SID_ATTR_PARA_RIGHT_TO_LEFT: 2710 { 2711 SvxFrameDirection eDirection = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT ) ? 2712 SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB; 2713 pTabViewShell->ApplyAttr( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) ); 2714 } 2715 break; 2716 } 2717 if (bEditMode) 2718 SC_MOD()->SetInputMode( SC_INPUT_TABLE ); 2719 } 2720 2721 void ScFormatShell::GetTextDirectionState( SfxItemSet& rSet ) 2722 { 2723 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell(); 2724 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet(); 2725 2726 bool bVertDontCare = 2727 (rAttrSet.GetItemState( ATTR_VERTICAL_ASIAN ) == SfxItemState::DONTCARE) || 2728 (rAttrSet.GetItemState( ATTR_STACKED ) == SfxItemState::DONTCARE); 2729 bool bLeftRight = !bVertDontCare && 2730 !rAttrSet.Get( ATTR_STACKED ).GetValue(); 2731 bool bTopBottom = !bVertDontCare && !bLeftRight && 2732 rAttrSet.Get( ATTR_VERTICAL_ASIAN ).GetValue(); 2733 2734 bool bBidiDontCare = (rAttrSet.GetItemState( ATTR_WRITINGDIR ) == SfxItemState::DONTCARE); 2735 EEHorizontalTextDirection eBidiDir = EEHorizontalTextDirection::Default; 2736 if ( !bBidiDontCare ) 2737 { 2738 SvxFrameDirection eCellDir = rAttrSet.Get( ATTR_WRITINGDIR ).GetValue(); 2739 if ( eCellDir == SvxFrameDirection::Environment ) 2740 eBidiDir = GetViewData().GetDocument(). 2741 GetEditTextDirection( GetViewData().GetTabNo() ); 2742 else if ( eCellDir == SvxFrameDirection::Horizontal_RL_TB ) 2743 eBidiDir = EEHorizontalTextDirection::R2L; 2744 else 2745 eBidiDir = EEHorizontalTextDirection::L2R; 2746 } 2747 2748 bool bDisableCTLFont = !SvtCTLOptions().IsCTLFontEnabled(); 2749 bool bDisableVerticalText = !SvtCJKOptions::IsVerticalTextEnabled(); 2750 2751 SfxWhichIter aIter( rSet ); 2752 sal_uInt16 nWhich = aIter.FirstWhich(); 2753 while( nWhich ) 2754 { 2755 switch( nWhich ) 2756 { 2757 case SID_TEXTDIRECTION_LEFT_TO_RIGHT: 2758 case SID_TEXTDIRECTION_TOP_TO_BOTTOM: 2759 if ( bDisableVerticalText ) 2760 rSet.DisableItem( nWhich ); 2761 else 2762 { 2763 if( bVertDontCare ) 2764 rSet.InvalidateItem( nWhich ); 2765 else if ( nWhich == SID_TEXTDIRECTION_LEFT_TO_RIGHT ) 2766 rSet.Put( SfxBoolItem( nWhich, bLeftRight ) ); 2767 else 2768 rSet.Put( SfxBoolItem( nWhich, bTopBottom ) ); 2769 } 2770 break; 2771 2772 case SID_ATTR_PARA_LEFT_TO_RIGHT: 2773 case SID_ATTR_PARA_RIGHT_TO_LEFT: 2774 if ( bDisableCTLFont ) 2775 rSet.DisableItem( nWhich ); 2776 else 2777 { 2778 if ( bTopBottom ) 2779 rSet.DisableItem( nWhich ); 2780 else if ( bBidiDontCare ) 2781 rSet.InvalidateItem( nWhich ); 2782 else if ( nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT ) 2783 rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::L2R ) ); 2784 else 2785 rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::R2L ) ); 2786 } 2787 } 2788 nWhich = aIter.NextWhich(); 2789 } 2790 } 2791 2792 void ScFormatShell::ExecFormatPaintbrush( const SfxRequest& rReq ) 2793 { 2794 ScViewFunc* pView = rViewData.GetView(); 2795 if ( pView->HasPaintBrush() ) 2796 { 2797 // cancel paintbrush mode 2798 pView->ResetBrushDocument(); 2799 } 2800 else 2801 { 2802 bool bLock = false; 2803 const SfxItemSet *pArgs = rReq.GetArgs(); 2804 if( pArgs && pArgs->Count() >= 1 ) 2805 bLock = pArgs->Get(SID_FORMATPAINTBRUSH).GetValue(); 2806 2807 // in case of multi selection, deselect all and use the cursor position 2808 ScRange aDummy; 2809 if ( rViewData.GetSimpleArea(aDummy) != SC_MARK_SIMPLE ) 2810 pView->Unmark(); 2811 2812 ScDocumentUniquePtr pBrushDoc(new ScDocument( SCDOCMODE_CLIP )); 2813 pView->CopyToClip( pBrushDoc.get(), false, true ); 2814 pView->SetBrushDocument( std::move(pBrushDoc), bLock ); 2815 } 2816 } 2817 2818 void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet ) 2819 { 2820 if ( rViewData.HasEditView( rViewData.GetActivePart() ) ) 2821 rSet.DisableItem( SID_FORMATPAINTBRUSH ); 2822 else 2823 rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, rViewData.GetView()->HasPaintBrush() ) ); 2824 } 2825 2826 SvNumFormatType ScFormatShell::GetCurrentNumberFormatType() 2827 { 2828 SvNumFormatType nType = SvNumFormatType::ALL; 2829 ScDocument& rDoc = GetViewData().GetDocument(); 2830 ScMarkData aMark(GetViewData().GetMarkData()); 2831 const SvNumberFormatter* pFormatter = rDoc.GetFormatTable(); 2832 if (!pFormatter) 2833 return nType; 2834 2835 // TODO: Find out how to get a selected table range in case multiple tables 2836 // are selected. Currently we only check for the current active table. 2837 2838 if ( aMark.IsMarked() || aMark.IsMultiMarked() ) 2839 { 2840 aMark.MarkToMulti(); 2841 ScRange aRange; 2842 aMark.GetMultiMarkArea(aRange); 2843 2844 const ScMultiSel& rMultiSel = aMark.GetMultiSelData(); 2845 2846 SvNumFormatType nComboType = SvNumFormatType::ALL; 2847 bool bFirstItem = true; 2848 for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol) 2849 { 2850 if (!rMultiSel.HasMarks(nCol)) 2851 continue; 2852 2853 SCROW nRow1, nRow2; 2854 ScMultiSelIter aMultiIter(rMultiSel, nCol); 2855 while (aMultiIter.Next(nRow1, nRow2)) 2856 { 2857 ScRange aColRange(nCol, nRow1, aRange.aStart.Tab()); 2858 aColRange.aEnd.SetRow(nRow2); 2859 sal_uInt32 nNumFmt = rDoc.GetNumberFormat(aColRange); 2860 SvNumFormatType nThisType = pFormatter->GetType(nNumFmt); 2861 if (bFirstItem) 2862 { 2863 bFirstItem = false; 2864 nComboType = nThisType; 2865 } 2866 else if (nComboType != nThisType) 2867 // mixed number format type. 2868 return SvNumFormatType::ALL; 2869 } 2870 } 2871 nType = nComboType; 2872 } 2873 else 2874 { 2875 sal_uInt32 nNumFmt = rDoc.GetNumberFormat( rViewData.GetCurX(), rViewData.GetCurY(), 2876 rViewData.GetTabNo()); 2877 nType = pFormatter->GetType( nNumFmt ); 2878 } 2879 return nType; 2880 } 2881 2882 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 2883
