Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  tabvwsha.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <com/sun/star/table/BorderLineStyle.hpp>
#include <officecfg/Office/Calc.hxx>

#include <comphelper/lok.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/langitem.hxx>
#include <o3tl/temporary.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <sfx2/sfxdlg.hxx>
#include <sfx2/sidebar/Sidebar.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/newstyle.hxx>
#include <sfx2/tplpitem.hxx>
#include <svl/ilstitem.hxx>
#include <svl/numformat.hxx>
#include <svl/zformat.hxx>
#include <svl/int64item.hxx>
#include <svl/ptitem.hxx>
#include <svl/srchitem.hxx>
#include <svl/srchdefs.hxx>
#include <svl/stritem.hxx>
#include <svl/whiter.hxx>
#include <svx/numinf.hxx>
#include <svx/xbtmpit.hxx>
#include <svx/xlndsit.hxx>
#include <svx/xlnstit.hxx>
#include <svx/xlnedit.hxx>
#include <svx/xflgrit.hxx>
#include <svx/xflftrit.hxx>
#include <svx/xflhtit.hxx>
#include <svx/zoomslideritem.hxx>

#include <global.hxx>
#include <appoptio.hxx>
#include <attrib.hxx>
#include <cellform.hxx>
#include <cellvalue.hxx>
#include <compiler.hxx>
#include <docsh.hxx>
#include <document.hxx>
#include <formulacell.hxx>
#include <globstr.hrc>
#include <inputhdl.hxx>
#include <inputwin.hxx>
#include <markdata.hxx>
#include <patattr.hxx>
#include <sc.hrc>
#include <scabstdlg.hxx>
#include <scitems.hxx>
#include <scmod.hxx>
#include <scresid.hxx>
#include <stlpool.hxx>
#include <tabvwsh.hxx>
#include <tokenarray.hxx>
#include <viewdata.hxx>
#include <printfun.hxx>
#include <undostyl.hxx>
#include <futext.hxx>

#include <memory>

using namespace com::sun::star;

bool ScTabViewShell::GetFunction( OUString& rFuncStr, FormulaError nErrCode )
{
    sal_uInt32 nFuncs = ScModule::get()->GetAppOptions().GetStatusFunc();
    ScViewData& rViewData   = GetViewData();
    ScMarkData& rMark       = rViewData.GetMarkData();
    bool bIgnoreError = (rMark.IsMarked() || rMark.IsMultiMarked());
    bool bFirst = true;
    for ( sal_uInt16 nFunc = 0; nFunc < 32; nFunc++ )
    {
        if ( !(nFuncs & (1U << nFunc)) )
            continue;
        ScSubTotalFunc eFunc = static_cast<ScSubTotalFunc>(nFunc);

        if (bIgnoreError && (eFunc == SUBTOTAL_FUNC_CNT || eFunc == SUBTOTAL_FUNC_CNT2))
            nErrCode = FormulaError::NONE;

        if (nErrCode != FormulaError::NONE)
        {
            rFuncStr = ScGlobal::GetLongErrorString(nErrCode);
            return true;
        }

        TranslateId pGlobStrId;
        switch (eFunc)
        {
            case SUBTOTAL_FUNC_AVE:  pGlobStrId = STR_FUN_TEXT_AVG; break;
            case SUBTOTAL_FUNC_CNT:  pGlobStrId = STR_FUN_TEXT_COUNT; break;
            case SUBTOTAL_FUNC_CNT2: pGlobStrId = STR_FUN_TEXT_COUNT2; break;
            case SUBTOTAL_FUNC_MAX:  pGlobStrId = STR_FUN_TEXT_MAX; break;
            case SUBTOTAL_FUNC_MIN:  pGlobStrId = STR_FUN_TEXT_MIN; break;
            case SUBTOTAL_FUNC_SUM:  pGlobStrId = STR_FUN_TEXT_SUM; break;
            case SUBTOTAL_FUNC_SELECTION_COUNT: pGlobStrId = STR_FUN_TEXT_SELECTION_COUNT; break;

            default:
            {
                // added to avoid warnings
            }
        }
        if (pGlobStrId)
        {
            ScDocument& rDoc        = rViewData.GetDocument();
            SCCOL       nPosX       = rViewData.GetCurX();
            SCROW       nPosY       = rViewData.GetCurY();
            SCTAB       nTab        = rViewData.GetTabNo();

            OUString aStr = ScResId(pGlobStrId) + ": ";

            ScAddress aCursor( nPosX, nPosY, nTab );
            double nVal;
            if ( rDoc.GetSelectionFunction( eFunc, aCursor, rMark, nVal ) )
            {
                if ( nVal == 0.0 )
                    aStr += "0";
                else
                {
                    // Number in the standard format, the other on the cursor position
                    ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
                    sal_uInt32 nNumFmt = 0;
                    if ( eFunc != SUBTOTAL_FUNC_CNT && eFunc != SUBTOTAL_FUNC_CNT2 && eFunc != SUBTOTAL_FUNC_SELECTION_COUNT)
                    {
                        // number format from attributes or formula
                        nNumFmt = rDoc.GetNumberFormat( nPosX, nPosY, nTab );
                        // If the number format is time (without date) and the
                        // result is not within 24 hours, use a duration
                        // format. Summing date+time doesn't make much sense
                        // otherwise but we also don't want to display duration
                        // for a single date+time value.
                        if (nVal < 0.0 || nVal >= 1.0)
                        {
                            const SvNumberformat* pFormat = rContext.NFGetFormatEntry(nNumFmt);
                            if (pFormat && (pFormat->GetType() == SvNumFormatType::TIME))
                                nNumFmt = rContext.NFGetTimeFormat( nVal, pFormat->GetLanguage(), true);
                        }
                    }

                    OUString aValStr;
                    const Color* pDummy;
                    rContext.NFGetOutputString( nVal, nNumFmt, aValStr, &pDummy );
                    aStr += aValStr;
                }
            }
            if ( bFirst )
            {
                rFuncStr += aStr;
                bFirst = false;
            }
            else
                rFuncStr += "; " + aStr;
        }
    }

    return !rFuncStr.isEmpty();
}

//  Functions that are disabled, depending on the selection
//  Default:
//      SID_DELETE,
//      SID_DELETE_CONTENTS,
//      FID_DELETE_CELL
//      FID_VALIDATION

