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


Quelle  docsh4.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 <config_features.h>

#include <com/sun/star/frame/Desktop.hpp>

#include <scitems.hxx>
#include <editeng/flstitem.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/infobar.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/sfxresid.hxx>
#include <sfx2/strings.hrc>
#include <svtools/ehdl.hxx>
#include <svtools/langtab.hxx>
#include <basic/sbxcore.hxx>
#include <basic/sberrors.hxx>
#include <svtools/sfxecode.hxx>
#include <svx/ofaitem.hxx>
#include <svx/svdograf.hxx>
#include <svl/stritem.hxx>
#include <svl/whiter.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <svx/dataaccessdescriptor.hxx>
#include <svx/drawitem.hxx>
#include <svx/fmshell.hxx>
#include <sfx2/passwd.hxx>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/sfxdlg.hxx>
#include <svl/PasswordHelper.hxx>
#include <svl/documentlockfile.hxx>
#include <svl/sharecontrolfile.hxx>
#include <tools/json_writer.hxx>
#include <unotools/securityoptions.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sal/log.hxx>
#include <unotools/charclass.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <o3tl/string_view.hxx>

#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <comphelper/propertyvalue.hxx>
#include <docuno.hxx>

#include <docsh.hxx>
#include "docshimp.hxx"
#include <docfunc.hxx>
#include <scres.hrc>
#include <strings.hrc>
#include <stlsheet.hxx>
#include <stlpool.hxx>
#include <appoptio.hxx>
#include <globstr.hrc>
#include <global.hxx>
#include <dbdocfun.hxx>
#include <printfun.hxx>
#include <viewdata.hxx>
#include <tabvwsh.hxx>
#include <impex.hxx>
#include <undodat.hxx>
#include <undocell.hxx>
#include <inputhdl.hxx>
#include <dbdata.hxx>
#include <servobj.hxx>
#include <rangenam.hxx>
#include <scmod.hxx>
#include <chgviset.hxx>
#include <reffact.hxx>
#include <chartlis.hxx>
#include <chartpos.hxx>
#include <tablink.hxx>
#include <drwlayer.hxx>
#include <docoptio.hxx>
#include <undostyl.hxx>
#include <rangeseq.hxx>
#include <chgtrack.hxx>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <scresid.hxx>
#include <scabstdlg.hxx>
#include <sharedocdlg.hxx>
#include <conditio.hxx>
#include <sheetevents.hxx>
#include <formulacell.hxx>
#include <documentlinkmgr.hxx>
#include <memory>
#include <sfx2/notebookbar/SfxNotebookBar.hxx>
#include <helpids.h>
#include <editeng/eeitem.hxx>
#include <editeng/langitem.hxx>
#include <officecfg/Office/Common.hxx>

#include <svx/xdef.hxx>

using namespace ::com::sun::star;

void ScDocShell::SetInitialLinkUpdate( const SfxMedium* pMed )
{
    if (pMed)
    {
        const SfxUInt16Item* pUpdateDocItem = pMed->GetItemSet().GetItem(SID_UPDATEDOCMODE, false);
        m_nCanUpdate = pUpdateDocItem ? pUpdateDocItem->GetValue() : css::document::UpdateDocMode::NO_UPDATE;
    }

    // GetLinkUpdateModeState() evaluates m_nCanUpdate so that must have
    // been set first. Do not override an already forbidden LinkUpdate (the
    // default is allow).
    comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = getEmbeddedObjectContainer();
    if (rEmbeddedObjectContainer.getUserAllowsLinkUpdate())
    {
        // For anything else than LM_ALWAYS we need user confirmation.
        rEmbeddedObjectContainer.setUserAllowsLinkUpdate( GetLinkUpdateModeState() == LM_ALWAYS);
    }
}

ScLkUpdMode ScDocShell::GetLinkUpdateModeState() const
{
    ScLkUpdMode nSet;
    if (m_nCanUpdate == css::document::UpdateDocMode::NO_UPDATE)
        nSet = LM_NEVER;
    else if (m_nCanUpdate == css::document::UpdateDocMode::FULL_UPDATE)
        nSet = LM_ALWAYS;
    else
    {
        nSet = GetDocument().GetLinkMode();
        if (nSet == LM_UNKNOWN)
        {
            ScAppOptions aAppOptions = ScModule::get()->GetAppOptions();
            nSet = aAppOptions.GetLinkMode();
        }
    }

    if (nSet != LM_NEVER
        && (SvtSecurityOptions::isUntrustedReferer(
                GetMedium() == nullptr ? OUString() : GetMedium()->GetName())
            || (IsDocShared() && SvtSecurityOptions::isUntrustedReferer(GetSharedFileURL()))))
    {
        nSet = LM_NEVER;
    }
    else if (nSet == LM_ALWAYS
            && !(SvtSecurityOptions::isTrustedLocationUriForUpdatingLinks(
                    GetMedium() == nullptr ? OUString() : GetMedium()->GetName())
                || (IsDocShared()
                    && SvtSecurityOptions::isTrustedLocationUriForUpdatingLinks(
                        GetSharedFileURL()))))
    {
        nSet = LM_ON_DEMAND;
    }
    if (m_nCanUpdate == css::document::UpdateDocMode::QUIET_UPDATE
            && nSet == LM_ON_DEMAND)
    {
        nSet = LM_NEVER;
    }

    return nSet;
}

void ScDocShell::AllowLinkUpdate()
{
    m_pDocument->SetLinkFormulaNeedingCheck(false);
    getEmbeddedObjectContainer().setUserAllowsLinkUpdate(true);
}

void ScDocShell::ReloadAllLinks()
{
    AllowLinkUpdate();

    ReloadTabLinks();
    weld::Window *pDialogParent = GetActiveDialogParent();
    m_pDocument->UpdateExternalRefLinks(pDialogParent);

    bool bAnyDde = m_pDocument->GetDocLinkManager().updateDdeOrOleOrWebServiceLinks(pDialogParent);

    if (bAnyDde)
    {
        //  calculate formulas and paint like in the TrackTimeHdl
        m_pDocument->TrackFormulas();
        Broadcast(SfxHint(SfxHintId::ScDataChanged));

        //  Should FID_DATACHANGED become asynchronous some time
        //  (e.g., with Invalidate at Window), an update needs to be forced here.
    }

    m_pDocument->UpdateAreaLinks();
}

IMPL_LINK( ScDocShell, ReloadAllLinksHdl, weld::Button&, rButton, void )
{
    ScDocument& rDoc = GetDocument();
    if (rDoc.HasLinkFormulaNeedingCheck() && rDoc.GetDocLinkManager().hasExternalRefLinks())
    {
        // If we have WEBSERVICE/Dde link and other external links in the document, it might indicate some
        // exfiltration attempt, add *another* warning about this on top of the "Security Warning"
        // shown in the infobar before they got here.
        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(&rButton,
                                                       VclMessageType::Warning, VclButtonsType::YesNo,
                                                       ScResId(STR_TRUST_DOCUMENT_WARNING)));
        xQueryBox->set_secondary_text(ScResId(STR_WEBSERVICE_WITH_LINKS_WARNING));
        xQueryBox->set_default_response(RET_NO);
        if (xQueryBox->run() != RET_YES)
            return;
    }

    ReloadAllLinks();

    ScTabViewShell* pViewSh = GetBestViewShell();
    SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr;
    if (pViewFrame)
        pViewFrame->RemoveInfoBar(u"enablecontent");
    SAL_WARN_IF(!pViewFrame, "sc""expected there to be a ViewFrame");
}

namespace
{
    class LinkHelp
    {
    public:
        DECL_STATIC_LINK(LinkHelp, DispatchHelpLinksHdl, weld::Button&, void);
    };
}

IMPL_STATIC_LINK(LinkHelp, DispatchHelpLinksHdl, weld::Button&, rBtn, void)
{
    if (Help* pHelp = Application::GetHelp())
        pHelp->Start(HID_UPDATE_LINK_WARNING, &rBtn);
}

void ScDocShell::Execute( SfxRequest& rReq )
{
    const SfxItemSet* pReqArgs = rReq.GetArgs();
    SfxBindings* pBindings = GetViewBindings();
    bool bUndo (m_pDocument->IsUndoEnabled());

    sal_uInt16 nSlot = rReq.GetSlot();
    switch ( nSlot )
    {
        case SID_SC_SETTEXT:
        {
            const SfxPoolItem* pColItem;
            const SfxPoolItem* pRowItem;
            const SfxPoolItem* pTabItem;
            const SfxPoolItem* pTextItem;
            if( pReqArgs && pReqArgs->HasItem( FN_PARAM_1, &pColItem ) &&
                            pReqArgs->HasItem( FN_PARAM_2, &pRowItem ) &&
                            pReqArgs->HasItem( FN_PARAM_3, &pTabItem ) &&
                            pReqArgs->HasItem( SID_SC_SETTEXT, &pTextItem ) )
            {
                //  parameters are  1-based !!!
                SCCOL nCol = static_cast<const SfxInt16Item*>(pColItem)->GetValue() - 1;
                SCROW nRow = static_cast<const SfxInt32Item*>(pRowItem)->GetValue() - 1;
                SCTAB nTab = static_cast<const SfxInt16Item*>(pTabItem)->GetValue() - 1;

                SCTAB nTabCount = m_pDocument->GetTableCount();
                if ( m_pDocument->ValidCol(nCol) && m_pDocument->ValidRow(nRow) && ValidTab(nTab,nTabCount) )
                {
                    if ( m_pDocument->IsBlockEditable( nTab, nCol,nRow, nCol, nRow ) )
                    {
                        OUString aVal = static_cast<const SfxStringItem*>(pTextItem)->GetValue();
                        m_pDocument->SetString( nCol, nRow, nTab, aVal );

                        PostPaintCell( nCol, nRow, nTab );
                        SetDocumentModified();

                        rReq.Done();
                        break;
                    }
                    else                // protected cell
                    {
#if HAVE_FEATURE_SCRIPTING
                        SbxBase::SetError( ERRCODE_BASIC_BAD_PARAMETER );      //! which error ?
#endif
                        break;
                    }
                }
            }
#if HAVE_FEATURE_SCRIPTING
            SbxBase::SetError( ERRCODE_BASIC_NO_OBJECT );
#endif
        }
        break;

        case SID_SBA_IMPORT:
        {
            if (pReqArgs)
            {
                const SfxPoolItem* pItem;
                svx::ODataAccessDescriptor aDesc;
                if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
                {
                    uno::Any aAny = static_cast<const SfxUnoAnyItem*>(pItem)->GetValue();
                    uno::Sequence<beans::PropertyValue> aProperties;
                    if ( aAny >>= aProperties )
                        aDesc.initializeFrom( aProperties );
                }

                OUString sTarget;
                if ( pReqArgs->GetItemState( FN_PARAM_1, true, &pItem ) == SfxItemState::SET )
                    sTarget = static_cast<const SfxStringItem*>(pItem)->GetValue();

                bool bIsNewArea = true;         // Default sal_True (no inquiry)
                if ( pReqArgs->GetItemState( FN_PARAM_2, true, &pItem ) == SfxItemState::SET )
                    bIsNewArea = static_cast<const SfxBoolItem*>(pItem)->GetValue();

                // if necessary, create new database area
                bool bMakeArea = false;
                if (bIsNewArea)
                {
                    ScDBCollection* pDBColl = m_pDocument->GetDBCollection();
                    if ( !pDBColl || !pDBColl->getNamedDBs().findByUpperName(ScGlobal::getCharClass().uppercase(sTarget)) )
                    {
                        ScAddress aPos;
                        if ( aPos.Parse( sTarget, *m_pDocument, m_pDocument->GetAddressConvention() ) & ScRefFlags::VALID )
                        {
                            bMakeArea = true;
                            if (bUndo)
                            {
                                OUString aStrImport = ScResId( STR_UNDO_IMPORTDATA );
                                ViewShellId nViewShellId(-1);
                                if (ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell())
                                    nViewShellId = pViewSh->GetViewShellId();
                                GetUndoManager()->EnterListAction( aStrImport, aStrImport, 0, nViewShellId );
                            }

                            ScDBData* pDBData = GetDBData( ScRange(aPos), SC_DB_IMPORT, ScGetDBSelection::Keep );
                            assert(pDBData && "Cannot create DB data");
                            sTarget = pDBData->GetName();
                        }
                    }
                }

                // inquire, before old DB range gets overwritten
                bool bDo = true;
                if (!bIsNewArea)
                {
                    OUString aTemplate = ScResId( STR_IMPORT_REPLACE );
                    OUString aMessage = o3tl::getToken(aTemplate, 0, '#' )
                        + sTarget
                        + o3tl::getToken(aTemplate, 1, '#' );

                    std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(nullptr,
                                                                   VclMessageType::Question, VclButtonsType::YesNo,
                                                                   aMessage));
                    xQueryBox->set_default_response(RET_YES);
                    bDo = xQueryBox->run() == RET_YES;
                }

                if (bDo)
                {
                    ScDBDocFunc(*this).UpdateImport( sTarget, aDesc );
                    rReq.Done();

                    //  UpdateImport also updates the internal operations
                }
                else
                    rReq.Ignore();

                if ( bMakeArea && bUndo)
                    GetUndoManager()->LeaveListAction();
            }
            else
            {
                OSL_FAIL( "arguments expected" );
            }
        }
        break;

        case SID_CHART_SOURCE:
        case SID_CHART_ADDSOURCE:
            ExecuteChartSource(rReq);
            break;

        case FID_AUTO_CALC:
            {
                bool bNewVal;
                const SfxPoolItem* pItem;
                if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) )
                    bNewVal = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                else
                    bNewVal = !m_pDocument->GetAutoCalc();     // Toggle for menu
                m_pDocument->SetAutoCalc( bNewVal );
                SetDocumentModified();
                if (pBindings)
                {
                    pBindings->Invalidate( FID_AUTO_CALC );
                }
                rReq.AppendItem( SfxBoolItem( FID_AUTO_CALC, bNewVal ) );
                rReq.Done();
            }
            break;
        case SID_OPEN_HYPERLINK:
            {
                ScViewData* pViewData = GetViewData();
                if ( !pViewData )
                {
                    rReq.Ignore();
                    break;
                }

                if (ScModule::get()->IsEditMode())
                {
                    if (EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart()))
                    {
                        const SvxFieldItem* pFieldItem = pEditView->GetFieldAtSelection(/*bAlsoCheckBeforeCursor=*/true);
                        const SvxFieldData* pField = pFieldItem ? pFieldItem->GetField() : nullptr;
                        if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
                        {
                            ScGlobal::OpenURL(pURLField->GetURL(), pURLField->GetTargetFrame(), true);
                            rReq.Done();
                            break;
                        }
                    }
                    rReq.Ignore();
                    break;
                }

                ScGridWindow* pWin = pViewData->GetActiveWin();
                if ( !pWin )
                {
                    rReq.Ignore();
                    break;
                }

                ScAddress aCell {pViewData->GetCurPos()};
                std::vector<UrlData> vUrls = pWin->GetEditUrls(aCell);
                if (vUrls.empty())
                {
                    rReq.Ignore();
                    break;
                }

                for (UrlData& data : vUrls)
                {
                    ScGlobal::OpenURL(data.aUrl, data.aTarget, true);
                }
                rReq.Done();
            }
            break;
        case FID_RECALC:
            DoRecalc( rReq.IsAPI() );
            rReq.Done();
            break;
        case FID_HARD_RECALC:
            DoHardRecalc();
            rReq.Done();
            break;
        case SID_UPDATETABLINKS:
            {
                ScLkUpdMode nSet = GetLinkUpdateModeState();

                if (nSet == LM_ALWAYS)
                {
                    ReloadAllLinks();
                    rReq.Done();
                }
                else if (nSet == LM_NEVER)
                {
                    getEmbeddedObjectContainer().setUserAllowsLinkUpdate(false);
                    rReq.Ignore();
                }
                else if (nSet == LM_ON_DEMAND)
                {
                    ScTabViewShell* pViewSh = GetBestViewShell();
                    SfxViewFrame* pViewFrame = pViewSh ? pViewSh->GetFrame() : nullptr;
                    if (pViewFrame)
                    {
                        pViewFrame->RemoveInfoBar(u"enablecontent");
                        auto pInfoBar = pViewFrame->AppendInfoBar(u"enablecontent"_ustr, SfxResId(RID_SECURITY_WARNING_TITLE),
                                                                  ScResId(STR_RELOAD_TABLES), InfobarType::WARNING);
                        if (pInfoBar)
                        {
                            weld::Button& rHelpBtn = pInfoBar->addButton();
                            rHelpBtn.set_label(GetStandardText(StandardButtonType::Help).replaceFirst("~"""));
                            rHelpBtn.connect_clicked(LINK(nullptr, LinkHelp, DispatchHelpLinksHdl));
                            weld::Button& rBtn = pInfoBar->addButton();
                            rBtn.set_label(ScResId(STR_ENABLE_CONTENT));
                            rBtn.set_tooltip_text(ScResId(STR_ENABLE_CONTENT_TOOLTIP));
                            rBtn.connect_clicked(LINK(this, ScDocShell, ReloadAllLinksHdl));

                            // when active content is disabled the "Allow updating" button has no functionality.
                            if (officecfg::Office::Common::Security::Scripting::DisableActiveContent::get())
                            {
                                rBtn.set_tooltip_text(ScResId(STR_ENABLE_CONTENT_TOOLTIP_DISABLED));
                                rBtn.set_sensitive(false);
                            }
                        }
                    }
                    rReq.Done();
                }
            }
            break;

        case SID_REIMPORT_AFTER_LOAD:
            {
                //  Is called after loading if there are DB areas with omitted data

                bool bDone = false;
                ScDBCollection* pDBColl = m_pDocument->GetDBCollection();

                if ((m_nCanUpdate != css::document::UpdateDocMode::NO_UPDATE) &&
                   (m_nCanUpdate != css::document::UpdateDocMode::QUIET_UPDATE))
                {
                    ScRange aRange;
                    ScTabViewShell* pViewSh = GetBestViewShell();
                    OSL_ENSURE(pViewSh,"SID_REIMPORT_AFTER_LOAD: no View");
                    if (pViewSh && pDBColl)
                    {
                        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetActiveDialogParent(),
                                                                       VclMessageType::Question, VclButtonsType::YesNo,
                                                                       ScResId(STR_REIMPORT_AFTER_LOAD)));
                        xQueryBox->set_default_response(RET_YES);
                        if (xQueryBox->run() == RET_YES)
                        {
                            ScDBCollection::NamedDBs& rDBs = pDBColl->getNamedDBs();
                            for (const auto& rxDB : rDBs)
                            {
                                ScDBData& rDBData = *rxDB;
                                if ( rDBData.IsStripData() &&
                                     rDBData.HasImportParam() && !rDBData.HasImportSelection() )
                                {
                                    rDBData.GetArea(aRange);
                                    pViewSh->MarkRange(aRange);

                                    //  Import and internal operations like SID_REFRESH_DBAREA
                                    //  (inquiry for import not needed here)

                                    ScImportParam aImportParam;
                                    rDBData.GetImportParam( aImportParam );
                                    bool bContinue = pViewSh->ImportData( aImportParam );
                                    rDBData.SetImportParam( aImportParam );

                                    //  mark (size may have changed)
                                    rDBData.GetArea(aRange);
                                    pViewSh->MarkRange(aRange);

                                    if ( bContinue )    // error at import -> abort
                                    {
                                        //  internal operations, if some where saved

                                        if ( rDBData.HasQueryParam() || rDBData.HasSortParam() ||
                                             rDBData.HasSubTotalParam() )
                                            pViewSh->RepeatDB();

                                        //  pivot tables, which have the range as source data

                                        RefreshPivotTables(aRange);
                                    }
                                }
                            }
                            bDone = true;
                        }
                    }
                }

                if ( !bDone && pDBColl )
                {
                    //  if not, but then update the dependent formulas
                    //! also for individual ranges, which cannot be updated

                    m_pDocument->CalcAll();        //! only for the dependent
                    PostDataChanged();
                }

                if (bDone)
                    rReq.Done();
                else
                    rReq.Ignore();
            }
            break;

        case SID_AUTO_STYLE:
            OSL_FAIL("use ScAutoStyleHint instead of SID_AUTO_STYLE");
            break;

        case SID_GET_COLORLIST:
            {
                const SvxColorListItem* pColItem = GetItem(SID_COLOR_TABLE);
                const XColorListRef& pList = pColItem->GetColorList();
                rReq.SetReturnValue(OfaXColorListItem(SID_GET_COLORLIST, pList));
            }
            break;

        case FID_CHG_RECORD:
            {
                ScDocument& rDoc = GetDocument();
                // get argument (recorded macro)
                const SfxBoolItem* pItem = rReq.GetArg<SfxBoolItem>(FID_CHG_RECORD);
                bool bDo = true;

                // desired state
                ScChangeTrack* pChangeTrack = rDoc.GetChangeTrack();
                bool bActivateTracking = (pChangeTrack == nullptr);   // toggle
                if ( pItem )
                    bActivateTracking = pItem->GetValue();      // from argument

                if ( !bActivateTracking )
                {
                    if ( !pItem )
                    {
                        // no dialog on playing the macro
                        std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
                                                                   VclMessageType::Warning, VclButtonsType::YesNo,
                                                                   ScResId(STR_END_REDLINING)));
                        xWarn->set_default_response(RET_NO);
                        bDo = (xWarn->run() == RET_YES );
                    }

                    if ( bDo )
                    {
                        if (pChangeTrack)
                        {
                            if ( pChangeTrack->IsProtected() )
                                bDo = ExecuteChangeProtectionDialog();
                        }
                        if ( bDo )
                        {
                            rDoc.EndChangeTracking();
                            PostPaintGridAll();
                        }
                    }
                }
                else
                {
                    rDoc.StartChangeTracking();
                    ScChangeViewSettings aChangeViewSet;
                    aChangeViewSet.SetShowChanges(true);
                    rDoc.SetChangeViewSettings(aChangeViewSet);
                }

                if ( bDo )
                {
                    UpdateAcceptChangesDialog();

                    // invalidate slots
                    if (pBindings)
                        pBindings->InvalidateAll(false);
                    if ( !pItem )
                        rReq.AppendItem( SfxBoolItem( FID_CHG_RECORD, bActivateTracking ) );
                    rReq.Done();
                }
                else
                    rReq.Ignore();
            }
            break;

        case SID_CHG_PROTECT :
            {
                if ( ExecuteChangeProtectionDialog() )
                {
                    rReq.Done();
                    SetDocumentModified();
                }
                else
                    rReq.Ignore();
            }
            break;

        case SID_DOCUMENT_MERGE:
        case SID_DOCUMENT_COMPARE:
            {
                bool bDo = true;
                ScChangeTrack* pChangeTrack = m_pDocument->GetChangeTrack();
                if ( pChangeTrack && !m_pImpl->bIgnoreLostRedliningWarning )
                {
                    if ( nSlot == SID_DOCUMENT_COMPARE )
                    {   //! old changes trace will be lost
                        std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(GetActiveDialogParent(),
                                                                   VclMessageType::Warning, VclButtonsType::YesNo,
                                                                   ScResId(STR_END_REDLINING)));
                        xWarn->set_default_response(RET_NO);
                        if (xWarn->run() == RET_YES)
                            bDo = ExecuteChangeProtectionDialog( true );
                        else
                            bDo = false;
                    }
                    else    // merge might reject some actions
                        bDo = ExecuteChangeProtectionDialog( true );
                }
                if ( !bDo )
                {
                    rReq.Ignore();
                    break;
                }
                SfxApplication* pApp = SfxGetpApp();
                const SfxPoolItem* pItem;
                const SfxStringItem* pFileNameItem(nullptr);
                SfxMedium* pMed = nullptr;
                if (pReqArgs)
                    pFileNameItem = pReqArgs->GetItemIfSet(SID_FILE_NAME);
                if (pFileNameItem)
                {
                    OUString aFileName = pFileNameItem->GetValue();

                    OUString aFilterName;
                    if (const SfxStringItem* pFilterItem = pReqArgs->GetItemIfSet(SID_FILTER_NAME))
                    {
                        aFilterName = pFilterItem->GetValue();
                    }
                    OUString aOptions;
                    if (const SfxStringItem* pOptionsItem = pReqArgs->GetItemIfSet(SID_FILE_FILTEROPTIONS))
                    {
                        aOptions = pOptionsItem->GetValue();
                    }
                    short nVersion = 0;
                    const SfxInt16Item* pInt16Item(nullptr);
                    if (pReqArgs->GetItemState(SID_VERSION, true, &pItem) == SfxItemState::SET)
                        pInt16Item = dynamic_cast<const SfxInt16Item*>(pItem);
                    if (pInt16Item)
                    {
                        nVersion = pInt16Item->GetValue();
                    }

                    //  no filter specified -> detection
                    if (aFilterName.isEmpty())
                        ScDocumentLoader::GetFilterName( aFileName, aFilterName, aOptions, truefalse );

                    //  filter name from dialog contains application prefix,
                    //  GetFilter needs name without the prefix.
                    ScDocumentLoader::RemoveAppPrefix( aFilterName );

                    std::shared_ptr<const SfxFilter> pFilter = ScDocShell::Factory().GetFilterContainer()->GetFilter4FilterName( aFilterName );
                    auto pSet = std::make_shared<SfxAllItemSet>( pApp->GetPool() );
                    if (!aOptions.isEmpty())
                        pSet->Put( SfxStringItem( SID_FILE_FILTEROPTIONS, aOptions ) );
                    if ( nVersion != 0 )
                        pSet->Put( SfxInt16Item( SID_VERSION, nVersion ) );
                    pMed = new SfxMedium( aFileName, StreamMode::STD_READ, std::move(pFilter), std::move(pSet) );
                }
                else
                {
                    const sfx2::DocumentInserter::Mode mode { nSlot==SID_DOCUMENT_COMPARE
                        ? sfx2::DocumentInserter::Mode::Compare
                        : sfx2::DocumentInserter::Mode::Merge};
                    // start file dialog asynchronous
                    m_pImpl->bIgnoreLostRedliningWarning = true;
                    m_pImpl->pRequest.reset(new SfxRequest( rReq ));
                    m_pImpl->pDocInserter.reset();

                    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
                    weld::Window* pParent = pViewSh ? pViewSh->GetFrameWeld() : nullptr;
                    m_pImpl->pDocInserter.reset( new ::sfx2::DocumentInserter(pParent,
                        ScDocShell::Factory().GetFactoryName(), mode ) );
                    m_pImpl->pDocInserter->StartExecuteModal( LINK( this, ScDocShell, DialogClosedHdl ) );
                    return ;
                }

                // now execute in earnest...
                SfxErrorContext aEc( ERRCTX_SFX_OPENDOC, pMed->GetName() );

                // pOtherDocSh->DoClose() will be called explicitly later, but it is still more safe to use SfxObjectShellLock here
                rtl::Reference<ScDocShell> pOtherDocSh = new ScDocShell;
                pOtherDocSh->DoLoad( pMed );
                ErrCodeMsg nErr = pOtherDocSh->GetErrorCode();
                if (nErr)
                    ErrorHandler::HandleError( nErr );          // also warnings

                if ( !pOtherDocSh->GetErrorIgnoreWarning() )                 // only errors
                {
                    bool bHadTrack = ( m_pDocument->GetChangeTrack() != nullptr );
#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
                    sal_uLong nStart = 0;
                    if ( nSlot == SID_DOCUMENT_MERGE && pChangeTrack )
                    {
                        nStart = pChangeTrack->GetActionMax() + 1;
                    }
#endif
                    if ( nSlot == SID_DOCUMENT_COMPARE )
                        CompareDocument( pOtherDocSh->GetDocument() );
                    else
                        MergeDocument( pOtherDocSh->GetDocument() );

                    //  show "accept changes" dialog
                    //! get view for this document!
                    if ( !IsDocShared() )
                    {
                        SfxViewFrame* pViewFrm = SfxViewFrame::Current();
                        if ( pViewFrm )
                        {
                            pViewFrm->ShowChildWindow( ScAcceptChgDlgWrapper::GetChildWindowId() ); //@51669
                        }
                        if ( pBindings )
                        {
                            pBindings->Invalidate( FID_CHG_ACCEPT );
                        }
                    }

                    rReq.SetReturnValue( SfxInt32Item( TypedWhichId<SfxInt32Item>(nSlot), 0 ) );        //! ???????
                    rReq.Done();

                    if (!bHadTrack)         //  newly turned on -> show as well
                    {
                        ScChangeViewSettings* pOldSet = m_pDocument->GetChangeViewSettings();
                        if ( !pOldSet || !pOldSet->ShowChanges() )
                        {
                            ScChangeViewSettings aChangeViewSet;
                            aChangeViewSet.SetShowChanges(true);
                            m_pDocument->SetChangeViewSettings(aChangeViewSet);
                        }
                    }
#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
                    else if ( nSlot == SID_DOCUMENT_MERGE && IsDocShared() && pChangeTrack )
                    {
                        sal_uLong nEnd = pChangeTrack->GetActionMax();
                        if ( nEnd >= nStart )
                        {
                            // only show changes from merged document
                            ScChangeViewSettings aChangeViewSet;
                            aChangeViewSet.SetShowChanges( true );
                            aChangeViewSet.SetShowAccepted( true );
                            aChangeViewSet.SetHasActionRange();
                            aChangeViewSet.SetTheActionRange( nStart, nEnd );
                            m_pDocument->SetChangeViewSettings( aChangeViewSet );

                            // update view
                            PostPaintExtras();
                            PostPaintGridAll();
                        }
                    }
#endif
                }
                pOtherDocSh->DoClose();     // delete happens with the Ref
            }
            break;

        case SID_DELETE_SCENARIO:
            if (pReqArgs)
            {
                const SfxPoolItem* pItem;
                if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
                {
                    if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem))
                    {
                        const OUString& aName = pStringItem->GetValue();
                        SCTAB nTab;
                        if (m_pDocument->GetTable( aName, nTab ))
                        {
                            //  move DeleteTable from viewfunc to docfunc!

                            ScTabViewShell* pSh = GetBestViewShell();
                            if ( pSh )
                            {
                                //! omit SetTabNo in DeleteTable?
                                SCTAB nDispTab = pSh->GetViewData().GetTabNo();
                                pSh->DeleteTable( nTab );
                                pSh->SetTabNo(nDispTab);
                                rReq.Done();
                            }
                        }
                    }
                }
            }
            break;

        case SID_EDIT_SCENARIO:
            {
                const SfxPoolItem* pItem;
                if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
                {
                    if (const SfxStringItem* pStringItem = dynamic_cast<const SfxStringItem*>(pItem))
                    {
                        OUString aName = pStringItem->GetValue();
                        SCTAB nTab;
                        if (m_pDocument->GetTable( aName, nTab ))
                        {
                            if (m_pDocument->IsScenario(nTab))
                            {
                                OUString aComment;
                                Color aColor;
                                ScScenarioFlags nFlags;
                                m_pDocument->GetScenarioData( nTab, aComment, aColor, nFlags );

                                // Determine if the Sheet that the Scenario was created on
                                // is protected. But first we need to find that Sheet.
                                // Rewind back to the actual sheet.
                                SCTAB nActualTab = nTab;
                                do
                                {
                                    nActualTab--;
                                }
                                while(m_pDocument->IsScenario(nActualTab));
                                bool bSheetProtected = m_pDocument->IsTabProtected(nActualTab);

                                ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

                                ScopedVclPtr<AbstractScNewScenarioDlg> pNewDlg(pFact->CreateScNewScenarioDlg(GetActiveDialogParent(), aName, true, bSheetProtected));
                                pNewDlg->SetScenarioData( aName, aComment, aColor, nFlags );
                                if ( pNewDlg->Execute() == RET_OK )
                                {
                                    pNewDlg->GetScenarioData( aName, aComment, aColor, nFlags );
                                    ModifyScenario( nTab, aName, aComment, aColor, nFlags );
                                    rReq.Done();
                                }
                            }
                        }
                    }
                }
            }
            break;

        case SID_ATTR_YEAR2000 :
        {
            const SfxPoolItem* pItem;
            if ( pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET )
            {
                if (const SfxUInt16Item* pInt16Item = dynamic_cast<const SfxUInt16Item*>(pItem))
                {
                    sal_uInt16 nY2k = pInt16Item->GetValue();
                    // set always to DocOptions, so that it is also saved for S050
                    // (and all inquiries run up until now on it as well).
                    // SetDocOptions propagates that to the NumberFormatter
                    ScDocOptions aDocOpt( m_pDocument->GetDocOptions() );
                    aDocOpt.SetYear2000( nY2k );
                    m_pDocument->SetDocOptions( aDocOpt );
                    // the FormShell shall notice it as well
                    ScTabViewShell* pSh = GetBestViewShell();
                    if ( pSh )
                    {
                        FmFormShell* pFSh = pSh->GetFormShell();
                        if ( pFSh )
                            pFSh->SetY2KState( nY2k );
                    }
                }
            }
        }
        break;

#if HAVE_FEATURE_MULTIUSER_ENVIRONMENT
        case SID_SHARE_DOC:
            {
                ScViewData* pViewData = GetViewData();
                if ( !pViewData )
                {
                    rReq.Ignore();
                    break;
                }

                weld::Window* pWin = GetActiveDialogParent();
                ScShareDocumentDlg aDlg(pWin, *pViewData);
                if (aDlg.run() == RET_OK)
                {
                    bool bSetShared = aDlg.IsShareDocumentChecked();
                    if ( bSetShared != IsDocShared() )
                    {
                        if ( bSetShared )
                        {
                            bool bContinue = true;
                            if ( HasName() )
                            {
                                std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(pWin,
                                                                               VclMessageType::Question, VclButtonsType::YesNo,
                                                                               ScResId(STR_DOC_WILLBESAVED)));
                                xQueryBox->set_default_response(RET_YES);
                                if (xQueryBox->run() == RET_NO)
                                {
                                    bContinue = false;
                                }
                            }
                            if ( bContinue )
                            {
                                EnableSharedSettings( true );

                                ScModule* mod = ScModule::get();
                                mod->SetInSharedDocSaving(true);
                                if ( !SwitchToShared( truetrue ) )
                                {
                                    // TODO/LATER: what should be done in case the switch has failed?
                                    // for example in case the user has cancelled the saveAs operation
                                }

                                mod->SetInSharedDocSaving(false);

                                InvalidateName();
                                GetUndoManager()->Clear();

                                ScTabView* pTabView = pViewData->GetView();
                                if ( pTabView )
                                {
                                    pTabView->UpdateLayerLocks();
                                }
                            }
                        }
                        else
                        {
                            uno::Reference< frame::XModel > xModel;
                            try
                            {
                                // load shared file
                                xModel.set( LoadSharedDocument(), uno::UNO_SET_THROW );
                                uno::Reference< util::XCloseable > xCloseable( xModel, uno::UNO_QUERY_THROW );

                                // check if shared flag is set in shared file
                                bool bShared = false;
                                ScModelObj* pDocObj = comphelper::getFromUnoTunnel<ScModelObj>( xModel );
                                if ( pDocObj )
                                {
                                    ScDocShell* pDocShell = dynamic_cast< ScDocShell* >( pDocObj->GetEmbeddedObject() );
                                    if ( pDocShell )
                                    {
                                        bShared = pDocShell->HasSharedXMLFlagSet();
                                    }
                                }

                                // #i87870# check if shared status was disabled and enabled again
                                bool bOwnEntry = false;
                                try
                                {
                                    ::svt::ShareControlFile aControlFile( GetSharedFileURL() );
                                    bOwnEntry = aControlFile.HasOwnEntry();
                                }
                                catch ( uno::Exception& )
                                {
                                }

                                if ( bShared && bOwnEntry )
                                {
                                    uno::Reference< frame::XStorable > xStorable( xModel, uno::UNO_QUERY_THROW );
                                    if ( xStorable->isReadonly() )
                                    {
                                        xCloseable->close( true );

                                        OUString aUserName( ScResId( STR_UNKNOWN_USER ) );
                                        try
                                        {
                                            ::svt::DocumentLockFile aLockFile( GetSharedFileURL() );
                                            LockFileEntry aData = aLockFile.GetLockData();
                                            if ( !aData[LockFileComponent::OOOUSERNAME].isEmpty() )
                                            {
                                                aUserName = aData[LockFileComponent::OOOUSERNAME];
                                            }
                                            else if ( !aData[LockFileComponent::SYSUSERNAME].isEmpty() )
                                            {
                                                aUserName = aData[LockFileComponent::SYSUSERNAME];
                                            }
                                        }
                                        catch ( uno::Exception& )
                                        {
                                        }
                                        OUString aMessage( ScResId( STR_FILE_LOCKED_TRY_LATER ) );
                                        aMessage = aMessage.replaceFirst( "%1", aUserName );

                                        std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin,
                                                                                   VclMessageType::Warning, VclButtonsType::Ok,
                                                                                   aMessage));
                                        xWarn->run();
                                    }
                                    else
                                    {
                                        std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin,
                                                                                   VclMessageType::Warning, VclButtonsType::YesNo,
                                                                                   ScResId(STR_DOC_DISABLESHARED)));
                                        xWarn->set_default_response(RET_YES);

                                        if (xWarn->run() == RET_YES)
                                        {
                                            xCloseable->close( true );

                                            if ( !SwitchToShared( falsetrue ) )
                                            {
                                                // TODO/LATER: what should be done in case the switch has failed?
                                                // for example in case the user has cancelled the saveAs operation
                                            }

                                            EnableSharedSettings( false );

                                            // Do *not* use dispatch mechanism in this place - we don't want others (extensions etc.) to intercept this.
                                            GetModel()->store();

                                            ScTabView* pTabView = pViewData->GetView();
                                            if ( pTabView )
                                            {
                                                pTabView->UpdateLayerLocks();
                                            }
                                        }
                                        else
                                        {
                                            xCloseable->close( true );
                                        }
                                    }
                                }
                                else
                                {
                                    xCloseable->close( true );
                                    std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(pWin,
                                                                               VclMessageType::Warning, VclButtonsType::Ok,
                                                                               ScResId(STR_DOC_NOLONGERSHARED)));
                                    xWarn->run();
                                }
                            }
                            catch ( uno::Exception& )
                            {
                                TOOLS_WARN_EXCEPTION( "sc""SID_SHARE_DOC" );
                                ScModule::get()->SetInSharedDocSaving(false);

                                try
                                {
                                    uno::Reference< util::XCloseable > xClose( xModel, uno::UNO_QUERY_THROW );
                                    xClose->close( true );
                                }
                                catch ( uno::Exception& )
                                {
                                }
                            }
                        }
                    }
                }
                rReq.Done();
            }
            break;
#endif
        case SID_OPEN_CALC:
        {
            ScViewData* pViewData = GetViewData();
            if (pViewData)
            {
                SfxStringItem aApp(SID_DOC_SERVICE, u"com.sun.star.sheet.SpreadsheetDocument"_ustr);
                SfxStringItem aTarget(SID_TARGETNAME, u"_blank"_ustr);
                pViewData->GetDispatcher().ExecuteList(
                    SID_OPENDOC, SfxCallMode::API|SfxCallMode::SYNCHRON,
                    { &aApp, &aTarget });
            }
        }
        break;
        case SID_NOTEBOOKBAR:
        {
            const SfxStringItem* pFile = rReq.GetArg<SfxStringItem>( SID_NOTEBOOKBAR );

            if ( pBindings && sfx2::SfxNotebookBar::IsActive() )
                sfx2::SfxNotebookBar::ExecMethod(*pBindings, pFile ? pFile->GetValue() : u""_ustr);
            else if ( pBindings )
                sfx2::SfxNotebookBar::CloseMethod(*pBindings);
        }
        break;
        case SID_LANGUAGE_STATUS:
        {
            OUString aLangText;
            const SfxStringItem* pItem = rReq.GetArg<SfxStringItem>(nSlot);
            if ( pItem )
                aLangText = pItem->GetValue();

            if ( !aLangText.isEmpty() )
            {
                LanguageType eLang, eLatin, eCjk, eCtl;
                static constexpr OUString aSelectionLangPrefix(u"Current_"_ustr);
                static constexpr OUString aParagraphLangPrefix(u"Paragraph_"_ustr);
                static constexpr OUString aDocLangPrefix(u"Default_"_ustr);

                bool bSelection = false;
                bool bParagraph = false;

                ScDocument& rDoc = GetDocument();
                rDoc.GetLanguage( eLatin, eCjk, eCtl );

                sal_Int32 nPos = 0;
                if ( aLangText == "*" )
                {
                    if (ScTabViewShell* pSh = GetBestViewShell())
                    {
                        pSh->ExecuteCellFormatDlg(rReq, u"font"_ustr);
                        pBindings->Invalidate(SID_LANGUAGE_STATUS);
                    }
                }
                else if ( (nPos = aLangText.indexOf(aDocLangPrefix)) != -1 )
                {
                    aLangText = aLangText.replaceAt(nPos, aDocLangPrefix.getLength(), u"");

                    if ( aLangText == "LANGUAGE_NONE" )
                    {
                        eLang = LANGUAGE_NONE;
                        rDoc.SetLanguage( eLang, eCjk, eCtl );
                    }
                    else if ( aLangText == "RESET_LANGUAGES" )
                    {
                        ScModule::GetSpellSettings(eLang, eCjk, eCtl);
                        rDoc.SetLanguage(eLang, eCjk, eCtl);
                    }
                    else
                    {
                        eLang = SvtLanguageTable::GetLanguageType( aLangText );
                        if ( eLang != LANGUAGE_DONTKNOW  && SvtLanguageOptions::GetScriptTypeOfLanguage(eLang) == SvtScriptType::LATIN )
                        {
                            rDoc.SetLanguage( eLang, eCjk, eCtl );
                        }
                        else
                        {
                            eLang = eLatin;
                        }
                    }
                }
                else if (-1 != (nPos = aLangText.indexOf( aSelectionLangPrefix )))
                {
                    bSelection = true;
                    aLangText = aLangText.replaceAt( nPos, aSelectionLangPrefix.getLength(), u"" );
                }
                else if (-1 != (nPos = aLangText.indexOf( aParagraphLangPrefix )))
                {
                    bParagraph = true;
                    aLangText = aLangText.replaceAt( nPos, aParagraphLangPrefix.getLength(), u"" );
                }

                if (bSelection)
                {
                    ScTabViewShell* pViewShell = GetBestViewShell();
                    if (pViewShell)
                    {
                        const ScPatternAttr* pSelAttrs = pViewShell->GetSelectionPattern();
                        if (pSelAttrs)
                        {
                            const SfxItemSet& rOldSet = pSelAttrs->GetItemSet();
                            SfxItemPool* pItemPool = rOldSet.GetPool();
                            auto pNewSet = std::make_shared<SfxItemSet>(*pItemPool);

                            if (aLangText == "LANGUAGE_NONE")
                            {
                                pNewSet->Put(SvxLanguageItem(LANGUAGE_NONE,
                                                             pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_LANGUAGE)));
                                pNewSet->Put(SvxLanguageItem(LANGUAGE_NONE,
                                                             pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_CJK_LANGUAGE)));
                                pNewSet->Put(SvxLanguageItem(LANGUAGE_NONE,
                                                             pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_CTL_LANGUAGE)));
                            }
                            else
                            {
                                const LanguageType nLangType = SvtLanguageTable::GetLanguageType(aLangText);
                                const SvtScriptType nScriptType =
                                    SvtLanguageOptions::GetScriptTypeOfLanguage(nLangType);
                                if (nScriptType == SvtScriptType::LATIN)
                                    pNewSet->Put(SvxLanguageItem(nLangType,
                                                                 pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_LANGUAGE)));
                                if (nScriptType == SvtScriptType::COMPLEX)
                                    pNewSet->Put(SvxLanguageItem(nLangType,
                                                                 pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_CTL_LANGUAGE)));
                                if (nScriptType == SvtScriptType::ASIAN)
                                    pNewSet->Put(SvxLanguageItem(nLangType,
                                                                 pItemPool->GetWhichIDFromSlotID(SID_ATTR_CHAR_CJK_LANGUAGE)));
                            }
                            pViewShell->ApplyAttributes(*pNewSet, rOldSet);
                            pBindings->Invalidate(SID_LANGUAGE_STATUS);
                        }
                    }
                }
                else if (bParagraph)
                {
                    ScViewData* pViewData = GetViewData();
                    if (!pViewData)
                        return;

                    EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart());
                    if (!pEditView)
                        return;

                    const LanguageType nLangToUse = SvtLanguageTable::GetLanguageType( aLangText );
                    SvtScriptType nScriptType = SvtLanguageOptions::GetScriptTypeOfLanguage( nLangToUse );

                    SfxItemSet aAttrs = pEditView->getEditEngine().GetEmptyItemSet();
                    if (nScriptType == SvtScriptType::LATIN)
                        aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE ) );
                    if (nScriptType == SvtScriptType::COMPLEX)
                        aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CTL ) );
                    if (nScriptType == SvtScriptType::ASIAN)
                        aAttrs.Put( SvxLanguageItem( nLangToUse, EE_CHAR_LANGUAGE_CJK ) );
                    ESelection aOldSel;
                    if (bParagraph)
                    {
                        ESelection aSel = pEditView->GetSelection();
                        aOldSel = aSel;
                        aSel.start.nIndex = 0;
                        aSel.end.nIndex = EE_TEXTPOS_MAX;
                        pEditView->SetSelection( aSel );
                    }

                    pEditView->SetAttribs( aAttrs );
                    if (bParagraph)
                        pEditView->SetSelection( aOldSel );
                }
                else if ( eLang != eLatin )
                {
                    if ( ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell() )
                    {
                        ScInputHandler* pInputHandler = ScModule::get()->GetInputHdl(pViewSh);
                        if ( pInputHandler )
                            pInputHandler->UpdateSpellSettings();

                        pViewSh->UpdateDrawTextOutliner();
                    }

                    SetDocumentModified();
                    Broadcast(SfxHint(SfxHintId::LanguageChanged));
                    PostPaintGridAll();
                }
            }
        }
        break;
        case SID_SPELLCHECK_IGNORE_ALL:
        {
            ScViewData* pViewData = GetViewData();
            if (!pViewData)
                return;

            EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart());
            if (!pEditView)
                return;

            OUString sIgnoreText;
            const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
            if (pItem2)
                sIgnoreText = pItem2->GetValue();

            if(sIgnoreText == "Spelling")
            {
                ESelection aOldSel = pEditView->GetSelection();
                pEditView->SpellIgnoreWord();
                pEditView->SetSelection( aOldSel );
            }
        }
        break;
        case SID_SPELLCHECK_APPLY_SUGGESTION:
        {
            ScViewData* pViewData = GetViewData();
            if (!pViewData)
                return;

            EditView* pEditView = pViewData->GetEditView(pViewData->GetActivePart());
            if (!pEditView)
                return;

            OUString sApplyText;
            const SfxStringItem* pItem2 = rReq.GetArg<SfxStringItem>(FN_PARAM_1);
            if (pItem2)
                sApplyText = pItem2->GetValue();

            static constexpr OUString sSpellingRule(u"Spelling_"_ustr);
            sal_Int32 nPos = 0;
            if(-1 != (nPos = sApplyText.indexOf( sSpellingRule )))
            {
                sApplyText = sApplyText.replaceAt(nPos, sSpellingRule.getLength(), u"");
                pEditView->InsertText( sApplyText );
            }
        }
        break;
        case SID_REFRESH_VIEW:
        {
            PostPaintGridAll();
        }
        break;
        case SID_PROTECTPOS:
        case SID_PROTECTSIZE:
        {
            ScTabViewShell* pViewShell = GetBestViewShell();
            if (!pViewShell)
                return;
            ScDrawView* pScDrawView = pViewShell->GetViewData().GetScDrawView();
            if (!pScDrawView)
                return;

            const SdrMarkList& rMarkList = pScDrawView->GetMarkedObjectList();
            assert ( rMarkList.GetMarkCount() == 1 );

            SdrObject* pGraphicObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
            if (nSlot == SID_PROTECTSIZE)
                pGraphicObj->SetResizeProtect(!pGraphicObj->IsResizeProtect());
            else
                pGraphicObj->SetMoveProtect(!pGraphicObj->IsMoveProtect());
        }
        break;
        default:
        {
            // small (?) hack -> forwarding of the slots to TabViewShell
            ScTabViewShell* pSh = GetBestViewShell();
            if ( pSh )
                pSh->Execute( rReq );
#if HAVE_FEATURE_SCRIPTING
            else
                SbxBase::SetError( ERRCODE_BASIC_NO_ACTIVE_OBJECT );
#endif
        }
    }
}

