Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sc/source/ui/view/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 46 kB image not shown  

Quelle  tabvwshf.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 <memory>

#include <sfx2/dialogrequesthelper.hxx>
#include <sfx2/request.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/viewfrm.hxx>
#include <basic/sbstar.hxx>
#include <basic/sberrors.hxx>
#include <svl/ctloptions.hxx>
#include <svl/stritem.hxx>
#include <svl/whiter.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <sfx2/objface.hxx>
#include <svx/svxdlg.hxx>
#include <editeng/colritem.hxx>

#include <tabvwsh.hxx>
#include <sc.hrc>
#include <helpids.h>
#include <docsh.hxx>
#include <document.hxx>
#include <scresid.hxx>
#include <globstr.hrc>
#include <strings.hrc>
#include <docfunc.hxx>
#include <eventuno.hxx>
#include <dpobject.hxx>
#include <dpshttab.hxx>

#include <scabstdlg.hxx>

#include <tabbgcolor.hxx>
#include <markdata.hxx>

#include <vector>

using std::unique_ptr;
using namespace com::sun::star;

void ScTabViewShell::ExecuteTable( SfxRequest& rReq )
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();

    SCTAB       nCurrentTab = rViewData.GetTabNo();
    SCTAB       nTabCount   = rDoc.GetTableCount();
    sal_uInt16  nSlot       = rReq.GetSlot();
    const SfxItemSet* pReqArgs = rReq.GetArgs();

    HideListBox();                  // Autofilter-DropDown-Listbox

    switch ( nSlot )
    {
        case FID_TABLE_VISIBLE:
            {
                OUString aName;
                rDoc.GetName( nCurrentTab, aName );

                bool bVisible=true;
                if( pReqArgs != nullptr )
                {
                    const SfxPoolItem* pItem;
                    if( pReqArgs->HasItem( FID_TABLE_VISIBLE, &pItem ) )
                        bVisible = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                }

                if( ! bVisible )            // fade out
                {
                    if ( rDoc.IsDocEditable() )
                    {
                        ScMarkData& rMark = rViewData.GetMarkData();
                        HideTable( rMark );
                    }
                }
                else                        // fade in
                {
                    std::vector<OUString> rNames { aName };
                    ShowTable( rNames );
                }
            }
            break;

        case FID_TABLE_HIDE:
            {
                if ( rDoc.IsDocEditable() )
                {
                    ScMarkData& rMark = rViewData.GetMarkData();
                    SCTAB nActiveTab = -1;
                    // For the cases when user right clicks on a non-active tab and hides it. This case is possible for Online.
                    if (pReqArgs)
                    {
                        const SfxPoolItem *pItem;
                        if( pReqArgs->HasItem( FID_TABLE_HIDE, &pItem ) )
                        {
                            SCTAB nTabNumber = static_cast<const SfxInt16Item*>(pItem)->GetValue();
                            // Does selected sheets (tabs) list include the sheet to be hidden?
                            std::set<SCTAB>::iterator it = rMark.GetSelectedTabs().find(nTabNumber);
                            if (it == rMark.GetSelectedTabs().end())
                            {
                                // No it doesn't, so we won't shift the selected tab. Let's remember its position.
                                nActiveTab = GetViewData().GetTabNo();
                            }
                            rMark.SelectOneTable(nTabNumber);
                        }
                    }
                    HideTable( rMark, nActiveTab );
                }
            }
            break;

        case FID_TABLE_SHOW:
            {
                std::vector<OUString> rNames;
                if ( pReqArgs )
                {
                    const SfxPoolItem* pItem;
                    if( pReqArgs->HasItem( FID_TABLE_SHOW, &pItem ) )
                    {
                        OUString aName = static_cast<const SfxStringItem*>(pItem)->GetValue();
                        rNames.push_back(aName);
                        ShowTable( rNames );

                        if( ! rReq.IsAPI() )
                            rReq.Done();
                    }
                }
                else
                {
                    ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

                    VclPtr<AbstractScShowTabDlg> pDlg(pFact->CreateScShowTabDlg(GetFrameWeld()));

                    OUString aTabName;
                    bool bFirst = true;
                    for ( SCTAB i=0; i != nTabCount; i++ )
                    {
                        if (!rDoc.IsVisible(i))
                        {
                            rDoc.GetName( i, aTabName );
                            pDlg->Insert( aTabName, bFirst );
                            bFirst = false;
                        }
                    }

                    std::shared_ptr<SfxRequest> xReq = std::make_shared<SfxRequest>(rReq);
                    pDlg->StartExecuteAsync([this, pDlg, xReq = std::move(xReq)](sal_Int32 nResult){
                        std::vector<OUString> sTables;
                        if (RET_OK == nResult)
                        {
                            std::vector<sal_Int32> aSelectedRows = pDlg->GetSelectedRows();
                            for (auto a : aSelectedRows)
                            {
                                OUString sTable = pDlg->GetEntry(a);
                                xReq->AppendItem( SfxStringItem( FID_TABLE_SHOW, sTable ) );
                                sTables.push_back(sTable);
                            }
                            ShowTable( sTables );
                            xReq->Done();
                        }
                        pDlg->disposeOnce();
                    });
                    rReq.Ignore();
                }
            }
            break;

        case FID_INS_TABLE:
        case FID_INS_TABLE_EXT:
            ExecuteInsertTable(rReq);
            break;

        case FID_TAB_APPEND:
        case FID_TAB_RENAME:
        case FID_TAB_MENU_RENAME:
            {
                //  FID_TAB_MENU_RENAME - "rename" in menu
                //  FID_TAB_RENAME      - "name"-property for basic
                //  equal execute, but MENU_RENAME may be disabled inside GetState

                ExecuteAppendOrRenameTable(rReq);
            }
            break;

        case FID_TAB_MOVE:
            {
                ExecuteMoveTable(rReq);
            }
            break;

        case FID_TAB_DUPLICATE:
            {
                // Get info about current document and selected tab
                SCTAB nTab = rViewData.GetTabNo();
                OUString aDocName = GetViewData().GetDocShell().GetTitle(SFX_TITLE_FULLNAME);
                sal_uInt16 nDoc = 0;
                bool bCpy = true;

                SfxObjectShell* pSh = SfxObjectShell::GetFirst();
                ScDocShell* pScSh = nullptr;
                sal_uInt16 i = 0;

                // Determine the index of the current document
                while ( pSh )
                {
                    pScSh = dynamic_cast<ScDocShell*>( pSh );

                    if( pScSh )
                    {
                        if (aDocName == pScSh->GetTitle(SFX_TITLE_FULLNAME))
                        {
                            nDoc = i;
                            break;
                        }
                        // Only count ScDocShell
                        i++;
                    }
                    pSh = SfxObjectShell::GetNext( *pSh );
                }

                MoveTable( nDoc, nTab + 1, bCpy );
            }
            break;

        case FID_DELETE_TABLE:
            {
                bool bHasIndex = (pReqArgs != nullptr);

                // allow removing via the Index/FID_DELETE_TABLE parameter
                SCTAB nTabNr = nCurrentTab;
                if (bHasIndex)
                {
                    const SfxPoolItem* pItem;
                    if (pReqArgs->HasItem(FID_DELETE_TABLE, &pItem))
                    {
                        nTabNr = static_cast<const SfxUInt16Item*>(pItem)->GetValue();

                        // inserting is 1-based, let's be consistent
                        if (nTabNr > 0)
                            --nTabNr;
                    }
                }

                bool bDoIt = bHasIndex;
                if (!bDoIt)
                {
                    bool bTabWithPivotTable = false;
                    if (rDoc.HasPivotTable())
                    {
                        const ScDPCollection* pDPs = rDoc.GetDPCollection();
                        if (pDPs)
                        {
                            const ScMarkData::MarkedTabsType& rSelectedTabs = rViewData.GetMarkData().GetSelectedTabs();
                            const size_t nCount = pDPs->GetCount();
                            for (size_t i = 0; i < nCount; ++i)
                            {
                                const ScDPObject& rDPObj = (*pDPs)[i];
                                const ScSheetSourceDesc* pSheetSourceDesc = rDPObj.GetSheetDesc();
                                if (pSheetSourceDesc)
                                {
                                    SCTAB nTabOut = rDPObj.GetOutRange().aStart.Tab();
                                    SCTAB nTabSource = pSheetSourceDesc->GetSourceRange().aStart.Tab();
                                    bool bTabOutSel = false;
                                    for (const SCTAB nSelTab : rSelectedTabs)
                                    {
                                        if (nSelTab == nTabSource)
                                            bTabWithPivotTable = true;
                                        if (nSelTab == nTabOut)
                                            bTabOutSel = true;
                                        if (bTabWithPivotTable && bTabOutSel)
                                            break;
                                    }
                                    // if both pivot table and data are selected
                                    // no need to warn for source data losing
                                    if (bTabWithPivotTable && bTabOutSel)
                                        bTabWithPivotTable = false;
                                    if (bTabWithPivotTable)
                                        break;
                                }
                            }
                        }
                    }

                    SCTAB nTabSelCnt = rViewData.GetMarkData().GetSelectCount();
                    OUString aTabSelCnt = Application::GetSettings().GetUILocaleDataWrapper().getNum( nTabSelCnt, 0 );
                    OUString aQueryDeleteTab = ScResId( STR_QUERY_DELTAB, nTabSelCnt )
                                                        .replaceAll( "%d", aTabSelCnt );
                    if (bTabWithPivotTable)
                    {
                        OUString aStr = ScResId( STR_QUERY_PIVOTTABLE_DELTAB, nTabSelCnt )
                                                        .replaceAll( "%d", aTabSelCnt )
                                                        + " " + aQueryDeleteTab;

                        std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                                       VclMessageType::Question, VclButtonsType::YesNo,
                                                                       aStr));
                        xQueryBox->set_default_response(RET_NO);

                        // Hard warning as there is potential of data loss on deletion
                        bDoIt = (RET_YES == xQueryBox->run());
                    }
                    else
                    {
                        bool bHasData = false;
                        ScMarkData& rMark = rViewData.GetMarkData();
                        for ( SCTAB i = 0; i < nTabCount && !bHasData; i++ )
                        {
                            if ( rMark.GetTableSelect(i) && !rDoc.IsTabProtected(i) )
                            {
                                SCCOL nStartCol;
                                SCROW nStartRow;
                                bHasData = rDoc.GetDataStart( i, nStartCol, nStartRow );
                            }
                        }
                        // Do not ask for confirmation if all selected tabs are empty
                        if (bHasData)
                        {
                            std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                                           VclMessageType::Question, VclButtonsType::YesNo,
                                                                           aQueryDeleteTab));
                            xQueryBox->set_default_response(RET_YES);

                            // no parameter given, ask for confirmation
                            bDoIt = (RET_YES == xQueryBox->run());
                        }
                        else
                            bDoIt = true;
                    }
                }

                if (bDoIt)
                {
                    SCTAB nNewTab = nCurrentTab;
                    std::vector<SCTAB> TheTabs;

                    if (bHasIndex)
                    {
                        // sheet no. provided by the parameter
                        TheTabs.push_back(nTabNr);
                        if (nNewTab > nTabNr && nNewTab > 0)
                            --nNewTab;
                    }
                    else
                    {
                        SCTAB nFirstTab = 0;
                        bool bTabFlag = false;
                        ScMarkData& rMark = rViewData.GetMarkData();
                        for (SCTAB i = 0; i < nTabCount; i++)
                        {
                            if (rMark.GetTableSelect(i) && !rDoc.IsTabProtected(i))
                            {
                                TheTabs.push_back(i);
                                bTabFlag = true;
                                if (nNewTab == i && i+1 < nTabCount)
                                    nNewTab++;
                            }
                            if (!bTabFlag)
                                nFirstTab = i;
                        }
                        if (nNewTab >= nTabCount - static_cast<SCTAB>(TheTabs.size()))
                            nNewTab = nFirstTab;
                    }

                    rViewData.SetTabNo(nNewTab);
                    DeleteTables(TheTabs);
                    TheTabs.clear();
                    rReq.Done();
                }
            }
            break;

        case FID_TAB_RTL:
            {
                ScDocShell& rDocSh = rViewData.GetDocShell();
                ScDocFunc &rFunc = rDocSh.GetDocFunc();
                bool bSet = !rDoc.IsLayoutRTL( nCurrentTab );

                const ScMarkData& rMark = rViewData.GetMarkData();
                if ( rMark.GetSelectCount() != 0 )
                {
                    //  handle several sheets

                    SfxUndoManager* pUndoManager = rDocSh.GetUndoManager();
                    OUString aUndo = ScResId( STR_UNDO_TAB_RTL );
                    pUndoManager->EnterListAction( aUndo, aUndo, 0, rViewData.GetViewShell()->GetViewShellId() );

                    for (const auto& rTab : rMark)
                        rFunc.SetLayoutRTL( rTab, bSet );

                    pUndoManager->LeaveListAction();
                }
                else
                    rFunc.SetLayoutRTL( nCurrentTab, bSet );
            }
            break;

        case FID_TAB_TOGGLE_GRID:
            {
                bool bShowGrid = rViewData.GetShowGrid();
                rViewData.SetShowGrid(!bShowGrid);
                SfxBindings& rBindings = GetViewFrame().GetBindings();
                rBindings.Invalidate( FID_TAB_TOGGLE_GRID );
                ScDocShellModificator aModificator(rViewData.GetDocShell());
                aModificator.SetDocumentModified();
                PaintGrid();
                rReq.Done();
            }
            break;

        case FID_TAB_SET_TAB_BG_COLOR:
        case FID_TAB_MENU_SET_TAB_BG_COLOR:
            ExecuteSetTableBackgroundCol(rReq);
            break;

        case FID_TAB_EVENTS:
                {
                    ScDocShell& rDocSh = rViewData.GetDocShell();
                    uno::Reference<container::XNameReplace> xEvents( new ScSheetEventsObj( &rDocSh, nCurrentTab ) );
                    uno::Reference<frame::XFrame> xFrame = GetViewFrame().GetFrame().GetFrameInterface();
                    SvxAbstractDialogFactory* pDlgFactory = SvxAbstractDialogFactory::Create();
                    VclPtr<VclAbstractDialog> pDialog( pDlgFactory->CreateSvxMacroAssignDlg(
                        GetFrameWeld(), xFrame, false, xEvents, 0 ) );
                    // the dialog modifies the settings directly
                    pDialog->StartExecuteAsync(
                        [pDialog] (sal_Int32 /*nResult*/)->void
                        {
                            pDialog->disposeOnce();
                        }
                    );
                }
                break;
        case FID_TOGGLEHIDDENCOLROW:
                {
                    svtools::EditableColorConfig aEditableConfig;
                    svtools::ColorConfigValue aValue = aEditableConfig.GetColorValue(svtools::CALCHIDDENROWCOL);
                    aValue.bIsVisible = !aValue.bIsVisible;
                    aEditableConfig.SetColorValue(svtools::CALCHIDDENROWCOL, aValue);
                }
                break;
        default:
                OSL_FAIL("unknown message for ViewShell");
                break;
    }
}

void ScTabViewShell::GetStateTable( SfxItemSet& rSet )
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    ScDocShell& rDocShell   = rViewData.GetDocShell();
    ScMarkData& rMark       = GetViewData().GetMarkData();
    SCTAB       nTab        = rViewData.GetTabNo();

    SCTAB nTabCount = rDoc.GetTableCount();
    SCTAB nTabSelCount = rMark.GetSelectCount();

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

    while ( nWhich )
    {
        switch ( nWhich )
        {

            case FID_TABLE_VISIBLE:
                rSet.Put( SfxBoolItem( nWhich, rDoc.IsVisible(nTab) ));
                break;

            case FID_TABLE_HIDE:
                {
                    sal_uInt16 nVis = 0;
                    // enable menu : check to make sure we won't hide all sheets. we need at least one visible at all times.
                    for ( SCTAB i=0; i < nTabCount && nVis<nTabSelCount + 1; i++ )
                        if (rDoc.IsVisible(i))
                            ++nVis;
                    if ( nVis<=nTabSelCount || !rDoc.IsDocEditable() )
                        rSet.DisableItem( nWhich );
                }
                break;

            case FID_TABLE_SHOW:
                {
                    bool bHasHidden = false;
                    for ( SCTAB i=0; i < nTabCount && !bHasHidden; i++ )
                        if (!rDoc.IsVisible(i))
                            bHasHidden = true;
                    if ( !bHasHidden || rDoc.IsDocProtected() || nTabSelCount > 1 )
                        rSet.DisableItem( nWhich );
                }
                break;

            case FID_DELETE_TABLE:
                {
                    if ( rDoc.GetChangeTrack() )
                        rSet.DisableItem( nWhich );
                    else
                    {
                        sal_uInt16 nVis = 0;
                        for ( SCTAB i=0; i < nTabCount && nVis<2; i++ )
                            if (rDoc.IsVisible(i))
                                ++nVis;
                        if (   rDoc.IsTabProtected(nTab)
                            || !rDoc.IsDocEditable()
                            || nVis < 2
                            || nTabSelCount == nTabCount)
                            rSet.DisableItem( nWhich );
                    }
                }
                break;

            case FID_INS_TABLE:
            case FID_INS_TABLE_EXT:
            case FID_TAB_APPEND:
                if ( !rDoc.IsDocEditable() ||
                     nTabCount > MAXTAB ||
                     ( nWhich == FID_INS_TABLE_EXT && rDocShell.IsDocShared() ) )
                    rSet.DisableItem( nWhich );
                break;

            case FID_TAB_MOVE:
            case FID_TAB_DUPLICATE:
                if (   !rDoc.IsDocEditable()
                    || rDoc.GetChangeTrack() != nullptr
                    || nTabCount > MAXTAB)
                    rSet.DisableItem( nWhich );
                break;

            //  FID_TAB_MENU_RENAME - "rename" from Menu
            //  FID_TAB_RENAME      - "name"-property for Basic

            case FID_TAB_MENU_RENAME:
                if ( !rDoc.IsDocEditable() ||
                     rDoc.IsTabProtected(nTab) ||nTabSelCount > 1 ||
                     rDocShell.IsDocShared() )
                    rSet.DisableItem( nWhich );
                break;

            case FID_TAB_RENAME:
                {
                    OUString aTabName;
                    rDoc.GetName( nTab, aTabName );

                    rSet.Put( SfxStringItem( nWhich, aTabName ));

                }
                break;

            case FID_TAB_RTL:
                {
                    if ( !SvtCTLOptions::IsCTLFontEnabled() )
                        rSet.DisableItem( nWhich );
                    else
                        rSet.Put( SfxBoolItem( nWhich, rDoc.IsLayoutRTL( nTab ) ) );
                }
                break;

            case FID_TAB_MENU_SET_TAB_BG_COLOR:
                {
                    if ( !rDoc.IsDocEditable()
                        || rDocShell.IsDocShared()
                        || rDoc.IsTabProtected(nTab) )
                        rSet.DisableItem( nWhich );
                }
                break;

            case FID_TAB_SET_TAB_BG_COLOR:
                {
                    Color aColor = rDoc.GetTabBgColor( nTab );
                    rSet.Put( SvxColorItem( aColor, nWhich ) );
                }
                break;

            case FID_TAB_TOGGLE_GRID:
                rSet.Put( SfxBoolItem(nWhich, rViewData.GetShowGrid()) );
                break;
        }
        nWhich = aIter.NextWhich();
    }
}

void ScTabViewShell::ExecuteMoveTable( SfxRequest& rReq )
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    const SfxItemSet* pReqArgs = rReq.GetArgs();

    if ( rDoc.GetChangeTrack() != nullptr )
        return;    // if ChangeTracking is active, then no TabMove

    bool   bDoIt = false;
    sal_uInt16 nDoc = 0;
    SCTAB nTab = rViewData.GetTabNo();
    SCTAB nContextMenuTab = -1;
    bool bFromContextMenu = false;
    bool bFromMoveOrCopySheetDialog = false// FN_PARAM_6
    bool bCpy = false, bUseCurrentDocument = false;
    OUString aDocName;
    OUString aTabName;

    // if FID_TAB_MOVE has parameters
    if( pReqArgs != nullptr )
    {
        SCTAB nTableCount = rDoc.GetTableCount();
        const SfxPoolItem* pItem;

        // if UseCurrentDocument(FN_PARAM_3) is true ignore the document name provided and use current document
        if( pReqArgs->HasItem( FN_PARAM_3, &pItem ) )
            bUseCurrentDocument = static_cast<const SfxBoolItem*>(pItem)->GetValue();

        if (bUseCurrentDocument)
            aDocName = GetViewData().GetDocShell().GetTitle();
        else if(pReqArgs->HasItem( FID_TAB_MOVE, &pItem ))
            aDocName = static_cast<const SfxStringItem*>(pItem)->GetValue();

        if( pReqArgs->HasItem( FN_PARAM_1, &pItem ) )
        {
            // nTab is the target tab.
            // source tab is either the active tab or the tab that context menu opened on.
            //  table is 1-based
            nTab = static_cast<const SfxUInt16Item*>(pItem)->GetValue() - 1;
            if ( nTab >= nTableCount )
                nTab = SC_TAB_APPEND;
        }
        if( pReqArgs->HasItem( FN_PARAM_2, &pItem ) )
            bCpy = static_cast<const SfxBoolItem*>(pItem)->GetValue();

        if (pReqArgs->HasItem(FN_PARAM_4, &pItem))
        {
            bFromContextMenu = static_cast<const SfxBoolItem*>(pItem)->GetValue();

            if (bFromContextMenu)
            {
                // source tab: the tab that context menu opened on
                if (pReqArgs->HasItem(FN_PARAM_5, &pItem))
                    nContextMenuTab
                        = static_cast<const SfxUInt16Item*>(pItem)->GetValue();

                if (pReqArgs->HasItem(FN_PARAM_6, &pItem))
                    bFromMoveOrCopySheetDialog
                        = static_cast<const SfxBoolItem*>(pItem)->GetValue();
            }
        }

        if (bFromMoveOrCopySheetDialog)
        {
            OUString aDefaultName;
            rDoc.GetName(nContextMenuTab, aDefaultName);

            ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

            VclPtr<AbstractScMoveTableDlg> pDlg(
                pFact->CreateScMoveTableDlg(GetFrameWeld(), aDefaultName));

            ScMarkData& rMark = GetViewData().GetMarkData();
            SCTAB nTabSelCount = rMark.GetSelectCount();

            if (nTableCount == nTabSelCount)
            {
                pDlg->SetForceCopyTable();
            }

            // We support direct renaming of sheet only when one sheet
            // is selected.
            pDlg->EnableRenameTable(nTabSelCount == 1);

            std::shared_ptr<SfxRequest> xReq = std::make_shared<SfxRequest>(rReq);
            pDlg->StartExecuteAsync([this, pDlg, xReq=std::move(xReq),
                                     nContextMenuTab](sal_Int32 nResult) {

                OUString aTableName;
                sal_uInt16 nDocument = 0;
                SCTAB nTargetIndex = -1;
                bool bCopy = false;
                bool bDoItAsync = false;

                if (RET_OK == nResult)
                {
                    nDocument = pDlg->GetSelectedDocument();
                    nTargetIndex = pDlg->GetSelectedTable();
                    bCopy = pDlg->GetCopyTable();
                    bool bRna = pDlg->GetRenameTable();
                    // Leave aTabName string empty, when Rename is FALSE.
                    if (bRna)
                        pDlg->GetTabNameString(aTableName);

                    bDoItAsync = true;

                    OUString aFoundDocName;
                    if (nDocument != SC_DOC_NEW)
                    {
                        ScDocShell* pSh = ScDocShell::GetShellByNum(nDocument);
                        if (pSh)
                        {
                            aFoundDocName = pSh->GetTitle();
                            if (!pSh->GetDocument().IsDocEditable())
                            {
                                ErrorMessage(STR_READONLYERR);
                                bDoItAsync = false;
                            }
                        }
                    }
                    xReq->AppendItem(SfxStringItem(FID_TAB_MOVE, aFoundDocName));
                    // 1-based table, if not APPEND
                    SCTAB nBasicTab = (nContextMenuTab <= MAXTAB)
                                          ? (nContextMenuTab + 1)
                                          : nContextMenuTab;
                    xReq->AppendItem(
                        SfxUInt16Item(FN_PARAM_1, static_cast<sal_uInt16>(nBasicTab)));
                    xReq->AppendItem(SfxBoolItem(FN_PARAM_2, bCopy));

                    if (bDoItAsync)
                    {
                        xReq->Done();

                        // send move or copy request
                        MoveTable(nDocument, nTargetIndex, bCopy, &aTableName, true,
                                  nContextMenuTab);
                    }
                }
                pDlg->disposeOnce();
            });
            rReq.Ignore();
        }
        else
        {
            if (!aDocName.isEmpty())
            {
                SfxObjectShell* pSh     = SfxObjectShell::GetFirst();
                ScDocShell*     pScSh   = nullptr;
                sal_uInt16          i=0;

                while ( pSh )
                {
                    pScSh = dynamic_cast<ScDocShell*>( pSh  );

                    if( pScSh )
                    {
                        if (aDocName == pScSh->GetTitle())
                        {
                            nDoc = i;
                            ScDocument& rDestDoc = pScSh->GetDocument();
                            nTableCount = rDestDoc.GetTableCount();
                            bDoIt = rDestDoc.IsDocEditable();
                            break;
                        }

                        i++;        // only count ScDocShell
                    }
                    pSh = SfxObjectShell::GetNext( *pSh );
                }
            }
            else // no doc-name -> new doc
            {
                nDoc = SC_DOC_NEW;
                bDoIt = true;
            }

            if ( bDoIt && nTab >= nTableCount )     // if necessary append
                nTab = SC_TAB_APPEND;
        }
    }
    else
    {
        OUString aDefaultName;
        rDoc.GetName( rViewData.GetTabNo(), aDefaultName );

        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

        VclPtr<AbstractScMoveTableDlg> pDlg(pFact->CreateScMoveTableDlg(GetFrameWeld(),
            aDefaultName));

        SCTAB nTableCount = rDoc.GetTableCount();
        ScMarkData& rMark       = GetViewData().GetMarkData();
        SCTAB       nTabSelCount = rMark.GetSelectCount();

        if(nTableCount==nTabSelCount)
        {
            pDlg->SetForceCopyTable();
        }

        // We support direct renaming of sheet only when one sheet
        // is selected.
        pDlg->EnableRenameTable(nTabSelCount == 1);

        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)] (sal_Int32 nResult)->void
            {
                if (nResult == RET_OK)
                {
                    DoMoveTableFromDialog(*xRequest, pDlg);
                }
                pDlg->disposeOnce();
            }
        );
    }

    if( bDoIt )
    {
        rReq.Done();        // record, while doc is active

        if (bFromContextMenu)
            MoveTable(nDoc, nTab, bCpy, &aTabName, true,
                      nContextMenuTab);
        else
            MoveTable( nDoc, nTab, bCpy, &aTabName );
    }
}

void ScTabViewShell::ExecuteInsertTable(SfxRequest& rReq)
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    const SfxItemSet* pReqArgs = rReq.GetArgs();
    sal_uInt16  nSlot       = rReq.GetSlot();
    SCTAB       nCurrentTab = rViewData.GetTabNo();
    SCTAB       nTabCount   = rDoc.GetTableCount();
    ScMarkData& rMark    = rViewData.GetMarkData();
    SCTAB   nTabSelCount = rMark.GetSelectCount();
    SCTAB   nTabNr       = nCurrentTab;

    if ( !rDoc.IsDocEditable() )
        return;                          // locked

    if ( pReqArgs != nullptr )             // from basic
    {
        bool bOk = false;
        const SfxPoolItem*  pTabItem;
        const SfxPoolItem*  pNameItem;

        if ( pReqArgs->HasItem( FN_PARAM_1, &pTabItem ) &&
             pReqArgs->HasItem( nSlot, &pNameItem ) )
        {
            OUString aName = static_cast<const SfxStringItem*>(pNameItem)->GetValue();
            rDoc.CreateValidTabName(aName);

            // sheet number from basic: 1-based
            // 0 is special, means adding at the end
            nTabNr = static_cast<const SfxUInt16Item*>(pTabItem)->GetValue();
            if (nTabNr == 0)
                nTabNr = nTabCount;
            else
                --nTabNr;

            if (nTabNr > nTabCount)
                nTabNr = nTabCount;

            bOk = InsertTable(aName, nTabNr);
        }

        if (bOk)
        {
            rViewData.GetViewShell()->SetActive();
            rReq.Done( *pReqArgs );
        }
        //! else set error
    }
    else                                // dialog
    {
        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
        VclPtr<AbstractScInsertTableDlg> pDlg(pFact->CreateScInsertTableDlg(GetFrameWeld(), rViewData,
            nTabSelCount, nSlot == FID_INS_TABLE_EXT));
        sfx2::ExecDialogPerRequestAndDispose(pDlg, rReq,
                                             [this, pDlg](sal_Int32 nResult, SfxRequest& req)
                                             {
                                                 if (nResult == RET_OK)
                                                     DoInsertTableFromDialog(req, pDlg);
                                             });
    }
}

void ScTabViewShell::DoInsertTableFromDialog(SfxRequest& rReq, const VclPtr<AbstractScInsertTableDlg>& pDlg)
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    SCTAB       nCurrentTab = rViewData.GetTabNo();
    SCTAB       nTabNr      = nCurrentTab;
    SCTAB       nTabCount   = rDoc.GetTableCount();
    ScMarkData& rMark    = rViewData.GetMarkData();

    if (pDlg->GetTablesFromFile())
    {
        std::vector<SCTAB> nTabs;
        sal_uInt16 n = 0;
        const OUString* pStr = pDlg->GetFirstTable( &n );
        while ( pStr )
        {
            nTabs.push_back( static_cast<SCTAB>(n) );
            pStr = pDlg->GetNextTable( &n );
        }
        bool bLink = pDlg->GetTablesAsLink();
        if (!nTabs.empty())
        {
            if(pDlg->IsTableBefore())
            {
                ImportTables( pDlg->GetDocShellTables(), nTabs.size(), nTabs.data(),
                            bLink,nTabNr );
            }
            else
            {
                SCTAB   nTabAfter    = nTabNr+1;

                for(SCTAB j=nCurrentTab+1;j<nTabCount;j++)
                {
                    if(!rDoc.IsScenario(j))
                    {
                        nTabAfter=j;
                        break;
                    }
                }

                ImportTables( pDlg->GetDocShellTables(), nTabs.size(), nTabs.data(),
                            bLink,nTabAfter );
            }
        }
    }
    else
    {
        SCTAB nCount=pDlg->GetTableCount();
        if(pDlg->IsTableBefore())
        {
            if(nCount==1 && !pDlg->GetFirstTable()->isEmpty())
            {
                rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
                rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabNr) + 1 ) );        // 1-based
                rReq.Done();

                InsertTable( *pDlg->GetFirstTable(), nTabNr );
            }
            else
            {
                std::vector<OUString> aNames(0);
                InsertTables( aNames, nTabNr,nCount );
            }
        }
        else
        {
            SCTAB   nTabAfter    = nTabNr+1;
            SCTAB nSelHigh = rMark.GetLastSelected();

            for(SCTAB j=nSelHigh+1;j<nTabCount;j++)
            {
                if(!rDoc.IsScenario(j))
                {
                    nTabAfter=j;
                    break;
                }
                else // #101672#; increase nTabAfter, because it is possible that the scenario tables are the last
                    nTabAfter = j + 1;
            }

            if(nCount==1 && !pDlg->GetFirstTable()->isEmpty())
            {
                rReq.AppendItem( SfxStringItem( FID_INS_TABLE, *pDlg->GetFirstTable() ) );
                rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nTabAfter) + 1 ) );     // 1-based
                rReq.Done();

                InsertTable( *pDlg->GetFirstTable(), nTabAfter);
            }
            else
            {
                std::vector<OUString> aNames(0);
                InsertTables( aNames, nTabAfter,nCount);
            }
        }
    }
    rViewData.GetViewShell()->SetActive();
}

void ScTabViewShell::DoMoveTableFromDialog( SfxRequest& rReq, const VclPtr<AbstractScMoveTableDlg>& pDlg )
{
    sal_uInt16 nDoc = pDlg->GetSelectedDocument();
    SCTAB nTab = pDlg->GetSelectedTable();
    bool bCpy = pDlg->GetCopyTable();
    bool bRna = pDlg->GetRenameTable();
    OUString aTabName;
    // Leave aTabName string empty, when Rename is FALSE.
    if( bRna )
    {
       pDlg->GetTabNameString( aTabName );
    }
    bool bDoIt = true;

    OUString aFoundDocName;
    if ( nDoc != SC_DOC_NEW )
    {
        ScDocShell* pSh = ScDocShell::GetShellByNum( nDoc );
        if (pSh)
        {
            aFoundDocName = pSh->GetTitle();
            if ( !pSh->GetDocument().IsDocEditable() )
            {
                ErrorMessage(STR_READONLYERR);
                bDoIt = false;
            }
        }
    }
    rReq.AppendItem( SfxStringItem( FID_TAB_MOVE, aFoundDocName ) );
    // 1-based table, if not APPEND
    SCTAB nBasicTab = ( nTab <= MAXTAB ) ? (nTab+1) : nTab;
    rReq.AppendItem( SfxUInt16Item( FN_PARAM_1, static_cast<sal_uInt16>(nBasicTab) ) );
    rReq.AppendItem( SfxBoolItem( FN_PARAM_2, bCpy ) );
    if( bDoIt )
    {
        rReq.Done();        // record, while doc is active
        MoveTable( nDoc, nTab, bCpy, &aTabName );
    }
}

void ScTabViewShell::ExecuteAppendOrRenameTable(SfxRequest& rReq)
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    sal_uInt16  nSlot       = rReq.GetSlot();
    const SfxItemSet* pReqArgs = rReq.GetArgs();

    if ( nSlot == FID_TAB_MENU_RENAME )
        nSlot = FID_TAB_RENAME;             // equal execute

    SCTAB nTabNr = rViewData.GetTabNo();
    ScMarkData& rMark = rViewData.GetMarkData();
    SCTAB nTabSelCount = rMark.GetSelectCount();

    if ( !rDoc.IsDocEditable() )
        return// everything locked

    if ( nSlot != FID_TAB_APPEND &&
            ( rDoc.IsTabProtected( nTabNr ) || nTabSelCount > 1 ) )
        return// no rename

    if( pReqArgs != nullptr )
    {
        bool        bDone   = false;
        const SfxPoolItem* pItem;
        OUString      aName;

        if( pReqArgs->HasItem( FN_PARAM_1, &pItem ) )
        {
            nTabNr = static_cast<const SfxUInt16Item*>(pItem)->GetValue();

            // inserting is 1-based, let's be consistent
            if (nTabNr > 0)
                --nTabNr;
        }

        if( pReqArgs->HasItem( nSlot, &pItem ) )
            aName = static_cast<const SfxStringItem*>(pItem)->GetValue();

        switch ( nSlot )
        {
            case FID_TAB_APPEND:
                bDone = AppendTable( aName );
                break;
            case FID_TAB_RENAME:
                bDone = RenameTable( aName, nTabNr );
                break;
        }

        if( bDone )
        {
            rReq.Done( *pReqArgs );
        }
    }
    else
    {
        OUString aName;
        OUString aDlgTitle;
        OUString sHelpId;

        switch ( nSlot )
        {
            case FID_TAB_APPEND:
                aDlgTitle = ScResId(SCSTR_APDTABLE);
                rDoc.CreateValidTabName( aName );
                sHelpId = HID_SC_APPEND_NAME;
                break;

            case FID_TAB_RENAME:
                aDlgTitle = ScResId(SCSTR_RENAMETAB);
                rDoc.GetName( rViewData.GetTabNo(), aName );
                sHelpId = HID_SC_RENAME_NAME;
                break;
        }

        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();

        VclPtr<AbstractScStringInputDlg> pDlg(pFact->CreateScStringInputDlg(
            GetFrameWeld(), aDlgTitle, ScResId(SCSTR_NAME),
            aName, GetStaticInterface()->GetSlot(nSlot)->GetCommand(),
            sHelpId));

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

void ScTabViewShell::ExecuteAppendOrRenameTableDialog(const VclPtr<AbstractScStringInputDlg>& pDlg,
                        const std::shared_ptr<SfxRequest>& xReq,
                        sal_uInt16 nSlot)
{
    pDlg->StartExecuteAsync(
        [this, pDlg, xReq, nSlot] (sal_Int32 nResult)->void
        {
            if (DoAppendOrRenameTableDialog(nResult, pDlg, xReq, nSlot))
                ExecuteAppendOrRenameTableDialog(pDlg, xReq, nSlot);
            else
                pDlg->disposeOnce();
        }
    );
}

bool ScTabViewShell::DoAppendOrRenameTableDialog(sal_Int32 nResult, const VclPtr<AbstractScStringInputDlg>& pDlg,
                        const std::shared_ptr<SfxRequest>& xReq,
                        sal_uInt16 nSlot)
{
    if (nResult != RET_OK)
        return false;

    ScViewData& rViewData   = GetViewData();
    SCTAB nTabNr = rViewData.GetTabNo();
    bool     bDone   = false;

    OUString aName = pDlg->GetInputString();

    switch ( nSlot )
    {
        case FID_TAB_APPEND:
            bDone = AppendTable( aName );
            break;
        case FID_TAB_RENAME:
            bDone = RenameTable( aName, nTabNr );
            break;
    }

    if ( bDone )
    {
        if (nSlot == FID_TAB_APPEND)
            rViewData.GetViewShell()->SetActive();
        xReq->AppendItem( SfxStringItem( nSlot, aName ) );
        xReq->Done();
    }
    else
    {
        if( xReq->IsAPI() )
        {
#if HAVE_FEATURE_SCRIPTING
            StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED ); // XXX error handling???
#endif
        }
        else
        {
            OUString aErrMsg ( ScResId( STR_INVALIDTABNAME ) );
            std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
                                                      VclMessageType::Warning, VclButtonsType::Ok, aErrMsg));
            xBox->run();
        }
    }

    return !bDone;
}

void ScTabViewShell::ExecuteSetTableBackgroundCol(SfxRequest& rReq)
{
    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    sal_uInt16  nSlot       = rReq.GetSlot();
    const SfxItemSet* pReqArgs = rReq.GetArgs();
    if ( nSlot == FID_TAB_MENU_SET_TAB_BG_COLOR )
        nSlot = FID_TAB_SET_TAB_BG_COLOR;
    SCTAB nTabNr = rViewData.GetTabNo();
    ScMarkData& rMark = rViewData.GetMarkData();
    SCTAB nTabSelCount = rMark.GetSelectCount();
    SCTAB nCurrentTab = rViewData.GetTabNo();

    if ( !rDoc.IsDocEditable() )
        return;

    if ( rDoc.IsTabProtected( nTabNr ) ) // ||nTabSelCount > 1
        return;

    if( pReqArgs != nullptr )
    {
        bool                bDone = false;
        const SfxPoolItem*  pItem;
        Color               aColor;

        if( pReqArgs->HasItem( nSlot, &pItem ) )
            aColor = static_cast<const SvxColorItem*>(pItem)->GetValue();

        if ( nTabSelCount > 1 )
        {
            std::unique_ptr<ScUndoTabColorInfo::List>
                pTabColorList(new ScUndoTabColorInfo::List);
            for (const auto& rTab : rMark)
            {
                if ( !rDoc.IsTabProtected(rTab) )
                {
                    ScUndoTabColorInfo aTabColorInfo(rTab);
                    aTabColorInfo.maNewTabBgColor = aColor;
                    pTabColorList->push_back(aTabColorInfo);
                }
            }
            bDone = SetTabBgColor( *pTabColorList );
        }
        else
        {
            bDone = SetTabBgColor( aColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
        }
        if( bDone )
        {
            rReq.Done( *pReqArgs );
        }
    }
    else
    {
        Color aTabBgColor = rDoc.GetTabBgColor( nCurrentTab );
        ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
        VclPtr<AbstractScTabBgColorDlg> pDlg(pFact->CreateScTabBgColorDlg(
                                                    GetFrameWeld(),
                                                    ScResId(SCSTR_SET_TAB_BG_COLOR),
                                                    ScResId(SCSTR_NO_TAB_BG_COLOR),
                                                    aTabBgColor));

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

void ScTabViewShell::ExecuteTableBackgroundDialog(const VclPtr<AbstractScTabBgColorDlg>& pDlg,
                        const std::shared_ptr<SfxRequest>& xReq,
                        Color aOldTabBgColor, sal_uInt16 nSlot)
{
    pDlg->StartExecuteAsync(
        [this, pDlg, xReq, aOldTabBgColor, nSlot] (sal_Int32 nResult)->void
        {
            if (DoTableBackgroundDialog(nResult, pDlg, xReq, aOldTabBgColor, nSlot))
                ExecuteTableBackgroundDialog(pDlg, xReq, aOldTabBgColor, nSlot);
            else
                pDlg->disposeOnce();
        }
    );
}

bool ScTabViewShell::DoTableBackgroundDialog(sal_Int32 nResult, const VclPtr<AbstractScTabBgColorDlg>& pDlg,
                        const std::shared_ptr<SfxRequest>& xReq,
                        Color aOldTabBgColor, sal_uInt16 nSlot)
{
    if (nResult != RET_OK)
        return false;

    ScViewData& rViewData   = GetViewData();
    ScDocument& rDoc        = rViewData.GetDocument();
    ScMarkData& rMark = rViewData.GetMarkData();
    SCTAB nCurrentTab = rViewData.GetTabNo();
    SCTAB nTabSelCount = rMark.GetSelectCount();
    bool bDone   = false/// temp
    Color aSelectedColor;
    pDlg->GetSelectedColor(aSelectedColor);
    std::unique_ptr<ScUndoTabColorInfo::List>
        pTabColorList(new ScUndoTabColorInfo::List);
    if ( nTabSelCount > 1 )
    {
        for (const auto& rTab : rMark)
        {
            if ( !rDoc.IsTabProtected(rTab) )
            {
                ScUndoTabColorInfo aTabColorInfo(rTab);
                aTabColorInfo.maNewTabBgColor = aSelectedColor;
                pTabColorList->push_back(aTabColorInfo);
            }
        }
        bDone = SetTabBgColor( *pTabColorList );
    }
    else
    {
        bDone = SetTabBgColor( aSelectedColor, nCurrentTab ); //ScViewFunc.SetTabBgColor
    }

    if ( bDone )
    {
        xReq->AppendItem( SvxColorItem( aOldTabBgColor, nSlot ) );
        xReq->Done();
    }
    else
    {
        if( xReq->IsAPI() )
        {
#if HAVE_FEATURE_SCRIPTING
            StarBASIC::Error( ERRCODE_BASIC_SETPROP_FAILED );
#endif
        }
    }

    return !bDone;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.33 Sekunden  ¤

*© 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.