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