void UpdateAcceptChangesDialog()
{
    //  update "accept changes" dialog
    //! notify all views
    SfxViewFrame* pViewFrm = SfxViewFrame::Current();
    if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) )
    {
        SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT );
        if ( pChild )
            static_cast<ScAcceptChgDlgWrapper*>(pChild)->ReInitDlg();
    }
}

void ScDocShell::ExecuteChartSource(SfxRequest& rReq)
{
    const SfxItemSet* pReqArgs = rReq.GetArgs();
    sal_uInt16 nSlot = rReq.GetSlot();
    bool bUndo (m_pDocument->IsUndoEnabled());
    if (!pReqArgs)
    {
        OSL_FAIL("SID_CHART_SOURCE without arguments");
        return;
    }

    ScDocument& rDoc = GetDocument();
    const   SfxPoolItem* pItem;
    OUString  aChartName, aRangeName;

    ScRange         aSingleRange;
    ScRangeListRef  aRangeListRef;
    bool            bMultiRange = false;

    bool bColHeaders = true;
    bool bRowHeaders = true;
    bool bColInit = false;
    bool bRowInit = false;
    bool bAddRange = (nSlot == SID_CHART_ADDSOURCE);

    ifconst SfxStringItem* pChartItem = pReqArgs->GetItemIfSet( SID_CHART_NAME ) )
        aChartName = pChartItem->GetValue();

    ifconst SfxStringItem* pChartItem = pReqArgs->GetItemIfSet( SID_CHART_SOURCE ) )
        aRangeName = pChartItem->GetValue();

    if( pReqArgs->HasItem( FN_PARAM_1, &pItem ) )
    {
        bColHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue();
        bColInit = true;
    }
    if( pReqArgs->HasItem( FN_PARAM_2, &pItem ) )
    {
        bRowHeaders = static_cast<const SfxBoolItem*>(pItem)->GetValue();
        bRowInit = true;
    }

    ScAddress::Details aDetails(rDoc.GetAddressConvention(), 0, 0);
    bool bValid = (aSingleRange.ParseAny(aRangeName, rDoc, aDetails) & ScRefFlags::VALID) != ScRefFlags::ZERO;
    if (!bValid)
    {
        aRangeListRef = new ScRangeList;
        aRangeListRef->Parse( aRangeName, rDoc, rDoc.GetAddressConvention());
        if ( !aRangeListRef->empty() )
        {
            bMultiRange = true;
            aSingleRange = aRangeListRef->front(); // for header
            bValid = true;
        }
        else
            aRangeListRef.clear();
    }

    ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
    if (!pViewSh || !bValid || aChartName.isEmpty() )
    {
        OSL_FAIL("UpdateChartArea: no ViewShell or wrong data");
        rReq.Done();
        return;
    }

    weld::Window* pParent = pViewSh->GetFrameWeld();

    SCCOL nCol1 = aSingleRange.aStart.Col();
    SCROW nRow1 = aSingleRange.aStart.Row();
    SCCOL nCol2 = aSingleRange.aEnd.Col();
    SCROW nRow2 = aSingleRange.aEnd.Row();
    SCTAB nTab = aSingleRange.aStart.Tab();

    //! limit always or not at all ???
    if (!bMultiRange)
        m_pDocument->LimitChartArea( nTab, nCol1,nRow1, nCol2,nRow2 );

    // Dialog for column/row headers
    if ( !bAddRange && ( !bColInit || !bRowInit ) )
    {
        ScChartPositioner aChartPositioner( *m_pDocument, nTab, nCol1,nRow1, nCol2,nRow2 );
        if (!bColInit)
            bColHeaders = aChartPositioner.HasColHeaders();
        if (!bRowInit)
            bRowHeaders = aChartPositioner.HasRowHeaders();

        auto xRequest = std::make_shared<SfxRequest>(rReq);
        rReq.Ignore(); // the 'old' request is not relevant any more
        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
        VclPtr<AbstractScColRowLabelDlg> pDlg(pFact->CreateScColRowLabelDlg(pParent, bRowHeaders, bColHeaders));
        pDlg->StartExecuteAsync(
            [this, pDlg, xRequest=std::move(xRequest), bUndo, bMultiRange,
             aChartName, aRangeListRef=std::move(aRangeListRef), bAddRange,
             nCol1, nRow1, nCol2, nRow2, nTab] (sal_Int32 nResult)->void
            {
                if (nResult == RET_OK)
                {
                    bool bColHeaders2 = pDlg->IsRow();
                    bool bRowHeaders2 = pDlg->IsCol();

                    xRequest->AppendItem(SfxBoolItem(FN_PARAM_1, bColHeaders2));
                    xRequest->AppendItem(SfxBoolItem(FN_PARAM_2, bRowHeaders2));
                    ExecuteChartSourcePost(bUndo, bMultiRange,
                        aChartName, aRangeListRef, bColHeaders2, bRowHeaders2, bAddRange,
                        nCol1, nRow1, nCol2, nRow2, nTab);
                }
                pDlg->disposeOnce();
                xRequest->Done();
            }
        );
    }
    else
    {
        ExecuteChartSourcePost(bUndo, bMultiRange,
            aChartName, aRangeListRef, bColHeaders, bRowHeaders, bAddRange,
            nCol1, nRow1,nCol2, nRow2, nTab);
        rReq.Done();
    }
}

void ScDocShell::ExecuteChartSourcePost(bool bUndo, bool bMultiRange,
    const OUString& rChartName, const ScRangeListRef& rRangeListRef,
--> --------------------

--> maximum size reached

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

Messung V0.5
C=95 H=99 G=96

¤ Dauer der Verarbeitung: 0.40 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