void ScTabViewShell::GetState( SfxItemSet& rSet )
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    ScDocShell& rDocShell   = rViewData.GetDocShell();
    ScMarkData& rMark       = rViewData.GetMarkData();
    SCCOL       nPosX       = rViewData.GetCurX();
    SCROW       nPosY       = rViewData.GetCurY();
    SCTAB       nTab        = rViewData.GetTabNo();

    SfxViewFrame& rThisFrame = GetViewFrame();
    bool bOle = GetViewFrame().GetFrame().IsInPlace();

    SCTAB nTabSelCount = rMark.GetSelectCount();

    SfxWhichIter    aIter(rSet);
    sal_uInt16          nWhich = aIter.FirstWhich();

    while ( nWhich )
    {
        switch ( nWhich )
        {
            case FID_CHG_COMMENT:
                {
                    ScAddress aPos( nPosX, nPosY, nTab );
                    if ( rDocShell.IsReadOnly() || !rDocShell.GetChangeAction(aPos) || rDocShell.IsDocShared() )
                        rSet.DisableItem( nWhich );
                }
                break;

            case SID_OPENDLG_EDIT_PRINTAREA:
            case SID_ADD_PRINTAREA:
            case SID_DEFINE_PRINTAREA:
                {
                    if ( rDocShell.IsDocShared() )
                    {
                        rSet.DisableItem( nWhich );
                    }
                }
                break;

            case SID_DELETE_PRINTAREA:
                if ( rDocShell.IsDocShared() )
                {
                    rSet.DisableItem( nWhich );
                }
                else if (rDoc.IsPrintEntireSheet(nTab))
                    rSet.DisableItem(nWhich);
                break;

            case SID_STATUS_PAGESTYLE:
            case SID_HFEDIT:
                GetViewData().GetDocShell().GetStatePageStyle( rSet, nTab );
                break;

            case SID_SEARCH_ITEM:
            {
                SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
                // Search on current selection if a range is marked.
                aItem.SetSelection(rMark.IsMarked());
                rSet.Put(aItem);
                break;
            }

            case SID_SEARCH_OPTIONS:
                {
                    // Anything goes
                    SearchOptionFlags nOptions = SearchOptionFlags::ALL;

                    // No replacement if ReadOnly
                    if (GetViewData().GetDocShell().IsReadOnly() || IsCurrentLokViewReadOnly())
                        nOptions &= ~SearchOptionFlags( SearchOptionFlags::REPLACE | SearchOptionFlags::REPLACE_ALL );
                    rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(nOptions) ) );
                }
                break;

            case SID_CURRENTCELL:
                {
                    ScAddress aScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), 0 );
                    OUString  aAddr(aScAddress.Format(ScRefFlags::ADDR_ABS, nullptr, rDoc.GetAddressConvention()));
                    SfxStringItem   aPosItem( SID_CURRENTCELL, aAddr );

                    rSet.Put( aPosItem );
                }
                break;

            case SID_CURRENTTAB:
                // Table for Basic is 1-based
                rSet.Put( SfxUInt16Item( nWhich, static_cast<sal_uInt16>(GetViewData().GetTabNo()) + 1 ) );
                break;

            case SID_CURRENTDOC:
                rSet.Put( SfxStringItem( nWhich, GetViewData().GetDocShell().GetTitle() ) );
                break;

            case FID_TOGGLEINPUTLINE:
                {
                    sal_uInt16 nId = ScInputWindowWrapper::GetChildWindowId();

                    if ( rThisFrame.KnowsChildWindow( nId ) )
                    {
                        SfxChildWindow* pWnd = rThisFrame.GetChildWindow( nId );
                        rSet.Put( SfxBoolItem( nWhich, pWnd != nullptr ) );
                    }
                    else
                        rSet.DisableItem( nWhich );
                }
                break;

            case FID_DEL_MANUALBREAKS:
                if (!rDoc.HasManualBreaks(nTab))
                    rSet.DisableItem( nWhich );
                break;

            case FID_RESET_PRINTZOOM:
                {
                    // disable if already set to default

                    OUString aStyleName = rDoc.GetPageStyle( nTab );
                    ScStyleSheetPool* pStylePool = rDoc.GetStyleSheetPool();
                    SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName,
                                                    SfxStyleFamily::Page );
                    OSL_ENSURE( pStyleSheet, "PageStyle not found" );
                    if ( pStyleSheet )
                    {
                        SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
                        sal_uInt16 nScale = rStyleSet.Get(ATTR_PAGE_SCALE).GetValue();
                        sal_uInt16 nPages = rStyleSet.Get(ATTR_PAGE_SCALETOPAGES).GetValue();
                        if ( nScale == 100 && nPages == 0 )
                            rSet.DisableItem( nWhich );
                    }
                }
                break;

            case SID_ZOOM_IN:
                {
                    const Fraction& rZoomY = GetViewData().GetZoomY();
                    tools::Long nZoom = tools::Long(rZoomY * 100);
                    if (nZoom >= MAXZOOM)
                        rSet.DisableItem(nWhich);
                }
                break;
            case SID_ZOOM_OUT:
                {
                    const Fraction& rZoomY = GetViewData().GetZoomY();
                    tools::Long nZoom = tools::Long(rZoomY * 100);
                    if (nZoom <= MINZOOM)
                        rSet.DisableItem(nWhich);
                }
                break;

            case FID_SCALE:
            case SID_ATTR_ZOOM:
                if ( bOle )
                    rSet.DisableItem( nWhich );
                else
                {
                    const Fraction& rOldY = GetViewData().GetZoomY();
                    sal_uInt16 nZoom = static_cast<sal_uInt16>(tools::Long( rOldY * 100 ));
                    rSet.Put( SvxZoomItem( SvxZoomType::PERCENT, nZoom, TypedWhichId<SvxZoomItem>(nWhich) ) );
                }
                break;

            case SID_ATTR_ZOOMSLIDER:
                {
                    if ( bOle )
                        rSet.DisableItem( nWhich );
                    else
                    {
                        const Fraction& rOldY = GetViewData().GetZoomY();
                        sal_uInt16 nCurrentZoom = static_cast<sal_uInt16>(tools::Long( rOldY * 100 ));

                        if( nCurrentZoom )
                        {
                            SvxZoomSliderItem aZoomSliderItem( nCurrentZoom, MINZOOM, MAXZOOM, SID_ATTR_ZOOMSLIDER );
                            aZoomSliderItem.AddSnappingPoint( 100 );
                            rSet.Put( aZoomSliderItem );
                        }
                    }
                }
                break;

            case FID_FUNCTION_BOX:
            {
                const bool bBoxOpen = ::sfx2::sidebar::Sidebar::IsPanelVisible(u"ScFunctionsPanel",
                                                    rThisFrame.GetFrame().GetFrameInterface());
                rSet.Put(SfxBoolItem(nWhich, bBoxOpen));
                break;
            }

            case FID_TOGGLESYNTAX:
                rSet.Put(SfxBoolItem(nWhich, GetViewData().IsSyntaxMode()));
                break;

            case FID_TOGGLECOLROWHIGHLIGHTING:
                rSet.Put(SfxBoolItem(
                    nWhich,
                    officecfg::Office::Calc::Content::Display::ColumnRowHighlighting::get()));
                break;

            case FID_TOGGLEHEADERS:
                rSet.Put(SfxBoolItem(nWhich, GetViewData().IsHeaderMode()));
                break;

            case FID_TOGGLEFORMULA:
                {
                    const ScViewOptions& rOpts = rViewData.GetOptions();
                    bool bFormulaMode = rOpts.GetOption( VOPT_FORMULAS );
                    rSet.Put(SfxBoolItem(nWhich, bFormulaMode ));
                }
                break;

            case FID_NORMALVIEWMODE:
            case FID_PAGEBREAKMODE:
                // always handle both slots - they exclude each other
                if ( bOle )
                {
                    rSet.DisableItem( FID_NORMALVIEWMODE );
                    rSet.DisableItem( FID_PAGEBREAKMODE );
                }
                else
                {
                    rSet.Put(SfxBoolItem(FID_NORMALVIEWMODE, !GetViewData().IsPagebreakMode()));
                    rSet.Put(SfxBoolItem(FID_PAGEBREAKMODE, GetViewData().IsPagebreakMode()));
                }
                break;

            case FID_PROTECT_DOC:
                {
                    if ( rDocShell.IsDocShared() )
                    {
                        rSet.DisableItem( nWhich );
                    }
                    else
                    {
                        rSet.Put( SfxBoolItem( nWhich, rDoc.IsDocProtected() ) );
                    }
                }
                break;

            case FID_PROTECT_TABLE:
                {
                    if ( rDocShell.IsDocShared() )
                    {
                        rSet.DisableItem( nWhich );
                    }
                    else
                    {
                        rSet.Put( SfxBoolItem( nWhich, rDoc.IsTabProtected( nTab ) ) );
                    }
                }
                break;

            case SID_AUTO_OUTLINE:
                {
                    if (rDoc.GetChangeTrack()!=nullptr || GetViewData().IsMultiMarked())
                    {
                        rSet.DisableItem( nWhich );
                    }
                }
                break;

            case SID_OUTLINE_DELETEALL:
                {
                    SCTAB nOlTab = GetViewData().GetTabNo();
                    ScOutlineTable* pOlTable = rDoc.GetOutlineTable( nOlTab );
                    if (pOlTable == nullptr)
                        rSet.DisableItem( nWhich );
                }
                break;

            case SID_WINDOW_SPLIT:
                rSet.Put(SfxBoolItem(nWhich,
                            rViewData.GetHSplitMode() == SC_SPLIT_NORMAL ||
                            rViewData.GetVSplitMode() == SC_SPLIT_NORMAL ));
                break;

            case SID_WINDOW_FIX:
                if(!comphelper::LibreOfficeKit::isActive())
                {
                    rSet.Put(SfxBoolItem(nWhich,
                                rViewData.GetHSplitMode() == SC_SPLIT_FIX ||
                                rViewData.GetVSplitMode() == SC_SPLIT_FIX ));
                }
                else
                {
                    rSet.Put(SfxBoolItem(nWhich,
                            rViewData.GetLOKSheetFreezeIndex(true) > 0 ||
                            rViewData.GetLOKSheetFreezeIndex(false) > 0 ));
                }
                break;

            case SID_WINDOW_FIX_COL:
            case SID_WINDOW_FIX_ROW:
                {
                    Point aPos;
                    bool bIsCol = (nWhich == SID_WINDOW_FIX_COL);
                    aPos.setX(rViewData.GetLOKSheetFreezeIndex(bIsCol));
                    aPos.setY(rViewData.GetTabNo());
                    rSet.Put(SfxPointItem(nWhich, aPos));
                }
                break;

            case FID_CHG_SHOW:
                {
                    if ( rDoc.GetChangeTrack() == nullptr || ( rDocShell.IsDocShared() ) )
                        rSet.DisableItem( nWhich );
                }
                break;
            case FID_CHG_ACCEPT:
                {
                    if(
                       ( !rDoc.GetChangeTrack() && !rThisFrame.HasChildWindow(FID_CHG_ACCEPT) )
                       ||
                       ( rDocShell.IsDocShared() )
                      )
                    {
                        rSet.DisableItem( nWhich);
                    }
                    else
                    {
                        rSet.Put(SfxBoolItem(FID_CHG_ACCEPT,
                            rThisFrame.HasChildWindow(FID_CHG_ACCEPT)));
                    }
                }
                break;

            case SID_FORMATPAGE:
                // in protected tables
                if ( rDocShell.IsReadOnly() || rDocShell.IsDocShared() )
                    rSet.DisableItem( nWhich );
                break;

            case SID_PRINTPREVIEW:
                // Toggle slot needs a State
                rSet.Put( SfxBoolItem( nWhich, false ) );
                break;

            case SID_READONLY_MODE:
                rSet.Put( SfxBoolItem( nWhich, GetViewData().GetDocShell().IsReadOnly() ) );
                break;

            case FID_TAB_DESELECTALL:
                if ( nTabSelCount == 1 )
                    rSet.DisableItem( nWhich );     // enabled only if several sheets are selected
                break;

            case FID_TOGGLEHIDDENCOLROW:
                const svtools::ColorConfig& rColorCfg = ScModule::get()->GetColorConfig();
                rSet.Put( SfxBoolItem( nWhich, rColorCfg.GetColorValue(svtools::CALCHIDDENROWCOL).bIsVisible) );
                break;

        } // switch ( nWitch )
        nWhich = aIter.NextWhich();
    } // while ( nWitch )
}

void ScTabViewShell::ExecuteCellFormatDlg(SfxRequest& rReq, const OUString &rName)
{
    ScDocument& rDoc = GetViewData().GetDocument();

    std::shared_ptr<SvxBoxItem> aLineOuter(std::make_shared<SvxBoxItem>(ATTR_BORDER));
    std::shared_ptr<SvxBoxInfoItem> aLineInner(std::make_shared<SvxBoxInfoItem>(ATTR_BORDER_INNER));

    const ScPatternAttr*    pOldAttrs       = GetSelectionPattern();

    auto xOldSet = std::make_shared<SfxItemSet>(pOldAttrs->GetItemSet());

    xOldSet->MergeRange(XATTR_FILLSTYLE, XATTR_FILLCOLOR);

    xOldSet->MergeRange(SID_ATTR_BORDER_STYLES, SID_ATTR_BORDER_DEFAULT_WIDTH);

    // We only allow these border line types.
    std::vector<sal_Int32> aBorderStyles{
        table::BorderLineStyle::SOLID,
        table::BorderLineStyle::DOTTED,
        table::BorderLineStyle::DASHED,
        table::BorderLineStyle::FINE_DASHED,
        table::BorderLineStyle::DASH_DOT,
        table::BorderLineStyle::DASH_DOT_DOT,
        table::BorderLineStyle::DOUBLE_THIN };

    xOldSet->Put(SfxIntegerListItem(SID_ATTR_BORDER_STYLES, std::move(aBorderStyles)));

    // Set the default border width to 0.75 points.
    SfxInt64Item aBorderWidthItem(SID_ATTR_BORDER_DEFAULT_WIDTH, 75);
    xOldSet->Put(aBorderWidthItem);

    // Get border items and put them in the set:
    GetSelectionFrame( aLineOuter, aLineInner );

    //Fix border incorrect for RTL fdo#62399
    if( rDoc.IsLayoutRTL( GetViewData().GetTabNo() ) )
    {
        std::unique_ptr<SvxBoxItem> aNewFrame(aLineOuter->Clone());
        std::unique_ptr<SvxBoxInfoItem> aTempInfo(aLineInner->Clone());

        if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::LEFT) )
            aNewFrame->SetLine( aLineOuter->GetLeft(), SvxBoxItemLine::RIGHT );
        if ( aLineInner->IsValid(SvxBoxInfoItemValidFlags::RIGHT) )
            aNewFrame->SetLine( aLineOuter->GetRight(), SvxBoxItemLine::LEFT );

        aLineInner->SetValid( SvxBoxInfoItemValidFlags::LEFT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::RIGHT));
        aLineInner->SetValid( SvxBoxInfoItemValidFlags::RIGHT, aTempInfo->IsValid(SvxBoxInfoItemValidFlags::LEFT));

        xOldSet->Put( std::move(aNewFrame) );
    }
    else
    {
        xOldSet->Put( *aLineOuter );
    }

    xOldSet->Put( *aLineInner );

    // Generate NumberFormat Value from Value and Language and box it.
    if (pOldAttrs->HasNumberFormat()) // tdf#42989: don't set it for multi-format selection
        xOldSet->Put(
            SfxUInt32Item(ATTR_VALUE_FORMAT, pOldAttrs->GetNumberFormat(rDoc.GetFormatTable())));
    else // Make sure it's invalid, when ATTR_LANGUAGE_FORMAT is invalid
        xOldSet->InvalidateItem(ATTR_VALUE_FORMAT);

    std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem = MakeNumberInfoItem(rDoc, GetViewData());
    xOldSet->MergeRange( SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO );
    xOldSet->Put( std::move(pNumberInfoItem) );

    bInFormatDialog = true;
    ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

    VclPtr<SfxAbstractTabDialog> pDlg(pFact->CreateScAttrDlg(GetFrameWeld(), xOldSet.get()));

    if (!rName.isEmpty())
        pDlg->SetCurPageId(rName);

    auto xRequest = std::make_shared<SfxRequest>(rReq);
    rReq.Ignore(); // the 'old' request is not relevant any more

    pDlg->StartExecuteAsync([pDlg, xOldSet=std::move(xOldSet), xRequest=std::move(xRequest), this](sal_Int32 nResult){
        bInFormatDialog = false;

        if ( nResult == RET_OK )
        {
            const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();
            if(const SvxNumberInfoItem* pItem = pOutSet->GetItemIfSet(SID_ATTR_NUMBERFORMAT_INFO))
            {
                UpdateNumberFormatter(*pItem);
            }

            ApplyAttributes(*pOutSet, *xOldSet);

            xRequest->Done(*pOutSet);
        }

        pDlg->disposeOnce();
    });
}

const OUString* ScTabViewShell::GetEditString() const
{
    if (mpInputHandler)
        return &mpInputHandler->GetEditString();

    return nullptr;
}

bool ScTabViewShell::IsRefInputMode() const
{
    if (ScModule* pScMod = ScModule::get())
    {
        if( pScMod->IsRefDialogOpen() )
            return pScMod->IsFormulaMode();
        if( pScMod->IsFormulaMode() )
        {
            ScInputHandler* pHdl = pScMod->GetInputHdl();
            if ( pHdl )
            {
                const ScViewData& rViewData = GetViewData();
                ScDocument& rDoc = rViewData.GetDocument();
                const ScAddress aPos( rViewData.GetCurPos() );
                const sal_uInt32 nIndex = rDoc.GetAttr(aPos, ATTR_VALUE_FORMAT )->GetValue();
                const SvNumFormatType nType = rDoc.GetFormatTable()->GetType(nIndex);
                if (nType == SvNumFormatType::TEXT)
                {
                    return false;
                }
                OUString aString = pHdl->GetEditString();
                if ( !pHdl->GetSelIsRef() && aString.getLength() > 1 &&
                     ( aString[0] == '+' || aString[0] == '-' ) )
                {
                    ScCompiler aComp( rDoc, aPos, rDoc.GetGrammar() );
                    aComp.SetCloseBrackets( false );
                    std::unique_ptr<ScTokenArray> pArr(aComp.CompileString(aString));
                    if ( pArr && pArr->MayReferenceFollow() )
                    {
                        return true;
                    }
                }
                else
                {
                    return true;
                }
            }
        }
    }

    return false;
}

void ScTabViewShell::ExecuteInputDirect()
{
    if ( !IsRefInputMode() )
    {
        if (ScModule* pScMod = ScModule::get())
        {
            pScMod->InputEnterHandler();
        }
    }
}

void ScTabViewShell::UpdateInputHandler( bool bForce /* = sal_False */, bool bStopEditing /* = sal_True */ )
{
    ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : ScModule::get()->GetInputHdl();

    if ( pHdl )
    {
        OUString                aString;
        const EditTextObject*   pObject     = nullptr;
        ScViewData&             rViewData   = GetViewData();
        ScDocument&             rDoc        = rViewData.GetDocument();
        SCCOL                   nPosX       = rViewData.GetCurX();
        SCROW                   nPosY       = rViewData.GetCurY();
        SCTAB                   nTab        = rViewData.GetTabNo();
        SCTAB                   nStartTab   = 0;
        SCTAB                   nEndTab     = 0;
        SCCOL                   nStartCol   = 0;
        SCROW                   nStartRow   = 0;
        SCCOL                   nEndCol     = 0;
        SCROW                   nEndRow     = 0;
        ScAddress aPos = rViewData.GetCurPos();

        rViewData.GetSimpleArea( nStartCol, nStartRow, nStartTab,
                                  nEndCol,   nEndRow,   nEndTab );

        PutInOrder( nStartCol, nEndCol );
        PutInOrder( nStartRow, nEndRow );
        PutInOrder( nStartTab, nEndTab );

        bool bHideFormula = false;
        bool bHideAll     = false;

        if (rDoc.IsTabProtected(nTab))
        {
            const ScProtectionAttr* pProt = rDoc.GetAttr( nPosX,nPosY,nTab,
                                                           ATTR_PROTECTION);
            bHideFormula = pProt->GetHideFormula();
            bHideAll     = pProt->GetHideCell();
        }

        if (!bHideAll)
        {
            ScRefCellValue rCell(rDoc, aPos);
            if (rCell.getType() == CELLTYPE_FORMULA)
            {
                if (!bHideFormula)
                    aString = rCell.getFormula()->GetFormula();
            }
            else if (rCell.getType() == CELLTYPE_EDIT)
            {
                pObject = rCell.getEditText();
            }
            else
            {
                ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
                sal_uInt32 nNumFmt = rDoc.GetNumberFormat( ScRange(aPos) );

                aString = ScCellFormat::GetInputString( rCell, nNumFmt, &rContext, rDoc );
                if (rCell.getType() == CELLTYPE_STRING)
                {
                    // Put a ' in front if necessary, so that the string is not
                    // unintentionally interpreted as a number, and to show the
                    // user that it is a string (#35060#).
                    // If cell is not formatted as Text, a leading apostrophe
                    // needs another prepended, also '=' or '+' or '-'
                    // otherwise starting a formula.
                    // NOTE: this corresponds with
                    // sc/source/core/data/column3.cxx ScColumn::ParseString()
                    // removing one apostrophe.
                    // For number format Text IsNumberFormat() would never
                    // result in numeric anyway.
                    if (!rContext.NFIsTextFormat(nNumFmt) && (aString.startsWith("'")
                                || aString.startsWith("=") || aString.startsWith("+") || aString.startsWith("-")
                                || rContext.NFIsNumberFormat(aString, nNumFmt, o3tl::temporary(double()))))
                        aString = "'" + aString;
                }
            }
        }

        ScInputHdlState aState( ScAddress( nPosX,     nPosY,     nTab ),
                                ScAddress( nStartCol, nStartRow, nTab ),
                                ScAddress( nEndCol,   nEndRow,   nTab ),
                                aString,
                                pObject );

        //  if using the view's local input handler, this view can always be set
        //  as current view inside NotifyChange.
        ScTabViewShell* pSourceSh = mpInputHandler ? this : nullptr;

        pHdl->NotifyChange( &aState, bForce, pSourceSh, bStopEditing );
    }

    SfxBindings& rBindings = GetViewFrame().GetBindings();
    rBindings.Invalidate( SID_STATUS_SUM );         // always together with the input row
    rBindings.Invalidate( SID_ATTR_SIZE );
    rBindings.Invalidate( SID_TABLE_CELL );
}

void ScTabViewShell::UpdateInputHandlerCellAdjust( SvxCellHorJustify eJust )
{
    if( ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : ScModule::get()->GetInputHdl() )
        pHdl->UpdateCellAdjust( eJust );
}

void ScTabViewShell::ExecuteSave( SfxRequest& rReq )
{
    // only SID_SAVEDOC / SID_SAVEASDOC
    bool bCommitChanges = true;
    const SfxItemSet* pReqArgs = rReq.GetArgs();
    const SfxPoolItem* pItem = nullptr;

    bool bHasDontTerminateEdit = pReqArgs && pReqArgs->HasItem(FN_PARAM_1, &pItem);
    if (bHasDontTerminateEdit && pItem)
        bCommitChanges = !static_cast<const SfxBoolItem*>(pItem)->GetValue();

    // Finish entering unless 'DontTerminateEdit' is specified, even if a formula is being processed
    if (bCommitChanges)
    {
        bool bLOKActive = comphelper::LibreOfficeKit::isActive();

        // Disable error dialog box when about to save in lok mode as
        // this ultimately invokes SvpSalInstance::DoYield() when we want
        // to save immediately without committing any erroneous input in possibly
        // a cell with validation rules. After save is complete the user
        // can continue editing.
        ScModule::get()->InputEnterHandler(ScEnterMode::NORMAL, bLOKActive /* bBeforeSavingInLOK */);

        if (bLOKActive)
        {
            // Normally this isn't needed, but in Calc when editing a cell formula
            // and manually saving (without changing cells or hitting enter), while
            // InputEnterHandler will mark the doc as modified (when it is), because
            // we will save the doc immediately afterwards, the modified state event
            // is clobbered. To avoid that, we need to update SID_DOC_MODIFIED so that
            // a possible state of "true" after "InputEnterHandler" will be sent
            // as a notification. It is important that the notification goes through
            // normal process (cache) rather than directly notifying the views.
            // Otherwise, because there is a previous state of "false" in cache, the
            // "false" state after saving will be ignored.
            // This will work only if .uno:ModifiedStatus message will be removed from
            // the mechanism that keeps in the message queue only last message of
            // a particular status even if the values are different.
            if (SfxBindings* pBindings = GetViewData().GetDocShell().GetViewBindings())
                pBindings->Update(SID_DOC_MODIFIED);
        }
    }

    if ( GetViewData().GetDocShell().IsDocShared() )
    {
        GetViewData().GetDocShell().SetDocumentModified();
    }

    // otherwise as normal
    GetViewData().GetDocShell().ExecuteSlot( rReq );
}

void ScTabViewShell::GetSaveState( SfxItemSet& rSet )
{
    SfxShell& rDocSh = GetViewData().GetDocShell();

    SfxWhichIter aIter(rSet);
    sal_uInt16 nWhich = aIter.FirstWhich();
    while( nWhich )
    {
        if ( nWhich != SID_SAVEDOC || !GetViewData().GetDocShell().IsDocShared() )
        {
            // get state from DocShell
            rDocSh.GetSlotState( nWhich, nullptr, &rSet );
        }
        nWhich = aIter.NextWhich();
    }
}

void ScTabViewShell::ExecDrawOpt( const SfxRequest& rReq )
{
    ScViewOptions aViewOptions = GetViewData().GetOptions();
    ScGridOptions aGridOptions = aViewOptions.GetGridOptions();

    SfxBindings& rBindings = GetViewFrame().GetBindings();
    const SfxItemSet* pArgs = rReq.GetArgs();
    const SfxPoolItem* pItem;
    sal_uInt16 nSlotId = rReq.GetSlot();
    switch (nSlotId)
    {
        case SID_GRID_VISIBLE:
            if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
            {
                aGridOptions.SetGridVisible( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
                aViewOptions.SetGridOptions(aGridOptions);
                rBindings.Invalidate(SID_GRID_VISIBLE);
            }
            break;

        case SID_GRID_USE:
            if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
            {
                aGridOptions.SetUseGridSnap( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
                aViewOptions.SetGridOptions(aGridOptions);
                rBindings.Invalidate(SID_GRID_USE);
            }
            break;

        case SID_HELPLINES_MOVE:
            if ( pArgs && pArgs->GetItemState(nSlotId,true,&pItem) == SfxItemState::SET )
            {
                aViewOptions.SetOption( VOPT_HELPLINES, static_cast<const SfxBoolItem*>(pItem)->GetValue() );
                rBindings.Invalidate(SID_HELPLINES_MOVE);
            }
            break;
    }

    GetViewData().SetOptions(aViewOptions);
}

void ScTabViewShell::GetDrawOptState( SfxItemSet& rSet )
{
    SfxBoolItem aBool;

    const ScViewOptions& rViewOptions = GetViewData().GetOptions();
    const ScGridOptions& rGridOptions = rViewOptions.GetGridOptions();

    aBool.SetValue(rGridOptions.GetGridVisible());
    aBool.SetWhich( SID_GRID_VISIBLE );
    rSet.Put( aBool );

    aBool.SetValue(rGridOptions.GetUseGridSnap());
    aBool.SetWhich( SID_GRID_USE );
    rSet.Put( aBool );

    aBool.SetValue(rViewOptions.GetOption( VOPT_HELPLINES ));
    aBool.SetWhich( SID_HELPLINES_MOVE );
    rSet.Put( aBool );
}

void ScTabViewShell::ExecStyle( SfxRequest& rReq )
{
    const SfxItemSet* pArgs = rReq.GetArgs();
    const sal_uInt16  nSlotId = rReq.GetSlot();
    if ( !pArgs && nSlotId != SID_STYLE_NEW_BY_EXAMPLE && nSlotId != SID_STYLE_UPDATE_BY_EXAMPLE )
    {
        // in case of vertical toolbar, sidebar shortcut icon
        GetDispatcher()->Execute( SID_STYLE_DESIGNER, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
        return;
    }

    SfxBindings&        rBindings   = GetViewData().GetBindings();
    const SCTAB         nCurTab     = GetViewData().GetTabNo();
    ScDocShell&         rDocSh      = GetViewData().GetDocShell();
    ScDocument&         rDoc        = rDocSh.GetDocument();
    ScMarkData&         rMark       = GetViewData().GetMarkData();
    ScModule*           pScMod      = ScModule::get();
    SdrObject*          pEditObject = GetDrawView()->GetTextEditObject();
    OutlinerView*       pOLV        = GetDrawView()->GetTextEditOutlinerView();
    ESelection          aSelection  = pOLV ? pOLV->GetSelection() : ESelection();
    OUString            aRefName;
    bool                bUndo       = rDoc.IsUndoEnabled();

    SfxStyleSheetBasePool*  pStylePool  = rDoc.GetStyleSheetPool();
    SfxStyleSheetBase*      pStyleSheet = nullptr;

    bool bStyleToMarked = false;
    bool bListAction = false;
    bool bAddUndo = false;          // add ScUndoModifyStyle (style modified)
    auto xOldData = std::make_shared<ScStyleSaveData>();       // for undo/redo
    auto xNewData = std::make_shared<ScStyleSaveData>();

    SfxStyleFamily eFamily = SfxStyleFamily::Para;
    const SfxUInt16Item* pFamItem;
    const SfxStringItem* pFamilyNameItem;
    if ( pArgs && (pFamItem = pArgs->GetItemIfSet( SID_STYLE_FAMILY )) )
        eFamily = static_cast<SfxStyleFamily>(pFamItem->GetValue());
    else if ( pArgs && (pFamilyNameItem = pArgs->GetItemIfSet( SID_STYLE_FAMILYNAME )) )
    {
        const OUString& sFamily = pFamilyNameItem->GetValue();
        if (sFamily == "CellStyles")
            eFamily = SfxStyleFamily::Para;
        else if (sFamily == "PageStyles")
            eFamily = SfxStyleFamily::Page;
        else if (sFamily == "GraphicStyles")
            eFamily = SfxStyleFamily::Frame;
    }

    OUString                aStyleName;
    sal_uInt16              nRetMask = 0xffff;

    switch ( nSlotId )
    {
        case SID_STYLE_NEW:
            {
                const SfxPoolItem* pNameItem;
                if (pArgs && SfxItemState::SET == pArgs->GetItemState( nSlotId, true, &pNameItem ))
                    aStyleName  = static_cast<const SfxStringItem*>(pNameItem)->GetValue();

                const SfxStringItem* pRefItem=nullptr;
                if (pArgs && (pRefItem = pArgs->GetItemIfSet( SID_STYLE_REFERENCE )))
                {
                    aRefName  = pRefItem->GetValue();
                }

                pStyleSheet = &(pStylePool->Make( aStyleName, eFamily,
                                                  SfxStyleSearchBits::UserDefined ) );

                if (pStyleSheet->HasParentSupport())
                    pStyleSheet->SetParent(aRefName);
            }
            break;

        case SID_STYLE_APPLY:
        {
            const SfxStringItem* pNameItem = rReq.GetArg<SfxStringItem>(SID_APPLY_STYLE);
            const SfxStringItem* pFamilyItem = rReq.GetArg<SfxStringItem>(SID_STYLE_FAMILYNAME);
            if ( pFamilyItem && pNameItem )
            {
                try
                {
                    css::uno::Reference< css::container::XNameAccess > xStyles;
                    css::uno::Reference< css::container::XNameAccess > xCont = rDocSh.GetModel()->getStyleFamilies();
                    xCont->getByName(pFamilyItem->GetValue()) >>= xStyles;
                    css::uno::Reference< css::beans::XPropertySet > xInfo;
                    xStyles->getByName( pNameItem->GetValue() ) >>= xInfo;
                    OUString aUIName;
                    xInfo->getPropertyValue(u"DisplayName"_ustr) >>= aUIName;
                    if ( !aUIName.isEmpty() )
                        rReq.AppendItem( SfxStringItem( SID_STYLE_APPLY, aUIName ) );
                }
                catch( css::uno::Exception& )
                {
                }
            }
            [[fallthrough]];
        }
        case SID_STYLE_EDIT:
        case SID_STYLE_DELETE:
        case SID_STYLE_HIDE:
        case SID_STYLE_SHOW:
        case SID_STYLE_NEW_BY_EXAMPLE:
            {
                const SfxPoolItem* pNameItem;
                if (pArgs && SfxItemState::SET == pArgs->GetItemState(nSlotId, true, &pNameItem))
                    aStyleName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
                else if ( nSlotId == SID_STYLE_NEW_BY_EXAMPLE )
                {
                    weld::Window* pDialogParent = rReq.GetFrameWeld();
                    if (!pDialogParent)
                        pDialogParent = GetFrameWeld();
                    SfxNewStyleDlg aDlg(pDialogParent, *pStylePool, eFamily);
                    if (aDlg.run() != RET_OK)
                        return;
                    aStyleName = aDlg.GetName();
                }

                pStyleSheet = pStylePool->Find( aStyleName, eFamily );

                xOldData->InitFromStyle( pStyleSheet );
            }
            break;

        case SID_STYLE_WATERCAN:
        {
            bool bWaterCan = pScMod->GetIsWaterCan();

            if( !bWaterCan )
            {
                const SfxPoolItem* pItem;

                if (pArgs && SfxItemState::SET == pArgs->GetItemState(nSlotId, true, &pItem))
                {
                    const SfxStringItem* pStrItem = dynamic_castconst SfxStringItem *>( pItem );
                    if ( pStrItem )
                    {
                        aStyleName  = pStrItem->GetValue();
                        pStyleSheet = pStylePool->Find( aStyleName, eFamily );

                        if ( pStyleSheet )
                        {
                            static_cast<ScStyleSheetPool*>(pStylePool)->
                                    SetActualStyleSheet( pStyleSheet );
                            rReq.Done();
                        }
                    }
                }
            }

            if ( !bWaterCan && pStyleSheet )
            {
                pScMod->SetWaterCan( true );
                SetActivePointer( PointerStyle::Fill );
                rReq.Done();
            }
            else
            {
                pScMod->SetWaterCan( false );
                SetActivePointer( PointerStyle::Arrow );
                rReq.Done();
            }
        }
        break;

        default:
            break;
    }

    // set new style for paintbrush format mode
    if ( nSlotId == SID_STYLE_APPLY && pScMod->GetIsWaterCan() && pStyleSheet )
        static_cast<ScStyleSheetPool*>(pStylePool)->SetActualStyleSheet( pStyleSheet );

    switch ( eFamily )
    {
        case SfxStyleFamily::Para:
        {
            switch ( nSlotId )
            {
                case SID_STYLE_DELETE:
                {
                    if ( pStyleSheet )
                    {
                        RemoveStyleSheetInUse( pStyleSheet );
                        pStylePool->Remove( pStyleSheet );
                        InvalidateAttribs();
                        nRetMask = sal_uInt16(true);
                        bAddUndo = true;
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_HIDE:
                case SID_STYLE_SHOW:
                {
                    if ( pStyleSheet )
                    {
                        pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
                        InvalidateAttribs();
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_APPLY:
                {
                    if ( pStyleSheet && !pScMod->GetIsWaterCan() )
                    {
                        // apply style sheet to document
                        SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) );
                        InvalidateAttribs();
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_NEW_BY_EXAMPLE:
                case SID_STYLE_UPDATE_BY_EXAMPLE:
                {
                    // create/replace style sheet by attributes
                    // at cursor position:

                    const ScPatternAttr* pAttrItem = nullptr;

                    // The query if marked, was always wrong here,
                    // so now no more, and just from the cursor.
                    // If attributes are to be removed from the selection, still need to be
                    // cautious not to adopt items from templates
                    // (GetSelectionPattern also collects items from originals) (# 44748 #)
                    SCCOL       nCol = GetViewData().GetCurX();
                    SCROW       nRow = GetViewData().GetCurY();
                    pAttrItem = rDoc.GetPattern( nCol, nRow, nCurTab );

                    SfxItemSet aAttrSet = pAttrItem->GetItemSet();
                    aAttrSet.ClearItem( ATTR_MERGE );
                    aAttrSet.ClearItem( ATTR_MERGE_FLAG );

                    // Do not adopt conditional formatting and validity,
                    // because they can not be edited in the template
                    aAttrSet.ClearItem( ATTR_VALIDDATA );
                    aAttrSet.ClearItem( ATTR_CONDITIONAL );

                    if ( SID_STYLE_NEW_BY_EXAMPLE == nSlotId )
                    {
                        if ( bUndo )
                        {
                            OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE );
                            rDocSh.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
                            bListAction = true;
                        }

                        bool bConvertBack = false;
                        SfxStyleSheet*  pSheetInUse = const_cast<SfxStyleSheet*>(GetStyleSheetFromMarked());

                        // when a new style is present and is used in the selection,
                        // then the parent can not be adopted:
                        if ( pStyleSheet && pSheetInUse && pStyleSheet == pSheetInUse )
                            pSheetInUse = nullptr;

                        // if already present, first remove ...
                        if ( pStyleSheet )
                        {
                            // style pointer to names before erase,
                            // otherwise cells will get invalid pointer
                            //!!! As it happens, a method that does it for a particular style
                            rDoc.getCellAttributeHelper().AllStylesToNames();
                            bConvertBack = true;
                            pStylePool->Remove(pStyleSheet);
                        }

                        // ...and create new
                        pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
                                                         SfxStyleSearchBits::UserDefined );

                        // when a style is present, then this will become
                        // the parent of the new style:
                        if ( pSheetInUse && pStyleSheet->HasParentSupport() )
                            pStyleSheet->SetParent( pSheetInUse->GetName() );

                        if ( bConvertBack )
                            // Name to style pointer
                            rDoc.getCellAttributeHelper().UpdateAllStyleSheets(rDoc);
                        else
                            rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, aStyleName);

                        // Adopt attribute and use style
                        pStyleSheet->GetItemSet().Put( aAttrSet );
                        UpdateStyleSheetInUse( pStyleSheet );

                        //  call SetStyleSheetToMarked after adding the ScUndoModifyStyle
                        //  (pStyleSheet pointer is used!)
                        bStyleToMarked = true;
                    }
                    else // ( nSlotId == SID_STYLE_UPDATE_BY_EXAMPLE )
                    {
                        pStyleSheet = const_cast<SfxStyleSheet*>(GetStyleSheetFromMarked());

                        if ( pStyleSheet )
                        {
                            xOldData->InitFromStyle( pStyleSheet );

                            if ( bUndo )
                            {
                                OUString aUndo = ScResId( STR_UNDO_EDITCELLSTYLE );
                                rDocSh.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
                                bListAction = true;
                            }

                            pStyleSheet->GetItemSet().Put( aAttrSet );
                            UpdateStyleSheetInUse( pStyleSheet );

                            //  call SetStyleSheetToMarked after adding the ScUndoModifyStyle
                            //  (pStyleSheet pointer is used!)
                            bStyleToMarked = true;
                        }
                    }

                    xNewData->InitFromStyle( pStyleSheet );
                    bAddUndo = true;
                    rReq.Done();
                }
                break;

                default:
                    break;
            }
        } // case SfxStyleFamily::Para:
        break;

        case SfxStyleFamily::Page:
        {
            switch ( nSlotId )
            {
                case SID_STYLE_DELETE:
                {
                    nRetMask = sal_uInt16( nullptr != pStyleSheet );
                    if ( pStyleSheet )
                    {
                        if ( rDoc.RemovePageStyleInUse( pStyleSheet->GetName() ) )
                        {
                            ScPrintFunc( rDocSh, GetPrinter(true), nCurTab ).UpdatePages();
                            rBindings.Invalidate( SID_STATUS_PAGESTYLE );
                            rBindings.Invalidate( FID_RESET_PRINTZOOM );
                        }
                        pStylePool->Remove( pStyleSheet );
                        rBindings.Invalidate( SID_STYLE_FAMILY4 );
                        rDocSh.SetDocumentModified();
                        bAddUndo = true;
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_HIDE:
                case SID_STYLE_SHOW:
                {
                    nRetMask = sal_uInt16( nullptr != pStyleSheet );
                    if ( pStyleSheet )
                    {
                        pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
                        rBindings.Invalidate( SID_STYLE_FAMILY4 );
                        rDocSh.SetDocumentModified();
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_APPLY:
                {
                    nRetMask = sal_uInt16( nullptr != pStyleSheet );
                    if ( pStyleSheet && !pScMod->GetIsWaterCan() )
                    {
                        std::unique_ptr<ScUndoApplyPageStyle> pUndoAction;
                        SCTAB nTabCount = rDoc.GetTableCount();
                        for (const auto& rTab : rMark)
                        {
                            if (rTab >= nTabCount)
                                break;
                            OUString aOldName = rDoc.GetPageStyle( rTab );
                            if ( aOldName != aStyleName )
                            {
                                rDoc.SetPageStyle( rTab, aStyleName );
                                ScPrintFunc( rDocSh, GetPrinter(true), rTab ).UpdatePages();
                                if( !pUndoAction )
                                    pUndoAction.reset(new ScUndoApplyPageStyle( rDocSh, aStyleName ));
                                pUndoAction->AddSheetAction( rTab, aOldName );
                            }
                        }
                        if( pUndoAction )
                        {
                            rDocSh.GetUndoManager()->AddUndoAction( std::move(pUndoAction) );
                            rDocSh.SetDocumentModified();
                            rBindings.Invalidate( SID_STYLE_FAMILY4 );
                            rBindings.Invalidate( SID_STATUS_PAGESTYLE );
                            rBindings.Invalidate( FID_RESET_PRINTZOOM );
                        }
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_NEW_BY_EXAMPLE:
                {
                    const OUString aStrCurStyle = rDoc.GetPageStyle( nCurTab );

                    if ( aStrCurStyle != aStyleName )
                    {
                        SfxStyleSheetBase*  pCurStyle = pStylePool->Find( aStrCurStyle, eFamily );
                        SfxItemSet          aAttrSet  = pCurStyle->GetItemSet();
                        SCTAB               nInTab;
                        bool                bUsed = rDoc.IsPageStyleInUse( aStyleName, &nInTab );

                        // if already present, first remove...
                        if ( pStyleSheet )
                            pStylePool->Remove( pStyleSheet );

                        // ...and create new
                        pStyleSheet = &pStylePool->Make( aStyleName, eFamily,
                                                         SfxStyleSearchBits::UserDefined );

                        // Adopt attribute
                        pStyleSheet->GetItemSet().Put( aAttrSet );
                        rDocSh.SetDocumentModified();

                        // If being used -> Update
                        if ( bUsed )
                            ScPrintFunc( rDocSh, GetPrinter(true), nInTab ).UpdatePages();

                        xNewData->InitFromStyle( pStyleSheet );
                        bAddUndo = true;
                        rReq.Done();
                        nRetMask = sal_uInt16(true);
                    }
                }
                break;

                default:
                    break;
            } // switch ( nSlotId )
        } // case SfxStyleFamily::Page:
        break;

        case SfxStyleFamily::Frame:
        {
            switch ( nSlotId )
            {
                case SID_STYLE_DELETE:
                {
                    if ( pStyleSheet )
                    {
                        pStylePool->Remove( pStyleSheet );
                        InvalidateAttribs();
                        rDocSh.SetDocumentModified();
                        nRetMask = sal_uInt16(true);
                        bAddUndo = true;
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_HIDE:
                case SID_STYLE_SHOW:
                {
                    if ( pStyleSheet )
                    {
                        pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
                        InvalidateAttribs();
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_APPLY:
                {
                    if ( pStyleSheet && !pScMod->GetIsWaterCan() )
                    {
                        GetScDrawView()->ScEndTextEdit();
                        GetScDrawView()->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), false);

                        GetScDrawView()->InvalidateAttribs();
                        InvalidateAttribs();
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_NEW_BY_EXAMPLE:
                case SID_STYLE_UPDATE_BY_EXAMPLE:
                {
                    if (nSlotId == SID_STYLE_NEW_BY_EXAMPLE)
                    {
                        pStyleSheet = &pStylePool->Make( aStyleName, eFamily, SfxStyleSearchBits::UserDefined );

                        // when a style is present, then this will become
                        // the parent of the new style:
                        if (SfxStyleSheet* pOldStyle = GetDrawView()->GetStyleSheet())
                            pStyleSheet->SetParent(pOldStyle->GetName());
                    }
                    else
                    {
                        pStyleSheet = GetDrawView()->GetStyleSheet();
                        xOldData->InitFromStyle( pStyleSheet );
                    }

                    if ( bUndo )
                    {
                        OUString aUndo = ScResId( STR_UNDO_EDITGRAPHICSTYLE );
                        rDocSh.GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
                        bListAction = true;
                    }

                    SfxItemSet aCoreSet(GetDrawView()->GetModel().GetItemPool());
                    GetDrawView()->GetAttributes(aCoreSet, true);

                    SfxItemSet* pStyleSet = &pStyleSheet->GetItemSet();
                    pStyleSet->Put(aCoreSet);
                    static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));

                    xNewData->InitFromStyle( pStyleSheet );
                    bAddUndo = true;

                    //  call SetStyleSheet after adding the ScUndoModifyStyle
                    //  (pStyleSheet pointer is used!)
                    bStyleToMarked = true;
                    rReq.Done();
                }
                break;
                default:
                    break;
            }
        }
        break;
        default:
            break;
    } // switch ( eFamily )

    // create new or process through Dialog:
    if ( nSlotId == SID_STYLE_NEW || nSlotId == SID_STYLE_EDIT )
    {
        if (pStyleSheet)
        {
            ExecuteStyleEdit(rReq, pStyleSheet, nRetMask, nSlotId, bAddUndo, bUndo,
                    xOldData, xNewData, eFamily, bStyleToMarked, bListAction, pEditObject, aSelection);
            return// skip calling ExecuteStyleEditPost because we invoked an async dialog
        }
    }

    ExecuteStyleEditPost(rReq, pStyleSheet, nSlotId, nRetMask, bAddUndo, bUndo,
            eFamily, *xOldData, *xNewData, bStyleToMarked, bListAction, pEditObject, aSelection);
}

void ScTabViewShell::ExecuteStyleEdit(SfxRequest& rReq, SfxStyleSheetBase* pStyleSheet, sal_uInt16 nRetMask,
                        sal_uInt16 nSlotId, bool bAddUndo, bool bUndo,
                        const std::shared_ptr<ScStyleSaveData>& rOldData,
                        const std::shared_ptr<ScStyleSaveData>& rNewData, SfxStyleFamily eFamily,
                        bool bStyleToMarked, bool bListAction,
                        SdrObject* pEditObject, ESelection aSelection)
{
    ScDocShell&     rDocSh      = GetViewData().GetDocShell();
    ScDocument&     rDoc        = rDocSh.GetDocument();
    SfxStyleFamily  eFam = pStyleSheet->GetFamily();
    VclPtr<SfxAbstractTabDialog> pDlg;
    bool bPage = false;

    // Store old Items from the style
    std::shared_ptr<SfxItemSet> xOldSet = std::make_shared<SfxItemSet>(pStyleSheet->GetItemSet());
    OUString aOldName = pStyleSheet->GetName();

    switch ( eFam )
    {
        case SfxStyleFamily::Page:
            bPage = true;
            break;

        case SfxStyleFamily::Para:
            {
                SfxItemSet& rSet = pStyleSheet->GetItemSet();

                if ( const SfxUInt32Item* pItem = rSet.GetItemIfSet( ATTR_VALUE_FORMAT,
                        false ) )
                {
                    // Produce and format NumberFormat Value from Value and Language
                    sal_uLong nFormat = pItem->GetValue();
                    LanguageType eLang =
                        rSet.Get(ATTR_LANGUAGE_FORMAT ).GetLanguage();
                    sal_uLong nLangFormat = rDoc.GetFormatTable()->
                        GetFormatForLanguageIfBuiltIn( nFormat, eLang );
                    if ( nLangFormat != nFormat )
                    {
                        SfxUInt32Item aNewItem( ATTR_VALUE_FORMAT, nLangFormat );
                        rSet.Put( aNewItem );
                        xOldSet->Put( aNewItem );
                        // Also in aOldSet for comparison after the  dialog,
                        // Otherwise might miss a language change
                    }
                }

                std::unique_ptr<SvxNumberInfoItem> pNumberInfoItem(
                    ScTabViewShell::MakeNumberInfoItem(rDoc, GetViewData()));

                rDocSh.PutItem( *pNumberInfoItem );
                bPage = false;

                // Definitely a SvxBoxInfoItem with Table = sal_False in set:
                // (If there is no item, the dialogue will also delete the
                // BORDER_OUTER SvxBoxItem from the Template Set)
                if ( rSet.GetItemState( ATTR_BORDER_INNER, false ) != SfxItemState::SET )
                {
                    SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
                    aBoxInfoItem.SetTable(false);       // no inner lines
                    aBoxInfoItem.SetDist(true);
                    aBoxInfoItem.SetMinDist(false);
                    rSet.Put( aBoxInfoItem );
                }
            }
            break;

        case SfxStyleFamily::Frame:
        default:
            break;
    }

    SetInFormatDialog(true);

    SfxItemSet& rStyleSet = pStyleSheet->GetItemSet();
    rStyleSet.MergeRange( XATTR_FILL_FIRST, XATTR_FILL_LAST );

    ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

    weld::Window* pDialogParent = rReq.GetFrameWeld();
    if (!pDialogParent)
        pDialogParent = GetFrameWeld();

    if (eFam == SfxStyleFamily::Frame)
        pDlg = pFact->CreateScDrawStyleDlg(pDialogParent, *pStyleSheet, GetDrawView());
    else
        pDlg = pFact->CreateScStyleDlg(pDialogParent, *pStyleSheet, bPage);

    auto xRequest = std::make_shared<SfxRequest>(rReq);
    rReq.Ignore(); // the 'old' request is not relevant any more
    pDlg->StartExecuteAsync(
        [this, pDlg, xRequest=std::move(xRequest), pStyleSheet,
            nRetMask, xOldSet=std::move(xOldSet), nSlotId, bAddUndo, bUndo,
            xOldData = rOldData, xNewData = rNewData, aOldName, eFamily, bStyleToMarked,
            bListAction, pEditObject, aSelection]
        (sal_Int32 nResult) mutable -> void
        {
            SetInFormatDialog(false);
            ExecuteStyleEditDialog(pDlg, pStyleSheet, nResult, nRetMask, xOldSet, nSlotId,
                    bAddUndo, *xNewData, aOldName);
            pDlg->disposeOnce();
            ExecuteStyleEditPost(*xRequest, pStyleSheet, nSlotId, nRetMask, bAddUndo, bUndo, eFamily,
                    *xOldData, *xNewData, bStyleToMarked, bListAction, pEditObject, aSelection);
        }
    );
}

void ScTabViewShell::ExecuteStyleEditDialog(VclPtr<SfxAbstractTabDialog> pDlg,
                        SfxStyleSheetBase* pStyleSheet, sal_uInt16 nResult,
                        sal_uInt16& rnRetMask, std::shared_ptr<SfxItemSet> xOldSet, const sal_uInt16 nSlotId,
                        bool& rbAddUndo, ScStyleSaveData& rNewData, std::u16string_view aOldName)
{
    ScDocShell&     rDocSh = GetViewData().GetDocShell();
    ScDocument&     rDoc = rDocSh.GetDocument();
    SfxBindings&    rBindings = GetViewData().GetBindings();
    SfxStyleSheetBasePool* pStylePool = rDoc.GetStyleSheetPool();
    SfxStyleFamily  eFam = pStyleSheet->GetFamily();
    if ( nResult == RET_OK )
    {
        const SfxItemSet* pOutSet = pDlg->GetOutputItemSet();

        if ( pOutSet )
        {
            rnRetMask = sal_uInt16(pStyleSheet->GetMask());

            // Attribute comparisons (earlier in ModifyStyleSheet) now here
            // with the old values (the style is already changed)
            if ( SfxStyleFamily::Para == eFam )
            {
                SfxItemSet& rNewSet = pStyleSheet->GetItemSet();
                bool bNumFormatChanged;
                if ( ScGlobal::CheckWidthInvalidate(
                                    bNumFormatChanged, rNewSet, *xOldSet ) )
                    rDoc.InvalidateTextWidth( nullptr, nullptr, bNumFormatChanged );

                SCTAB nTabCount = rDoc.GetTableCount();
                for (SCTAB nTab=0; nTab<nTabCount; nTab++)
                    rDoc.SetStreamValid(nTab, false);

                sal_uLong nOldFormat = xOldSet->Get( ATTR_VALUE_FORMAT ).GetValue();
                sal_uLong nNewFormat = rNewSet.Get( ATTR_VALUE_FORMAT ).GetValue();
                if ( nNewFormat != nOldFormat )
                {
                    ScInterpreterContext& rContext = rDoc.GetNonThreadedContext();
                    const SvNumberformat* pOld = rContext.NFGetFormatEntry( nOldFormat );
                    const SvNumberformat* pNew = rContext.NFGetFormatEntry( nNewFormat );
                    if ( pOld && pNew && pOld->GetLanguage() != pNew->GetLanguage() )
                        rNewSet.Put( SvxLanguageItem(
                                        pNew->GetLanguage(), ATTR_LANGUAGE_FORMAT ) );
                }

                rDoc.getCellAttributeHelper().CellStyleCreated(rDoc, pStyleSheet->GetName());
            }
            else if ( SfxStyleFamily::Page == eFam )
            {
                //! Here also queries for Page Styles

--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=94 H=97 G=95

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge