1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/table/BorderLineStyle.hpp>
21 #include <officecfg/Office/Calc.hxx>
23 #include <comphelper/lok.hxx>
24 #include <editeng/boxitem.hxx>
25 #include <editeng/langitem.hxx>
26 #include <o3tl/temporary.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/request.hxx>
29 #include <sfx2/sfxdlg.hxx>
30 #include <sfx2/sidebar/Sidebar.hxx>
31 #include <sfx2/viewfrm.hxx>
32 #include <sfx2/dispatch.hxx>
33 #include <sfx2/newstyle.hxx>
34 #include <sfx2/tplpitem.hxx>
35 #include <svl/ilstitem.hxx>
36 #include <svl/numformat.hxx>
37 #include <svl/zformat.hxx>
38 #include <svl/int64item.hxx>
39 #include <svl/ptitem.hxx>
40 #include <svl/srchitem.hxx>
41 #include <svl/srchdefs.hxx>
42 #include <svl/stritem.hxx>
43 #include <svl/whiter.hxx>
44 #include <svx/numinf.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/xlndsit.hxx>
47 #include <svx/xlnstit.hxx>
48 #include <svx/xlnedit.hxx>
49 #include <svx/xflgrit.hxx>
50 #include <svx/xflftrit.hxx>
51 #include <svx/xflhtit.hxx>
52 #include <svx/zoomslideritem.hxx>
55 #include <appoptio.hxx>
57 #include <cellform.hxx>
58 #include <cellvalue.hxx>
59 #include <compiler.hxx>
61 #include <document.hxx>
62 #include <formulacell.hxx>
63 #include <globstr.hrc>
64 #include <inputhdl.hxx>
65 #include <inputwin.hxx>
66 #include <markdata.hxx>
67 #include <patattr.hxx>
69 #include <scabstdlg.hxx>
70 #include <scitems.hxx>
72 #include <scresid.hxx>
73 #include <stlpool.hxx>
74 #include <tabvwsh.hxx>
75 #include <tokenarray.hxx>
76 #include <viewdata.hxx>
77 #include <printfun.hxx>
78 #include <undostyl.hxx>
83 using namespace com::sun::star
;
85 bool ScTabViewShell::GetFunction( OUString
& rFuncStr
, FormulaError nErrCode
)
87 sal_uInt32 nFuncs
= ScModule::get()->GetAppOptions().GetStatusFunc();
88 ScViewData
& rViewData
= GetViewData();
89 ScMarkData
& rMark
= rViewData
.GetMarkData();
90 bool bIgnoreError
= (rMark
.IsMarked() || rMark
.IsMultiMarked());
92 for ( sal_uInt16 nFunc
= 0; nFunc
< 32; nFunc
++ )
94 if ( !(nFuncs
& (1U << nFunc
)) )
96 ScSubTotalFunc eFunc
= static_cast<ScSubTotalFunc
>(nFunc
);
98 if (bIgnoreError
&& (eFunc
== SUBTOTAL_FUNC_CNT
|| eFunc
== SUBTOTAL_FUNC_CNT2
))
99 nErrCode
= FormulaError::NONE
;
101 if (nErrCode
!= FormulaError::NONE
)
103 rFuncStr
= ScGlobal::GetLongErrorString(nErrCode
);
107 TranslateId pGlobStrId
;
110 case SUBTOTAL_FUNC_AVE
: pGlobStrId
= STR_FUN_TEXT_AVG
; break;
111 case SUBTOTAL_FUNC_CNT
: pGlobStrId
= STR_FUN_TEXT_COUNT
; break;
112 case SUBTOTAL_FUNC_CNT2
: pGlobStrId
= STR_FUN_TEXT_COUNT2
; break;
113 case SUBTOTAL_FUNC_MAX
: pGlobStrId
= STR_FUN_TEXT_MAX
; break;
114 case SUBTOTAL_FUNC_MIN
: pGlobStrId
= STR_FUN_TEXT_MIN
; break;
115 case SUBTOTAL_FUNC_SUM
: pGlobStrId
= STR_FUN_TEXT_SUM
; break;
116 case SUBTOTAL_FUNC_SELECTION_COUNT
: pGlobStrId
= STR_FUN_TEXT_SELECTION_COUNT
; break;
120 // added to avoid warnings
125 ScDocument
& rDoc
= rViewData
.GetDocument();
126 SCCOL nPosX
= rViewData
.GetCurX();
127 SCROW nPosY
= rViewData
.GetCurY();
128 SCTAB nTab
= rViewData
.GetTabNo();
130 OUString aStr
= ScResId(pGlobStrId
) + ": ";
132 ScAddress
aCursor( nPosX
, nPosY
, nTab
);
134 if ( rDoc
.GetSelectionFunction( eFunc
, aCursor
, rMark
, nVal
) )
140 // Number in the standard format, the other on the cursor position
141 ScInterpreterContext
& rContext
= rDoc
.GetNonThreadedContext();
142 sal_uInt32 nNumFmt
= 0;
143 if ( eFunc
!= SUBTOTAL_FUNC_CNT
&& eFunc
!= SUBTOTAL_FUNC_CNT2
&& eFunc
!= SUBTOTAL_FUNC_SELECTION_COUNT
)
145 // number format from attributes or formula
146 nNumFmt
= rDoc
.GetNumberFormat( nPosX
, nPosY
, nTab
);
147 // If the number format is time (without date) and the
148 // result is not within 24 hours, use a duration
149 // format. Summing date+time doesn't make much sense
150 // otherwise but we also don't want to display duration
151 // for a single date+time value.
152 if (nVal
< 0.0 || nVal
>= 1.0)
154 const SvNumberformat
* pFormat
= rContext
.NFGetFormatEntry(nNumFmt
);
155 if (pFormat
&& (pFormat
->GetType() == SvNumFormatType::TIME
))
156 nNumFmt
= rContext
.NFGetTimeFormat( nVal
, pFormat
->GetLanguage(), true);
162 rContext
.NFGetOutputString( nVal
, nNumFmt
, aValStr
, &pDummy
);
172 rFuncStr
+= "; " + aStr
;
176 return !rFuncStr
.isEmpty();
179 // Functions that are disabled, depending on the selection
182 // SID_DELETE_CONTENTS,
186 void ScTabViewShell::GetState( SfxItemSet
& rSet
)
188 ScViewData
& rViewData
= GetViewData();
189 ScDocument
& rDoc
= rViewData
.GetDocument();
190 ScDocShell
* pDocShell
= rViewData
.GetDocShell();
191 ScMarkData
& rMark
= rViewData
.GetMarkData();
192 SCCOL nPosX
= rViewData
.GetCurX();
193 SCROW nPosY
= rViewData
.GetCurY();
194 SCTAB nTab
= rViewData
.GetTabNo();
196 SfxViewFrame
& rThisFrame
= GetViewFrame();
197 bool bOle
= GetViewFrame().GetFrame().IsInPlace();
199 SCTAB nTabSelCount
= rMark
.GetSelectCount();
201 SfxWhichIter
aIter(rSet
);
202 sal_uInt16 nWhich
= aIter
.FirstWhich();
208 case FID_CHG_COMMENT
:
210 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
211 ScAddress
aPos( nPosX
, nPosY
, nTab
);
212 if ( pDocSh
->IsReadOnly() || !pDocSh
->GetChangeAction(aPos
) || pDocSh
->IsDocShared() )
213 rSet
.DisableItem( nWhich
);
217 case SID_OPENDLG_EDIT_PRINTAREA
:
218 case SID_ADD_PRINTAREA
:
219 case SID_DEFINE_PRINTAREA
:
221 if ( pDocShell
&& pDocShell
->IsDocShared() )
223 rSet
.DisableItem( nWhich
);
228 case SID_DELETE_PRINTAREA
:
229 if ( pDocShell
&& pDocShell
->IsDocShared() )
231 rSet
.DisableItem( nWhich
);
233 else if (rDoc
.IsPrintEntireSheet(nTab
))
234 rSet
.DisableItem(nWhich
);
237 case SID_STATUS_PAGESTYLE
:
239 GetViewData().GetDocShell()->GetStatePageStyle( rSet
, nTab
);
242 case SID_SEARCH_ITEM
:
244 SvxSearchItem
aItem(ScGlobal::GetSearchItem()); // make a copy.
245 // Search on current selection if a range is marked.
246 aItem
.SetSelection(rMark
.IsMarked());
251 case SID_SEARCH_OPTIONS
:
254 SearchOptionFlags nOptions
= SearchOptionFlags::ALL
;
256 // No replacement if ReadOnly
257 if (GetViewData().GetDocShell()->IsReadOnly())
258 nOptions
&= ~SearchOptionFlags( SearchOptionFlags::REPLACE
| SearchOptionFlags::REPLACE_ALL
);
259 rSet
.Put( SfxUInt16Item( nWhich
, static_cast<sal_uInt16
>(nOptions
) ) );
263 case SID_CURRENTCELL
:
265 ScAddress
aScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), 0 );
266 OUString
aAddr(aScAddress
.Format(ScRefFlags::ADDR_ABS
, nullptr, rDoc
.GetAddressConvention()));
267 SfxStringItem
aPosItem( SID_CURRENTCELL
, aAddr
);
269 rSet
.Put( aPosItem
);
274 // Table for Basic is 1-based
275 rSet
.Put( SfxUInt16Item( nWhich
, static_cast<sal_uInt16
>(GetViewData().GetTabNo()) + 1 ) );
279 rSet
.Put( SfxStringItem( nWhich
, GetViewData().GetDocShell()->GetTitle() ) );
282 case FID_TOGGLEINPUTLINE
:
284 sal_uInt16 nId
= ScInputWindowWrapper::GetChildWindowId();
286 if ( rThisFrame
.KnowsChildWindow( nId
) )
288 SfxChildWindow
* pWnd
= rThisFrame
.GetChildWindow( nId
);
289 rSet
.Put( SfxBoolItem( nWhich
, pWnd
!= nullptr ) );
292 rSet
.DisableItem( nWhich
);
296 case FID_DEL_MANUALBREAKS
:
297 if (!rDoc
.HasManualBreaks(nTab
))
298 rSet
.DisableItem( nWhich
);
301 case FID_RESET_PRINTZOOM
:
303 // disable if already set to default
305 OUString aStyleName
= rDoc
.GetPageStyle( nTab
);
306 ScStyleSheetPool
* pStylePool
= rDoc
.GetStyleSheetPool();
307 SfxStyleSheetBase
* pStyleSheet
= pStylePool
->Find( aStyleName
,
308 SfxStyleFamily::Page
);
309 OSL_ENSURE( pStyleSheet
, "PageStyle not found" );
312 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
313 sal_uInt16 nScale
= rStyleSet
.Get(ATTR_PAGE_SCALE
).GetValue();
314 sal_uInt16 nPages
= rStyleSet
.Get(ATTR_PAGE_SCALETOPAGES
).GetValue();
315 if ( nScale
== 100 && nPages
== 0 )
316 rSet
.DisableItem( nWhich
);
323 const Fraction
& rZoomY
= GetViewData().GetZoomY();
324 tools::Long nZoom
= tools::Long(rZoomY
* 100);
325 if (nZoom
>= MAXZOOM
)
326 rSet
.DisableItem(nWhich
);
331 const Fraction
& rZoomY
= GetViewData().GetZoomY();
332 tools::Long nZoom
= tools::Long(rZoomY
* 100);
333 if (nZoom
<= MINZOOM
)
334 rSet
.DisableItem(nWhich
);
341 rSet
.DisableItem( nWhich
);
344 const Fraction
& rOldY
= GetViewData().GetZoomY();
345 sal_uInt16 nZoom
= static_cast<sal_uInt16
>(tools::Long( rOldY
* 100 ));
346 rSet
.Put( SvxZoomItem( SvxZoomType::PERCENT
, nZoom
, TypedWhichId
<SvxZoomItem
>(nWhich
) ) );
350 case SID_ATTR_ZOOMSLIDER
:
353 rSet
.DisableItem( nWhich
);
356 const Fraction
& rOldY
= GetViewData().GetZoomY();
357 sal_uInt16 nCurrentZoom
= static_cast<sal_uInt16
>(tools::Long( rOldY
* 100 ));
361 SvxZoomSliderItem
aZoomSliderItem( nCurrentZoom
, MINZOOM
, MAXZOOM
, SID_ATTR_ZOOMSLIDER
);
362 aZoomSliderItem
.AddSnappingPoint( 100 );
363 rSet
.Put( aZoomSliderItem
);
369 case FID_FUNCTION_BOX
:
371 const bool bBoxOpen
= ::sfx2::sidebar::Sidebar::IsPanelVisible(u
"ScFunctionsPanel",
372 rThisFrame
.GetFrame().GetFrameInterface());
373 rSet
.Put(SfxBoolItem(nWhich
, bBoxOpen
));
377 case FID_TOGGLESYNTAX
:
378 rSet
.Put(SfxBoolItem(nWhich
, GetViewData().IsSyntaxMode()));
381 case FID_TOGGLECOLROWHIGHLIGHTING
:
382 rSet
.Put(SfxBoolItem(
384 officecfg::Office::Calc::Content::Display::ColumnRowHighlighting::get()));
387 case FID_TOGGLEHEADERS
:
388 rSet
.Put(SfxBoolItem(nWhich
, GetViewData().IsHeaderMode()));
391 case FID_TOGGLEFORMULA
:
393 const ScViewOptions
& rOpts
= rViewData
.GetOptions();
394 bool bFormulaMode
= rOpts
.GetOption( VOPT_FORMULAS
);
395 rSet
.Put(SfxBoolItem(nWhich
, bFormulaMode
));
399 case FID_NORMALVIEWMODE
:
400 case FID_PAGEBREAKMODE
:
401 // always handle both slots - they exclude each other
404 rSet
.DisableItem( FID_NORMALVIEWMODE
);
405 rSet
.DisableItem( FID_PAGEBREAKMODE
);
409 rSet
.Put(SfxBoolItem(FID_NORMALVIEWMODE
, !GetViewData().IsPagebreakMode()));
410 rSet
.Put(SfxBoolItem(FID_PAGEBREAKMODE
, GetViewData().IsPagebreakMode()));
414 case FID_PROTECT_DOC
:
416 if ( pDocShell
&& pDocShell
->IsDocShared() )
418 rSet
.DisableItem( nWhich
);
422 rSet
.Put( SfxBoolItem( nWhich
, rDoc
.IsDocProtected() ) );
427 case FID_PROTECT_TABLE
:
429 if ( pDocShell
&& pDocShell
->IsDocShared() )
431 rSet
.DisableItem( nWhich
);
435 rSet
.Put( SfxBoolItem( nWhich
, rDoc
.IsTabProtected( nTab
) ) );
440 case SID_AUTO_OUTLINE
:
442 if (rDoc
.GetChangeTrack()!=nullptr || GetViewData().IsMultiMarked())
444 rSet
.DisableItem( nWhich
);
449 case SID_OUTLINE_DELETEALL
:
451 SCTAB nOlTab
= GetViewData().GetTabNo();
452 ScOutlineTable
* pOlTable
= rDoc
.GetOutlineTable( nOlTab
);
453 if (pOlTable
== nullptr)
454 rSet
.DisableItem( nWhich
);
458 case SID_WINDOW_SPLIT
:
459 rSet
.Put(SfxBoolItem(nWhich
,
460 rViewData
.GetHSplitMode() == SC_SPLIT_NORMAL
||
461 rViewData
.GetVSplitMode() == SC_SPLIT_NORMAL
));
465 if(!comphelper::LibreOfficeKit::isActive())
467 rSet
.Put(SfxBoolItem(nWhich
,
468 rViewData
.GetHSplitMode() == SC_SPLIT_FIX
||
469 rViewData
.GetVSplitMode() == SC_SPLIT_FIX
));
473 rSet
.Put(SfxBoolItem(nWhich
,
474 rViewData
.GetLOKSheetFreezeIndex(true) > 0 ||
475 rViewData
.GetLOKSheetFreezeIndex(false) > 0 ));
479 case SID_WINDOW_FIX_COL
:
480 case SID_WINDOW_FIX_ROW
:
483 bool bIsCol
= (nWhich
== SID_WINDOW_FIX_COL
);
484 aPos
.setX(rViewData
.GetLOKSheetFreezeIndex(bIsCol
));
485 aPos
.setY(rViewData
.GetTabNo());
486 rSet
.Put(SfxPointItem(nWhich
, aPos
));
492 if ( rDoc
.GetChangeTrack() == nullptr || ( pDocShell
&& pDocShell
->IsDocShared() ) )
493 rSet
.DisableItem( nWhich
);
499 ( !rDoc
.GetChangeTrack() && !rThisFrame
.HasChildWindow(FID_CHG_ACCEPT
) )
501 ( pDocShell
&& pDocShell
->IsDocShared() )
504 rSet
.DisableItem( nWhich
);
508 rSet
.Put(SfxBoolItem(FID_CHG_ACCEPT
,
509 rThisFrame
.HasChildWindow(FID_CHG_ACCEPT
)));
515 // in protected tables
516 if ( pDocShell
&& ( pDocShell
->IsReadOnly() || pDocShell
->IsDocShared() ) )
517 rSet
.DisableItem( nWhich
);
520 case SID_PRINTPREVIEW
:
521 // Toggle slot needs a State
522 rSet
.Put( SfxBoolItem( nWhich
, false ) );
525 case SID_READONLY_MODE
:
526 rSet
.Put( SfxBoolItem( nWhich
, GetViewData().GetDocShell()->IsReadOnly() ) );
529 case FID_TAB_DESELECTALL
:
530 if ( nTabSelCount
== 1 )
531 rSet
.DisableItem( nWhich
); // enabled only if several sheets are selected
534 case FID_TOGGLEHIDDENCOLROW
:
535 const svtools::ColorConfig
& rColorCfg
= ScModule::get()->GetColorConfig();
536 rSet
.Put( SfxBoolItem( nWhich
, rColorCfg
.GetColorValue(svtools::CALCHIDDENROWCOL
).bIsVisible
) );
539 } // switch ( nWitch )
540 nWhich
= aIter
.NextWhich();
541 } // while ( nWitch )
544 void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest
& rReq
, const OUString
&rName
)
546 ScDocument
& rDoc
= GetViewData().GetDocument();
548 std::shared_ptr
<SvxBoxItem
> aLineOuter(std::make_shared
<SvxBoxItem
>(ATTR_BORDER
));
549 std::shared_ptr
<SvxBoxInfoItem
> aLineInner(std::make_shared
<SvxBoxInfoItem
>(ATTR_BORDER_INNER
));
551 const ScPatternAttr
* pOldAttrs
= GetSelectionPattern();
553 auto xOldSet
= std::make_shared
<SfxItemSet
>(pOldAttrs
->GetItemSet());
555 xOldSet
->MergeRange(XATTR_FILLSTYLE
, XATTR_FILLCOLOR
);
557 xOldSet
->MergeRange(SID_ATTR_BORDER_STYLES
, SID_ATTR_BORDER_DEFAULT_WIDTH
);
559 // We only allow these border line types.
560 std::vector
<sal_Int32
> aBorderStyles
{
561 table::BorderLineStyle::SOLID
,
562 table::BorderLineStyle::DOTTED
,
563 table::BorderLineStyle::DASHED
,
564 table::BorderLineStyle::FINE_DASHED
,
565 table::BorderLineStyle::DASH_DOT
,
566 table::BorderLineStyle::DASH_DOT_DOT
,
567 table::BorderLineStyle::DOUBLE_THIN
};
569 xOldSet
->Put(SfxIntegerListItem(SID_ATTR_BORDER_STYLES
, std::move(aBorderStyles
)));
571 // Set the default border width to 0.75 points.
572 SfxInt64Item
aBorderWidthItem(SID_ATTR_BORDER_DEFAULT_WIDTH
, 75);
573 xOldSet
->Put(aBorderWidthItem
);
575 // Get border items and put them in the set:
576 GetSelectionFrame( aLineOuter
, aLineInner
);
578 //Fix border incorrect for RTL fdo#62399
579 if( rDoc
.IsLayoutRTL( GetViewData().GetTabNo() ) )
581 std::unique_ptr
<SvxBoxItem
> aNewFrame(aLineOuter
->Clone());
582 std::unique_ptr
<SvxBoxInfoItem
> aTempInfo(aLineInner
->Clone());
584 if ( aLineInner
->IsValid(SvxBoxInfoItemValidFlags::LEFT
) )
585 aNewFrame
->SetLine( aLineOuter
->GetLeft(), SvxBoxItemLine::RIGHT
);
586 if ( aLineInner
->IsValid(SvxBoxInfoItemValidFlags::RIGHT
) )
587 aNewFrame
->SetLine( aLineOuter
->GetRight(), SvxBoxItemLine::LEFT
);
589 aLineInner
->SetValid( SvxBoxInfoItemValidFlags::LEFT
, aTempInfo
->IsValid(SvxBoxInfoItemValidFlags::RIGHT
));
590 aLineInner
->SetValid( SvxBoxInfoItemValidFlags::RIGHT
, aTempInfo
->IsValid(SvxBoxInfoItemValidFlags::LEFT
));
592 xOldSet
->Put( std::move(aNewFrame
) );
596 xOldSet
->Put( *aLineOuter
);
599 xOldSet
->Put( *aLineInner
);
601 // Generate NumberFormat Value from Value and Language and box it.
602 xOldSet
->Put( SfxUInt32Item( ATTR_VALUE_FORMAT
,
603 pOldAttrs
->GetNumberFormat( rDoc
.GetFormatTable() ) ) );
605 std::unique_ptr
<SvxNumberInfoItem
> pNumberInfoItem
= MakeNumberInfoItem(rDoc
, GetViewData());
606 xOldSet
->MergeRange( SID_ATTR_NUMBERFORMAT_INFO
, SID_ATTR_NUMBERFORMAT_INFO
);
607 xOldSet
->Put( std::move(pNumberInfoItem
) );
609 bInFormatDialog
= true;
610 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
612 VclPtr
<SfxAbstractTabDialog
> pDlg(pFact
->CreateScAttrDlg(GetFrameWeld(), xOldSet
.get()));
614 if (!rName
.isEmpty())
615 pDlg
->SetCurPageId(rName
);
617 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
618 rReq
.Ignore(); // the 'old' request is not relevant any more
620 pDlg
->StartExecuteAsync([pDlg
, xOldSet
=std::move(xOldSet
), xRequest
=std::move(xRequest
), this](sal_Int32 nResult
){
621 bInFormatDialog
= false;
623 if ( nResult
== RET_OK
)
625 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
626 if(const SvxNumberInfoItem
* pItem
= pOutSet
->GetItemIfSet(SID_ATTR_NUMBERFORMAT_INFO
))
628 UpdateNumberFormatter(*pItem
);
631 ApplyAttributes(*pOutSet
, *xOldSet
);
633 xRequest
->Done(*pOutSet
);
640 const OUString
* ScTabViewShell::GetEditString() const
643 return &mpInputHandler
->GetEditString();
648 bool ScTabViewShell::IsRefInputMode() const
650 if (ScModule
* pScMod
= ScModule::get())
652 if( pScMod
->IsRefDialogOpen() )
653 return pScMod
->IsFormulaMode();
654 if( pScMod
->IsFormulaMode() )
656 ScInputHandler
* pHdl
= pScMod
->GetInputHdl();
659 const ScViewData
& rViewData
= GetViewData();
660 ScDocument
& rDoc
= rViewData
.GetDocument();
661 const ScAddress
aPos( rViewData
.GetCurPos() );
662 const sal_uInt32 nIndex
= rDoc
.GetAttr(aPos
, ATTR_VALUE_FORMAT
)->GetValue();
663 const SvNumFormatType nType
= rDoc
.GetFormatTable()->GetType(nIndex
);
664 if (nType
== SvNumFormatType::TEXT
)
668 OUString aString
= pHdl
->GetEditString();
669 if ( !pHdl
->GetSelIsRef() && aString
.getLength() > 1 &&
670 ( aString
[0] == '+' || aString
[0] == '-' ) )
672 ScCompiler
aComp( rDoc
, aPos
, rDoc
.GetGrammar() );
673 aComp
.SetCloseBrackets( false );
674 std::unique_ptr
<ScTokenArray
> pArr(aComp
.CompileString(aString
));
675 if ( pArr
&& pArr
->MayReferenceFollow() )
691 void ScTabViewShell::ExecuteInputDirect()
693 if ( !IsRefInputMode() )
695 if (ScModule
* pScMod
= ScModule::get())
697 pScMod
->InputEnterHandler();
702 void ScTabViewShell::UpdateInputHandler( bool bForce
/* = sal_False */, bool bStopEditing
/* = sal_True */ )
704 ScInputHandler
* pHdl
= mpInputHandler
? mpInputHandler
.get() : ScModule::get()->GetInputHdl();
709 const EditTextObject
* pObject
= nullptr;
710 ScViewData
& rViewData
= GetViewData();
711 ScDocument
& rDoc
= rViewData
.GetDocument();
712 SCCOL nPosX
= rViewData
.GetCurX();
713 SCROW nPosY
= rViewData
.GetCurY();
714 SCTAB nTab
= rViewData
.GetTabNo();
721 ScAddress aPos
= rViewData
.GetCurPos();
723 rViewData
.GetSimpleArea( nStartCol
, nStartRow
, nStartTab
,
724 nEndCol
, nEndRow
, nEndTab
);
726 PutInOrder( nStartCol
, nEndCol
);
727 PutInOrder( nStartRow
, nEndRow
);
728 PutInOrder( nStartTab
, nEndTab
);
730 bool bHideFormula
= false;
731 bool bHideAll
= false;
733 if (rDoc
.IsTabProtected(nTab
))
735 const ScProtectionAttr
* pProt
= rDoc
.GetAttr( nPosX
,nPosY
,nTab
,
737 bHideFormula
= pProt
->GetHideFormula();
738 bHideAll
= pProt
->GetHideCell();
743 ScRefCellValue
rCell(rDoc
, aPos
);
744 if (rCell
.getType() == CELLTYPE_FORMULA
)
747 aString
= rCell
.getFormula()->GetFormula();
749 else if (rCell
.getType() == CELLTYPE_EDIT
)
751 pObject
= rCell
.getEditText();
755 ScInterpreterContext
& rContext
= rDoc
.GetNonThreadedContext();
756 sal_uInt32 nNumFmt
= rDoc
.GetNumberFormat( ScRange(aPos
) );
758 aString
= ScCellFormat::GetInputString( rCell
, nNumFmt
, &rContext
, rDoc
);
759 if (rCell
.getType() == CELLTYPE_STRING
)
761 // Put a ' in front if necessary, so that the string is not
762 // unintentionally interpreted as a number, and to show the
763 // user that it is a string (#35060#).
764 // If cell is not formatted as Text, a leading apostrophe
765 // needs another prepended, also '=' or '+' or '-'
766 // otherwise starting a formula.
767 // NOTE: this corresponds with
768 // sc/source/core/data/column3.cxx ScColumn::ParseString()
769 // removing one apostrophe.
770 // For number format Text IsNumberFormat() would never
771 // result in numeric anyway.
772 if (!rContext
.NFIsTextFormat(nNumFmt
) && (aString
.startsWith("'")
773 || aString
.startsWith("=") || aString
.startsWith("+") || aString
.startsWith("-")
774 || rContext
.NFIsNumberFormat(aString
, nNumFmt
, o3tl::temporary(double()))))
775 aString
= "'" + aString
;
780 ScInputHdlState
aState( ScAddress( nPosX
, nPosY
, nTab
),
781 ScAddress( nStartCol
, nStartRow
, nTab
),
782 ScAddress( nEndCol
, nEndRow
, nTab
),
786 // if using the view's local input handler, this view can always be set
787 // as current view inside NotifyChange.
788 ScTabViewShell
* pSourceSh
= mpInputHandler
? this : nullptr;
790 pHdl
->NotifyChange( &aState
, bForce
, pSourceSh
, bStopEditing
);
793 SfxBindings
& rBindings
= GetViewFrame().GetBindings();
794 rBindings
.Invalidate( SID_STATUS_SUM
); // always together with the input row
795 rBindings
.Invalidate( SID_ATTR_SIZE
);
796 rBindings
.Invalidate( SID_TABLE_CELL
);
799 void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust
)
801 if( ScInputHandler
* pHdl
= mpInputHandler
? mpInputHandler
.get() : ScModule::get()->GetInputHdl() )
802 pHdl
->UpdateCellAdjust( eJust
);
805 void ScTabViewShell::ExecuteSave( SfxRequest
& rReq
)
807 // only SID_SAVEDOC / SID_SAVEASDOC
808 bool bCommitChanges
= true;
809 const SfxItemSet
* pReqArgs
= rReq
.GetArgs();
810 const SfxPoolItem
* pItem
;
812 if (pReqArgs
&& pReqArgs
->HasItem(FN_PARAM_1
, &pItem
))
813 bCommitChanges
= !static_cast<const SfxBoolItem
*>(pItem
)->GetValue();
815 // Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed
818 bool bLOKActive
= comphelper::LibreOfficeKit::isActive();
820 // Disable error dialog box when about to save in lok mode as
821 // this ultimately invokes SvpSalInstance::DoYield() when we want
822 // to save immediately without committing any erroneous input in possibly
823 // a cell with validation rules. After save is complete the user
824 // can continue editing.
825 ScModule::get()->InputEnterHandler(ScEnterMode::NORMAL
, bLOKActive
/* bBeforeSavingInLOK */);
829 // Normally this isn't needed, but in Calc when editing a cell formula
830 // and manually saving (without changing cells or hitting enter), while
831 // InputEnterHandler will mark the doc as modified (when it is), because
832 // we will save the doc immediately afterwards, the modified state event
833 // is clobbered. To avoid that, we need to update SID_DOC_MODIFIED so that
834 // a possible state of "true" after "InputEnterHandler" will be sent
835 // as a notification. It is important that the notification goes through
836 // normal process (cache) rather than directly notifying the views.
837 // Otherwise, because there is a previous state of "false" in cache, the
838 // "false" state after saving will be ignored.
839 // This will work only if .uno:ModifiedStatus message will be removed from
840 // the mechanism that keeps in the message queue only last message of
841 // a particular status even if the values are different.
842 if (SfxBindings
* pBindings
= GetViewData().GetDocShell()->GetViewBindings())
843 pBindings
->Update(SID_DOC_MODIFIED
);
847 if ( GetViewData().GetDocShell()->IsDocShared() )
849 GetViewData().GetDocShell()->SetDocumentModified();
852 // otherwise as normal
853 GetViewData().GetDocShell()->ExecuteSlot( rReq
);
856 void ScTabViewShell::GetSaveState( SfxItemSet
& rSet
)
858 SfxShell
* pDocSh
= GetViewData().GetDocShell();
860 SfxWhichIter
aIter(rSet
);
861 sal_uInt16 nWhich
= aIter
.FirstWhich();
864 if ( nWhich
!= SID_SAVEDOC
|| !GetViewData().GetDocShell()->IsDocShared() )
866 // get state from DocShell
867 pDocSh
->GetSlotState( nWhich
, nullptr, &rSet
);
869 nWhich
= aIter
.NextWhich();
873 void ScTabViewShell::ExecDrawOpt( const SfxRequest
& rReq
)
875 ScViewOptions aViewOptions
= GetViewData().GetOptions();
876 ScGridOptions aGridOptions
= aViewOptions
.GetGridOptions();
878 SfxBindings
& rBindings
= GetViewFrame().GetBindings();
879 const SfxItemSet
* pArgs
= rReq
.GetArgs();
880 const SfxPoolItem
* pItem
;
881 sal_uInt16 nSlotId
= rReq
.GetSlot();
884 case SID_GRID_VISIBLE
:
885 if ( pArgs
&& pArgs
->GetItemState(nSlotId
,true,&pItem
) == SfxItemState::SET
)
887 aGridOptions
.SetGridVisible( static_cast<const SfxBoolItem
*>(pItem
)->GetValue() );
888 aViewOptions
.SetGridOptions(aGridOptions
);
889 rBindings
.Invalidate(SID_GRID_VISIBLE
);
894 if ( pArgs
&& pArgs
->GetItemState(nSlotId
,true,&pItem
) == SfxItemState::SET
)
896 aGridOptions
.SetUseGridSnap( static_cast<const SfxBoolItem
*>(pItem
)->GetValue() );
897 aViewOptions
.SetGridOptions(aGridOptions
);
898 rBindings
.Invalidate(SID_GRID_USE
);
902 case SID_HELPLINES_MOVE
:
903 if ( pArgs
&& pArgs
->GetItemState(nSlotId
,true,&pItem
) == SfxItemState::SET
)
905 aViewOptions
.SetOption( VOPT_HELPLINES
, static_cast<const SfxBoolItem
*>(pItem
)->GetValue() );
906 rBindings
.Invalidate(SID_HELPLINES_MOVE
);
911 GetViewData().SetOptions(aViewOptions
);
914 void ScTabViewShell::GetDrawOptState( SfxItemSet
& rSet
)
918 const ScViewOptions
& rViewOptions
= GetViewData().GetOptions();
919 const ScGridOptions
& rGridOptions
= rViewOptions
.GetGridOptions();
921 aBool
.SetValue(rGridOptions
.GetGridVisible());
922 aBool
.SetWhich( SID_GRID_VISIBLE
);
925 aBool
.SetValue(rGridOptions
.GetUseGridSnap());
926 aBool
.SetWhich( SID_GRID_USE
);
929 aBool
.SetValue(rViewOptions
.GetOption( VOPT_HELPLINES
));
930 aBool
.SetWhich( SID_HELPLINES_MOVE
);
934 void ScTabViewShell::ExecStyle( SfxRequest
& rReq
)
936 const SfxItemSet
* pArgs
= rReq
.GetArgs();
937 const sal_uInt16 nSlotId
= rReq
.GetSlot();
938 if ( !pArgs
&& nSlotId
!= SID_STYLE_NEW_BY_EXAMPLE
&& nSlotId
!= SID_STYLE_UPDATE_BY_EXAMPLE
)
940 // in case of vertical toolbar
941 GetDispatcher()->Execute( SID_STYLE_DESIGNER
, SfxCallMode::ASYNCHRON
| SfxCallMode::RECORD
);
945 SfxBindings
& rBindings
= GetViewData().GetBindings();
946 const SCTAB nCurTab
= GetViewData().GetTabNo();
947 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
948 ScDocument
& rDoc
= pDocSh
->GetDocument();
949 ScMarkData
& rMark
= GetViewData().GetMarkData();
950 ScModule
* pScMod
= ScModule::get();
951 SdrObject
* pEditObject
= GetDrawView()->GetTextEditObject();
952 OutlinerView
* pOLV
= GetDrawView()->GetTextEditOutlinerView();
953 ESelection aSelection
= pOLV
? pOLV
->GetSelection() : ESelection();
955 bool bUndo
= rDoc
.IsUndoEnabled();
957 SfxStyleSheetBasePool
* pStylePool
= rDoc
.GetStyleSheetPool();
958 SfxStyleSheetBase
* pStyleSheet
= nullptr;
960 bool bStyleToMarked
= false;
961 bool bListAction
= false;
962 bool bAddUndo
= false; // add ScUndoModifyStyle (style modified)
963 auto xOldData
= std::make_shared
<ScStyleSaveData
>(); // for undo/redo
964 auto xNewData
= std::make_shared
<ScStyleSaveData
>();
966 SfxStyleFamily eFamily
= SfxStyleFamily::Para
;
967 const SfxUInt16Item
* pFamItem
;
968 const SfxStringItem
* pFamilyNameItem
;
969 if ( pArgs
&& (pFamItem
= pArgs
->GetItemIfSet( SID_STYLE_FAMILY
)) )
970 eFamily
= static_cast<SfxStyleFamily
>(pFamItem
->GetValue());
971 else if ( pArgs
&& (pFamilyNameItem
= pArgs
->GetItemIfSet( SID_STYLE_FAMILYNAME
)) )
973 const OUString
& sFamily
= pFamilyNameItem
->GetValue();
974 if (sFamily
== "CellStyles")
975 eFamily
= SfxStyleFamily::Para
;
976 else if (sFamily
== "PageStyles")
977 eFamily
= SfxStyleFamily::Page
;
978 else if (sFamily
== "GraphicStyles")
979 eFamily
= SfxStyleFamily::Frame
;
983 sal_uInt16 nRetMask
= 0xffff;
989 const SfxPoolItem
* pNameItem
;
990 if (pArgs
&& SfxItemState::SET
== pArgs
->GetItemState( nSlotId
, true, &pNameItem
))
991 aStyleName
= static_cast<const SfxStringItem
*>(pNameItem
)->GetValue();
993 const SfxStringItem
* pRefItem
=nullptr;
994 if (pArgs
&& (pRefItem
= pArgs
->GetItemIfSet( SID_STYLE_REFERENCE
)))
996 aRefName
= pRefItem
->GetValue();
999 pStyleSheet
= &(pStylePool
->Make( aStyleName
, eFamily
,
1000 SfxStyleSearchBits::UserDefined
) );
1002 if (pStyleSheet
->HasParentSupport())
1003 pStyleSheet
->SetParent(aRefName
);
1007 case SID_STYLE_APPLY
:
1009 const SfxStringItem
* pNameItem
= rReq
.GetArg
<SfxStringItem
>(SID_APPLY_STYLE
);
1010 const SfxStringItem
* pFamilyItem
= rReq
.GetArg
<SfxStringItem
>(SID_STYLE_FAMILYNAME
);
1011 if ( pFamilyItem
&& pNameItem
)
1015 css::uno::Reference
< css::container::XNameAccess
> xStyles
;
1016 css::uno::Reference
< css::container::XNameAccess
> xCont
= pDocSh
->GetModel()->getStyleFamilies();
1017 xCont
->getByName(pFamilyItem
->GetValue()) >>= xStyles
;
1018 css::uno::Reference
< css::beans::XPropertySet
> xInfo
;
1019 xStyles
->getByName( pNameItem
->GetValue() ) >>= xInfo
;
1021 xInfo
->getPropertyValue(u
"DisplayName"_ustr
) >>= aUIName
;
1022 if ( !aUIName
.isEmpty() )
1023 rReq
.AppendItem( SfxStringItem( SID_STYLE_APPLY
, aUIName
) );
1025 catch( css::uno::Exception
& )
1031 case SID_STYLE_EDIT
:
1032 case SID_STYLE_DELETE
:
1033 case SID_STYLE_HIDE
:
1034 case SID_STYLE_SHOW
:
1035 case SID_STYLE_NEW_BY_EXAMPLE
:
1037 const SfxPoolItem
* pNameItem
;
1038 if (pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(nSlotId
, true, &pNameItem
))
1039 aStyleName
= static_cast<const SfxStringItem
*>(pNameItem
)->GetValue();
1040 else if ( nSlotId
== SID_STYLE_NEW_BY_EXAMPLE
)
1042 weld::Window
* pDialogParent
= rReq
.GetFrameWeld();
1044 pDialogParent
= GetFrameWeld();
1045 SfxNewStyleDlg
aDlg(pDialogParent
, *pStylePool
, eFamily
);
1046 if (aDlg
.run() != RET_OK
)
1048 aStyleName
= aDlg
.GetName();
1051 pStyleSheet
= pStylePool
->Find( aStyleName
, eFamily
);
1053 xOldData
->InitFromStyle( pStyleSheet
);
1057 case SID_STYLE_WATERCAN
:
1059 bool bWaterCan
= pScMod
->GetIsWaterCan();
1063 const SfxPoolItem
* pItem
;
1065 if (pArgs
&& SfxItemState::SET
== pArgs
->GetItemState(nSlotId
, true, &pItem
))
1067 const SfxStringItem
* pStrItem
= dynamic_cast< const SfxStringItem
*>( pItem
);
1070 aStyleName
= pStrItem
->GetValue();
1071 pStyleSheet
= pStylePool
->Find( aStyleName
, eFamily
);
1075 static_cast<ScStyleSheetPool
*>(pStylePool
)->
1076 SetActualStyleSheet( pStyleSheet
);
1083 if ( !bWaterCan
&& pStyleSheet
)
1085 pScMod
->SetWaterCan( true );
1086 SetActivePointer( PointerStyle::Fill
);
1091 pScMod
->SetWaterCan( false );
1092 SetActivePointer( PointerStyle::Arrow
);
1102 // set new style for paintbrush format mode
1103 if ( nSlotId
== SID_STYLE_APPLY
&& pScMod
->GetIsWaterCan() && pStyleSheet
)
1104 static_cast<ScStyleSheetPool
*>(pStylePool
)->SetActualStyleSheet( pStyleSheet
);
1108 case SfxStyleFamily::Para
:
1112 case SID_STYLE_DELETE
:
1116 RemoveStyleSheetInUse( pStyleSheet
);
1117 pStylePool
->Remove( pStyleSheet
);
1118 InvalidateAttribs();
1119 nRetMask
= sal_uInt16(true);
1124 nRetMask
= sal_uInt16(false);
1128 case SID_STYLE_HIDE
:
1129 case SID_STYLE_SHOW
:
1133 pStyleSheet
->SetHidden( nSlotId
== SID_STYLE_HIDE
);
1134 InvalidateAttribs();
1138 nRetMask
= sal_uInt16(false);
1142 case SID_STYLE_APPLY
:
1144 if ( pStyleSheet
&& !pScMod
->GetIsWaterCan() )
1146 // apply style sheet to document
1147 SetStyleSheetToMarked( static_cast<SfxStyleSheet
*>(pStyleSheet
) );
1148 InvalidateAttribs();
1154 case SID_STYLE_NEW_BY_EXAMPLE
:
1155 case SID_STYLE_UPDATE_BY_EXAMPLE
:
1157 // create/replace style sheet by attributes
1158 // at cursor position:
1160 const ScPatternAttr
* pAttrItem
= nullptr;
1162 // The query if marked, was always wrong here,
1163 // so now no more, and just from the cursor.
1164 // If attributes are to be removed from the selection, still need to be
1165 // cautious not to adopt items from templates
1166 // (GetSelectionPattern also collects items from originals) (# 44748 #)
1167 SCCOL nCol
= GetViewData().GetCurX();
1168 SCROW nRow
= GetViewData().GetCurY();
1169 pAttrItem
= rDoc
.GetPattern( nCol
, nRow
, nCurTab
);
1171 SfxItemSet aAttrSet
= pAttrItem
->GetItemSet();
1172 aAttrSet
.ClearItem( ATTR_MERGE
);
1173 aAttrSet
.ClearItem( ATTR_MERGE_FLAG
);
1175 // Do not adopt conditional formatting and validity,
1176 // because they can not be edited in the template
1177 aAttrSet
.ClearItem( ATTR_VALIDDATA
);
1178 aAttrSet
.ClearItem( ATTR_CONDITIONAL
);
1180 if ( SID_STYLE_NEW_BY_EXAMPLE
== nSlotId
)
1184 OUString aUndo
= ScResId( STR_UNDO_EDITCELLSTYLE
);
1185 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
, 0, GetViewShellId() );
1189 bool bConvertBack
= false;
1190 SfxStyleSheet
* pSheetInUse
= const_cast<SfxStyleSheet
*>(GetStyleSheetFromMarked());
1192 // when a new style is present and is used in the selection,
1193 // then the parent can not be adopted:
1194 if ( pStyleSheet
&& pSheetInUse
&& pStyleSheet
== pSheetInUse
)
1195 pSheetInUse
= nullptr;
1197 // if already present, first remove ...
1200 // style pointer to names before erase,
1201 // otherwise cells will get invalid pointer
1202 //!!! As it happens, a method that does it for a particular style
1203 rDoc
.getCellAttributeHelper().AllStylesToNames();
1204 bConvertBack
= true;
1205 pStylePool
->Remove(pStyleSheet
);
1208 // ...and create new
1209 pStyleSheet
= &pStylePool
->Make( aStyleName
, eFamily
,
1210 SfxStyleSearchBits::UserDefined
);
1212 // when a style is present, then this will become
1213 // the parent of the new style:
1214 if ( pSheetInUse
&& pStyleSheet
->HasParentSupport() )
1215 pStyleSheet
->SetParent( pSheetInUse
->GetName() );
1218 // Name to style pointer
1219 rDoc
.getCellAttributeHelper().UpdateAllStyleSheets(rDoc
);
1221 rDoc
.getCellAttributeHelper().CellStyleCreated(rDoc
, aStyleName
);
1223 // Adopt attribute and use style
1224 pStyleSheet
->GetItemSet().Put( aAttrSet
);
1225 UpdateStyleSheetInUse( pStyleSheet
);
1227 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
1228 // (pStyleSheet pointer is used!)
1229 bStyleToMarked
= true;
1231 else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE )
1233 pStyleSheet
= const_cast<SfxStyleSheet
*>(GetStyleSheetFromMarked());
1237 xOldData
->InitFromStyle( pStyleSheet
);
1241 OUString aUndo
= ScResId( STR_UNDO_EDITCELLSTYLE
);
1242 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
, 0, GetViewShellId() );
1246 pStyleSheet
->GetItemSet().Put( aAttrSet
);
1247 UpdateStyleSheetInUse( pStyleSheet
);
1249 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle
1250 // (pStyleSheet pointer is used!)
1251 bStyleToMarked
= true;
1255 xNewData
->InitFromStyle( pStyleSheet
);
1264 } // case SfxStyleFamily::Para:
1267 case SfxStyleFamily::Page
:
1271 case SID_STYLE_DELETE
:
1273 nRetMask
= sal_uInt16( nullptr != pStyleSheet
);
1276 if ( rDoc
.RemovePageStyleInUse( pStyleSheet
->GetName() ) )
1278 ScPrintFunc( pDocSh
, GetPrinter(true), nCurTab
).UpdatePages();
1279 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
1280 rBindings
.Invalidate( FID_RESET_PRINTZOOM
);
1282 pStylePool
->Remove( pStyleSheet
);
1283 rBindings
.Invalidate( SID_STYLE_FAMILY4
);
1284 pDocSh
->SetDocumentModified();
1291 case SID_STYLE_HIDE
:
1292 case SID_STYLE_SHOW
:
1294 nRetMask
= sal_uInt16( nullptr != pStyleSheet
);
1297 pStyleSheet
->SetHidden( nSlotId
== SID_STYLE_HIDE
);
1298 rBindings
.Invalidate( SID_STYLE_FAMILY4
);
1299 pDocSh
->SetDocumentModified();
1305 case SID_STYLE_APPLY
:
1307 nRetMask
= sal_uInt16( nullptr != pStyleSheet
);
1308 if ( pStyleSheet
&& !pScMod
->GetIsWaterCan() )
1310 std::unique_ptr
<ScUndoApplyPageStyle
> pUndoAction
;
1311 SCTAB nTabCount
= rDoc
.GetTableCount();
1312 for (const auto& rTab
: rMark
)
1314 if (rTab
>= nTabCount
)
1316 OUString aOldName
= rDoc
.GetPageStyle( rTab
);
1317 if ( aOldName
!= aStyleName
)
1319 rDoc
.SetPageStyle( rTab
, aStyleName
);
1320 ScPrintFunc( pDocSh
, GetPrinter(true), rTab
).UpdatePages();
1322 pUndoAction
.reset(new ScUndoApplyPageStyle( pDocSh
, aStyleName
));
1323 pUndoAction
->AddSheetAction( rTab
, aOldName
);
1328 pDocSh
->GetUndoManager()->AddUndoAction( std::move(pUndoAction
) );
1329 pDocSh
->SetDocumentModified();
1330 rBindings
.Invalidate( SID_STYLE_FAMILY4
);
1331 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
1332 rBindings
.Invalidate( FID_RESET_PRINTZOOM
);
1339 case SID_STYLE_NEW_BY_EXAMPLE
:
1341 const OUString aStrCurStyle
= rDoc
.GetPageStyle( nCurTab
);
1343 if ( aStrCurStyle
!= aStyleName
)
1345 SfxStyleSheetBase
* pCurStyle
= pStylePool
->Find( aStrCurStyle
, eFamily
);
1346 SfxItemSet aAttrSet
= pCurStyle
->GetItemSet();
1348 bool bUsed
= rDoc
.IsPageStyleInUse( aStyleName
, &nInTab
);
1350 // if already present, first remove...
1352 pStylePool
->Remove( pStyleSheet
);
1354 // ...and create new
1355 pStyleSheet
= &pStylePool
->Make( aStyleName
, eFamily
,
1356 SfxStyleSearchBits::UserDefined
);
1359 pStyleSheet
->GetItemSet().Put( aAttrSet
);
1360 pDocSh
->SetDocumentModified();
1362 // If being used -> Update
1364 ScPrintFunc( pDocSh
, GetPrinter(true), nInTab
).UpdatePages();
1366 xNewData
->InitFromStyle( pStyleSheet
);
1369 nRetMask
= sal_uInt16(true);
1376 } // switch ( nSlotId )
1377 } // case SfxStyleFamily::Page:
1380 case SfxStyleFamily::Frame
:
1384 case SID_STYLE_DELETE
:
1388 pStylePool
->Remove( pStyleSheet
);
1389 InvalidateAttribs();
1390 pDocSh
->SetDocumentModified();
1391 nRetMask
= sal_uInt16(true);
1396 nRetMask
= sal_uInt16(false);
1400 case SID_STYLE_HIDE
:
1401 case SID_STYLE_SHOW
:
1405 pStyleSheet
->SetHidden( nSlotId
== SID_STYLE_HIDE
);
1406 InvalidateAttribs();
1410 nRetMask
= sal_uInt16(false);
1414 case SID_STYLE_APPLY
:
1416 if ( pStyleSheet
&& !pScMod
->GetIsWaterCan() )
1418 GetScDrawView()->ScEndTextEdit();
1419 GetScDrawView()->SetStyleSheet(static_cast<SfxStyleSheet
*>(pStyleSheet
), false);
1421 GetScDrawView()->InvalidateAttribs();
1422 InvalidateAttribs();
1428 case SID_STYLE_NEW_BY_EXAMPLE
:
1429 case SID_STYLE_UPDATE_BY_EXAMPLE
:
1431 if (nSlotId
== SID_STYLE_NEW_BY_EXAMPLE
)
1433 pStyleSheet
= &pStylePool
->Make( aStyleName
, eFamily
, SfxStyleSearchBits::UserDefined
);
1435 // when a style is present, then this will become
1436 // the parent of the new style:
1437 if (SfxStyleSheet
* pOldStyle
= GetDrawView()->GetStyleSheet())
1438 pStyleSheet
->SetParent(pOldStyle
->GetName());
1442 pStyleSheet
= GetDrawView()->GetStyleSheet();
1443 xOldData
->InitFromStyle( pStyleSheet
);
1448 OUString aUndo
= ScResId( STR_UNDO_EDITGRAPHICSTYLE
);
1449 pDocSh
->GetUndoManager()->EnterListAction( aUndo
, aUndo
, 0, GetViewShellId() );
1453 SfxItemSet
aCoreSet(GetDrawView()->GetModel().GetItemPool());
1454 GetDrawView()->GetAttributes(aCoreSet
, true);
1456 SfxItemSet
* pStyleSet
= &pStyleSheet
->GetItemSet();
1457 pStyleSet
->Put(aCoreSet
);
1458 static_cast<SfxStyleSheet
*>(pStyleSheet
)->Broadcast(SfxHint(SfxHintId::DataChanged
));
1460 xNewData
->InitFromStyle( pStyleSheet
);
1463 // call SetStyleSheet after adding the ScUndoModifyStyle
1464 // (pStyleSheet pointer is used!)
1465 bStyleToMarked
= true;
1476 } // switch ( eFamily )
1478 // create new or process through Dialog:
1479 if ( nSlotId
== SID_STYLE_NEW
|| nSlotId
== SID_STYLE_EDIT
)
1483 ExecuteStyleEdit(rReq
, pStyleSheet
, nRetMask
, nSlotId
, bAddUndo
, bUndo
,
1484 xOldData
, xNewData
, eFamily
, bStyleToMarked
, bListAction
, pEditObject
, aSelection
);
1485 return; // skip calling ExecuteStyleEditPost because we invoked an async dialog
1489 ExecuteStyleEditPost(rReq
, pStyleSheet
, nSlotId
, nRetMask
, bAddUndo
, bUndo
,
1490 eFamily
, *xOldData
, *xNewData
, bStyleToMarked
, bListAction
, pEditObject
, aSelection
);
1493 void ScTabViewShell::ExecuteStyleEdit(SfxRequest
& rReq
, SfxStyleSheetBase
* pStyleSheet
, sal_uInt16 nRetMask
,
1494 sal_uInt16 nSlotId
, bool bAddUndo
, bool bUndo
,
1495 const std::shared_ptr
<ScStyleSaveData
>& rOldData
,
1496 const std::shared_ptr
<ScStyleSaveData
>& rNewData
, SfxStyleFamily eFamily
,
1497 bool bStyleToMarked
, bool bListAction
,
1498 SdrObject
* pEditObject
, ESelection aSelection
)
1500 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1501 ScDocument
& rDoc
= pDocSh
->GetDocument();
1502 SfxStyleFamily eFam
= pStyleSheet
->GetFamily();
1503 VclPtr
<SfxAbstractTabDialog
> pDlg
;
1506 // Store old Items from the style
1507 std::shared_ptr
<SfxItemSet
> xOldSet
= std::make_shared
<SfxItemSet
>(pStyleSheet
->GetItemSet());
1508 OUString aOldName
= pStyleSheet
->GetName();
1512 case SfxStyleFamily::Page
:
1516 case SfxStyleFamily::Para
:
1518 SfxItemSet
& rSet
= pStyleSheet
->GetItemSet();
1520 if ( const SfxUInt32Item
* pItem
= rSet
.GetItemIfSet( ATTR_VALUE_FORMAT
,
1523 // Produce and format NumberFormat Value from Value and Language
1524 sal_uLong nFormat
= pItem
->GetValue();
1525 LanguageType eLang
=
1526 rSet
.Get(ATTR_LANGUAGE_FORMAT
).GetLanguage();
1527 sal_uLong nLangFormat
= rDoc
.GetFormatTable()->
1528 GetFormatForLanguageIfBuiltIn( nFormat
, eLang
);
1529 if ( nLangFormat
!= nFormat
)
1531 SfxUInt32Item
aNewItem( ATTR_VALUE_FORMAT
, nLangFormat
);
1532 rSet
.Put( aNewItem
);
1533 xOldSet
->Put( aNewItem
);
1534 // Also in aOldSet for comparison after the dialog,
1535 // Otherwise might miss a language change
1539 std::unique_ptr
<SvxNumberInfoItem
> pNumberInfoItem(
1540 ScTabViewShell::MakeNumberInfoItem(rDoc
, GetViewData()));
1542 pDocSh
->PutItem( *pNumberInfoItem
);
1545 // Definitely a SvxBoxInfoItem with Table = sal_False in set:
1546 // (If there is no item, the dialogue will also delete the
1547 // BORDER_OUTER SvxBoxItem from the Template Set)
1548 if ( rSet
.GetItemState( ATTR_BORDER_INNER
, false ) != SfxItemState::SET
)
1550 SvxBoxInfoItem
aBoxInfoItem( ATTR_BORDER_INNER
);
1551 aBoxInfoItem
.SetTable(false); // no inner lines
1552 aBoxInfoItem
.SetDist(true);
1553 aBoxInfoItem
.SetMinDist(false);
1554 rSet
.Put( aBoxInfoItem
);
1559 case SfxStyleFamily::Frame
:
1564 SetInFormatDialog(true);
1566 SfxItemSet
& rStyleSet
= pStyleSheet
->GetItemSet();
1567 rStyleSet
.MergeRange( XATTR_FILL_FIRST
, XATTR_FILL_LAST
);
1569 ScAbstractDialogFactory
* pFact
= ScAbstractDialogFactory::Create();
1571 weld::Window
* pDialogParent
= rReq
.GetFrameWeld();
1573 pDialogParent
= GetFrameWeld();
1575 if (eFam
== SfxStyleFamily::Frame
)
1576 pDlg
= pFact
->CreateScDrawStyleDlg(pDialogParent
, *pStyleSheet
, GetDrawView());
1578 pDlg
= pFact
->CreateScStyleDlg(pDialogParent
, *pStyleSheet
, bPage
);
1580 auto xRequest
= std::make_shared
<SfxRequest
>(rReq
);
1581 rReq
.Ignore(); // the 'old' request is not relevant any more
1582 pDlg
->StartExecuteAsync(
1583 [this, pDlg
, xRequest
=std::move(xRequest
), pStyleSheet
,
1584 nRetMask
, xOldSet
=std::move(xOldSet
), nSlotId
, bAddUndo
, bUndo
,
1585 xOldData
= rOldData
, xNewData
= rNewData
, aOldName
, eFamily
, bStyleToMarked
,
1586 bListAction
, pEditObject
, aSelection
]
1587 (sal_Int32 nResult
) mutable -> void
1589 SetInFormatDialog(false);
1590 ExecuteStyleEditDialog(pDlg
, pStyleSheet
, nResult
, nRetMask
, xOldSet
, nSlotId
,
1591 bAddUndo
, *xNewData
, aOldName
);
1592 pDlg
->disposeOnce();
1593 ExecuteStyleEditPost(*xRequest
, pStyleSheet
, nSlotId
, nRetMask
, bAddUndo
, bUndo
, eFamily
,
1594 *xOldData
, *xNewData
, bStyleToMarked
, bListAction
, pEditObject
, aSelection
);
1599 void ScTabViewShell::ExecuteStyleEditDialog(VclPtr
<SfxAbstractTabDialog
> pDlg
,
1600 SfxStyleSheetBase
* pStyleSheet
, sal_uInt16 nResult
,
1601 sal_uInt16
& rnRetMask
, std::shared_ptr
<SfxItemSet
> xOldSet
, const sal_uInt16 nSlotId
,
1602 bool& rbAddUndo
, ScStyleSaveData
& rNewData
, std::u16string_view aOldName
)
1604 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1605 ScDocument
& rDoc
= pDocSh
->GetDocument();
1606 SfxBindings
& rBindings
= GetViewData().GetBindings();
1607 SfxStyleSheetBasePool
* pStylePool
= rDoc
.GetStyleSheetPool();
1608 SfxStyleFamily eFam
= pStyleSheet
->GetFamily();
1609 if ( nResult
== RET_OK
)
1611 const SfxItemSet
* pOutSet
= pDlg
->GetOutputItemSet();
1615 rnRetMask
= sal_uInt16(pStyleSheet
->GetMask());
1617 // Attribute comparisons (earlier in ModifyStyleSheet) now here
1618 // with the old values (the style is already changed)
1619 if ( SfxStyleFamily::Para
== eFam
)
1621 SfxItemSet
& rNewSet
= pStyleSheet
->GetItemSet();
1622 bool bNumFormatChanged
;
1623 if ( ScGlobal::CheckWidthInvalidate(
1624 bNumFormatChanged
, rNewSet
, *xOldSet
) )
1625 rDoc
.InvalidateTextWidth( nullptr, nullptr, bNumFormatChanged
);
1627 SCTAB nTabCount
= rDoc
.GetTableCount();
1628 for (SCTAB nTab
=0; nTab
<nTabCount
; nTab
++)
1629 rDoc
.SetStreamValid(nTab
, false);
1631 sal_uLong nOldFormat
= xOldSet
->Get( ATTR_VALUE_FORMAT
).GetValue();
1632 sal_uLong nNewFormat
= rNewSet
.Get( ATTR_VALUE_FORMAT
).GetValue();
1633 if ( nNewFormat
!= nOldFormat
)
1635 ScInterpreterContext
& rContext
= rDoc
.GetNonThreadedContext();
1636 const SvNumberformat
* pOld
= rContext
.NFGetFormatEntry( nOldFormat
);
1637 const SvNumberformat
* pNew
= rContext
.NFGetFormatEntry( nNewFormat
);
1638 if ( pOld
&& pNew
&& pOld
->GetLanguage() != pNew
->GetLanguage() )
1639 rNewSet
.Put( SvxLanguageItem(
1640 pNew
->GetLanguage(), ATTR_LANGUAGE_FORMAT
) );
1643 rDoc
.getCellAttributeHelper().CellStyleCreated(rDoc
, pStyleSheet
->GetName());
1645 else if ( SfxStyleFamily::Page
== eFam
)
1647 //! Here also queries for Page Styles
1649 OUString aNewName
= pStyleSheet
->GetName();
1650 if ( aNewName
!= aOldName
&&
1651 rDoc
.RenamePageStyleInUse( aOldName
, aNewName
) )
1653 rBindings
.Invalidate( SID_STATUS_PAGESTYLE
);
1654 rBindings
.Invalidate( FID_RESET_PRINTZOOM
);
1657 rDoc
.ModifyStyleSheet( *pStyleSheet
, *pOutSet
);
1658 rBindings
.Invalidate( FID_RESET_PRINTZOOM
);
1662 SfxItemSet
& rAttr
= pStyleSheet
->GetItemSet();
1663 sdr::properties::CleanupFillProperties(rAttr
);
1665 // check for unique names of named items for xml
1666 auto checkForUniqueItem
= [&] (auto nWhichId
)
1668 if (auto pOldItem
= rAttr
.GetItemIfSet(nWhichId
, false))
1670 if (auto pNewItem
= pOldItem
->checkForUniqueItem(GetDrawView()->GetModel()))
1671 rAttr
.Put(std::move(pNewItem
));
1675 checkForUniqueItem(XATTR_FILLBITMAP
);
1676 checkForUniqueItem(XATTR_LINEDASH
);
1677 checkForUniqueItem(XATTR_LINESTART
);
1678 checkForUniqueItem(XATTR_LINEEND
);
1679 checkForUniqueItem(XATTR_FILLGRADIENT
);
1680 checkForUniqueItem(XATTR_FILLFLOATTRANSPARENCE
);
1681 checkForUniqueItem(XATTR_FILLHATCH
);
1683 static_cast<SfxStyleSheet
*>(pStyleSheet
)->Broadcast(SfxHint(SfxHintId::DataChanged
));
1684 GetScDrawView()->InvalidateAttribs();
1687 pDocSh
->SetDocumentModified();
1689 if ( SfxStyleFamily::Para
== eFam
)
1691 ScTabViewShell::UpdateNumberFormatter(
1692 *( pDocSh
->GetItem(SID_ATTR_NUMBERFORMAT_INFO
) ));
1694 UpdateStyleSheetInUse( pStyleSheet
);
1695 InvalidateAttribs();
1698 rNewData
.InitFromStyle( pStyleSheet
);
1704 if ( nSlotId
== SID_STYLE_NEW
)
1705 pStylePool
->Remove( pStyleSheet
);
1708 // If in the meantime something was painted with the
1709 // temporary changed item set
1710 pDocSh
->PostPaintGridAll();
1715 void ScTabViewShell::ExecuteStyleEditPost(SfxRequest
& rReq
, SfxStyleSheetBase
* pStyleSheet
,
1716 sal_uInt16 nSlotId
, sal_uInt16 nRetMask
, bool bAddUndo
, bool bUndo
,
1717 const SfxStyleFamily eFamily
,
1718 ScStyleSaveData
& rOldData
, ScStyleSaveData
& rNewData
,
1719 bool bStyleToMarked
, bool bListAction
,
1720 SdrObject
* pEditObject
, ESelection aSelection
)
1722 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1724 rReq
.SetReturnValue( SfxUInt16Item( nSlotId
, nRetMask
) );
1726 if ( bAddUndo
&& bUndo
)
1727 pDocSh
->GetUndoManager()->AddUndoAction(
1728 std::make_unique
<ScUndoModifyStyle
>( pDocSh
, eFamily
, rOldData
, rNewData
) );
1730 if ( bStyleToMarked
)
1732 // call SetStyleSheetToMarked after adding the ScUndoModifyStyle,
1733 // so redo will find the modified style
1734 if (eFamily
== SfxStyleFamily::Para
)
1736 SetStyleSheetToMarked( static_cast<SfxStyleSheet
*>(pStyleSheet
) );
1738 else if (eFamily
== SfxStyleFamily::Frame
)
1740 GetScDrawView()->ScEndTextEdit();
1741 GetScDrawView()->SetStyleSheet( static_cast<SfxStyleSheet
*>(pStyleSheet
), false );
1743 InvalidateAttribs();
1747 pDocSh
->GetUndoManager()->LeaveListAction();
1749 // The above call to ScEndTextEdit left us in an inconsistent state:
1750 // Text editing isn't active, but the text edit shell still is. And we
1751 // couldn't just deactivate it fully, because in case of editing a
1752 // comment, that will make the comment disappear. So let's try to
1753 // reactivate text editing instead:
1754 auto pFuText
= dynamic_cast<FuText
*>(GetDrawFuncPtr());
1755 if (pFuText
&& pEditObject
!= GetDrawView()->GetTextEditObject())
1757 pFuText
->SetInEditMode(pEditObject
);
1758 if (GetDrawView()->GetTextEditOutlinerView())
1759 GetDrawView()->GetTextEditOutlinerView()->SetSelection(aSelection
);
1763 void ScTabViewShell::GetStyleState( SfxItemSet
& rSet
)
1765 ScDocument
& rDoc
= GetViewData().GetDocument();
1766 SfxStyleSheetBasePool
* pStylePool
= rDoc
.GetStyleSheetPool();
1768 bool bProtected
= false;
1769 SCTAB nTabCount
= rDoc
.GetTableCount();
1770 for (SCTAB i
=0; i
<nTabCount
&& !bProtected
; i
++)
1771 if (rDoc
.IsTabProtected(i
)) // look after protected table
1774 SfxWhichIter
aIter(rSet
);
1775 sal_uInt16 nWhich
= aIter
.FirstWhich();
1776 sal_uInt16 nSlotId
= 0;
1780 nSlotId
= SfxItemPool::IsWhich( nWhich
)
1781 ? GetPool().GetSlotId( nWhich
)
1786 case SID_STYLE_APPLY
:
1788 rSet
.DisableItem( nSlotId
);
1791 case SID_STYLE_FAMILY2
: // cell style sheets
1793 SfxStyleSheet
* pStyleSheet
= const_cast<SfxStyleSheet
*>(GetStyleSheetFromMarked());
1796 rSet
.Put( SfxTemplateItem( nSlotId
, pStyleSheet
->GetName() ) );
1798 rSet
.Put( SfxTemplateItem( nSlotId
, OUString() ) );
1802 case SID_STYLE_FAMILY3
: // drawing style sheets
1804 SfxStyleSheet
* pStyleSheet
= GetDrawView()->GetStyleSheet();
1807 rSet
.Put( SfxTemplateItem( nSlotId
, pStyleSheet
->GetName() ) );
1809 rSet
.Put( SfxTemplateItem( nSlotId
, OUString() ) );
1813 case SID_STYLE_FAMILY4
: // page style sheets
1815 SCTAB nCurTab
= GetViewData().GetTabNo();
1816 OUString aPageStyle
= rDoc
.GetPageStyle( nCurTab
);
1817 SfxStyleSheet
* pStyleSheet
= pStylePool
? static_cast<SfxStyleSheet
*>(pStylePool
->
1818 Find( aPageStyle
, SfxStyleFamily::Page
)) : nullptr;
1821 rSet
.Put( SfxTemplateItem( nSlotId
, aPageStyle
) );
1823 rSet
.Put( SfxTemplateItem( nSlotId
, OUString() ) );
1827 case SID_STYLE_WATERCAN
:
1829 rSet
.Put(SfxBoolItem(nSlotId
, ScModule::get()->GetIsWaterCan()));
1833 case SID_STYLE_UPDATE_BY_EXAMPLE
:
1835 std::unique_ptr
<SfxUInt16Item
> pFamilyItem
;
1836 GetViewFrame().GetBindings().QueryState(SID_STYLE_FAMILY
, pFamilyItem
);
1838 bool bPage
= pFamilyItem
&& SfxStyleFamily::Page
== static_cast<SfxStyleFamily
>(pFamilyItem
->GetValue());
1840 if ( bProtected
|| bPage
)
1841 rSet
.DisableItem( nSlotId
);
1845 case SID_STYLE_EDIT
:
1846 case SID_STYLE_DELETE
:
1847 case SID_STYLE_HIDE
:
1848 case SID_STYLE_SHOW
:
1850 std::unique_ptr
<SfxUInt16Item
> pFamilyItem
;
1851 GetViewFrame().GetBindings().QueryState(SID_STYLE_FAMILY
, pFamilyItem
);
1852 bool bPage
= pFamilyItem
&& SfxStyleFamily::Page
== static_cast<SfxStyleFamily
>(pFamilyItem
->GetValue());
1854 if ( bProtected
&& !bPage
)
1855 rSet
.DisableItem( nSlotId
);
1863 nWhich
= aIter
.NextWhich();
1867 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */