tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / ui / view / formatsh.cxx
blobe8f1baf7e7451199776aadc83bc8fa2c513fc765
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
22 #include <scitems.hxx>
23 #include <editeng/borderline.hxx>
25 #include <sfx2/viewfrm.hxx>
26 #include <sfx2/bindings.hxx>
27 #include <sfx2/objface.hxx>
28 #include <sfx2/request.hxx>
29 #include <svl/whiter.hxx>
31 #include <svl/stritem.hxx>
32 #include <svl/numformat.hxx>
33 #include <svl/zformat.hxx>
34 #include <svl/languageoptions.hxx>
35 #include <svl/cjkoptions.hxx>
36 #include <svl/ctloptions.hxx>
37 #include <editeng/boxitem.hxx>
38 #include <editeng/langitem.hxx>
39 #include <editeng/svxenum.hxx>
40 #include <editeng/wghtitem.hxx>
41 #include <editeng/postitem.hxx>
42 #include <editeng/udlnitem.hxx>
43 #include <editeng/lineitem.hxx>
44 #include <editeng/colritem.hxx>
45 #include <editeng/brushitem.hxx>
46 #include <editeng/frmdiritem.hxx>
47 #include <editeng/scripttypeitem.hxx>
48 #include <editeng/shaditem.hxx>
49 #include <editeng/justifyitem.hxx>
50 #include <editeng/fhgtitem.hxx>
51 #include <sal/log.hxx>
52 #include <osl/diagnose.h>
53 #include <comphelper/lok.hxx>
54 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
56 #include <formatsh.hxx>
57 #include <sc.hrc>
58 #include <docsh.hxx>
59 #include <patattr.hxx>
60 #include <scmod.hxx>
61 #include <stlpool.hxx>
62 #include <stlsheet.hxx>
63 #include <docpool.hxx>
64 #include <tabvwsh.hxx>
65 #include <attrib.hxx>
67 #define ShellClass_ScFormatShell
68 #define ShellClass_TableFont
69 #define ShellClass_FormatForSelection
70 #include <scslots.hxx>
72 #include <editeng/fontitem.hxx>
73 #include <sfx2/classificationhelper.hxx>
75 #include <memory>
77 namespace {
79 SvxCellHorJustify lclConvertSlotToHAlign( sal_uInt16 nSlot )
81 SvxCellHorJustify eHJustify = SvxCellHorJustify::Standard;
82 switch( nSlot )
84 case SID_ALIGN_ANY_HDEFAULT: eHJustify = SvxCellHorJustify::Standard; break;
85 case SID_ALIGN_ANY_LEFT: eHJustify = SvxCellHorJustify::Left; break;
86 case SID_ALIGN_ANY_HCENTER: eHJustify = SvxCellHorJustify::Center; break;
87 case SID_ALIGN_ANY_RIGHT: eHJustify = SvxCellHorJustify::Right; break;
88 case SID_ALIGN_ANY_JUSTIFIED: eHJustify = SvxCellHorJustify::Block; break;
89 default: OSL_FAIL( "lclConvertSlotToHAlign - invalid slot" );
91 return eHJustify;
94 SvxCellVerJustify lclConvertSlotToVAlign( sal_uInt16 nSlot )
96 SvxCellVerJustify eVJustify = SvxCellVerJustify::Standard;
97 switch( nSlot )
99 case SID_ALIGN_ANY_VDEFAULT: eVJustify = SvxCellVerJustify::Standard; break;
100 case SID_ALIGN_ANY_TOP: eVJustify = SvxCellVerJustify::Top; break;
101 case SID_ALIGN_ANY_VCENTER: eVJustify = SvxCellVerJustify::Center; break;
102 case SID_ALIGN_ANY_BOTTOM: eVJustify = SvxCellVerJustify::Bottom; break;
103 default: OSL_FAIL( "lclConvertSlotToVAlign - invalid slot" );
105 return eVJustify;
108 } // namespace
111 SFX_IMPL_INTERFACE(ScFormatShell, SfxShell)
113 void ScFormatShell::InitInterface_Impl()
115 GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
116 SfxVisibilityFlags::Standard | SfxVisibilityFlags::Server,
117 ToolbarId::Objectbar_Format);
120 ScFormatShell::ScFormatShell(ScViewData& rData) :
121 SfxShell(rData.GetViewShell()),
122 rViewData(rData)
124 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
126 SetPool( &pTabViewShell->GetPool() );
127 SfxUndoManager* pMgr = rViewData.GetSfxDocShell()->GetUndoManager();
128 SetUndoManager( pMgr );
129 if (pMgr && !rViewData.GetDocument().IsUndoEnabled())
131 pMgr->SetMaxUndoActionCount( 0 );
133 SetName(u"Format"_ustr);
136 ScFormatShell::~ScFormatShell()
140 void ScFormatShell::ExecuteStyle( SfxRequest& rReq )
142 const SfxItemSet* pArgs = rReq.GetArgs();
143 const sal_uInt16 nSlotId = rReq.GetSlot();
145 ScDocShell* pDocSh = GetViewData().GetDocShell();
146 ScTabViewShell* pTabViewShell= GetViewData().GetViewShell();
147 ScDocument& rDoc = pDocSh->GetDocument();
148 SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool();
150 if ( (nSlotId == SID_STYLE_PREVIEW)
151 || (nSlotId == SID_STYLE_END_PREVIEW) )
153 if (nSlotId == SID_STYLE_PREVIEW)
155 SfxStyleFamily eFamily = SfxStyleFamily::Para;
156 const SfxUInt16Item* pFamItem;
157 if ( pArgs && (pFamItem = pArgs->GetItemIfSet( SID_STYLE_FAMILY )) )
158 eFamily = static_cast<SfxStyleFamily>(pFamItem->GetValue());
159 const SfxPoolItem* pNameItem;
160 OUString aStyleName;
161 if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem ))
162 aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
163 if ( eFamily == SfxStyleFamily::Para ) // CellStyles
165 ScMarkData aFuncMark( rViewData.GetMarkData() );
166 ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
167 aFuncMark.MarkToMulti();
169 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
171 SCCOL nCol = rViewData.GetCurX();
172 SCROW nRow = rViewData.GetCurY();
173 SCTAB nTab = rViewData.GetTabNo();
174 ScRange aRange( nCol, nRow, nTab );
175 aFuncMark.SetMarkArea( aRange );
177 rDoc.SetPreviewSelection( aFuncMark );
178 ScStyleSheet* pPreviewStyle = static_cast<ScStyleSheet*>( pStylePool->Find( aStyleName, eFamily ) );
179 rDoc.SetPreviewCellStyle( pPreviewStyle );
180 ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aFuncMark ) );
181 aAttr.SetStyleSheet( pPreviewStyle );
183 SfxItemSet aItemSet( GetPool() );
185 ScPatternAttr aNewAttrs(GetViewData().GetDocument().getCellAttributeHelper());
186 SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
187 rNewSet.Put( aItemSet, false );
189 rDoc.ApplySelectionPattern( aNewAttrs, rDoc.GetPreviewSelection() );
190 pTabViewShell->UpdateSelectionArea( aFuncMark, &aAttr );
193 else
195 // No mark at all happens when creating a new document, in which
196 // case the selection pattern obtained would be empty (created of
197 // GetPool()) anyway and nothing needs to be applied.
198 ScMarkData aPreviewMark( rDoc.GetPreviewSelection());
199 if (aPreviewMark.IsMarked() || aPreviewMark.IsMultiMarked())
201 ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aPreviewMark ) );
202 if ( ScStyleSheet* pPreviewStyle = rDoc.GetPreviewCellStyle() )
203 aAttr.SetStyleSheet( pPreviewStyle );
204 rDoc.SetPreviewCellStyle(nullptr);
206 SfxItemSet aItemSet( GetPool() );
208 ScPatternAttr aNewAttrs(GetViewData().GetDocument().getCellAttributeHelper());
209 SfxItemSet& rNewSet = aNewAttrs.GetItemSet();
210 rNewSet.Put( aItemSet, false );
211 rDoc.ApplySelectionPattern( aNewAttrs, aPreviewMark );
212 pTabViewShell->UpdateSelectionArea( aPreviewMark, &aAttr );
216 else if (nSlotId == SID_CLASSIFICATION_APPLY)
218 const SfxPoolItem* pItem = nullptr;
219 if (pArgs && pArgs->GetItemState(nSlotId, false, &pItem) == SfxItemState::SET)
221 const OUString& rName = static_cast<const SfxStringItem*>(pItem)->GetValue();
222 SfxClassificationHelper aHelper(pDocSh->getDocProperties());
223 auto eType = SfxClassificationPolicyType::IntellectualProperty;
224 if (const SfxStringItem* pNameItem = pArgs->GetItemIfSet(SID_TYPE_NAME, false))
226 const OUString& rType = pNameItem->GetValue();
227 eType = SfxClassificationHelper::stringToPolicyType(rType);
229 aHelper.SetBACName(rName, eType);
231 else
232 SAL_WARN("sc.ui", "missing parameter for SID_CLASSIFICATION_APPLY");
234 else
236 OSL_FAIL( "Unknown slot (ScViewShell::ExecuteStyle)" );
240 void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq )
242 ScModule* pScMod = ScModule::get();
243 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
244 const SfxItemSet* pReqArgs = rReq.GetArgs();
245 sal_uInt16 nSlot = rReq.GetSlot();
246 SfxBindings& rBindings = pTabViewShell->GetViewFrame().GetBindings();
248 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
250 // End input
251 if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) )
253 switch ( nSlot )
255 case SID_NUMBER_TYPE_FORMAT:
256 case SID_NUMBER_TWODEC:
257 case SID_NUMBER_SCIENTIFIC:
258 case SID_NUMBER_DATE:
259 case SID_NUMBER_CURRENCY:
260 case SID_NUMBER_PERCENT:
261 case SID_NUMBER_STANDARD:
262 case SID_NUMBER_FORMAT:
263 case SID_NUMBER_INCDEC:
264 case SID_NUMBER_DECDEC:
265 case SID_NUMBER_THOUSANDS:
266 case FID_DEFINE_NAME:
267 case FID_ADD_NAME:
268 case FID_USE_NAME:
269 case FID_INSERT_NAME:
270 case SID_SPELL_DIALOG:
271 case SID_HANGUL_HANJA_CONVERSION:
273 pScMod->InputEnterHandler();
274 pTabViewShell->UpdateInputHandler();
275 break;
277 default:
278 break;
282 SvNumFormatType nType = GetCurrentNumberFormatType();
283 switch ( nSlot )
285 case SID_NUMBER_TWODEC:
287 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
288 sal_uInt32 nNumberFormat = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue();
290 if ((nType & SvNumFormatType::NUMBER) && nNumberFormat == 4)
291 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
292 else
293 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 4 );
294 rBindings.Invalidate( nSlot );
295 rReq.Done();
297 break;
298 case SID_NUMBER_SCIENTIFIC:
299 if (nType & SvNumFormatType::SCIENTIFIC)
300 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
301 else
302 pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC );
303 rBindings.Invalidate( nSlot );
304 rReq.Done();
305 break;
306 case SID_NUMBER_DATE:
307 if (nType & SvNumFormatType::DATE)
308 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
309 else
310 pTabViewShell->SetNumberFormat( SvNumFormatType::DATE );
311 rBindings.Invalidate( nSlot );
312 rReq.Done();
313 break;
314 case SID_NUMBER_TIME:
315 if (nType & SvNumFormatType::TIME)
316 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
317 else
318 pTabViewShell->SetNumberFormat( SvNumFormatType::TIME );
319 rBindings.Invalidate( nSlot );
320 rReq.Done();
321 break;
322 case SID_NUMBER_CURRENCY:
323 if(pReqArgs)
325 const SfxPoolItem* pItem;
326 if ( pReqArgs->HasItem( SID_NUMBER_CURRENCY, &pItem ) )
328 sal_uInt32 nNewFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
329 ScDocument& rDoc = rViewData.GetDocument();
330 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
331 const SfxItemSet& rOldSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
333 LanguageType eOldLang = rOldSet.Get( ATTR_LANGUAGE_FORMAT ).GetLanguage();
334 sal_uInt32 nOldFormat = rOldSet.Get( ATTR_VALUE_FORMAT ).GetValue();
336 if ( nOldFormat != nNewFormat )
338 const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
339 ScPatternAttr aNewAttrs(rDoc.getCellAttributeHelper());
340 SfxItemSet& rSet = aNewAttrs.GetItemSet();
341 LanguageType eNewLang = pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
342 if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
343 rSet.Put( SvxLanguageItem( eNewLang, ATTR_LANGUAGE_FORMAT ) );
344 rSet.Put( SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) );
345 pTabViewShell->ApplySelectionPattern( aNewAttrs );
347 else
348 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
351 else
353 if ( nType & SvNumFormatType::CURRENCY )
354 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
355 else
356 pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY );
358 rBindings.Invalidate( nSlot );
359 rReq.Done();
360 break;
361 case SID_NUMBER_PERCENT:
362 if (nType & SvNumFormatType::PERCENT)
363 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
364 else
365 pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT );
366 rBindings.Invalidate( nSlot );
367 rReq.Done();
368 break;
369 case SID_NUMBER_STANDARD:
370 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
371 rReq.Done();
372 break;
373 case SID_NUMBER_INCDEC:
374 pTabViewShell->ChangeNumFmtDecimals( true );
375 rReq.Done();
376 break;
377 case SID_NUMBER_DECDEC:
378 pTabViewShell->ChangeNumFmtDecimals( false );
379 rReq.Done();
380 break;
381 case SID_NUMBER_THOUSANDS:
383 ScDocument& rDoc = rViewData.GetDocument();
384 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
385 bool bThousand(false);
386 bool bNegRed(false);
387 sal_uInt16 nPrecision(0);
388 sal_uInt16 nLeadZeroes(0);
389 LanguageType eLanguage = ScGlobal::eLnge;
391 sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat(
392 rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
393 const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat);
395 if (pEntry)
396 eLanguage = pEntry->GetLanguage();
398 pFormatter->GetFormatSpecialInfo(nCurrentNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes);
399 bThousand = !bThousand;
400 OUString aCode = pFormatter->GenerateFormat(
401 nCurrentNumberFormat,
402 eLanguage,
403 bThousand,
404 bNegRed,
405 nPrecision,
406 nLeadZeroes);
407 pTabViewShell->SetNumFmtByStr(aCode);
409 rBindings.Invalidate(nSlot);
410 rReq.Done();
412 break;
413 case SID_NUMBER_FORMAT:
414 // symphony version with format interpretation
415 if(pReqArgs)
417 const SfxPoolItem* pItem;
418 ScDocument& rDoc = rViewData.GetDocument();
419 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
421 sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat(
422 rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
423 const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat);
425 if(!pEntry)
426 break;
428 LanguageType eLanguage = pEntry->GetLanguage();
429 SvNumFormatType eType = pEntry->GetMaskedType();
431 //Just use eType to judge whether the command is fired for NUMBER/PERCENT/CURRENCY/SCIENTIFIC/FRACTION/TIME
432 //In sidebar, users can fire SID_NUMBER_FORMAT command by operating the related UI controls before they are disable
433 if(!(eType == SvNumFormatType::ALL
434 || eType == SvNumFormatType::NUMBER
435 || eType == SvNumFormatType::PERCENT
436 || eType == SvNumFormatType::CURRENCY
437 || eType == SvNumFormatType::SCIENTIFIC
438 || eType == SvNumFormatType::TIME
439 || eType == SvNumFormatType::FRACTION))
440 pEntry = nullptr;
442 if(SfxItemState::SET == pReqArgs->GetItemState(nSlot, true, &pItem) && pEntry)
444 OUString aCode = static_cast<const SfxStringItem*>(pItem)->GetValue();
445 sal_uInt16 aLen = aCode.getLength();
446 std::unique_ptr<OUString[]> sFormat( new OUString[4] );
447 OUStringBuffer sTmpStr;
448 sal_uInt16 nCount(0);
449 sal_uInt16 nStrCount(0);
451 while(nCount < aLen)
453 sal_Unicode cChar = aCode[nCount];
455 if(cChar == ',')
457 sFormat[nStrCount] = sTmpStr.makeStringAndClear();
458 nStrCount++;
460 else
462 sTmpStr.append(cChar);
465 nCount++;
467 if(nStrCount > 3)
468 break;
471 const bool bThousand = static_cast<bool>(sFormat[0].toInt32());
472 const bool bNegRed = static_cast<bool>(sFormat[1].toInt32());
473 const sal_uInt16 nPrecision = static_cast<sal_uInt16>(sFormat[2].toInt32());
474 const sal_uInt16 nLeadZeroes = static_cast<sal_uInt16>(sFormat[3].toInt32());
476 aCode = pFormatter->GenerateFormat(
477 nCurrentNumberFormat,//modify
478 eLanguage,
479 bThousand,
480 bNegRed,
481 nPrecision,
482 nLeadZeroes);
483 pTabViewShell->SetNumFmtByStr(aCode);
486 break;
488 case SID_ATTR_NUMBERFORMAT_VALUE:
489 if ( pReqArgs )
491 if ( const SfxUInt32Item* pItem = pReqArgs->GetItemIfSet( ATTR_VALUE_FORMAT ) )
493 // We have to accomplish this using ApplyAttributes()
494 // because we also need the language information to be
495 // considered.
496 const SfxItemSet& rOldSet =
497 pTabViewShell->GetSelectionPattern()->GetItemSet();
498 SfxItemPool* pDocPool = GetViewData().GetDocument().GetPool();
499 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *pDocPool );
500 aNewSet.Put( *pItem );
501 pTabViewShell->ApplyAttributes( aNewSet, rOldSet );
504 break;
506 case SID_NUMBER_TYPE_FORMAT:
507 if ( pReqArgs )
509 const SfxPoolItem* pItem;
510 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
512 sal_uInt16 nFormat = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
513 switch(nFormat)
515 case 0:
516 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER); //Modify
517 break;
518 case 1:
519 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 2 ); //Modify
520 break;
521 case 2:
522 pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT );
523 break;
524 case 3:
525 pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY );
526 break;
527 case 4:
528 pTabViewShell->SetNumberFormat( SvNumFormatType::DATE );
529 break;
530 case 5:
531 pTabViewShell->SetNumberFormat( SvNumFormatType::TIME );
532 break;
533 case 6:
534 pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC );
535 break;
536 case 7:
537 pTabViewShell->SetNumberFormat( SvNumFormatType::FRACTION );
538 break;
539 case 8:
540 pTabViewShell->SetNumberFormat( SvNumFormatType::LOGICAL );
541 break;
542 case 9:
543 pTabViewShell->SetNumberFormat( SvNumFormatType::TEXT );
544 break;
545 default:
548 rReq.Done();
551 break;
553 default:
554 OSL_FAIL("ExecuteEdit: invalid slot");
555 break;
559 void ScFormatShell::ExecuteAlignment( SfxRequest& rReq )
561 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
562 SfxBindings& rBindings = rViewData.GetBindings();
563 const SfxItemSet* pSet = rReq.GetArgs();
564 sal_uInt16 nSlot = rReq.GetSlot();
566 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
568 switch( nSlot )
570 // pseudo slots for Format menu
571 case SID_ALIGN_ANY_HDEFAULT:
572 case SID_ALIGN_ANY_LEFT:
573 case SID_ALIGN_ANY_HCENTER:
574 case SID_ALIGN_ANY_RIGHT:
575 case SID_ALIGN_ANY_JUSTIFIED:
576 pTabViewShell->ApplyAttr( SvxHorJustifyItem( lclConvertSlotToHAlign( nSlot ), ATTR_HOR_JUSTIFY ) );
577 break;
578 case SID_ALIGN_ANY_VDEFAULT:
579 case SID_ALIGN_ANY_TOP:
580 case SID_ALIGN_ANY_VCENTER:
581 case SID_ALIGN_ANY_BOTTOM:
582 pTabViewShell->ApplyAttr( SvxVerJustifyItem( lclConvertSlotToVAlign( nSlot ), ATTR_VER_JUSTIFY ) );
583 break;
585 default:
586 if( pSet )
588 const SfxPoolItem* pItem = nullptr;
589 if( pSet->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), true, &pItem ) == SfxItemState::SET )
592 switch ( nSlot )
594 case SID_ATTR_ALIGN_HOR_JUSTIFY:
595 case SID_ATTR_ALIGN_VER_JUSTIFY:
596 case SID_ATTR_ALIGN_INDENT:
597 case SID_ATTR_ALIGN_HYPHENATION:
598 case SID_ATTR_ALIGN_DEGREES:
599 case SID_ATTR_ALIGN_LOCKPOS:
600 case SID_ATTR_ALIGN_MARGIN:
601 case SID_ATTR_ALIGN_STACKED:
602 pTabViewShell->ApplyAttr( *pItem );
603 break;
605 case SID_H_ALIGNCELL:
607 SvxCellHorJustify eJust = static_cast<const SvxHorJustifyItem*>(pItem)->GetValue();
608 // #i78476# update alignment of text in cell edit mode
609 pTabViewShell->UpdateInputHandlerCellAdjust( eJust );
610 pTabViewShell->ApplyAttr( SvxHorJustifyItem( eJust, ATTR_HOR_JUSTIFY ) );
612 break;
613 case SID_V_ALIGNCELL:
614 pTabViewShell->ApplyAttr( SvxVerJustifyItem( static_cast<const SvxVerJustifyItem*>(pItem)->GetValue(), ATTR_VER_JUSTIFY ) );
615 break;
616 default:
617 OSL_FAIL( "ExecuteAlignment: invalid slot" );
618 return;
623 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
624 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
625 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
626 rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
627 rBindings.Invalidate( SID_ALIGNLEFT );
628 rBindings.Invalidate( SID_ALIGNRIGHT );
629 rBindings.Invalidate( SID_ALIGNCENTERHOR );
630 rBindings.Invalidate( SID_ALIGNBLOCK );
631 rBindings.Invalidate( SID_ALIGNTOP );
632 rBindings.Invalidate( SID_ALIGNBOTTOM );
633 rBindings.Invalidate( SID_ALIGNCENTERVER );
634 rBindings.Invalidate( SID_V_ALIGNCELL );
635 rBindings.Invalidate( SID_H_ALIGNCELL );
636 // pseudo slots for Format menu
637 rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
638 rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
639 rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
640 rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
641 rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
642 rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
643 rBindings.Invalidate( SID_ALIGN_ANY_TOP );
644 rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
645 rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
646 rBindings.Update();
648 if( ! rReq.IsAPI() )
649 rReq.Done();
652 void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq )
654 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
655 SfxBindings& rBindings = rViewData.GetBindings();
656 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
657 const SfxItemSet* pSet = rReq.GetArgs();
658 sal_uInt16 nSlot = rReq.GetSlot();
659 std::optional<SfxAllItemSet> pNewSet;
661 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
663 if ( (nSlot == SID_ATTR_CHAR_WEIGHT)
664 ||(nSlot == SID_ATTR_CHAR_POSTURE)
665 ||(nSlot == SID_ATTR_CHAR_UNDERLINE)
666 ||(nSlot == SID_ULINE_VAL_NONE)
667 ||(nSlot == SID_ULINE_VAL_SINGLE)
668 ||(nSlot == SID_ULINE_VAL_DOUBLE)
669 ||(nSlot == SID_ULINE_VAL_DOTTED) )
671 pNewSet.emplace( GetPool() );
673 switch ( nSlot )
675 case SID_ATTR_CHAR_WEIGHT:
677 // #i78017 establish the same behaviour as in Writer
678 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
680 SfxItemPool& rPool = GetPool();
681 SvxScriptSetItem aSetItem( nSlot, rPool );
682 if ( pSet )
683 aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_WEIGHT ) );
684 else
686 // toggle manually
688 FontWeight eWeight = WEIGHT_BOLD;
689 SvxScriptSetItem aOldSetItem( nSlot, rPool );
690 aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false );
691 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
692 if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() == WEIGHT_BOLD )
693 eWeight = WEIGHT_NORMAL;
695 aSetItem.PutItemForScriptType( nScript, SvxWeightItem( eWeight, ATTR_FONT_WEIGHT ) );
697 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
698 pNewSet->Put( aSetItem.GetItemSet(), false );
700 break;
702 case SID_ATTR_CHAR_POSTURE:
704 // #i78017 establish the same behaviour as in Writer
705 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
707 SfxItemPool& rPool = GetPool();
708 SvxScriptSetItem aSetItem( nSlot, rPool );
709 if ( pSet )
710 aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_POSTURE ) );
711 else
713 // toggle manually
715 FontItalic eItalic = ITALIC_NORMAL;
716 SvxScriptSetItem aOldSetItem( nSlot, rPool );
717 aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false );
718 const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
719 if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetPosture() == ITALIC_NORMAL )
720 eItalic = ITALIC_NONE;
722 aSetItem.PutItemForScriptType( nScript, SvxPostureItem( eItalic, ATTR_FONT_POSTURE ) );
724 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
725 pNewSet->Put( aSetItem.GetItemSet(), false );
727 break;
729 case SID_ATTR_CHAR_UNDERLINE:
731 if( pSet )
733 const SfxPoolItem& rUnderline = pSet->Get( ATTR_FONT_UNDERLINE );
735 if( dynamic_cast<const SvxUnderlineItem*>( &rUnderline) != nullptr )
737 pTabViewShell->ApplyAttr( rUnderline );
738 pNewSet->Put( rUnderline );
740 else if ( auto pTextLineItem = dynamic_cast<const SvxTextLineItem*>( &rUnderline) )
742 // #i106580# also allow SvxTextLineItem (base class of SvxUnderlineItem)
743 SvxUnderlineItem aNewItem( pTextLineItem->GetLineStyle(), pTextLineItem->Which() );
744 aNewItem.SetColor( pTextLineItem->GetColor() );
745 pTabViewShell->ApplyAttr( aNewItem );
746 pNewSet->Put( aNewItem );
749 else
751 SvxUnderlineItem aUnderline( pAttrs->GetItem( ATTR_FONT_UNDERLINE ) );
752 FontLineStyle eUnderline = (LINESTYLE_NONE != aUnderline.GetLineStyle())
753 ? LINESTYLE_NONE
754 : LINESTYLE_SINGLE;
755 aUnderline.SetLineStyle( eUnderline );
756 pTabViewShell->ApplyAttr( aUnderline );
757 pNewSet->Put( aUnderline );
760 break;
762 case SID_ULINE_VAL_NONE:
763 pTabViewShell->ApplyAttr( SvxUnderlineItem( LINESTYLE_NONE, ATTR_FONT_UNDERLINE ) );
764 break;
765 case SID_ULINE_VAL_SINGLE: // Toggles
766 case SID_ULINE_VAL_DOUBLE:
767 case SID_ULINE_VAL_DOTTED:
769 FontLineStyle eOld = pAttrs->GetItem(ATTR_FONT_UNDERLINE).GetLineStyle();
770 FontLineStyle eNew = eOld;
771 switch (nSlot)
773 case SID_ULINE_VAL_SINGLE:
774 eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
775 break;
776 case SID_ULINE_VAL_DOUBLE:
777 eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
778 break;
779 case SID_ULINE_VAL_DOTTED:
780 eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
781 break;
783 pTabViewShell->ApplyAttr( SvxUnderlineItem( eNew, ATTR_FONT_UNDERLINE ) );
785 break;
787 default:
788 break;
790 rBindings.Invalidate( nSlot );
792 else
795 * "Self-made" functionality of radio buttons
796 * At the toggle the default state is used, this means
797 * no button was clicked.
800 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
801 const SvxHorJustifyItem* pHorJustify = rAttrSet.GetItemIfSet(ATTR_HOR_JUSTIFY);
802 const SvxVerJustifyItem* pVerJustify = rAttrSet.GetItemIfSet(ATTR_VER_JUSTIFY );
803 SvxCellHorJustify eHorJustify = SvxCellHorJustify::Standard;
804 SvxCellVerJustify eVerJustify = SvxCellVerJustify::Standard;
806 if (pHorJustify)
808 eHorJustify = pHorJustify->GetValue();
810 if (pVerJustify)
812 eVerJustify = pVerJustify->GetValue();
815 switch ( nSlot )
817 case SID_ALIGNLEFT:
818 rReq.SetSlot( SID_H_ALIGNCELL );
819 rReq.AppendItem( SvxHorJustifyItem(
820 !pHorJustify || (eHorJustify != SvxCellHorJustify::Left) ?
821 SvxCellHorJustify::Left : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
822 ExecuteSlot( rReq, GetInterface() );
823 return;
825 case SID_ALIGNRIGHT:
826 rReq.SetSlot( SID_H_ALIGNCELL );
827 rReq.AppendItem( SvxHorJustifyItem(
828 !pHorJustify || (eHorJustify != SvxCellHorJustify::Right) ?
829 SvxCellHorJustify::Right : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
830 ExecuteSlot( rReq, GetInterface() );
831 return;
833 case SID_ALIGNCENTERHOR:
834 rReq.SetSlot( SID_H_ALIGNCELL );
835 rReq.AppendItem( SvxHorJustifyItem(
836 !pHorJustify || (eHorJustify != SvxCellHorJustify::Center) ?
837 SvxCellHorJustify::Center : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
838 ExecuteSlot( rReq, GetInterface() );
839 return;
841 case SID_ALIGNBLOCK:
842 rReq.SetSlot( SID_H_ALIGNCELL );
843 rReq.AppendItem( SvxHorJustifyItem(
844 !pHorJustify || (eHorJustify != SvxCellHorJustify::Block) ?
845 SvxCellHorJustify::Block : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
846 ExecuteSlot( rReq, GetInterface() );
847 return;
849 case SID_ALIGNTOP:
850 rReq.SetSlot( SID_V_ALIGNCELL );
851 rReq.AppendItem( SvxVerJustifyItem(
852 !pVerJustify || (eVerJustify != SvxCellVerJustify::Top) ?
853 SvxCellVerJustify::Top : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
854 ExecuteSlot( rReq, GetInterface() );
855 return;
857 case SID_ALIGNBOTTOM:
858 rReq.SetSlot( SID_V_ALIGNCELL );
859 rReq.AppendItem( SvxVerJustifyItem(
860 !pVerJustify || (eVerJustify != SvxCellVerJustify::Bottom) ?
861 SvxCellVerJustify::Bottom : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
862 ExecuteSlot( rReq, GetInterface() );
863 return;
865 case SID_ALIGNCENTERVER:
866 rReq.SetSlot( SID_V_ALIGNCELL );
867 rReq.AppendItem( SvxVerJustifyItem(
868 !pVerJustify || (eVerJustify != SvxCellVerJustify::Center) ?
869 SvxCellVerJustify::Center : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
870 ExecuteSlot( rReq, GetInterface() );
871 return;
873 default:
874 break;
879 rBindings.Update();
881 if( pNewSet )
883 rReq.Done( *pNewSet );
884 pNewSet.reset();
886 else
888 rReq.Done();
893 void ScFormatShell::ExecuteAttr( SfxRequest& rReq )
895 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
896 SfxBindings& rBindings = rViewData.GetBindings();
897 const SfxItemSet* pNewAttrs = rReq.GetArgs();
898 sal_uInt16 nSlot = rReq.GetSlot();
900 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
901 ScDocument& rDoc = GetViewData().GetDocument();
902 if ( !pNewAttrs )
904 switch ( nSlot )
906 case SID_GROW_FONT_SIZE:
907 case SID_SHRINK_FONT_SIZE:
909 SfxItemPool& rPool = GetPool();
910 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool );
911 aSetItem.GetItemSet().Put( pTabViewShell->GetSelectionPattern()->GetItemSet(), false );
913 SvtScriptType nScriptTypes = pTabViewShell->GetSelectionScriptType();
914 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( nScriptTypes ) ) );
916 if ( pSize )
918 SvxFontHeightItem aSize( *pSize );
919 sal_uInt32 nSize = aSize.GetHeight();
921 const sal_uInt32 nFontInc = 40; // 2pt
922 const sal_uInt32 nFontMaxSz = 19998; // 999.9pt
923 if ( nSlot == SID_GROW_FONT_SIZE )
924 nSize = std::min< sal_uInt32 >( nSize + nFontInc, nFontMaxSz );
925 else
926 nSize = std::max< sal_Int32 >( nSize - nFontInc, nFontInc );
928 aSize.SetHeight( nSize );
929 aSetItem.PutItemForScriptType( nScriptTypes, aSize );
930 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
932 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
934 break;
936 case SID_ATTR_CHAR_ENDPREVIEW_FONT:
938 rDoc.SetPreviewFont(nullptr);
939 pTabViewShell->UpdateSelectionArea( rDoc.GetPreviewSelection() );
940 break;
942 case SID_ATTR_CHAR_COLOR:
943 case SID_ATTR_CHAR_FONT:
944 case SID_ATTR_CHAR_FONTHEIGHT:
945 pTabViewShell->ExecuteCellFormatDlg(rReq, u"font"_ustr); // when ToolBar is vertical
946 break;
948 case SID_BACKGROUND_COLOR:
950 SvxBrushItem aBrushItem(
951 pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) );
952 aBrushItem.SetColor( COL_TRANSPARENT );
953 pTabViewShell->ApplyAttr( aBrushItem, false );
955 break;
957 case SID_ATTR_ALIGN_LINEBREAK: // without parameter as toggle
959 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
960 bool bOld = pAttrs->GetItem(ATTR_LINEBREAK).GetValue();
961 ScLineBreakCell aBreakItem(!bOld);
962 pTabViewShell->ApplyAttr( aBreakItem );
964 SfxAllItemSet aNewSet( GetPool() );
965 aNewSet.Put( aBreakItem );
966 rReq.Done( aNewSet );
968 rBindings.Invalidate( nSlot );
970 break;
972 case SID_SCATTR_CELLPROTECTION: // without parameter as toggle
974 const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
975 bool bProtect = pAttrs->GetItem(ATTR_PROTECTION).GetProtection();
976 bool bHideFormula = pAttrs->GetItem(ATTR_PROTECTION).GetHideFormula();
977 bool bHideCell = pAttrs->GetItem(ATTR_PROTECTION).GetHideCell();
978 bool bHidePrint = pAttrs->GetItem(ATTR_PROTECTION).GetHidePrint();
980 ScProtectionAttr aProtectionItem( !bProtect, bHideFormula, bHideCell, bHidePrint );
981 pTabViewShell->ApplyAttr( aProtectionItem );
983 SfxAllItemSet aNewSet( GetPool() );
984 aNewSet.Put( aProtectionItem );
985 aNewSet.Put( SfxBoolItem( SID_SCATTR_CELLPROTECTION, !bProtect ) );
986 rReq.Done( aNewSet );
988 rBindings.Invalidate( nSlot );
990 break;
993 else
995 switch ( nSlot )
997 case SID_ATTR_CHAR_PREVIEW_FONT:
999 SfxItemPool& rPool = GetPool();
1000 sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
1001 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(pNewAttrs->Get( nWhich ));
1002 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, rPool );
1003 SvtScriptType nScript = pTabViewShell->GetSelectionScriptType();
1004 aSetItem.PutItemForScriptType( nScript, rFont );
1006 ScMarkData aFuncMark( rViewData.GetMarkData() );
1007 ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1008 rDoc.SetPreviewFont( aSetItem.GetItemSet().Clone() );
1009 aFuncMark.MarkToMulti();
1011 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1013 SCCOL nCol = rViewData.GetCurX();
1014 SCROW nRow = rViewData.GetCurY();
1015 SCTAB nTab = rViewData.GetTabNo();
1016 ScRange aRange( nCol, nRow, nTab );
1017 aFuncMark.SetMarkArea( aRange );
1019 rDoc.SetPreviewSelection( aFuncMark );
1020 pTabViewShell->UpdateSelectionArea( aFuncMark );
1021 break;
1023 case SID_ATTR_CHAR_OVERLINE:
1024 case SID_ATTR_CHAR_STRIKEOUT:
1025 case SID_ATTR_ALIGN_LINEBREAK:
1026 case SID_ATTR_CHAR_CONTOUR:
1027 case SID_ATTR_CHAR_SHADOWED:
1028 case SID_ATTR_CHAR_RELIEF:
1029 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhichIDFromSlotID( nSlot ) ) );
1030 rBindings.Invalidate( nSlot );
1031 rBindings.Update( nSlot );
1032 break;
1033 case SID_ATTR_CHAR_COLOR:
1034 case SID_SCATTR_PROTECTION :
1036 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhichIDFromSlotID( nSlot) ), false);
1038 rBindings.Invalidate( nSlot );
1039 rBindings.Update( nSlot );
1042 break;
1044 case SID_ATTR_CHAR_FONT:
1045 case SID_ATTR_CHAR_FONTHEIGHT:
1047 // #i78017 establish the same behaviour as in Writer
1048 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1049 if (nSlot == SID_ATTR_CHAR_FONT)
1050 nScript = pTabViewShell->GetSelectionScriptType();
1052 SfxItemPool& rPool = GetPool();
1053 SvxScriptSetItem aSetItem( nSlot, rPool );
1054 sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
1055 aSetItem.PutItemForScriptType( nScript, pNewAttrs->Get( nWhich ) );
1057 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
1059 rBindings.Invalidate( nSlot );
1060 rBindings.Update( nSlot );
1062 break;
1064 case SID_FRAME_LINESTYLE:
1066 // Update default line
1067 const ::editeng::SvxBorderLine* pLine =
1068 pNewAttrs->Get( SID_FRAME_LINESTYLE ).
1069 GetLine();
1071 if ( pLine )
1073 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
1075 if ( pDefLine )
1077 pDefLine->SetBorderLineStyle(
1078 pLine->GetBorderLineStyle());
1079 pDefLine->SetWidth( pLine->GetWidth( ) );
1080 pTabViewShell->SetSelectionFrameLines( pDefLine, false );
1082 else
1084 pTabViewShell->SetDefaultFrameLine( pLine );
1085 pTabViewShell->GetDefaultFrameLine()->SetColor( COL_BLACK );
1086 pTabViewShell->SetSelectionFrameLines( pLine, false );
1089 else
1091 Color aColorBlack( COL_BLACK );
1092 ::editeng::SvxBorderLine aDefLine( &aColorBlack, 20,
1093 SvxBorderLineStyle::SOLID );
1094 pTabViewShell->SetDefaultFrameLine( &aDefLine );
1095 pTabViewShell->SetSelectionFrameLines( nullptr, false );
1098 break;
1100 case SID_FRAME_LINECOLOR:
1102 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
1104 Color aColor = pNewAttrs->Get( SID_FRAME_LINECOLOR ).GetValue();
1106 // Update default line
1107 if ( pDefLine )
1109 pDefLine->SetColor( aColor );
1110 pTabViewShell->SetSelectionFrameLines( pDefLine, true );
1112 else
1114 ::editeng::SvxBorderLine aDefLine( &aColor, 20, SvxBorderLineStyle::SOLID );
1115 pTabViewShell->SetDefaultFrameLine( &aDefLine );
1116 pTabViewShell->SetSelectionFrameLines( &aDefLine, false );
1119 break;
1121 case SID_ATTR_BORDER_OUTER:
1122 case SID_ATTR_BORDER:
1124 ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
1125 const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern();
1126 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aOldSet( *rDoc.GetPool() );
1127 SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *rDoc.GetPool() );
1128 const SfxPoolItem& rBorderAttr =
1129 pOldAttrs->GetItemSet().
1130 Get( ATTR_BORDER );
1132 // Evaluate border items from controller:
1134 if ( const SvxBoxItem* pBoxItem = pNewAttrs->GetItemIfSet( ATTR_BORDER ) )
1136 // The SvxFrameToolBoxControl toolbox controller uses a default
1137 // SvxBorderLine (all widths 0) to mark the lines that should be set.
1138 // Macro recording uses a SvxBoxItem with the real values (OutWidth > 0)
1139 // or NULL pointers for no lines.
1140 // -> Substitute existing lines with pDefLine only if widths are 0.
1141 SvxBoxItem aBoxItem ( *pBoxItem );
1142 if ( aBoxItem.GetTop() && aBoxItem.GetTop()->GetOutWidth() == 0 )
1143 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::TOP );
1144 if ( aBoxItem.GetBottom() && aBoxItem.GetBottom()->GetOutWidth() == 0 )
1145 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::BOTTOM );
1146 if ( aBoxItem.GetLeft() && aBoxItem.GetLeft()->GetOutWidth() == 0 )
1147 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::LEFT );
1148 if ( aBoxItem.GetRight() && aBoxItem.GetRight()->GetOutWidth() == 0 )
1149 aBoxItem.SetLine( pDefLine, SvxBoxItemLine::RIGHT );
1150 aNewSet.Put( aBoxItem );
1151 rReq.AppendItem( aBoxItem );
1154 if ( const SvxBoxInfoItem* pBoxInfoItem = pNewAttrs->GetItemIfSet( ATTR_BORDER_INNER ) )
1156 SvxBoxInfoItem aBoxInfoItem( *pBoxInfoItem );
1157 if ( aBoxInfoItem.GetHori() && aBoxInfoItem.GetHori()->GetOutWidth() == 0 )
1158 aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::HORI );
1159 if ( aBoxInfoItem.GetVert() && aBoxInfoItem.GetVert()->GetOutWidth() == 0 )
1160 aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::VERT );
1161 aNewSet.Put( aBoxInfoItem );
1162 rReq.AppendItem( aBoxInfoItem );
1164 else
1166 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
1167 aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
1168 aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
1169 aNewSet.Put( aBoxInfoItem );
1172 aOldSet.Put( rBorderAttr );
1173 pTabViewShell->ApplyAttributes( aNewSet, aOldSet );
1175 break;
1177 case SID_ATTR_BORDER_DIAG_TLBR:
1178 case SID_ATTR_BORDER_DIAG_BLTR:
1180 const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern();
1181 SfxItemSet aOldSet(pOldAttrs->GetItemSet());
1182 SfxItemSet aNewSet(aOldSet);
1184 if(SID_ATTR_BORDER_DIAG_TLBR == nSlot)
1186 if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_TLBR))
1188 SvxLineItem aItem(ATTR_BORDER_TLBR);
1189 aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_TLBR).GetLine());
1190 aNewSet.Put(aItem);
1191 rReq.AppendItem(aItem);
1192 pTabViewShell->ApplyAttributes(aNewSet, aOldSet);
1195 else // if( nSlot == SID_ATTR_BORDER_DIAG_BLTR )
1197 if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_BLTR ))
1199 SvxLineItem aItem(ATTR_BORDER_BLTR);
1200 aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_BLTR).GetLine());
1201 aNewSet.Put(aItem);
1202 rReq.AppendItem(aItem);
1203 pTabViewShell->ApplyAttributes(aNewSet, aOldSet);
1207 rBindings.Invalidate(nSlot);
1209 break;
1211 // ATTR_BACKGROUND (=SID_ATTR_BRUSH) has to be set to two IDs:
1212 case SID_BACKGROUND_COLOR:
1214 const SvxColorItem& rNewColorItem = pNewAttrs->Get( SID_BACKGROUND_COLOR );
1215 Color aColor = rNewColorItem.GetValue();
1217 SvxBrushItem aBrushItem(
1218 pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) );
1219 aBrushItem.SetColor(aColor);
1220 aBrushItem.setComplexColor(rNewColorItem.getComplexColor());
1222 pTabViewShell->ApplyAttr( aBrushItem, false );
1224 break;
1226 case SID_ATTR_BRUSH:
1228 SvxBrushItem aBrushItem( pTabViewShell->GetSelectionPattern()->
1229 GetItem( ATTR_BACKGROUND ) );
1230 const SvxBrushItem& rNewBrushItem = static_cast<const SvxBrushItem&>(
1231 pNewAttrs->Get( GetPool().GetWhichIDFromSlotID(nSlot) ) );
1232 aBrushItem.SetColor(rNewBrushItem.GetColor());
1233 aBrushItem.setComplexColor(rNewBrushItem.getComplexColor());
1234 pTabViewShell->ApplyAttr( aBrushItem );
1236 break;
1238 case SID_ATTR_BORDER_SHADOW:
1240 const SvxShadowItem& rNewShadowItem =
1241 pNewAttrs->Get( ATTR_SHADOW );
1242 pTabViewShell->ApplyAttr( rNewShadowItem );
1244 break;
1246 default:
1247 break;
1250 if( ! rReq.IsAPI() && ! rReq.IsDone() )
1251 rReq.Done();
1255 void ScFormatShell::GetAttrState( SfxItemSet& rSet )
1257 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1258 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1259 const SvxBrushItem& rBrushItem = rAttrSet.Get( ATTR_BACKGROUND );
1260 SfxWhichIter aIter( rSet );
1261 sal_uInt16 nWhich = aIter.FirstWhich();
1263 rSet.Put( rAttrSet, false );
1265 // choose font info according to selection script type
1266 SvtScriptType nScript = SvtScriptType::NONE; // GetSelectionScriptType never returns 0
1267 if ( rSet.GetItemState( ATTR_FONT ) != SfxItemState::UNKNOWN )
1269 nScript = pTabViewShell->GetSelectionScriptType();
1270 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT, nScript );
1272 if ( rSet.GetItemState( ATTR_FONT_HEIGHT ) != SfxItemState::UNKNOWN )
1274 if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType();
1275 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_HEIGHT, nScript );
1278 while ( nWhich )
1280 switch(nWhich)
1282 case SID_BACKGROUND_COLOR:
1284 rSet.Put( SvxColorItem( rBrushItem.GetColor(), SID_BACKGROUND_COLOR ) );
1285 if(SfxItemState::INVALID == rAttrSet.GetItemState(ATTR_BACKGROUND))
1287 rSet.InvalidateItem(SID_BACKGROUND_COLOR);
1290 break;
1291 case SID_FRAME_LINESTYLE:
1292 case SID_FRAME_LINECOLOR:
1294 // handled together because both need the cell border information for decisions
1295 Color aCol;
1296 editeng::SvxBorderLine aLine(nullptr,0,SvxBorderLineStyle::SOLID);
1297 bool bCol = false;
1298 bool bColDisable = false, bStyleDisable = false;
1299 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER));
1300 std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
1302 pTabViewShell->GetSelectionFrame(aBoxItem, aInfoItem);
1304 if( aBoxItem->GetTop() )
1306 bCol = true;
1307 aCol = aBoxItem->GetTop()->GetColor() ;
1308 aLine.SetColor(aCol);
1309 aLine.SetWidth( aBoxItem->GetTop()->GetWidth());
1310 aLine.SetBorderLineStyle( aBoxItem->GetTop()->GetBorderLineStyle());
1313 if( aBoxItem->GetBottom() )
1315 if(!bCol)
1317 bCol = true;
1318 aCol = aBoxItem->GetBottom()->GetColor() ;
1319 aLine.SetColor(aCol);
1320 aLine.SetWidth( aBoxItem->GetBottom()->GetWidth());
1321 aLine.SetBorderLineStyle( aBoxItem->GetBottom()->GetBorderLineStyle());
1323 else
1325 if(aCol != aBoxItem->GetBottom()->GetColor() )
1326 bColDisable = true;
1327 if( aLine != *aBoxItem->GetBottom() )
1328 bStyleDisable = true;
1332 if( aBoxItem->GetLeft() )
1334 if(!bCol)
1336 bCol = true;
1337 aCol = aBoxItem->GetLeft()->GetColor() ;
1338 aLine.SetColor(aCol);
1339 aLine.SetWidth( aBoxItem->GetLeft()->GetWidth());
1340 aLine.SetBorderLineStyle( aBoxItem->GetLeft()->GetBorderLineStyle());
1342 else
1344 if(aCol != aBoxItem->GetLeft()->GetColor() )
1345 bColDisable = true;
1346 if( aLine != *aBoxItem->GetLeft() )
1347 bStyleDisable = true;
1351 if( aBoxItem->GetRight() )
1353 if(!bCol)
1355 bCol = true;
1356 aCol = aBoxItem->GetRight()->GetColor() ;
1357 aLine.SetColor(aCol);
1358 aLine.SetWidth( aBoxItem->GetRight()->GetWidth());
1359 aLine.SetBorderLineStyle( aBoxItem->GetRight()->GetBorderLineStyle());
1361 else
1363 if(aCol != aBoxItem->GetRight()->GetColor() )
1364 bColDisable = true;
1365 if( aLine != *aBoxItem->GetRight() )
1366 bStyleDisable = true;
1370 if( aInfoItem->GetVert())
1372 if(!bCol)
1374 bCol = true;
1375 aCol = aInfoItem->GetVert()->GetColor() ;
1376 aLine.SetColor(aCol);
1377 aLine.SetWidth( aInfoItem->GetVert()->GetWidth());
1378 aLine.SetBorderLineStyle( aInfoItem->GetVert()->GetBorderLineStyle());
1380 else
1382 if(aCol != aInfoItem->GetVert()->GetColor() )
1383 bColDisable = true;
1384 if( aLine != *aInfoItem->GetVert() )
1385 bStyleDisable = true;
1389 if( aInfoItem->GetHori())
1391 if(!bCol)
1393 bCol = true;
1394 aCol = aInfoItem->GetHori()->GetColor() ;
1395 aLine.SetColor(aCol);
1396 aLine.SetWidth( aInfoItem->GetHori()->GetWidth());
1397 aLine.SetBorderLineStyle( aInfoItem->GetHori()->GetBorderLineStyle());
1399 else
1401 if(aCol != aInfoItem->GetHori()->GetColor() )
1402 bColDisable = true;
1403 if( aLine != *aInfoItem->GetHori() )
1404 bStyleDisable = true;
1408 if( !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT )
1409 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI )
1410 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT )
1411 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT )
1412 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP )
1413 || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) )
1415 bColDisable = true;
1416 bStyleDisable = true;
1419 if(SID_FRAME_LINECOLOR == nWhich)
1421 if(bColDisable) // if different lines have different colors
1423 aCol = COL_TRANSPARENT;
1424 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1425 rSet.InvalidateItem(SID_FRAME_LINECOLOR);
1427 else if (!bCol) // if no line available
1429 aCol = COL_AUTO;
1430 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1432 else
1433 rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1435 else // if( nWhich == SID_FRAME_LINESTYLE)
1437 if(bStyleDisable) // if have several lines but don't have same style
1439 aLine.SetWidth( 1 );
1440 SvxLineItem aItem(SID_FRAME_LINESTYLE);
1441 aItem.SetLine(&aLine);
1442 rSet.Put( aItem );
1443 rSet.InvalidateItem(SID_FRAME_LINESTYLE);
1445 else // all the lines have same style or no line available, use initial value (0,0,0,0)
1447 SvxLineItem aItem(SID_FRAME_LINESTYLE);
1448 aItem.SetLine(&aLine);
1449 rSet.Put( aItem );
1453 break;
1454 case SID_ATTR_BRUSH:
1456 rSet.Put( rBrushItem.CloneSetWhich(GetPool().GetWhichIDFromSlotID(nWhich)) );
1458 break;
1459 case SID_SCATTR_CELLPROTECTION:
1461 bool bProtect = rAttrSet.Get( ATTR_PROTECTION ).GetProtection();
1462 rSet.Put( SfxBoolItem(SID_SCATTR_CELLPROTECTION, bProtect) );
1464 break;
1466 nWhich = aIter.NextWhich();
1469 // stuff for sidebar panels
1470 Invalidate(SID_ATTR_ALIGN_DEGREES);
1471 Invalidate(SID_ATTR_ALIGN_LOCKPOS);
1472 Invalidate(SID_ATTR_ALIGN_STACKED);
1475 void ScFormatShell::GetTextAttrState( SfxItemSet& rSet )
1477 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1478 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1479 rSet.Put( rAttrSet, false ); // Include ItemStates in copy
1481 // choose font info according to selection script type
1482 SvtScriptType nScript = SvtScriptType::NONE; // GetSelectionScriptType never returns 0
1483 if ( rSet.GetItemState( ATTR_FONT_WEIGHT ) != SfxItemState::UNKNOWN )
1485 nScript = pTabViewShell->GetSelectionScriptType();
1486 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_WEIGHT, nScript );
1488 if ( rSet.GetItemState( ATTR_FONT_POSTURE ) != SfxItemState::UNKNOWN )
1490 if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType();
1491 ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_POSTURE, nScript );
1494 SfxItemState eState;
1496 // own control on radio button functionality:
1498 // underline
1500 eState = rAttrSet.GetItemState( ATTR_FONT_UNDERLINE );
1501 if ( eState == SfxItemState::INVALID )
1503 rSet.InvalidateItem( SID_ULINE_VAL_NONE );
1504 rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
1505 rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
1506 rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
1508 else
1510 FontLineStyle eUnderline =
1511 rAttrSet.Get(ATTR_FONT_UNDERLINE).GetLineStyle();
1512 rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE, eUnderline == LINESTYLE_SINGLE));
1513 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE, eUnderline == LINESTYLE_DOUBLE));
1514 rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED, eUnderline == LINESTYLE_DOTTED));
1515 rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE, eUnderline == LINESTYLE_NONE));
1518 // horizontal alignment
1520 const SvxHorJustifyItem* pHorJustify = nullptr;
1521 const SvxVerJustifyItem* pVerJustify = nullptr;
1522 SvxCellVerJustify eVerJustify = SvxCellVerJustify::Standard;
1523 sal_uInt16 nWhich = 0;
1524 bool bJustifyStd = false;
1525 SfxBoolItem aBoolItem ( 0, true );
1527 eState = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY, true,
1528 reinterpret_cast<const SfxPoolItem**>(&pHorJustify) );
1529 switch ( eState )
1531 case SfxItemState::SET:
1533 switch ( pHorJustify->GetValue() )
1535 case SvxCellHorJustify::Standard:
1536 break;
1538 case SvxCellHorJustify::Left:
1539 nWhich = SID_ALIGNLEFT;
1540 break;
1542 case SvxCellHorJustify::Right:
1543 nWhich = SID_ALIGNRIGHT;
1544 break;
1546 case SvxCellHorJustify::Center:
1547 nWhich = SID_ALIGNCENTERHOR;
1548 break;
1550 case SvxCellHorJustify::Block:
1551 nWhich = SID_ALIGNBLOCK;
1552 break;
1554 case SvxCellHorJustify::Repeat:
1555 default:
1556 bJustifyStd = true;
1557 break;
1560 break;
1562 case SfxItemState::INVALID:
1563 rSet.InvalidateItem( SID_ALIGNLEFT );
1564 rSet.InvalidateItem( SID_ALIGNRIGHT );
1565 rSet.InvalidateItem( SID_ALIGNCENTERHOR );
1566 rSet.InvalidateItem( SID_ALIGNBLOCK );
1567 break;
1569 default:
1570 bJustifyStd = true;
1571 break;
1574 if ( nWhich )
1576 aBoolItem.SetWhich( nWhich );
1577 rSet.Put( aBoolItem );
1579 else if ( bJustifyStd )
1581 aBoolItem.SetValue( false );
1582 aBoolItem.SetWhich( SID_ALIGNLEFT ); rSet.Put( aBoolItem );
1583 aBoolItem.SetWhich( SID_ALIGNRIGHT ); rSet.Put( aBoolItem );
1584 aBoolItem.SetWhich( SID_ALIGNCENTERHOR ); rSet.Put( aBoolItem );
1585 aBoolItem.SetWhich( SID_ALIGNBLOCK ); rSet.Put( aBoolItem );
1586 bJustifyStd = false;
1589 // vertical alignment
1591 nWhich = 0;
1592 aBoolItem.SetValue( true );
1594 eState = rAttrSet.GetItemState( ATTR_VER_JUSTIFY, true,
1595 reinterpret_cast<const SfxPoolItem**>(&pVerJustify) );
1597 switch ( eState )
1599 case SfxItemState::SET:
1601 eVerJustify = pVerJustify->GetValue();
1603 switch ( eVerJustify )
1605 case SvxCellVerJustify::Top:
1606 nWhich = SID_ALIGNTOP;
1607 break;
1609 case SvxCellVerJustify::Bottom:
1610 nWhich = SID_ALIGNBOTTOM;
1611 break;
1613 case SvxCellVerJustify::Center:
1614 nWhich = SID_ALIGNCENTERVER;
1615 break;
1617 case SvxCellVerJustify::Standard:
1618 default:
1619 bJustifyStd = true;
1620 break;
1623 break;
1625 case SfxItemState::INVALID:
1626 rSet.InvalidateItem( SID_ALIGNTOP );
1627 rSet.InvalidateItem( SID_ALIGNBOTTOM );
1628 rSet.InvalidateItem( SID_ALIGNCENTERVER );
1629 break;
1631 default:
1632 bJustifyStd = true;
1633 break;
1636 if ( nWhich )
1638 aBoolItem.SetWhich( nWhich );
1639 rSet.Put( aBoolItem );
1641 else if ( bJustifyStd )
1643 aBoolItem.SetValue( false );
1644 aBoolItem.SetWhich( SID_ALIGNTOP ); rSet.Put( aBoolItem );
1645 aBoolItem.SetWhich( SID_ALIGNBOTTOM ); rSet.Put( aBoolItem );
1646 aBoolItem.SetWhich( SID_ALIGNCENTERVER ); rSet.Put( aBoolItem );
1650 void ScFormatShell::GetBorderState( SfxItemSet& rSet )
1652 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1653 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER));
1654 std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
1656 pTabViewShell->GetSelectionFrame( aBoxItem, aInfoItem );
1658 if ( rSet.GetItemState( ATTR_BORDER ) != SfxItemState::UNKNOWN )
1659 rSet.Put( *aBoxItem );
1660 if ( rSet.GetItemState( ATTR_BORDER_INNER ) != SfxItemState::UNKNOWN )
1661 rSet.Put( *aInfoItem );
1664 void ScFormatShell::GetAlignState( SfxItemSet& rSet )
1666 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1667 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1668 SfxWhichIter aIter(rSet);
1669 sal_uInt16 nWhich = aIter.FirstWhich();
1671 SvxCellHorJustify eHAlign = SvxCellHorJustify::Standard;
1672 bool bHasHAlign = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY ) != SfxItemState::INVALID;
1673 if( bHasHAlign )
1674 eHAlign = rAttrSet.Get( ATTR_HOR_JUSTIFY ).GetValue();
1676 SvxCellVerJustify eVAlign = SvxCellVerJustify::Standard;
1677 bool bHasVAlign = rAttrSet.GetItemState( ATTR_VER_JUSTIFY ) != SfxItemState::INVALID;
1678 if( bHasVAlign )
1679 eVAlign = rAttrSet.Get( ATTR_VER_JUSTIFY ).GetValue();
1681 while ( nWhich )
1683 switch ( nWhich )
1685 case SID_H_ALIGNCELL:
1686 if ( bHasHAlign )
1687 rSet.Put( SvxHorJustifyItem( eHAlign, nWhich ));
1688 break;
1689 case SID_V_ALIGNCELL:
1690 if ( bHasVAlign )
1691 rSet.Put( SvxVerJustifyItem( eVAlign, nWhich ));
1692 break;
1694 // pseudo slots for Format menu
1695 case SID_ALIGN_ANY_HDEFAULT:
1696 case SID_ALIGN_ANY_LEFT:
1697 case SID_ALIGN_ANY_HCENTER:
1698 case SID_ALIGN_ANY_RIGHT:
1699 case SID_ALIGN_ANY_JUSTIFIED:
1700 rSet.Put( SfxBoolItem( nWhich, bHasHAlign && (eHAlign == lclConvertSlotToHAlign( nWhich )) ) );
1701 break;
1702 case SID_ALIGN_ANY_VDEFAULT:
1703 case SID_ALIGN_ANY_TOP:
1704 case SID_ALIGN_ANY_VCENTER:
1705 case SID_ALIGN_ANY_BOTTOM:
1706 rSet.Put( SfxBoolItem( nWhich, bHasVAlign && (eVAlign == lclConvertSlotToVAlign( nWhich )) ) );
1707 break;
1709 nWhich = aIter.NextWhich();
1713 void ScFormatShell::GetNumFormatState( SfxItemSet& rSet )
1715 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1716 ScDocument& rDoc = rViewData.GetDocument();
1717 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1718 const SfxItemState eItemState = rAttrSet.GetItemState( ATTR_VALUE_FORMAT );
1719 sal_uInt32 nNumberFormat = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue();
1720 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
1721 // If item state is default or set it
1722 // indicates one number format so we
1723 // don't have to iterate over all
1724 // selected cells' attribute ranges to
1725 // determine selected types.
1726 // Does *NOT* include the
1727 // SvNumFormatType::DEFINED bit.
1728 const SvNumFormatType nType = (eItemState >= SfxItemState::DEFAULT ? pFormatter->GetType( nNumberFormat) :
1729 GetCurrentNumberFormatType());
1730 NfIndexTableOffset nOffset = SvNumberFormatter::GetIndexTableOffset(nNumberFormat);
1732 SfxWhichIter aIter(rSet);
1733 sal_uInt16 nWhich = aIter.FirstWhich();
1735 while ( nWhich )
1737 switch ( nWhich )
1739 case SID_NUMBER_THOUSANDS:
1741 bool bEnable = (SfxItemState::INVALID != eItemState);
1742 if (bEnable)
1744 bEnable = ((nType != SvNumFormatType::ALL) && (nType &
1745 (SvNumFormatType::NUMBER |
1746 SvNumFormatType::PERCENT |
1747 SvNumFormatType::CURRENCY |
1748 SvNumFormatType::FRACTION)));
1749 if (bEnable)
1751 bool bThousand( false );
1752 bool bNegRed( false );
1753 sal_uInt16 nPrecision( 0 );
1754 sal_uInt16 nLeadZeroes( 0 );
1755 pFormatter->GetFormatSpecialInfo( nNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes);
1756 rSet.Put( SfxBoolItem( nWhich, bThousand));
1759 if (!bEnable)
1761 rSet.DisableItem( nWhich );
1764 break;
1765 case SID_NUMBER_FORMAT:
1766 // symphony version with format interpretation
1768 if(SfxItemState::INVALID != eItemState)
1770 bool bThousand(false);
1771 bool bNegRed(false);
1772 sal_uInt16 nPrecision(0);
1773 sal_uInt16 nLeadZeroes(0);
1775 pFormatter->GetFormatSpecialInfo(nNumberFormat,bThousand, bNegRed, nPrecision, nLeadZeroes);
1777 const SvNumberformat* pFormatEntry = pFormatter->GetEntry( nNumberFormat );
1778 if (pFormatEntry && (pFormatEntry->GetType() & SvNumFormatType::SCIENTIFIC))
1780 // if scientific, bThousand is used for engineering notation
1781 const sal_uInt16 nIntegerDigits = pFormatEntry->GetFormatIntegerDigits();
1782 bThousand = nIntegerDigits > 0 && ((nIntegerDigits % 3) == 0);
1784 OUString aFormat;
1785 static constexpr OUString sBreak = u","_ustr;
1786 const OUString sThousand = OUString::number(static_cast<sal_Int32>(bThousand));
1787 const OUString sNegRed = OUString::number(static_cast<sal_Int32>(bNegRed));
1788 const OUString sPrecision = OUString::number(nPrecision);
1789 const OUString sLeadZeroes = OUString::number(nLeadZeroes);
1790 const OUString sNatNum12 = OUString::number( static_cast< sal_Int32 >( pFormatter->IsNatNum12( nNumberFormat ) ) );
1792 aFormat += sThousand +
1793 sBreak +
1794 sNegRed +
1795 sBreak +
1796 sPrecision +
1797 sBreak +
1798 sLeadZeroes +
1799 sBreak +
1800 sNatNum12 +
1801 sBreak;
1803 rSet.Put(SfxStringItem(nWhich, aFormat));
1805 if (comphelper::LibreOfficeKit::isActive())
1807 OUString sPayload = ".uno:NumberFormat=" + aFormat;
1808 GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1809 OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
1812 else
1814 rSet.InvalidateItem( nWhich );
1817 break;
1819 case SID_NUMBER_TYPE_FORMAT:
1821 sal_Int16 nFormatCategory = -1;
1822 if ( eItemState >= SfxItemState::DEFAULT ) //Modify for more robust
1824 switch(nType)
1826 case SvNumFormatType::NUMBER:
1827 // Determine if General format.
1828 if ((nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
1829 nFormatCategory = 0;
1830 else
1831 nFormatCategory = 1;
1832 break;
1833 case SvNumFormatType::PERCENT:
1834 nFormatCategory = 2;
1835 break;
1836 case SvNumFormatType::CURRENCY:
1837 nFormatCategory = 3;
1838 break;
1839 case SvNumFormatType::DATE:
1840 //Add
1841 case SvNumFormatType::DATETIME:
1842 nFormatCategory = 4;
1843 break;
1844 case SvNumFormatType::TIME:
1845 nFormatCategory = 5;
1846 break;
1847 case SvNumFormatType::SCIENTIFIC:
1848 nFormatCategory = 6;
1849 break;
1850 case SvNumFormatType::FRACTION:
1851 nFormatCategory = 7;
1852 break;
1853 case SvNumFormatType::LOGICAL:
1854 nFormatCategory = 8;
1855 break;
1856 case SvNumFormatType::TEXT:
1857 nFormatCategory = 9;
1858 break;
1859 default:
1860 nFormatCategory = -1; //for more robust
1862 if( nFormatCategory == -1 )
1863 rSet.InvalidateItem( nWhich );
1864 else
1865 rSet.Put( SfxUInt16Item( nWhich, nFormatCategory ) );
1867 else
1869 rSet.InvalidateItem( nWhich );
1873 break;
1874 case SID_NUMBER_CURRENCY:
1875 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::CURRENCY)) );
1876 break;
1877 case SID_NUMBER_SCIENTIFIC:
1878 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::SCIENTIFIC)) );
1879 break;
1880 case SID_NUMBER_DATE:
1881 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::DATE)) );
1882 break;
1883 case SID_NUMBER_PERCENT:
1884 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::PERCENT)) );
1885 break;
1886 case SID_NUMBER_TIME:
1887 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::TIME)) );
1888 break;
1889 case SID_NUMBER_TWODEC:
1890 rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && nOffset == NF_NUMBER_1000DEC2 ) );
1891 break;
1892 case SID_NUMBER_STANDARD:
1893 rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && (nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) );
1894 break;
1896 nWhich = aIter.NextWhich();
1900 void ScFormatShell::ExecuteTextDirection( const SfxRequest& rReq )
1902 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1903 pTabViewShell->HideListBox(); // Autofilter-DropDown-Listbox
1904 bool bEditMode = false;
1905 if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) )
1907 bEditMode=true;
1908 ScModule::get()->InputEnterHandler();
1909 pTabViewShell->UpdateInputHandler();
1911 sal_uInt16 nSlot = rReq.GetSlot();
1912 switch( nSlot )
1914 case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
1915 case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
1917 bool bVert = (nSlot == SID_TEXTDIRECTION_TOP_TO_BOTTOM);
1918 ScPatternAttr aAttr(GetViewData().GetDocument().getCellAttributeHelper());
1919 SfxItemSet& rItemSet = aAttr.GetItemSet();
1920 rItemSet.Put( ScVerticalStackCell( bVert ) );
1921 rItemSet.Put( SfxBoolItem( ATTR_VERTICAL_ASIAN, bVert ) );
1922 pTabViewShell->ApplySelectionPattern( aAttr );
1923 pTabViewShell->AdjustBlockHeight();
1925 break;
1927 case SID_ATTR_PARA_LEFT_TO_RIGHT:
1928 case SID_ATTR_PARA_RIGHT_TO_LEFT:
1930 SvxFrameDirection eDirection = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT ) ?
1931 SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB;
1932 pTabViewShell->ApplyAttr( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) );
1934 break;
1936 if (bEditMode)
1937 ScModule::get()->SetInputMode(SC_INPUT_TABLE);
1940 void ScFormatShell::GetTextDirectionState( SfxItemSet& rSet )
1942 ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1943 const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1945 bool bVertDontCare =
1946 (rAttrSet.GetItemState( ATTR_VERTICAL_ASIAN ) == SfxItemState::INVALID) ||
1947 (rAttrSet.GetItemState( ATTR_STACKED ) == SfxItemState::INVALID);
1948 bool bLeftRight = !bVertDontCare &&
1949 !rAttrSet.Get( ATTR_STACKED ).GetValue();
1950 bool bTopBottom = !bVertDontCare && !bLeftRight &&
1951 rAttrSet.Get( ATTR_VERTICAL_ASIAN ).GetValue();
1953 bool bBidiDontCare = (rAttrSet.GetItemState( ATTR_WRITINGDIR ) == SfxItemState::INVALID);
1954 EEHorizontalTextDirection eBidiDir = EEHorizontalTextDirection::Default;
1955 if ( !bBidiDontCare )
1957 SvxFrameDirection eCellDir = rAttrSet.Get( ATTR_WRITINGDIR ).GetValue();
1958 if ( eCellDir == SvxFrameDirection::Environment )
1959 eBidiDir = GetViewData().GetDocument().
1960 GetEditTextDirection( GetViewData().GetTabNo() );
1961 else if ( eCellDir == SvxFrameDirection::Horizontal_RL_TB )
1962 eBidiDir = EEHorizontalTextDirection::R2L;
1963 else
1964 eBidiDir = EEHorizontalTextDirection::L2R;
1967 bool bDisableCTLFont = !SvtCTLOptions::IsCTLFontEnabled();
1968 bool bDisableVerticalText = !SvtCJKOptions::IsVerticalTextEnabled();
1970 SfxWhichIter aIter( rSet );
1971 sal_uInt16 nWhich = aIter.FirstWhich();
1972 while( nWhich )
1974 switch( nWhich )
1976 case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
1977 case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
1978 if ( bDisableVerticalText )
1979 rSet.DisableItem( nWhich );
1980 else
1982 if( bVertDontCare )
1983 rSet.InvalidateItem( nWhich );
1984 else if ( nWhich == SID_TEXTDIRECTION_LEFT_TO_RIGHT )
1985 rSet.Put( SfxBoolItem( nWhich, bLeftRight ) );
1986 else
1987 rSet.Put( SfxBoolItem( nWhich, bTopBottom ) );
1989 break;
1991 case SID_ATTR_PARA_LEFT_TO_RIGHT:
1992 case SID_ATTR_PARA_RIGHT_TO_LEFT:
1993 if ( bDisableCTLFont )
1994 rSet.DisableItem( nWhich );
1995 else
1997 if ( bTopBottom )
1998 rSet.DisableItem( nWhich );
1999 else if ( bBidiDontCare )
2000 rSet.InvalidateItem( nWhich );
2001 else if ( nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT )
2002 rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::L2R ) );
2003 else
2004 rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::R2L ) );
2007 nWhich = aIter.NextWhich();
2011 void ScFormatShell::ExecFormatPaintbrush( const SfxRequest& rReq )
2013 ScViewFunc* pView = rViewData.GetView();
2014 if ( pView->HasPaintBrush() )
2016 // cancel paintbrush mode
2017 pView->ResetBrushDocument();
2019 else
2021 bool bLock = false;
2022 const SfxItemSet *pArgs = rReq.GetArgs();
2023 if( pArgs && pArgs->Count() >= 1 )
2024 bLock = pArgs->Get(SID_FORMATPAINTBRUSH).GetValue();
2026 // in case of multi selection, deselect all and use the cursor position
2027 ScRange aDummy;
2028 if ( rViewData.GetSimpleArea(aDummy) != SC_MARK_SIMPLE )
2029 pView->Unmark();
2031 ScDocumentUniquePtr pBrushDoc(new ScDocument( SCDOCMODE_CLIP ));
2032 pView->CopyToClip( pBrushDoc.get(), false, true );
2033 pView->SetBrushDocument( std::move(pBrushDoc), bLock );
2037 void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet )
2039 if ( rViewData.HasEditView( rViewData.GetActivePart() ) )
2040 rSet.DisableItem( SID_FORMATPAINTBRUSH );
2041 else
2042 rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, rViewData.GetView()->HasPaintBrush() ) );
2045 SvNumFormatType ScFormatShell::GetCurrentNumberFormatType()
2047 SvNumFormatType nType = SvNumFormatType::ALL;
2048 ScDocument& rDoc = GetViewData().GetDocument();
2049 ScMarkData aMark(GetViewData().GetMarkData());
2050 const SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2051 if (!pFormatter)
2052 return nType;
2054 // TODO: Find out how to get a selected table range in case multiple tables
2055 // are selected. Currently we only check for the current active table.
2057 if ( aMark.IsMarked() || aMark.IsMultiMarked() )
2059 aMark.MarkToMulti();
2060 const ScRange& aRange = aMark.GetMultiMarkArea();
2061 const ScMultiSel& rMultiSel = aMark.GetMultiSelData();
2063 SvNumFormatType nComboType = SvNumFormatType::ALL;
2064 bool bFirstItem = true;
2065 for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
2067 if (!rMultiSel.HasMarks(nCol))
2068 continue;
2070 SCROW nRow1, nRow2;
2071 ScMultiSelIter aMultiIter(rMultiSel, nCol);
2072 while (aMultiIter.Next(nRow1, nRow2))
2074 ScRange aColRange(nCol, nRow1, aRange.aStart.Tab());
2075 aColRange.aEnd.SetRow(nRow2);
2076 sal_uInt32 nNumFmt = rDoc.GetNumberFormat(aColRange);
2077 SvNumFormatType nThisType = pFormatter->GetType(nNumFmt);
2078 if (bFirstItem)
2080 bFirstItem = false;
2081 nComboType = nThisType;
2083 else if (nComboType != nThisType)
2084 // mixed number format type.
2085 return SvNumFormatType::ALL;
2088 nType = nComboType;
2090 else
2092 sal_uInt32 nNumFmt = rDoc.GetNumberFormat( rViewData.GetCurX(), rViewData.GetCurY(),
2093 rViewData.GetTabNo());
2094 nType = pFormatter->GetType( nNumFmt );
2096 return nType;
2099 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */