xref: /core/sc/source/ui/view/formatsh.cxx (revision 598c7deeb470a70e664a4c24c79563e831b28517)
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 
22 #include <scitems.hxx>
23 #include <editeng/borderline.hxx>
24 
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>
30 
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/scriptsetitem.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>
55 
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>
66 
67 #define ShellClass_ScFormatShell
68 #define ShellClass_TableFont
69 #define ShellClass_FormatForSelection
70 #include <scslots.hxx>
71 
72 #include <editeng/fontitem.hxx>
73 #include <sfx2/classificationhelper.hxx>
74 
75 #include <memory>
76 
77 namespace {
78 
lclConvertSlotToHAlign(sal_uInt16 nSlot)79 SvxCellHorJustify lclConvertSlotToHAlign( sal_uInt16 nSlot )
80 {
81     SvxCellHorJustify eHJustify = SvxCellHorJustify::Standard;
82     switch( nSlot )
83     {
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" );
90     }
91     return eHJustify;
92 }
93 
lclConvertSlotToVAlign(sal_uInt16 nSlot)94 SvxCellVerJustify lclConvertSlotToVAlign( sal_uInt16 nSlot )
95 {
96     SvxCellVerJustify eVJustify = SvxCellVerJustify::Standard;
97     switch( nSlot )
98     {
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" );
104     }
105     return eVJustify;
106 }
107 
108 } // namespace
109 
110 
SFX_IMPL_INTERFACE(ScFormatShell,SfxShell)111 SFX_IMPL_INTERFACE(ScFormatShell, SfxShell)
112 
113 void ScFormatShell::InitInterface_Impl()
114 {
115     GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_OBJECT,
116                                             SfxVisibilityFlags::Standard | SfxVisibilityFlags::Server,
117                                             ToolbarId::Objectbar_Format);
118 }
119 
ScFormatShell(ScViewData & rData)120 ScFormatShell::ScFormatShell(ScViewData& rData) :
121     SfxShell(rData.GetViewShell()),
122     rViewData(rData)
123 {
124     ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
125 
126     SetPool( &pTabViewShell->GetPool() );
127     SfxUndoManager* pMgr = rViewData.GetSfxDocShell().GetUndoManager();
128     SetUndoManager( pMgr );
129     if (pMgr && !rViewData.GetDocument().IsUndoEnabled())
130     {
131         pMgr->SetMaxUndoActionCount( 0 );
132     }
133     SetName(u"Format"_ustr);
134 }
135 
~ScFormatShell()136 ScFormatShell::~ScFormatShell()
137 {
138 }
139 
ExecuteStyle(SfxRequest & rReq)140 void ScFormatShell::ExecuteStyle( SfxRequest& rReq )
141 {
142     const SfxItemSet* pArgs = rReq.GetArgs();
143     const sal_uInt16  nSlotId = rReq.GetSlot();
144 
145     ScDocShell&         rDocSh      = GetViewData().GetDocShell();
146     ScTabViewShell*     pTabViewShell= GetViewData().GetViewShell();
147     ScDocument&         rDoc        = rDocSh.GetDocument();
148     SfxStyleSheetBasePool*  pStylePool  = rDoc.GetStyleSheetPool();
149 
150     if (nSlotId == SID_STYLE_PREVIEW)
151     {
152         SfxStyleFamily eFamily = SfxStyleFamily::Para;
153         const SfxUInt16Item* pFamItem;
154         if ( pArgs && (pFamItem = pArgs->GetItemIfSet( SID_STYLE_FAMILY )) )
155             eFamily = static_cast<SfxStyleFamily>(pFamItem->GetValue());
156         const SfxPoolItem* pNameItem;
157         OUString aStyleName;
158         if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem ))
159             aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
160         if ( eFamily == SfxStyleFamily::Para ) // CellStyles
161         {
162             ScMarkData aFuncMark( rViewData.GetMarkData() );
163             ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
164             aFuncMark.MarkToMulti();
165 
166             if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
167             {
168                 SCCOL nCol = rViewData.GetCurX();
169                 SCROW nRow = rViewData.GetCurY();
170                 SCTAB nTab = rViewData.GetTabNo();
171                 ScRange aRange( nCol, nRow, nTab );
172                 aFuncMark.SetMarkArea( aRange );
173             }
174             rDoc.SetPreviewSelection( aFuncMark );
175             ScStyleSheet* pPreviewStyle = static_cast<ScStyleSheet*>( pStylePool->Find( aStyleName, eFamily ) );
176             rDoc.SetPreviewCellStyle( pPreviewStyle  );
177             ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aFuncMark ) );
178             aAttr.SetStyleSheet( pPreviewStyle );
179 
180             SfxItemSet aItemSet( GetPool() );
181 
182             ScPatternAttr aNewAttrs(GetViewData().GetDocument().getCellAttributeHelper());
183             SfxItemSet& rNewSet = aNewAttrs.GetItemSetWritable();
184             rNewSet.Put( aItemSet, false );
185 
186             rDoc.ApplySelectionPattern( aNewAttrs, rDoc.GetPreviewSelection() );
187             pTabViewShell->UpdateSelectionArea(aFuncMark, &aAttr, /*adjustHeight*/ false);
188         }
189     }
190     else if (nSlotId ==  SID_STYLE_END_PREVIEW)
191     {
192         // No mark at all happens when creating a new document, in which
193         // case the selection pattern obtained would be empty (created of
194         // GetPool()) anyway and nothing needs to be applied.
195         ScMarkData aPreviewMark( rDoc.GetPreviewSelection());
196         if (aPreviewMark.IsMarked() || aPreviewMark.IsMultiMarked())
197         {
198             ScPatternAttr aAttr( *rDoc.GetSelectionPattern( aPreviewMark ) );
199             if ( ScStyleSheet* pPreviewStyle = rDoc.GetPreviewCellStyle() )
200                 aAttr.SetStyleSheet( pPreviewStyle );
201             rDoc.SetPreviewCellStyle(nullptr);
202 
203             SfxItemSet aItemSet( GetPool() );
204 
205             ScPatternAttr aNewAttrs(GetViewData().GetDocument().getCellAttributeHelper());
206             SfxItemSet& rNewSet = aNewAttrs.GetItemSetWritable();
207             rNewSet.Put( aItemSet, false );
208             rDoc.ApplySelectionPattern( aNewAttrs, aPreviewMark );
209             pTabViewShell->UpdateSelectionArea(aPreviewMark, &aAttr, /*adjustHeight*/ false);
210         }
211     }
212     else if (nSlotId == SID_CLASSIFICATION_APPLY)
213     {
214         const SfxPoolItem* pItem = nullptr;
215         if (pArgs && pArgs->GetItemState(nSlotId, false, &pItem) == SfxItemState::SET)
216         {
217             const OUString& rName = static_cast<const SfxStringItem*>(pItem)->GetValue();
218             SfxClassificationHelper aHelper(rDocSh.getDocProperties());
219             auto eType = SfxClassificationPolicyType::IntellectualProperty;
220             if (const SfxStringItem* pNameItem = pArgs->GetItemIfSet(SID_TYPE_NAME, false))
221             {
222                 const OUString& rType = pNameItem->GetValue();
223                 eType = SfxClassificationHelper::stringToPolicyType(rType);
224             }
225             aHelper.SetBACName(rName, eType);
226         }
227         else
228             SAL_WARN("sc.ui", "missing parameter for SID_CLASSIFICATION_APPLY");
229     }
230     else
231     {
232         OSL_FAIL( "Unknown slot (ScViewShell::ExecuteStyle)" );
233     }
234 }
235 
ExecuteNumFormat(SfxRequest & rReq)236 void ScFormatShell::ExecuteNumFormat( SfxRequest& rReq )
237 {
238     ScModule* pScMod = ScModule::get();
239     ScTabViewShell*     pTabViewShell   = GetViewData().GetViewShell();
240     const SfxItemSet*   pReqArgs        = rReq.GetArgs();
241     sal_uInt16          nSlot           = rReq.GetSlot();
242     SfxBindings&        rBindings       = pTabViewShell->GetViewFrame().GetBindings();
243 
244     pTabViewShell->HideListBox();                   // Autofilter-DropDown-Listbox
245 
246     // End input
247     if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) )
248     {
249         switch ( nSlot )
250         {
251             case SID_NUMBER_TYPE_FORMAT:
252             case SID_NUMBER_TWODEC:
253             case SID_NUMBER_SCIENTIFIC:
254             case SID_NUMBER_DATE:
255             case SID_NUMBER_CURRENCY:
256             case SID_NUMBER_PERCENT:
257             case SID_NUMBER_STANDARD:
258             case SID_NUMBER_FORMAT:
259             case SID_NUMBER_INCDEC:
260             case SID_NUMBER_DECDEC:
261             case SID_NUMBER_THOUSANDS:
262             case FID_DEFINE_NAME:
263             case FID_ADD_NAME:
264             case FID_USE_NAME:
265             case FID_INSERT_NAME:
266             case SID_SPELL_DIALOG:
267             case SID_HANGUL_HANJA_CONVERSION:
268 
269             pScMod->InputEnterHandler();
270             pTabViewShell->UpdateInputHandler();
271             break;
272 
273             default:
274             break;
275         }
276     }
277 
278     SvNumFormatType nType = GetCurrentNumberFormatType();
279     switch ( nSlot )
280     {
281         case SID_NUMBER_TWODEC:
282         {
283             const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
284             sal_uInt32 nNumberFormat = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue();
285 
286             if ((nType & SvNumFormatType::NUMBER) && nNumberFormat == 4)
287                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
288             else
289                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 4 );
290             rBindings.Invalidate( nSlot );
291             rReq.Done();
292         }
293         break;
294         case SID_NUMBER_SCIENTIFIC:
295             if (nType & SvNumFormatType::SCIENTIFIC)
296                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
297             else
298                 pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC );
299             rBindings.Invalidate( nSlot );
300             rReq.Done();
301             break;
302         case SID_NUMBER_DATE:
303             if (nType & SvNumFormatType::DATE)
304                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
305             else
306                 pTabViewShell->SetNumberFormat( SvNumFormatType::DATE );
307             rBindings.Invalidate( nSlot );
308             rReq.Done();
309             break;
310         case SID_NUMBER_TIME:
311             if (nType & SvNumFormatType::TIME)
312                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
313             else
314                 pTabViewShell->SetNumberFormat( SvNumFormatType::TIME );
315             rBindings.Invalidate( nSlot );
316             rReq.Done();
317             break;
318         case SID_NUMBER_CURRENCY:
319             if(pReqArgs)
320             {
321                 const SfxPoolItem* pItem;
322                 if ( pReqArgs->HasItem( SID_NUMBER_CURRENCY, &pItem ) )
323                 {
324                     sal_uInt32 nNewFormat = static_cast<const SfxUInt32Item*>(pItem)->GetValue();
325                     ScDocument& rDoc = rViewData.GetDocument();
326                     SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
327                     const SfxItemSet& rOldSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
328 
329                     LanguageType eOldLang = rOldSet.Get( ATTR_LANGUAGE_FORMAT ).GetLanguage();
330                     sal_uInt32 nOldFormat = rOldSet.Get( ATTR_VALUE_FORMAT ).GetValue();
331 
332                     if ( nOldFormat != nNewFormat )
333                     {
334                         const SvNumberformat* pNewEntry = pFormatter->GetEntry( nNewFormat );
335                         ScPatternAttr aNewAttrs(rDoc.getCellAttributeHelper());
336                         LanguageType eNewLang = pNewEntry ? pNewEntry->GetLanguage() : LANGUAGE_DONTKNOW;
337                         if ( eNewLang != eOldLang && eNewLang != LANGUAGE_DONTKNOW )
338                             aNewAttrs.ItemSetPut(SvxLanguageItem(eNewLang, ATTR_LANGUAGE_FORMAT));
339                         aNewAttrs.ItemSetPut(SfxUInt32Item(ATTR_VALUE_FORMAT, nNewFormat));
340                         pTabViewShell->ApplySelectionPattern( aNewAttrs );
341                     }
342                     else
343                         pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
344                 }
345             }
346             else
347             {
348                 if ( nType & SvNumFormatType::CURRENCY )
349                     pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
350                 else
351                     pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY );
352             }
353             rBindings.Invalidate( nSlot );
354             rReq.Done();
355             break;
356         case SID_NUMBER_PERCENT:
357             if (nType & SvNumFormatType::PERCENT)
358                 pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
359             else
360                 pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT );
361             rBindings.Invalidate( nSlot );
362             rReq.Done();
363             break;
364         case SID_NUMBER_STANDARD:
365             pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER );
366             rReq.Done();
367             break;
368         case SID_NUMBER_INCDEC:
369             pTabViewShell->ChangeNumFmtDecimals( true );
370             rReq.Done();
371             break;
372         case SID_NUMBER_DECDEC:
373             pTabViewShell->ChangeNumFmtDecimals( false );
374             rReq.Done();
375             break;
376         case SID_NUMBER_THOUSANDS:
377         {
378             ScDocument& rDoc = rViewData.GetDocument();
379             SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
380             bool bThousand(false);
381             bool bNegRed(false);
382             sal_uInt16 nPrecision(0);
383             sal_uInt16 nLeadZeroes(0);
384             LanguageType eLanguage = ScGlobal::eLnge;
385 
386             sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat(
387                 rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
388             const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat);
389 
390             if (pEntry)
391                 eLanguage = pEntry->GetLanguage();
392 
393             pFormatter->GetFormatSpecialInfo(nCurrentNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes);
394             bThousand = !bThousand;
395             OUString aCode = pFormatter->GenerateFormat(
396                 nCurrentNumberFormat,
397                 eLanguage,
398                 bThousand,
399                 bNegRed,
400                 nPrecision,
401                 nLeadZeroes);
402             pTabViewShell->SetNumFmtByStr(aCode);
403 
404             rBindings.Invalidate(nSlot);
405             rReq.Done();
406         }
407         break;
408         case SID_NUMBER_FORMAT:
409             // symphony version with format interpretation
410             if(pReqArgs)
411             {
412                 const SfxPoolItem* pItem;
413                 ScDocument& rDoc = rViewData.GetDocument();
414                 SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
415 
416                 sal_uInt32 nCurrentNumberFormat = rDoc.GetNumberFormat(
417                     rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
418                 const SvNumberformat* pEntry = pFormatter->GetEntry(nCurrentNumberFormat);
419 
420                 if(!pEntry)
421                     break;
422 
423                 LanguageType eLanguage = pEntry->GetLanguage();
424                 SvNumFormatType eType = pEntry->GetMaskedType();
425 
426                 //Just use eType to judge whether the command is fired for NUMBER/PERCENT/CURRENCY/SCIENTIFIC/FRACTION/TIME
427                 //In sidebar, users can fire SID_NUMBER_FORMAT command by operating the related UI controls before they are disable
428                 if(!(eType == SvNumFormatType::ALL
429                      || eType == SvNumFormatType::NUMBER
430                      || eType == SvNumFormatType::PERCENT
431                      || eType == SvNumFormatType::CURRENCY
432                      || eType == SvNumFormatType::SCIENTIFIC
433                      || eType == SvNumFormatType::TIME
434                      || eType == SvNumFormatType::FRACTION))
435                     pEntry = nullptr;
436 
437                 if(SfxItemState::SET == pReqArgs->GetItemState(nSlot, true, &pItem) && pEntry)
438                 {
439                     OUString aCode = static_cast<const SfxStringItem*>(pItem)->GetValue();
440                     sal_uInt16 aLen = aCode.getLength();
441                     std::unique_ptr<OUString[]> sFormat( new OUString[4] );
442                     OUStringBuffer sTmpStr;
443                     sal_uInt16 nCount(0);
444                     sal_uInt16 nStrCount(0);
445 
446                     while(nCount < aLen)
447                     {
448                         sal_Unicode cChar = aCode[nCount];
449 
450                         if(cChar == ',')
451                         {
452                             sFormat[nStrCount] = sTmpStr.makeStringAndClear();
453                             nStrCount++;
454                         }
455                         else
456                         {
457                             sTmpStr.append(cChar);
458                         }
459 
460                         nCount++;
461 
462                         if(nStrCount > 3)
463                             break;
464                     }
465 
466                     const bool bThousand = static_cast<bool>(sFormat[0].toInt32());
467                     const bool bNegRed = static_cast<bool>(sFormat[1].toInt32());
468                     const sal_uInt16 nPrecision = static_cast<sal_uInt16>(sFormat[2].toInt32());
469                     const sal_uInt16 nLeadZeroes = static_cast<sal_uInt16>(sFormat[3].toInt32());
470 
471                     aCode = pFormatter->GenerateFormat(
472                         nCurrentNumberFormat,//modify
473                         eLanguage,
474                         bThousand,
475                         bNegRed,
476                         nPrecision,
477                         nLeadZeroes);
478                     pTabViewShell->SetNumFmtByStr(aCode);
479                 }
480             }
481             break;
482 
483         case SID_ATTR_NUMBERFORMAT_VALUE:
484             if ( pReqArgs )
485             {
486                 if ( const SfxUInt32Item* pItem = pReqArgs->GetItemIfSet( ATTR_VALUE_FORMAT ) )
487                 {
488                     // We have to accomplish this using ApplyAttributes()
489                     // because we also need the language information to be
490                     // considered.
491                     const SfxItemSet& rOldSet =
492                         pTabViewShell->GetSelectionPattern()->GetItemSet();
493                     SfxItemPool* pDocPool = GetViewData().GetDocument().GetPool();
494                     SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *pDocPool );
495                     aNewSet.Put( *pItem );
496                     pTabViewShell->ApplyAttributes( aNewSet, rOldSet );
497                 }
498             }
499             break;
500 
501         case SID_NUMBER_TYPE_FORMAT:
502             if ( pReqArgs )
503             {
504                 const SfxPoolItem* pItem;
505                 if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
506                 {
507                     sal_uInt16 nFormat = static_cast<const SfxUInt16Item *>(pItem)->GetValue();
508                     switch(nFormat)
509                     {
510                     case 0:
511                         pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER); //Modify
512                         break;
513                     case 1:
514                         pTabViewShell->SetNumberFormat( SvNumFormatType::NUMBER, 2 ); //Modify
515                         break;
516                     case 2:
517                         pTabViewShell->SetNumberFormat( SvNumFormatType::PERCENT );
518                         break;
519                     case 3:
520                         pTabViewShell->SetNumberFormat( SvNumFormatType::CURRENCY );
521                         break;
522                     case 4:
523                         pTabViewShell->SetNumberFormat( SvNumFormatType::DATE );
524                         break;
525                     case 5:
526                         pTabViewShell->SetNumberFormat( SvNumFormatType::TIME );
527                         break;
528                     case 6:
529                         pTabViewShell->SetNumberFormat( SvNumFormatType::SCIENTIFIC );
530                         break;
531                     case 7:
532                         pTabViewShell->SetNumberFormat( SvNumFormatType::FRACTION );
533                         break;
534                     case 8:
535                         pTabViewShell->SetNumberFormat( SvNumFormatType::LOGICAL );
536                         break;
537                     case 9:
538                         pTabViewShell->SetNumberFormat( SvNumFormatType::TEXT );
539                         break;
540                     default:
541                         ;
542                     }
543                     rReq.Done();
544                 }
545             }
546             break;
547 
548         default:
549             OSL_FAIL("ExecuteEdit: invalid slot");
550             break;
551     }
552 }
553 
ExecuteAlignment(SfxRequest & rReq)554 void ScFormatShell::ExecuteAlignment( SfxRequest& rReq )
555 {
556     ScTabViewShell* pTabViewShell       = GetViewData().GetViewShell();
557     SfxBindings&            rBindings   = rViewData.GetBindings();
558     const SfxItemSet*       pSet        = rReq.GetArgs();
559     sal_uInt16                  nSlot       = rReq.GetSlot();
560 
561     pTabViewShell->HideListBox();   // Autofilter-DropDown-Listbox
562 
563     switch( nSlot )
564     {
565         // pseudo slots for Format menu
566         case SID_ALIGN_ANY_HDEFAULT:
567         case SID_ALIGN_ANY_LEFT:
568         case SID_ALIGN_ANY_HCENTER:
569         case SID_ALIGN_ANY_RIGHT:
570         case SID_ALIGN_ANY_JUSTIFIED:
571             pTabViewShell->ApplyAttr( SvxHorJustifyItem( lclConvertSlotToHAlign( nSlot ), ATTR_HOR_JUSTIFY ) );
572         break;
573         case SID_ALIGN_ANY_VDEFAULT:
574         case SID_ALIGN_ANY_TOP:
575         case SID_ALIGN_ANY_VCENTER:
576         case SID_ALIGN_ANY_BOTTOM:
577             pTabViewShell->ApplyAttr( SvxVerJustifyItem( lclConvertSlotToVAlign( nSlot ), ATTR_VER_JUSTIFY ) );
578         break;
579 
580         default:
581             if( pSet )
582             {
583                 const SfxPoolItem* pItem = nullptr;
584                 if( pSet->GetItemState(GetPool().GetWhichIDFromSlotID(nSlot), true, &pItem  ) == SfxItemState::SET )
585                 {
586 
587                     switch ( nSlot )
588                     {
589                         case SID_ATTR_ALIGN_HOR_JUSTIFY:
590                         case SID_ATTR_ALIGN_VER_JUSTIFY:
591                         case SID_ATTR_ALIGN_INDENT:
592                         case SID_ATTR_ALIGN_HYPHENATION:
593                         case SID_ATTR_ALIGN_DEGREES:
594                         case SID_ATTR_ALIGN_LOCKPOS:
595                         case SID_ATTR_ALIGN_MARGIN:
596                         case SID_ATTR_ALIGN_STACKED:
597                             pTabViewShell->ApplyAttr( *pItem );
598                         break;
599 
600                         case SID_H_ALIGNCELL:
601                         {
602                             SvxCellHorJustify eJust = static_cast<const SvxHorJustifyItem*>(pItem)->GetValue();
603                             // #i78476# update alignment of text in cell edit mode
604                             pTabViewShell->UpdateInputHandlerCellAdjust( eJust );
605                             pTabViewShell->ApplyAttr( SvxHorJustifyItem( eJust, ATTR_HOR_JUSTIFY ) );
606                         }
607                         break;
608                         case SID_V_ALIGNCELL:
609                             pTabViewShell->ApplyAttr( SvxVerJustifyItem( static_cast<const SvxVerJustifyItem*>(pItem)->GetValue(), ATTR_VER_JUSTIFY ) );
610                         break;
611                         default:
612                             OSL_FAIL( "ExecuteAlignment: invalid slot" );
613                             return;
614                     }
615                 }
616             }
617     }
618     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_LEFT );
619     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_RIGHT );
620     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_BLOCK );
621     rBindings.Invalidate( SID_ATTR_PARA_ADJUST_CENTER);
622     rBindings.Invalidate( SID_ALIGNLEFT );
623     rBindings.Invalidate( SID_ALIGNRIGHT );
624     rBindings.Invalidate( SID_ALIGNCENTERHOR );
625     rBindings.Invalidate( SID_ALIGNBLOCK );
626     rBindings.Invalidate( SID_ALIGNTOP );
627     rBindings.Invalidate( SID_ALIGNBOTTOM );
628     rBindings.Invalidate( SID_ALIGNCENTERVER );
629     rBindings.Invalidate( SID_V_ALIGNCELL );
630     rBindings.Invalidate( SID_H_ALIGNCELL );
631     // pseudo slots for Format menu
632     rBindings.Invalidate( SID_ALIGN_ANY_HDEFAULT );
633     rBindings.Invalidate( SID_ALIGN_ANY_LEFT );
634     rBindings.Invalidate( SID_ALIGN_ANY_HCENTER );
635     rBindings.Invalidate( SID_ALIGN_ANY_RIGHT );
636     rBindings.Invalidate( SID_ALIGN_ANY_JUSTIFIED );
637     rBindings.Invalidate( SID_ALIGN_ANY_VDEFAULT );
638     rBindings.Invalidate( SID_ALIGN_ANY_TOP );
639     rBindings.Invalidate( SID_ALIGN_ANY_VCENTER );
640     rBindings.Invalidate( SID_ALIGN_ANY_BOTTOM );
641     rBindings.Update();
642 
643     if( ! rReq.IsAPI() )
644         rReq.Done();
645 }
646 
ExecuteTextAttr(SfxRequest & rReq)647 void ScFormatShell::ExecuteTextAttr( SfxRequest& rReq )
648 {
649     ScTabViewShell* pTabViewShell       = GetViewData().GetViewShell();
650     SfxBindings&            rBindings   = rViewData.GetBindings();
651     const ScPatternAttr*    pAttrs      = pTabViewShell->GetSelectionPattern();
652     const SfxItemSet*       pSet        = rReq.GetArgs();
653     sal_uInt16                  nSlot       = rReq.GetSlot();
654     std::optional<SfxAllItemSet> pNewSet;
655 
656     pTabViewShell->HideListBox();                   // Autofilter-DropDown-Listbox
657 
658     if (  (nSlot == SID_ATTR_CHAR_WEIGHT)
659         ||(nSlot == SID_ATTR_CHAR_POSTURE)
660         ||(nSlot == SID_ATTR_CHAR_UNDERLINE)
661         ||(nSlot == SID_ULINE_VAL_NONE)
662         ||(nSlot == SID_ULINE_VAL_SINGLE)
663         ||(nSlot == SID_ULINE_VAL_DOUBLE)
664         ||(nSlot == SID_ULINE_VAL_DOTTED) )
665     {
666         pNewSet.emplace( GetPool() );
667 
668         switch ( nSlot )
669         {
670             case SID_ATTR_CHAR_WEIGHT:
671             {
672                 // #i78017 establish the same behaviour as in Writer
673                 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
674 
675                 SfxItemPool& rPool = GetPool();
676                 SvxScriptSetItem aSetItem( nSlot, rPool );
677                 if ( pSet )
678                     aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_WEIGHT ) );
679                 else
680                 {
681                     //  toggle manually
682 
683                     FontWeight eWeight = WEIGHT_BOLD;
684                     SvxScriptSetItem aOldSetItem( nSlot, rPool );
685                     aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false );
686                     const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
687                     if ( pCore && static_cast<const SvxWeightItem*>(pCore)->GetWeight() == WEIGHT_BOLD )
688                         eWeight = WEIGHT_NORMAL;
689 
690                     aSetItem.PutItemForScriptType( nScript, SvxWeightItem( eWeight, ATTR_FONT_WEIGHT ) );
691                 }
692                 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
693                 pNewSet->Put( aSetItem.GetItemSet(), false );
694             }
695             break;
696 
697             case SID_ATTR_CHAR_POSTURE:
698             {
699                 // #i78017 establish the same behaviour as in Writer
700                 SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
701 
702                 SfxItemPool& rPool = GetPool();
703                 SvxScriptSetItem aSetItem( nSlot, rPool );
704                 if ( pSet )
705                     aSetItem.PutItemForScriptType( nScript, pSet->Get( ATTR_FONT_POSTURE ) );
706                 else
707                 {
708                     //  toggle manually
709 
710                     FontItalic eItalic = ITALIC_NORMAL;
711                     SvxScriptSetItem aOldSetItem( nSlot, rPool );
712                     aOldSetItem.GetItemSet().Put( pAttrs->GetItemSet(), false );
713                     const SfxPoolItem* pCore = aOldSetItem.GetItemOfScript( nScript );
714                     if ( pCore && static_cast<const SvxPostureItem*>(pCore)->GetPosture() == ITALIC_NORMAL )
715                         eItalic = ITALIC_NONE;
716 
717                     aSetItem.PutItemForScriptType( nScript, SvxPostureItem( eItalic, ATTR_FONT_POSTURE ) );
718                 }
719                 pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
720                 pNewSet->Put( aSetItem.GetItemSet(), false );
721             }
722             break;
723 
724             case SID_ATTR_CHAR_UNDERLINE:
725                 {
726                     if( pSet )
727                     {
728                         const SfxPoolItem& rUnderline = pSet->Get( ATTR_FONT_UNDERLINE );
729 
730                         if( dynamic_cast<const SvxUnderlineItem*>( &rUnderline) !=  nullptr )
731                         {
732                             pTabViewShell->ApplyAttr( rUnderline );
733                             pNewSet->Put( rUnderline );
734                         }
735                         else if ( auto pTextLineItem = dynamic_cast<const SvxTextLineItem*>( &rUnderline) )
736                         {
737                             // #i106580# also allow SvxTextLineItem (base class of SvxUnderlineItem)
738                             SvxUnderlineItem aNewItem( pTextLineItem->GetLineStyle(), pTextLineItem->Which() );
739                             aNewItem.SetColor( pTextLineItem->GetColor() );
740                             pTabViewShell->ApplyAttr( aNewItem );
741                             pNewSet->Put( aNewItem );
742                         }
743                     }
744                     else
745                     {
746                         SvxUnderlineItem aUnderline( pAttrs->GetItem( ATTR_FONT_UNDERLINE ) );
747                         FontLineStyle eUnderline = (LINESTYLE_NONE != aUnderline.GetLineStyle())
748                                     ? LINESTYLE_NONE
749                                     : LINESTYLE_SINGLE;
750                         aUnderline.SetLineStyle( eUnderline );
751                         pTabViewShell->ApplyAttr( aUnderline );
752                         pNewSet->Put( aUnderline );
753                     }
754                 }
755                 break;
756 
757             case SID_ULINE_VAL_NONE:
758                 pTabViewShell->ApplyAttr( SvxUnderlineItem( LINESTYLE_NONE, ATTR_FONT_UNDERLINE ) );
759                 break;
760             case SID_ULINE_VAL_SINGLE:      // Toggles
761             case SID_ULINE_VAL_DOUBLE:
762             case SID_ULINE_VAL_DOTTED:
763                 {
764                     FontLineStyle eOld = pAttrs->GetItem(ATTR_FONT_UNDERLINE).GetLineStyle();
765                     FontLineStyle eNew = eOld;
766                     switch (nSlot)
767                     {
768                         case SID_ULINE_VAL_SINGLE:
769                             eNew = ( eOld == LINESTYLE_SINGLE ) ? LINESTYLE_NONE : LINESTYLE_SINGLE;
770                             break;
771                         case SID_ULINE_VAL_DOUBLE:
772                             eNew = ( eOld == LINESTYLE_DOUBLE ) ? LINESTYLE_NONE : LINESTYLE_DOUBLE;
773                             break;
774                         case SID_ULINE_VAL_DOTTED:
775                             eNew = ( eOld == LINESTYLE_DOTTED ) ? LINESTYLE_NONE : LINESTYLE_DOTTED;
776                             break;
777                     }
778                     pTabViewShell->ApplyAttr( SvxUnderlineItem( eNew, ATTR_FONT_UNDERLINE ) );
779                 }
780                 break;
781 
782             default:
783                 break;
784         }
785         rBindings.Invalidate( nSlot );
786     }
787     else
788     {
789         /*
790          * "Self-made" functionality of radio buttons
791          * At the toggle the default state is used, this means
792          * no button was clicked.
793          */
794 
795         const SfxItemSet&        rAttrSet   = pTabViewShell->GetSelectionPattern()->GetItemSet();
796         const SvxHorJustifyItem* pHorJustify = rAttrSet.GetItemIfSet(ATTR_HOR_JUSTIFY);
797         const SvxVerJustifyItem* pVerJustify = rAttrSet.GetItemIfSet(ATTR_VER_JUSTIFY );
798         SvxCellHorJustify        eHorJustify = SvxCellHorJustify::Standard;
799         SvxCellVerJustify        eVerJustify = SvxCellVerJustify::Standard;
800 
801         if (pHorJustify)
802         {
803             eHorJustify = pHorJustify->GetValue();
804         }
805         if (pVerJustify)
806         {
807             eVerJustify = pVerJustify->GetValue();
808         }
809 
810         switch ( nSlot )
811         {
812             case SID_ALIGNLEFT:
813                 rReq.SetSlot( SID_H_ALIGNCELL );
814                 rReq.AppendItem( SvxHorJustifyItem(
815                     !pHorJustify || (eHorJustify != SvxCellHorJustify::Left) ?
816                     SvxCellHorJustify::Left : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
817                 ExecuteSlot( rReq, GetInterface() );
818                 return;
819 
820             case SID_ALIGNRIGHT:
821                 rReq.SetSlot( SID_H_ALIGNCELL );
822                 rReq.AppendItem( SvxHorJustifyItem(
823                     !pHorJustify || (eHorJustify != SvxCellHorJustify::Right) ?
824                     SvxCellHorJustify::Right : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
825                 ExecuteSlot( rReq, GetInterface() );
826                 return;
827 
828             case SID_ALIGNCENTERHOR:
829                 rReq.SetSlot( SID_H_ALIGNCELL );
830                 rReq.AppendItem( SvxHorJustifyItem(
831                     !pHorJustify || (eHorJustify != SvxCellHorJustify::Center) ?
832                     SvxCellHorJustify::Center : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
833                 ExecuteSlot( rReq, GetInterface() );
834                 return;
835 
836             case SID_ALIGNBLOCK:
837                 rReq.SetSlot( SID_H_ALIGNCELL );
838                 rReq.AppendItem( SvxHorJustifyItem(
839                     !pHorJustify || (eHorJustify != SvxCellHorJustify::Block) ?
840                     SvxCellHorJustify::Block : SvxCellHorJustify::Standard, SID_H_ALIGNCELL ) );
841                 ExecuteSlot( rReq, GetInterface() );
842                 return;
843 
844             case SID_ALIGNTOP:
845                 rReq.SetSlot( SID_V_ALIGNCELL );
846                 rReq.AppendItem( SvxVerJustifyItem(
847                     !pVerJustify || (eVerJustify != SvxCellVerJustify::Top) ?
848                     SvxCellVerJustify::Top : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
849                 ExecuteSlot( rReq, GetInterface() );
850                 return;
851 
852             case SID_ALIGNBOTTOM:
853                 rReq.SetSlot( SID_V_ALIGNCELL );
854                 rReq.AppendItem( SvxVerJustifyItem(
855                     !pVerJustify || (eVerJustify != SvxCellVerJustify::Bottom) ?
856                     SvxCellVerJustify::Bottom : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
857                 ExecuteSlot( rReq, GetInterface() );
858                 return;
859 
860             case SID_ALIGNCENTERVER:
861                 rReq.SetSlot( SID_V_ALIGNCELL );
862                 rReq.AppendItem( SvxVerJustifyItem(
863                     !pVerJustify || (eVerJustify != SvxCellVerJustify::Center) ?
864                     SvxCellVerJustify::Center : SvxCellVerJustify::Standard, SID_V_ALIGNCELL ) );
865                 ExecuteSlot( rReq, GetInterface() );
866                 return;
867 
868             default:
869             break;
870         }
871 
872     }
873 
874     rBindings.Update();
875 
876     if( pNewSet )
877     {
878         rReq.Done( *pNewSet );
879         pNewSet.reset();
880     }
881     else
882     {
883         rReq.Done();
884     }
885 
886 }
887 
ExecuteAttr(SfxRequest & rReq)888 void ScFormatShell::ExecuteAttr( SfxRequest& rReq )
889 {
890     ScTabViewShell*     pTabViewShell = GetViewData().GetViewShell();
891     SfxBindings&        rBindings = rViewData.GetBindings();
892     const SfxItemSet*   pNewAttrs = rReq.GetArgs();
893     sal_uInt16          nSlot = rReq.GetSlot();
894 
895     pTabViewShell->HideListBox();                   // Autofilter-DropDown-Listbox
896     ScDocument& rDoc = GetViewData().GetDocument();
897     if ( !pNewAttrs )
898     {
899         switch ( nSlot )
900         {
901             case SID_GROW_FONT_SIZE:
902             case SID_SHRINK_FONT_SIZE:
903             {
904                 SfxItemPool& rPool = GetPool();
905                 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONTHEIGHT, rPool );
906                 aSetItem.GetItemSet().Put( pTabViewShell->GetSelectionPattern()->GetItemSet(), false );
907 
908                 SvtScriptType nScriptTypes = pTabViewShell->GetSelectionScriptType();
909                 const SvxFontHeightItem* pSize( static_cast<const SvxFontHeightItem*>( aSetItem.GetItemOfScript( nScriptTypes ) ) );
910 
911                 if ( pSize )
912                 {
913                     SvxFontHeightItem aSize( *pSize );
914                     sal_uInt32 nSize = aSize.GetHeight();
915 
916                     const sal_uInt32 nFontInc = 40;      // 2pt
917                     const sal_uInt32 nFontMaxSz = 19998; // 999.9pt
918                     if ( nSlot == SID_GROW_FONT_SIZE )
919                         nSize = std::min< sal_uInt32 >( nSize + nFontInc, nFontMaxSz );
920                     else
921                         nSize = std::max< sal_Int32 >( nSize - nFontInc, nFontInc );
922 
923                     aSize.SetHeight( nSize );
924                     aSetItem.PutItemForScriptType( nScriptTypes, aSize );
925                     pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
926                 }
927                 rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
928             }
929             break;
930 
931             case SID_ATTR_CHAR_ENDPREVIEW_FONT:
932             {
933                 rDoc.SetPreviewFont(nullptr);
934                 pTabViewShell->UpdateSelectionArea(rDoc.GetPreviewSelection(), nullptr,
935                                                    /*adjustHeight*/ false);
936                 break;
937             }
938             case SID_ATTR_CHAR_COLOR:
939             case SID_ATTR_CHAR_FONT:
940             case SID_ATTR_CHAR_FONTHEIGHT:
941                 pTabViewShell->ExecuteCellFormatDlg(rReq, u"font"_ustr);       // when ToolBar is vertical
942                 break;
943 
944             case SID_BACKGROUND_COLOR:
945                 {
946                     SvxBrushItem aBrushItem(
947                                      pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) );
948                     aBrushItem.SetColor( COL_TRANSPARENT );
949                     pTabViewShell->ApplyAttr( aBrushItem, false );
950                 }
951                 break;
952 
953             case SID_ATTR_ALIGN_LINEBREAK:                  // without parameter as toggle
954                 {
955                     const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
956                     bool bOld = pAttrs->GetItem(ATTR_LINEBREAK).GetValue();
957                     ScLineBreakCell aBreakItem(!bOld);
958                     pTabViewShell->ApplyAttr( aBreakItem );
959 
960                     SfxAllItemSet aNewSet( GetPool() );
961                     aNewSet.Put( aBreakItem );
962                     rReq.Done( aNewSet );
963 
964                     rBindings.Invalidate( nSlot );
965                 }
966                 break;
967 
968             case SID_SCATTR_CELLPROTECTION:                  // without parameter as toggle
969                 {
970                     const ScPatternAttr* pAttrs = pTabViewShell->GetSelectionPattern();
971                     bool bProtect = pAttrs->GetItem(ATTR_PROTECTION).GetProtection();
972                     bool bHideFormula = pAttrs->GetItem(ATTR_PROTECTION).GetHideFormula();
973                     bool bHideCell = pAttrs->GetItem(ATTR_PROTECTION).GetHideCell();
974                     bool bHidePrint = pAttrs->GetItem(ATTR_PROTECTION).GetHidePrint();
975 
976                     ScProtectionAttr aProtectionItem( !bProtect, bHideFormula, bHideCell, bHidePrint );
977                     pTabViewShell->ApplyAttr( aProtectionItem );
978 
979                     SfxAllItemSet aNewSet( GetPool() );
980                     aNewSet.Put( aProtectionItem );
981                     aNewSet.Put( SfxBoolItem( SID_SCATTR_CELLPROTECTION, !bProtect ) );
982                     rReq.Done( aNewSet );
983 
984                     rBindings.Invalidate( nSlot );
985                 }
986                 break;
987         }
988     }
989     else
990     {
991         switch ( nSlot )
992         {
993             case SID_ATTR_CHAR_PREVIEW_FONT:
994             {
995                 SfxItemPool& rPool = GetPool();
996                 sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
997                 const SvxFontItem& rFont = static_cast<const SvxFontItem&>(pNewAttrs->Get( nWhich ));
998                 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, rPool );
999                 SvtScriptType nScript = pTabViewShell->GetSelectionScriptType();
1000                 aSetItem.PutItemForScriptType( nScript, rFont );
1001 
1002                 ScMarkData aFuncMark( rViewData.GetMarkData() );
1003                 ScViewUtil::UnmarkFiltered( aFuncMark, rDoc );
1004                 rDoc.SetPreviewFont( aSetItem.GetItemSet().Clone() );
1005                 aFuncMark.MarkToMulti();
1006 
1007                 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1008                 {
1009                     SCCOL nCol = rViewData.GetCurX();
1010                     SCROW nRow = rViewData.GetCurY();
1011                     SCTAB nTab = rViewData.GetTabNo();
1012                     ScRange aRange( nCol, nRow, nTab );
1013                     aFuncMark.SetMarkArea( aRange );
1014                 }
1015                 rDoc.SetPreviewSelection( aFuncMark );
1016                 pTabViewShell->UpdateSelectionArea(aFuncMark, nullptr, /*adjustHeight*/ false);
1017                 break;
1018             }
1019             case SID_ATTR_CHAR_OVERLINE:
1020             case SID_ATTR_CHAR_STRIKEOUT:
1021             case SID_ATTR_ALIGN_LINEBREAK:
1022             case SID_ATTR_CHAR_CONTOUR:
1023             case SID_ATTR_CHAR_SHADOWED:
1024             case SID_ATTR_CHAR_RELIEF:
1025                 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhichIDFromSlotID( nSlot ) ) );
1026                 rBindings.Invalidate( nSlot );
1027                 rBindings.Update( nSlot );
1028                 break;
1029             case SID_ATTR_CHAR_COLOR:
1030             case SID_SCATTR_PROTECTION :
1031             {
1032                 pTabViewShell->ApplyAttr( pNewAttrs->Get( pNewAttrs->GetPool()->GetWhichIDFromSlotID( nSlot) ), false);
1033 
1034                 rBindings.Invalidate( nSlot );
1035                 rBindings.Update( nSlot );
1036             }
1037 
1038             break;
1039 
1040             case SID_ATTR_CHAR_FONT:
1041             case SID_ATTR_CHAR_FONTHEIGHT:
1042                 {
1043                     // #i78017 establish the same behaviour as in Writer
1044                     SvtScriptType nScript = SvtScriptType::LATIN | SvtScriptType::ASIAN | SvtScriptType::COMPLEX;
1045                     if (nSlot == SID_ATTR_CHAR_FONT)
1046                         nScript = pTabViewShell->GetSelectionScriptType();
1047 
1048                     SfxItemPool& rPool = GetPool();
1049                     SvxScriptSetItem aSetItem( nSlot, rPool );
1050                     sal_uInt16 nWhich = rPool.GetWhichIDFromSlotID( nSlot );
1051                     aSetItem.PutItemForScriptType( nScript, pNewAttrs->Get( nWhich ) );
1052 
1053                     pTabViewShell->ApplyUserItemSet( aSetItem.GetItemSet() );
1054 
1055                     rBindings.Invalidate( nSlot );
1056                     rBindings.Update( nSlot );
1057                 }
1058                 break;
1059 
1060             case SID_FRAME_LINESTYLE:
1061                 {
1062                     // Update default line
1063                     ::editeng::SvxBorderLine aLine;
1064                     const ::editeng::SvxBorderLine* pLine = nullptr;
1065                     const SfxInt16Item* lineStyleItem = rReq.GetArg<SfxInt16Item>(FN_PARAM_1);
1066 
1067                     if (lineStyleItem)
1068                     {
1069                         const SfxInt16Item* InnerLineWidthItem
1070                             = rReq.GetArg<SfxInt16Item>(FN_PARAM_2);
1071                         const SfxInt16Item* OuterLineWidthItem
1072                             = rReq.GetArg<SfxInt16Item>(FN_PARAM_3);
1073                         const SfxInt16Item* LineDistanceItem
1074                             = rReq.GetArg<SfxInt16Item>(FN_PARAM_4);
1075 
1076                         sal_uInt16 InnerLineWidth, OuterLineWidth, LineDistance;
1077                         SvxBorderLineStyle lineStyle
1078                             = static_cast<SvxBorderLineStyle>(lineStyleItem->GetValue());
1079                         InnerLineWidth = InnerLineWidthItem ? InnerLineWidthItem->GetValue() : 0;
1080                         OuterLineWidth = OuterLineWidthItem ? OuterLineWidthItem->GetValue() : 0;
1081                         LineDistance = LineDistanceItem ? LineDistanceItem->GetValue() : 0;
1082 
1083                         aLine.GuessLinesWidths(
1084                             lineStyle, InnerLineWidth, OuterLineWidth, LineDistance);
1085 
1086                         pLine = &aLine;
1087                     }
1088                     else
1089                     {
1090                         pLine = pNewAttrs->Get(SID_FRAME_LINESTYLE).GetLine();
1091                     }
1092 
1093                     if ( pLine )
1094                     {
1095                         ::editeng::SvxBorderLine* pDefLine = pTabViewShell->GetDefaultFrameLine();
1096 
1097                         if ( pDefLine )
1098                         {
1099                             pDefLine->SetBorderLineStyle(
1100                                     pLine->GetBorderLineStyle());
1101                             pDefLine->SetWidth( pLine->GetWidth( ) );
1102                             pTabViewShell->SetSelectionFrameLines( pDefLine, false );
1103                         }
1104                         else
1105                         {
1106                             pTabViewShell->SetDefaultFrameLine( pLine );
1107                             pTabViewShell->GetDefaultFrameLine()->SetColor( COL_BLACK );
1108                             pTabViewShell->SetSelectionFrameLines( pLine, false );
1109                         }
1110                     }
1111                     else
1112                     {
1113                         Color           aColorBlack( COL_BLACK );
1114                         ::editeng::SvxBorderLine aDefLine( &aColorBlack, 20,
1115                                 SvxBorderLineStyle::SOLID );
1116                         pTabViewShell->SetDefaultFrameLine( &aDefLine );
1117                         pTabViewShell->SetSelectionFrameLines( nullptr, false );
1118                     }
1119                     rReq.Done();
1120                 }
1121                 break;
1122 
1123             case SID_FRAME_LINECOLOR:
1124                 {
1125                     ::editeng::SvxBorderLine*  pDefLine = pTabViewShell->GetDefaultFrameLine();
1126 
1127                     Color aColor = pNewAttrs->Get( SID_FRAME_LINECOLOR ).GetValue();
1128 
1129                     // Update default line
1130                     if ( pDefLine )
1131                     {
1132                         pDefLine->SetColor( aColor );
1133                         pTabViewShell->SetSelectionFrameLines( pDefLine, true );
1134                     }
1135                     else
1136                     {
1137                         ::editeng::SvxBorderLine aDefLine( &aColor, 20, SvxBorderLineStyle::SOLID );
1138                         pTabViewShell->SetDefaultFrameLine( &aDefLine );
1139                         pTabViewShell->SetSelectionFrameLines( &aDefLine, false );
1140                     }
1141                 }
1142                 break;
1143 
1144             case SID_ATTR_BORDER_OUTER:
1145             case SID_ATTR_BORDER:
1146                 {
1147                     ::editeng::SvxBorderLine*          pDefLine = pTabViewShell->GetDefaultFrameLine();
1148                     const ScPatternAttr*    pOldAttrs = pTabViewShell->GetSelectionPattern();
1149                     SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aOldSet( *rDoc.GetPool() );
1150                     SfxItemSetFixed<ATTR_PATTERN_START, ATTR_PATTERN_END> aNewSet( *rDoc.GetPool() );
1151                     const SfxPoolItem&      rBorderAttr =
1152                                                 pOldAttrs->GetItemSet().
1153                                                     Get( ATTR_BORDER );
1154 
1155                     // Evaluate border items from controller:
1156 
1157                     if ( const SvxBoxItem* pBoxItem = pNewAttrs->GetItemIfSet( ATTR_BORDER ) )
1158                     {
1159                         //  The SvxFrameToolBoxControl toolbox controller uses a default
1160                         //  SvxBorderLine (all widths 0) to mark the lines that should be set.
1161                         //  Macro recording uses a SvxBoxItem with the real values (OutWidth > 0)
1162                         //  or NULL pointers for no lines.
1163                         //  -> Substitute existing lines with pDefLine only if widths are 0.
1164                         SvxBoxItem aBoxItem ( *pBoxItem );
1165                         if ( aBoxItem.GetTop() && aBoxItem.GetTop()->GetOutWidth() == 0 )
1166                             aBoxItem.SetLine( pDefLine, SvxBoxItemLine::TOP );
1167                         if ( aBoxItem.GetBottom() && aBoxItem.GetBottom()->GetOutWidth() == 0 )
1168                             aBoxItem.SetLine( pDefLine, SvxBoxItemLine::BOTTOM );
1169                         if ( aBoxItem.GetLeft() && aBoxItem.GetLeft()->GetOutWidth() == 0 )
1170                             aBoxItem.SetLine( pDefLine, SvxBoxItemLine::LEFT );
1171                         if ( aBoxItem.GetRight() && aBoxItem.GetRight()->GetOutWidth() == 0 )
1172                             aBoxItem.SetLine( pDefLine, SvxBoxItemLine::RIGHT );
1173                         aNewSet.Put( aBoxItem );
1174                         rReq.AppendItem( aBoxItem );
1175                     }
1176 
1177                     if ( const SvxBoxInfoItem* pBoxInfoItem = pNewAttrs->GetItemIfSet( ATTR_BORDER_INNER ) )
1178                     {
1179                         SvxBoxInfoItem aBoxInfoItem( *pBoxInfoItem );
1180                         if ( aBoxInfoItem.GetHori() && aBoxInfoItem.GetHori()->GetOutWidth() == 0 )
1181                             aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::HORI );
1182                         if ( aBoxInfoItem.GetVert() && aBoxInfoItem.GetVert()->GetOutWidth() == 0 )
1183                             aBoxInfoItem.SetLine( pDefLine, SvxBoxInfoItemLine::VERT );
1184                         aNewSet.Put( aBoxInfoItem );
1185                         rReq.AppendItem( aBoxInfoItem );
1186                     }
1187                     else
1188                     {
1189                         SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
1190                         aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::HORI );
1191                         aBoxInfoItem.SetLine( nullptr, SvxBoxInfoItemLine::VERT );
1192                         aNewSet.Put( aBoxInfoItem );
1193                     }
1194 
1195                     aOldSet.Put( rBorderAttr );
1196                     pTabViewShell->ApplyAttributes( aNewSet, aOldSet );
1197                 }
1198                 break;
1199 
1200             case SID_ATTR_BORDER_DIAG_TLBR:
1201             case SID_ATTR_BORDER_DIAG_BLTR:
1202                 {
1203                     const ScPatternAttr* pOldAttrs = pTabViewShell->GetSelectionPattern();
1204                     SfxItemSet aOldSet(pOldAttrs->GetItemSet());
1205                     SfxItemSet aNewSet(aOldSet);
1206 
1207                     if(SID_ATTR_BORDER_DIAG_TLBR == nSlot)
1208                     {
1209                         if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_TLBR))
1210                         {
1211                             SvxLineItem aItem(ATTR_BORDER_TLBR);
1212                             aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_TLBR).GetLine());
1213                             aNewSet.Put(aItem);
1214                             rReq.AppendItem(aItem);
1215                             pTabViewShell->ApplyAttributes(aNewSet, aOldSet);
1216                         }
1217                     }
1218                     else // if( nSlot == SID_ATTR_BORDER_DIAG_BLTR )
1219                     {
1220                         if(SfxItemState::SET == pNewAttrs->GetItemState(ATTR_BORDER_BLTR ))
1221                         {
1222                             SvxLineItem aItem(ATTR_BORDER_BLTR);
1223                             aItem.SetLine(pNewAttrs->Get(ATTR_BORDER_BLTR).GetLine());
1224                             aNewSet.Put(aItem);
1225                             rReq.AppendItem(aItem);
1226                             pTabViewShell->ApplyAttributes(aNewSet, aOldSet);
1227                         }
1228                     }
1229 
1230                     rBindings.Invalidate(nSlot);
1231                 }
1232                 break;
1233 
1234             // ATTR_BACKGROUND (=SID_ATTR_BRUSH) has to be set to two IDs:
1235             case SID_BACKGROUND_COLOR:
1236                 {
1237                     const SvxColorItem&  rNewColorItem = pNewAttrs->Get( SID_BACKGROUND_COLOR );
1238                     Color aColor = rNewColorItem.GetValue();
1239 
1240                     SvxBrushItem aBrushItem(
1241                         pTabViewShell->GetSelectionPattern()->GetItem( ATTR_BACKGROUND ) );
1242                     aBrushItem.SetColor(aColor);
1243                     aBrushItem.setComplexColor(rNewColorItem.getComplexColor());
1244 
1245                     pTabViewShell->ApplyAttr( aBrushItem, false );
1246                 }
1247                 break;
1248 
1249                 case SID_ATTR_BRUSH:
1250                 {
1251                     SvxBrushItem        aBrushItem( pTabViewShell->GetSelectionPattern()->
1252                                                 GetItem( ATTR_BACKGROUND ) );
1253                     const SvxBrushItem& rNewBrushItem = static_cast<const SvxBrushItem&>(
1254                                             pNewAttrs->Get( GetPool().GetWhichIDFromSlotID(nSlot) ) );
1255                     aBrushItem.SetColor(rNewBrushItem.GetColor());
1256                     aBrushItem.setComplexColor(rNewBrushItem.getComplexColor());
1257                     pTabViewShell->ApplyAttr( aBrushItem );
1258                 }
1259                 break;
1260 
1261             case SID_ATTR_BORDER_SHADOW:
1262                 {
1263                     const SvxShadowItem& rNewShadowItem =
1264                                             pNewAttrs->Get( ATTR_SHADOW );
1265                     pTabViewShell->ApplyAttr( rNewShadowItem );
1266                 }
1267                 break;
1268 
1269             default:
1270             break;
1271         }
1272 
1273         if( ! rReq.IsAPI() && ! rReq.IsDone() )
1274             rReq.Done();
1275     }
1276 }
1277 
GetAttrState(SfxItemSet & rSet)1278 void ScFormatShell::GetAttrState( SfxItemSet& rSet )
1279 {
1280     ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
1281     const SfxItemSet&    rAttrSet   = pTabViewShell->GetSelectionPattern()->GetItemSet();
1282     const SvxBrushItem&  rBrushItem = rAttrSet.Get( ATTR_BACKGROUND );
1283     SfxWhichIter aIter( rSet );
1284     sal_uInt16 nWhich = aIter.FirstWhich();
1285 
1286     rSet.Put( rAttrSet, false );
1287 
1288     //  choose font info according to selection script type
1289     SvtScriptType nScript = SvtScriptType::NONE;      // GetSelectionScriptType never returns 0
1290     if ( rSet.GetItemState( ATTR_FONT ) != SfxItemState::UNKNOWN )
1291     {
1292         nScript = pTabViewShell->GetSelectionScriptType();
1293         ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT, nScript );
1294     }
1295     if ( rSet.GetItemState( ATTR_FONT_HEIGHT ) != SfxItemState::UNKNOWN )
1296     {
1297         if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType();
1298         ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_HEIGHT, nScript );
1299     }
1300 
1301     while ( nWhich )
1302     {
1303         switch(nWhich)
1304         {
1305             case SID_BACKGROUND_COLOR:
1306             {
1307                 rSet.Put( SvxColorItem( rBrushItem.GetColor(), SID_BACKGROUND_COLOR ) );
1308                 if(SfxItemState::INVALID == rAttrSet.GetItemState(ATTR_BACKGROUND))
1309                 {
1310                     rSet.InvalidateItem(SID_BACKGROUND_COLOR);
1311                 }
1312             }
1313             break;
1314             case SID_FRAME_LINESTYLE:
1315             case SID_FRAME_LINECOLOR:
1316             {
1317                 // handled together because both need the cell border information for decisions
1318                 Color aCol;
1319                 editeng::SvxBorderLine aLine(nullptr,0,SvxBorderLineStyle::SOLID);
1320                 bool bCol = false;
1321                 bool bColDisable = false, bStyleDisable = false;
1322                 std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER));
1323                 std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
1324 
1325                 pTabViewShell->GetSelectionFrame(aBoxItem, aInfoItem);
1326 
1327                 if( aBoxItem->GetTop() )
1328                 {
1329                     bCol = true;
1330                     aCol = aBoxItem->GetTop()->GetColor() ;
1331                     aLine.SetColor(aCol);
1332                     aLine.SetWidth( aBoxItem->GetTop()->GetWidth());
1333                     aLine.SetBorderLineStyle( aBoxItem->GetTop()->GetBorderLineStyle());
1334                 }
1335 
1336                 if( aBoxItem->GetBottom() )
1337                 {
1338                     if(!bCol)
1339                     {
1340                         bCol = true;
1341                         aCol = aBoxItem->GetBottom()->GetColor() ;
1342                         aLine.SetColor(aCol);
1343                         aLine.SetWidth( aBoxItem->GetBottom()->GetWidth());
1344                         aLine.SetBorderLineStyle( aBoxItem->GetBottom()->GetBorderLineStyle());
1345                     }
1346                     else
1347                     {
1348                         if(aCol != aBoxItem->GetBottom()->GetColor() )
1349                             bColDisable = true;
1350                         if( aLine != *aBoxItem->GetBottom() )
1351                             bStyleDisable = true;
1352                     }
1353                 }
1354 
1355                 if( aBoxItem->GetLeft() )
1356                 {
1357                     if(!bCol)
1358                     {
1359                         bCol = true;
1360                         aCol = aBoxItem->GetLeft()->GetColor() ;
1361                         aLine.SetColor(aCol);
1362                         aLine.SetWidth( aBoxItem->GetLeft()->GetWidth());
1363                         aLine.SetBorderLineStyle( aBoxItem->GetLeft()->GetBorderLineStyle());
1364                     }
1365                     else
1366                     {
1367                         if(aCol != aBoxItem->GetLeft()->GetColor() )
1368                             bColDisable = true;
1369                         if( aLine != *aBoxItem->GetLeft() )
1370                             bStyleDisable = true;
1371                     }
1372                 }
1373 
1374                 if( aBoxItem->GetRight() )
1375                 {
1376                     if(!bCol)
1377                     {
1378                         bCol = true;
1379                         aCol = aBoxItem->GetRight()->GetColor() ;
1380                         aLine.SetColor(aCol);
1381                         aLine.SetWidth( aBoxItem->GetRight()->GetWidth());
1382                         aLine.SetBorderLineStyle( aBoxItem->GetRight()->GetBorderLineStyle());
1383                     }
1384                     else
1385                     {
1386                         if(aCol != aBoxItem->GetRight()->GetColor() )
1387                             bColDisable = true;
1388                         if( aLine != *aBoxItem->GetRight() )
1389                             bStyleDisable = true;
1390                     }
1391                 }
1392 
1393                 if( aInfoItem->GetVert())
1394                 {
1395                     if(!bCol)
1396                     {
1397                         bCol = true;
1398                         aCol = aInfoItem->GetVert()->GetColor() ;
1399                         aLine.SetColor(aCol);
1400                         aLine.SetWidth( aInfoItem->GetVert()->GetWidth());
1401                         aLine.SetBorderLineStyle( aInfoItem->GetVert()->GetBorderLineStyle());
1402                     }
1403                     else
1404                     {
1405                         if(aCol != aInfoItem->GetVert()->GetColor() )
1406                             bColDisable = true;
1407                         if( aLine != *aInfoItem->GetVert() )
1408                             bStyleDisable = true;
1409                     }
1410                 }
1411 
1412                 if( aInfoItem->GetHori())
1413                 {
1414                     if(!bCol)
1415                     {
1416                         bCol = true;
1417                         aCol = aInfoItem->GetHori()->GetColor() ;
1418                         aLine.SetColor(aCol);
1419                         aLine.SetWidth( aInfoItem->GetHori()->GetWidth());
1420                         aLine.SetBorderLineStyle( aInfoItem->GetHori()->GetBorderLineStyle());
1421                     }
1422                     else
1423                     {
1424                         if(aCol != aInfoItem->GetHori()->GetColor() )
1425                             bColDisable = true;
1426                         if( aLine != *aInfoItem->GetHori() )
1427                             bStyleDisable = true;
1428                     }
1429                 }
1430 
1431                 if( !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT )
1432                     || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI )
1433                     || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT )
1434                     || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT )
1435                     || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP )
1436                     || !aInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) )
1437                 {
1438                     bColDisable = true;
1439                     bStyleDisable = true;
1440                 }
1441 
1442                 if(SID_FRAME_LINECOLOR == nWhich)
1443                 {
1444                     if(bColDisable) // if different lines have different colors
1445                     {
1446                         aCol = COL_TRANSPARENT;
1447                         rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1448                         rSet.InvalidateItem(SID_FRAME_LINECOLOR);
1449                     }
1450                     else if (!bCol) // if no line available
1451                     {
1452                         aCol = COL_AUTO;
1453                         rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1454                     }
1455                     else
1456                         rSet.Put( SvxColorItem(aCol, SID_FRAME_LINECOLOR ) );
1457                 }
1458                 else // if( nWhich == SID_FRAME_LINESTYLE)
1459                 {
1460                     if(bStyleDisable) // if have several lines but don't have same style
1461                     {
1462                         aLine.SetWidth( 1 );
1463                         SvxLineItem aItem(SID_FRAME_LINESTYLE);
1464                         aItem.SetLine(&aLine);
1465                         rSet.Put( aItem );
1466                         rSet.InvalidateItem(SID_FRAME_LINESTYLE);
1467                     }
1468                     else // all the lines have same style or no line available, use initial value (0,0,0,0)
1469                     {
1470                         SvxLineItem aItem(SID_FRAME_LINESTYLE);
1471                         aItem.SetLine(&aLine);
1472                         rSet.Put( aItem );
1473                         if (!aLine.GetWidth())
1474                             rSet.DisableItem(SID_FRAME_LINESTYLE);
1475                     }
1476                 }
1477             }
1478             break;
1479             case SID_ATTR_BRUSH:
1480             {
1481                 rSet.Put( rBrushItem.CloneSetWhich(GetPool().GetWhichIDFromSlotID(nWhich)) );
1482             }
1483             break;
1484             case SID_SCATTR_CELLPROTECTION:
1485             {
1486                 bool bProtect = rAttrSet.Get( ATTR_PROTECTION ).GetProtection();
1487                 rSet.Put( SfxBoolItem(SID_SCATTR_CELLPROTECTION, bProtect) );
1488             }
1489             break;
1490         }
1491         nWhich = aIter.NextWhich();
1492     }
1493 
1494     // stuff for sidebar panels
1495     Invalidate(SID_ATTR_ALIGN_DEGREES);
1496     Invalidate(SID_ATTR_ALIGN_LOCKPOS);
1497     Invalidate(SID_ATTR_ALIGN_STACKED);
1498 }
1499 
GetTextAttrState(SfxItemSet & rSet)1500 void ScFormatShell::GetTextAttrState( SfxItemSet& rSet )
1501 {
1502     ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
1503     const SfxItemSet& rAttrSet  = pTabViewShell->GetSelectionPattern()->GetItemSet();
1504     rSet.Put( rAttrSet, false ); // Include ItemStates in copy
1505 
1506     //  choose font info according to selection script type
1507     SvtScriptType nScript = SvtScriptType::NONE;      // GetSelectionScriptType never returns 0
1508     if ( rSet.GetItemState( ATTR_FONT_WEIGHT ) != SfxItemState::UNKNOWN )
1509     {
1510         nScript = pTabViewShell->GetSelectionScriptType();
1511         ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_WEIGHT, nScript );
1512     }
1513     if ( rSet.GetItemState( ATTR_FONT_POSTURE ) != SfxItemState::UNKNOWN )
1514     {
1515         if (nScript == SvtScriptType::NONE) nScript = pTabViewShell->GetSelectionScriptType();
1516         ScViewUtil::PutItemScript( rSet, rAttrSet, ATTR_FONT_POSTURE, nScript );
1517     }
1518 
1519     SfxItemState eState;
1520 
1521     // own control on radio button functionality:
1522 
1523     // underline
1524 
1525     eState = rAttrSet.GetItemState( ATTR_FONT_UNDERLINE );
1526     if ( eState == SfxItemState::INVALID )
1527     {
1528         rSet.InvalidateItem( SID_ULINE_VAL_NONE );
1529         rSet.InvalidateItem( SID_ULINE_VAL_SINGLE );
1530         rSet.InvalidateItem( SID_ULINE_VAL_DOUBLE );
1531         rSet.InvalidateItem( SID_ULINE_VAL_DOTTED );
1532     }
1533     else
1534     {
1535         FontLineStyle eUnderline =
1536                     rAttrSet.Get(ATTR_FONT_UNDERLINE).GetLineStyle();
1537         rSet.Put(SfxBoolItem(SID_ULINE_VAL_SINGLE, eUnderline == LINESTYLE_SINGLE));
1538         rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOUBLE, eUnderline == LINESTYLE_DOUBLE));
1539         rSet.Put(SfxBoolItem(SID_ULINE_VAL_DOTTED, eUnderline == LINESTYLE_DOTTED));
1540         rSet.Put(SfxBoolItem(SID_ULINE_VAL_NONE, eUnderline == LINESTYLE_NONE));
1541     }
1542 
1543     // horizontal alignment
1544 
1545     const SvxHorJustifyItem* pHorJustify = nullptr;
1546     const SvxVerJustifyItem* pVerJustify = nullptr;
1547     SvxCellVerJustify        eVerJustify = SvxCellVerJustify::Standard;
1548     sal_uInt16                   nWhich      = 0;
1549     bool                     bJustifyStd = false;
1550     SfxBoolItem              aBoolItem   ( 0, true );
1551 
1552     eState   = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY, true,
1553                                         reinterpret_cast<const SfxPoolItem**>(&pHorJustify) );
1554     switch ( eState )
1555     {
1556         case SfxItemState::SET:
1557             {
1558                 switch ( pHorJustify->GetValue() )
1559                 {
1560                     case SvxCellHorJustify::Standard:
1561                         break;
1562 
1563                     case SvxCellHorJustify::Left:
1564                         nWhich = SID_ALIGNLEFT;
1565                         break;
1566 
1567                     case SvxCellHorJustify::Right:
1568                         nWhich = SID_ALIGNRIGHT;
1569                         break;
1570 
1571                     case SvxCellHorJustify::Center:
1572                         nWhich = SID_ALIGNCENTERHOR;
1573                         break;
1574 
1575                     case SvxCellHorJustify::Block:
1576                         nWhich = SID_ALIGNBLOCK;
1577                         break;
1578 
1579                     case SvxCellHorJustify::Repeat:
1580                     default:
1581                         bJustifyStd = true;
1582                         break;
1583                 }
1584             }
1585             break;
1586 
1587         case SfxItemState::INVALID:
1588             rSet.InvalidateItem( SID_ALIGNLEFT );
1589             rSet.InvalidateItem( SID_ALIGNRIGHT );
1590             rSet.InvalidateItem( SID_ALIGNCENTERHOR );
1591             rSet.InvalidateItem( SID_ALIGNBLOCK );
1592             break;
1593 
1594         default:
1595             bJustifyStd = true;
1596             break;
1597     }
1598 
1599     if ( nWhich )
1600     {
1601         aBoolItem.SetWhich( nWhich );
1602         rSet.Put( aBoolItem );
1603     }
1604     else if ( bJustifyStd )
1605     {
1606         aBoolItem.SetValue( false );
1607         aBoolItem.SetWhich( SID_ALIGNLEFT );      rSet.Put( aBoolItem );
1608         aBoolItem.SetWhich( SID_ALIGNRIGHT );     rSet.Put( aBoolItem );
1609         aBoolItem.SetWhich( SID_ALIGNCENTERHOR ); rSet.Put( aBoolItem );
1610         aBoolItem.SetWhich( SID_ALIGNBLOCK );     rSet.Put( aBoolItem );
1611         bJustifyStd = false;
1612     }
1613 
1614     // vertical alignment
1615 
1616     nWhich = 0;
1617     aBoolItem.SetValue( true );
1618 
1619     eState = rAttrSet.GetItemState( ATTR_VER_JUSTIFY, true,
1620                                     reinterpret_cast<const SfxPoolItem**>(&pVerJustify) );
1621 
1622     switch ( eState )
1623     {
1624         case SfxItemState::SET:
1625             {
1626                 eVerJustify = pVerJustify->GetValue();
1627 
1628                 switch ( eVerJustify )
1629                 {
1630                     case SvxCellVerJustify::Top:
1631                         nWhich = SID_ALIGNTOP;
1632                         break;
1633 
1634                     case SvxCellVerJustify::Bottom:
1635                         nWhich = SID_ALIGNBOTTOM;
1636                         break;
1637 
1638                     case SvxCellVerJustify::Center:
1639                         nWhich = SID_ALIGNCENTERVER;
1640                         break;
1641 
1642                     case SvxCellVerJustify::Standard:
1643                     default:
1644                         bJustifyStd = true;
1645                         break;
1646                 }
1647             }
1648             break;
1649 
1650         case SfxItemState::INVALID:
1651             rSet.InvalidateItem( SID_ALIGNTOP );
1652             rSet.InvalidateItem( SID_ALIGNBOTTOM );
1653             rSet.InvalidateItem( SID_ALIGNCENTERVER );
1654             break;
1655 
1656         default:
1657             bJustifyStd = true;
1658             break;
1659     }
1660 
1661     if ( nWhich )
1662     {
1663         aBoolItem.SetWhich( nWhich );
1664         rSet.Put( aBoolItem );
1665     }
1666     else if ( bJustifyStd )
1667     {
1668         aBoolItem.SetValue( false );
1669         aBoolItem.SetWhich( SID_ALIGNTOP );       rSet.Put( aBoolItem );
1670         aBoolItem.SetWhich( SID_ALIGNBOTTOM );    rSet.Put( aBoolItem );
1671         aBoolItem.SetWhich( SID_ALIGNCENTERVER ); rSet.Put( aBoolItem );
1672     }
1673 }
1674 
GetBorderState(SfxItemSet & rSet)1675 void ScFormatShell::GetBorderState( SfxItemSet& rSet )
1676 {
1677     ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
1678     std::shared_ptr<SvxBoxItem> aBoxItem(std::make_shared<SvxBoxItem>(ATTR_BORDER));
1679     std::shared_ptr<SvxBoxInfoItem> aInfoItem(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));
1680 
1681     pTabViewShell->GetSelectionFrame( aBoxItem, aInfoItem );
1682 
1683     if ( rSet.GetItemState( ATTR_BORDER ) != SfxItemState::UNKNOWN )
1684         rSet.Put( *aBoxItem );
1685     if ( rSet.GetItemState( ATTR_BORDER_INNER ) != SfxItemState::UNKNOWN )
1686         rSet.Put( *aInfoItem );
1687 }
1688 
GetAlignState(SfxItemSet & rSet)1689 void ScFormatShell::GetAlignState( SfxItemSet& rSet )
1690 {
1691     ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
1692     const SfxItemSet& rAttrSet    = pTabViewShell->GetSelectionPattern()->GetItemSet();
1693     SfxWhichIter    aIter(rSet);
1694     sal_uInt16          nWhich = aIter.FirstWhich();
1695 
1696     SvxCellHorJustify eHAlign = SvxCellHorJustify::Standard;
1697     bool bHasHAlign = rAttrSet.GetItemState( ATTR_HOR_JUSTIFY ) != SfxItemState::INVALID;
1698     if( bHasHAlign )
1699         eHAlign = rAttrSet.Get( ATTR_HOR_JUSTIFY ).GetValue();
1700 
1701     SvxCellVerJustify eVAlign = SvxCellVerJustify::Standard;
1702     bool bHasVAlign = rAttrSet.GetItemState( ATTR_VER_JUSTIFY ) != SfxItemState::INVALID;
1703     if( bHasVAlign )
1704         eVAlign = rAttrSet.Get( ATTR_VER_JUSTIFY ).GetValue();
1705 
1706     while ( nWhich )
1707     {
1708         switch ( nWhich )
1709         {
1710             case SID_H_ALIGNCELL:
1711                 if ( bHasHAlign )
1712                     rSet.Put( SvxHorJustifyItem( eHAlign, nWhich ));
1713             break;
1714             case SID_V_ALIGNCELL:
1715                 if ( bHasVAlign )
1716                     rSet.Put( SvxVerJustifyItem( eVAlign, nWhich ));
1717             break;
1718 
1719             // pseudo slots for Format menu
1720             case SID_ALIGN_ANY_HDEFAULT:
1721             case SID_ALIGN_ANY_LEFT:
1722             case SID_ALIGN_ANY_HCENTER:
1723             case SID_ALIGN_ANY_RIGHT:
1724             case SID_ALIGN_ANY_JUSTIFIED:
1725                 rSet.Put( SfxBoolItem( nWhich, bHasHAlign && (eHAlign == lclConvertSlotToHAlign( nWhich )) ) );
1726             break;
1727             case SID_ALIGN_ANY_VDEFAULT:
1728             case SID_ALIGN_ANY_TOP:
1729             case SID_ALIGN_ANY_VCENTER:
1730             case SID_ALIGN_ANY_BOTTOM:
1731                 rSet.Put( SfxBoolItem( nWhich, bHasVAlign && (eVAlign == lclConvertSlotToVAlign( nWhich )) ) );
1732             break;
1733         }
1734         nWhich = aIter.NextWhich();
1735     }
1736 }
1737 
GetNumFormatState(SfxItemSet & rSet)1738 void ScFormatShell::GetNumFormatState( SfxItemSet& rSet )
1739 {
1740     ScTabViewShell* pTabViewShell   = GetViewData().GetViewShell();
1741     ScDocument& rDoc                = rViewData.GetDocument();
1742     const SfxItemSet& rAttrSet      = pTabViewShell->GetSelectionPattern()->GetItemSet();
1743     const SfxItemState eItemState   = rAttrSet.GetItemState( ATTR_VALUE_FORMAT );
1744     sal_uInt32 nNumberFormat        = rAttrSet.Get(ATTR_VALUE_FORMAT).GetValue();
1745     SvNumberFormatter* pFormatter   = rDoc.GetFormatTable();
1746                                       // If item state is default or set it
1747                                       // indicates one number format so we
1748                                       // don't have to iterate over all
1749                                       // selected cells' attribute ranges to
1750                                       // determine selected types.
1751                                       // Does *NOT* include the
1752                                       // SvNumFormatType::DEFINED bit.
1753     const SvNumFormatType nType     = (eItemState >= SfxItemState::DEFAULT ? pFormatter->GetType( nNumberFormat) :
1754                                        GetCurrentNumberFormatType());
1755     NfIndexTableOffset nOffset      = SvNumberFormatter::GetIndexTableOffset(nNumberFormat);
1756 
1757     SfxWhichIter aIter(rSet);
1758     sal_uInt16 nWhich = aIter.FirstWhich();
1759 
1760     while ( nWhich )
1761     {
1762         switch ( nWhich )
1763         {
1764             case SID_NUMBER_THOUSANDS:
1765                 {
1766                     bool bEnable = (SfxItemState::INVALID != eItemState);
1767                     if (bEnable)
1768                     {
1769                         bEnable = ((nType != SvNumFormatType::ALL) && (nType &
1770                                 (SvNumFormatType::NUMBER |
1771                                  SvNumFormatType::PERCENT |
1772                                  SvNumFormatType::CURRENCY |
1773                                  SvNumFormatType::FRACTION)));
1774                         if (bEnable)
1775                         {
1776                             bool bThousand( false );
1777                             bool bNegRed( false );
1778                             sal_uInt16 nPrecision( 0 );
1779                             sal_uInt16 nLeadZeroes( 0 );
1780                             pFormatter->GetFormatSpecialInfo( nNumberFormat, bThousand, bNegRed, nPrecision, nLeadZeroes);
1781                             rSet.Put( SfxBoolItem( nWhich, bThousand));
1782                         }
1783                     }
1784                     if (!bEnable)
1785                     {
1786                         rSet.DisableItem( nWhich );
1787                     }
1788                 }
1789                 break;
1790             case SID_NUMBER_FORMAT:
1791                 // symphony version with format interpretation
1792                 {
1793                     if(SfxItemState::INVALID != eItemState)
1794                     {
1795                         bool bThousand(false);
1796                         bool bNegRed(false);
1797                         sal_uInt16 nPrecision(0);
1798                         sal_uInt16 nLeadZeroes(0);
1799 
1800                         pFormatter->GetFormatSpecialInfo(nNumberFormat,bThousand, bNegRed, nPrecision, nLeadZeroes);
1801 
1802                         const SvNumberformat* pFormatEntry = pFormatter->GetEntry( nNumberFormat );
1803                         if (pFormatEntry && (pFormatEntry->GetType() & SvNumFormatType::SCIENTIFIC))
1804                         {
1805                             // if scientific, bThousand is used for engineering notation
1806                             const sal_uInt16 nIntegerDigits = pFormatEntry->GetFormatIntegerDigits();
1807                             bThousand = nIntegerDigits > 0 && ((nIntegerDigits % 3) == 0);
1808                         }
1809                         OUString aFormat;
1810                         static constexpr OUString sBreak = u","_ustr;
1811                         const OUString sThousand = OUString::number(static_cast<sal_Int32>(bThousand));
1812                         const OUString sNegRed = OUString::number(static_cast<sal_Int32>(bNegRed));
1813                         const OUString sPrecision = OUString::number(nPrecision);
1814                         const OUString sLeadZeroes = OUString::number(nLeadZeroes);
1815                         const OUString sNatNum12 = OUString::number( static_cast< sal_Int32 >( pFormatter->IsNatNum12( nNumberFormat ) ) );
1816 
1817                         aFormat += sThousand +
1818                             sBreak +
1819                             sNegRed +
1820                             sBreak +
1821                             sPrecision +
1822                             sBreak +
1823                             sLeadZeroes +
1824                             sBreak +
1825                             sNatNum12 +
1826                             sBreak;
1827 
1828                         rSet.Put(SfxStringItem(nWhich, aFormat));
1829 
1830                         if (comphelper::LibreOfficeKit::isActive())
1831                         {
1832                             OUString sPayload = ".uno:NumberFormat=" + aFormat;
1833                             GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED,
1834                                 OUStringToOString(sPayload, RTL_TEXTENCODING_ASCII_US));
1835                         }
1836                     }
1837                     else
1838                     {
1839                         rSet.InvalidateItem( nWhich );
1840                     }
1841                 }
1842                 break;
1843 
1844             case SID_NUMBER_TYPE_FORMAT:
1845                 {
1846                     sal_Int16 nFormatCategory = -1;
1847                     if ( eItemState >= SfxItemState::DEFAULT ) //Modify for more robust
1848                     {
1849                         switch(nType)
1850                         {
1851                         case SvNumFormatType::NUMBER:
1852                             // Determine if General format.
1853                             if ((nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0)
1854                                 nFormatCategory = 0;
1855                             else
1856                                 nFormatCategory = 1;
1857                             break;
1858                         case SvNumFormatType::PERCENT:
1859                             nFormatCategory = 2;
1860                             break;
1861                         case SvNumFormatType::CURRENCY:
1862                             nFormatCategory = 3;
1863                             break;
1864                         case SvNumFormatType::DATE:
1865                             //Add
1866                         case SvNumFormatType::DATETIME:
1867                             nFormatCategory = 4;
1868                             break;
1869                         case SvNumFormatType::TIME:
1870                             nFormatCategory = 5;
1871                             break;
1872                         case SvNumFormatType::SCIENTIFIC:
1873                             nFormatCategory = 6;
1874                             break;
1875                         case SvNumFormatType::FRACTION:
1876                             nFormatCategory = 7;
1877                             break;
1878                         case SvNumFormatType::LOGICAL:
1879                             nFormatCategory = 8;
1880                             break;
1881                         case SvNumFormatType::TEXT:
1882                             nFormatCategory = 9;
1883                             break;
1884                         default:
1885                             nFormatCategory = -1;   //for more robust
1886                         }
1887                         if( nFormatCategory == -1 )
1888                             rSet.InvalidateItem( nWhich );
1889                         else
1890                             rSet.Put( SfxUInt16Item( nWhich, nFormatCategory ) );
1891                     }
1892                     else
1893                     {
1894                         rSet.InvalidateItem( nWhich );
1895                     }
1896 
1897                 }
1898                 break;
1899             case SID_NUMBER_CURRENCY:
1900                 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::CURRENCY)) );
1901                 break;
1902             case SID_NUMBER_SCIENTIFIC:
1903                 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::SCIENTIFIC)) );
1904                 break;
1905             case SID_NUMBER_DATE:
1906                 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::DATE)) );
1907                 break;
1908             case SID_NUMBER_PERCENT:
1909                 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::PERCENT)) );
1910                 break;
1911             case SID_NUMBER_TIME:
1912                 rSet.Put( SfxBoolItem(nWhich, bool(nType & SvNumFormatType::TIME)) );
1913                 break;
1914             case SID_NUMBER_TWODEC:
1915                     rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && nOffset == NF_NUMBER_1000DEC2 ) );
1916                 break;
1917             case SID_NUMBER_STANDARD:
1918                     rSet.Put( SfxBoolItem(nWhich, (nType & SvNumFormatType::NUMBER) && (nNumberFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0) );
1919                 break;
1920         }
1921         nWhich = aIter.NextWhich();
1922     }
1923 }
1924 
ExecuteTextDirection(const SfxRequest & rReq)1925 void ScFormatShell::ExecuteTextDirection( const SfxRequest& rReq )
1926 {
1927     ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1928     pTabViewShell->HideListBox();               // Autofilter-DropDown-Listbox
1929     bool bEditMode = false;
1930     if ( GetViewData().HasEditView( GetViewData().GetActivePart() ) )
1931     {
1932         bEditMode=true;
1933         ScModule::get()->InputEnterHandler();
1934         pTabViewShell->UpdateInputHandler();
1935     }
1936     sal_uInt16 nSlot = rReq.GetSlot();
1937     switch( nSlot )
1938     {
1939         case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
1940         case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
1941         {
1942             bool bVert = (nSlot == SID_TEXTDIRECTION_TOP_TO_BOTTOM);
1943             ScPatternAttr aAttr(GetViewData().GetDocument().getCellAttributeHelper());
1944             aAttr.ItemSetPut(ScVerticalStackCell(bVert));
1945             aAttr.ItemSetPut(SfxBoolItem(ATTR_VERTICAL_ASIAN, bVert));
1946             pTabViewShell->ApplySelectionPattern( aAttr );
1947             pTabViewShell->AdjustBlockHeight();
1948         }
1949         break;
1950 
1951         case SID_ATTR_PARA_LEFT_TO_RIGHT:
1952         case SID_ATTR_PARA_RIGHT_TO_LEFT:
1953         {
1954             SvxFrameDirection eDirection = ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT ) ?
1955                                                 SvxFrameDirection::Horizontal_LR_TB : SvxFrameDirection::Horizontal_RL_TB;
1956             pTabViewShell->ApplyAttr( SvxFrameDirectionItem( eDirection, ATTR_WRITINGDIR ) );
1957         }
1958         break;
1959     }
1960     if (bEditMode)
1961         ScModule::get()->SetInputMode(SC_INPUT_TABLE);
1962 }
1963 
GetTextDirectionState(SfxItemSet & rSet)1964 void ScFormatShell::GetTextDirectionState( SfxItemSet& rSet )
1965 {
1966     ScTabViewShell* pTabViewShell = GetViewData().GetViewShell();
1967     const SfxItemSet& rAttrSet = pTabViewShell->GetSelectionPattern()->GetItemSet();
1968 
1969     bool bVertDontCare =
1970         (rAttrSet.GetItemState( ATTR_VERTICAL_ASIAN ) == SfxItemState::INVALID) ||
1971         (rAttrSet.GetItemState( ATTR_STACKED ) == SfxItemState::INVALID);
1972     bool bLeftRight = !bVertDontCare &&
1973         !rAttrSet.Get( ATTR_STACKED ).GetValue();
1974     bool bTopBottom = !bVertDontCare && !bLeftRight &&
1975         rAttrSet.Get( ATTR_VERTICAL_ASIAN ).GetValue();
1976 
1977     bool bBidiDontCare = (rAttrSet.GetItemState( ATTR_WRITINGDIR ) == SfxItemState::INVALID);
1978     EEHorizontalTextDirection eBidiDir = EEHorizontalTextDirection::Default;
1979     if ( !bBidiDontCare )
1980     {
1981         SvxFrameDirection eCellDir = rAttrSet.Get( ATTR_WRITINGDIR ).GetValue();
1982         if ( eCellDir == SvxFrameDirection::Environment )
1983             eBidiDir = GetViewData().GetDocument().
1984                                 GetEditTextDirection( GetViewData().GetTabNo() );
1985         else if ( eCellDir == SvxFrameDirection::Horizontal_RL_TB )
1986             eBidiDir = EEHorizontalTextDirection::R2L;
1987         else
1988             eBidiDir = EEHorizontalTextDirection::L2R;
1989     }
1990 
1991     bool bDisableCTLFont = !SvtCTLOptions::IsCTLFontEnabled();
1992     bool bDisableVerticalText = !SvtCJKOptions::IsVerticalTextEnabled();
1993 
1994     SfxWhichIter aIter( rSet );
1995     sal_uInt16 nWhich = aIter.FirstWhich();
1996     while( nWhich )
1997     {
1998         switch( nWhich )
1999         {
2000             case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
2001             case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
2002                 if ( bDisableVerticalText )
2003                     rSet.DisableItem( nWhich );
2004                 else
2005                 {
2006                     if( bVertDontCare )
2007                         rSet.InvalidateItem( nWhich );
2008                     else if ( nWhich == SID_TEXTDIRECTION_LEFT_TO_RIGHT )
2009                         rSet.Put( SfxBoolItem( nWhich, bLeftRight ) );
2010                     else
2011                         rSet.Put( SfxBoolItem( nWhich, bTopBottom ) );
2012                 }
2013             break;
2014 
2015             case SID_ATTR_PARA_LEFT_TO_RIGHT:
2016             case SID_ATTR_PARA_RIGHT_TO_LEFT:
2017                 if ( bDisableCTLFont )
2018                     rSet.DisableItem( nWhich );
2019                 else
2020                 {
2021                     if ( bTopBottom )
2022                         rSet.DisableItem( nWhich );
2023                     else if ( bBidiDontCare )
2024                         rSet.InvalidateItem( nWhich );
2025                     else if ( nWhich == SID_ATTR_PARA_LEFT_TO_RIGHT )
2026                         rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::L2R ) );
2027                     else
2028                         rSet.Put( SfxBoolItem( nWhich, eBidiDir == EEHorizontalTextDirection::R2L ) );
2029                 }
2030         }
2031         nWhich = aIter.NextWhich();
2032     }
2033 }
2034 
ExecFormatPaintbrush(const SfxRequest & rReq)2035 void ScFormatShell::ExecFormatPaintbrush( const SfxRequest& rReq )
2036 {
2037     ScViewFunc* pView = rViewData.GetView();
2038     if ( pView->HasPaintBrush() )
2039     {
2040         // cancel paintbrush mode
2041         pView->ResetBrushDocument();
2042     }
2043     else
2044     {
2045         bool bLock = false;
2046         const SfxItemSet *pArgs = rReq.GetArgs();
2047         if( pArgs && pArgs->Count() >= 1 )
2048             bLock = pArgs->Get(SID_FORMATPAINTBRUSH).GetValue();
2049 
2050         // in case of multi selection, deselect all and use the cursor position
2051         ScRange aDummy;
2052         if ( rViewData.GetSimpleArea(aDummy) != SC_MARK_SIMPLE )
2053             pView->Unmark();
2054 
2055         ScDocumentUniquePtr pBrushDoc(new ScDocument( SCDOCMODE_CLIP ));
2056         pView->CopyToClip( pBrushDoc.get(), false, true );
2057         pView->SetBrushDocument( std::move(pBrushDoc), bLock );
2058     }
2059 }
2060 
StateFormatPaintbrush(SfxItemSet & rSet)2061 void ScFormatShell::StateFormatPaintbrush( SfxItemSet& rSet )
2062 {
2063     if ( rViewData.HasEditView( rViewData.GetActivePart() ) )
2064         rSet.DisableItem( SID_FORMATPAINTBRUSH );
2065     else
2066         rSet.Put( SfxBoolItem( SID_FORMATPAINTBRUSH, rViewData.GetView()->HasPaintBrush() ) );
2067 }
2068 
GetCurrentNumberFormatType()2069 SvNumFormatType ScFormatShell::GetCurrentNumberFormatType()
2070 {
2071     SvNumFormatType nType = SvNumFormatType::ALL;
2072     ScDocument& rDoc = GetViewData().GetDocument();
2073     ScMarkData aMark(GetViewData().GetMarkData());
2074     const SvNumberFormatter* pFormatter = rDoc.GetFormatTable();
2075     if (!pFormatter)
2076         return nType;
2077 
2078     // TODO: Find out how to get a selected table range in case multiple tables
2079     // are selected.  Currently we only check for the current active table.
2080 
2081     if ( aMark.IsMarked() || aMark.IsMultiMarked() )
2082     {
2083         aMark.MarkToMulti();
2084         const ScRange& aRange = aMark.GetMultiMarkArea();
2085         const ScMultiSel& rMultiSel = aMark.GetMultiSelData();
2086 
2087         SvNumFormatType nComboType = SvNumFormatType::ALL;
2088         bool bFirstItem = true;
2089         for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol)
2090         {
2091             if (!rMultiSel.HasMarks(nCol))
2092                 continue;
2093 
2094             SCROW nRow1, nRow2;
2095             ScMultiSelIter aMultiIter(rMultiSel, nCol);
2096             while (aMultiIter.Next(nRow1, nRow2))
2097             {
2098                 ScRange aColRange(nCol, nRow1, aRange.aStart.Tab());
2099                 aColRange.aEnd.SetRow(nRow2);
2100                 sal_uInt32 nNumFmt = rDoc.GetNumberFormat(aColRange);
2101                 SvNumFormatType nThisType = pFormatter->GetType(nNumFmt);
2102                 if (bFirstItem)
2103                 {
2104                     bFirstItem = false;
2105                     nComboType = nThisType;
2106                 }
2107                 else if (nComboType != nThisType)
2108                     // mixed number format type.
2109                     return SvNumFormatType::ALL;
2110             }
2111         }
2112         nType = nComboType;
2113     }
2114     else
2115     {
2116         sal_uInt32 nNumFmt = rDoc.GetNumberFormat( rViewData.GetCurX(), rViewData.GetCurY(),
2117                                rViewData.GetTabNo());
2118         nType = pFormatter->GetType( nNumFmt );
2119     }
2120     return nType;
2121 }
2122 
2123 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2124