781 lines
27 KiB
C++
781 lines
27 KiB
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 <scitems.hxx>
|
|
#include <sfx2/childwin.hxx>
|
|
#include <sfx2/dispatch.hxx>
|
|
#include <svx/theme/ThemeColorChangerCommon.hxx>
|
|
#include <editeng/editview.hxx>
|
|
#include <inputhdl.hxx>
|
|
|
|
#include <tabvwsh.hxx>
|
|
#include <sc.hrc>
|
|
#include <scres.hrc>
|
|
#include <global.hxx>
|
|
#include <scmod.hxx>
|
|
#include <document.hxx>
|
|
#include <uiitems.hxx>
|
|
#include <namedlg.hxx>
|
|
#include <namedefdlg.hxx>
|
|
#include <solvrdlg.hxx>
|
|
#include <optsolver.hxx>
|
|
#include <tabopdlg.hxx>
|
|
#include <consdlg.hxx>
|
|
#include <filtdlg.hxx>
|
|
#include <dbnamdlg.hxx>
|
|
#include <areasdlg.hxx>
|
|
#include <crnrdlg.hxx>
|
|
#include <formula.hxx>
|
|
#include <highred.hxx>
|
|
#include <simpref.hxx>
|
|
#include <funcdesc.hxx>
|
|
#include <dpobject.hxx>
|
|
#include <markdata.hxx>
|
|
#include <reffact.hxx>
|
|
#include <condformatdlg.hxx>
|
|
#include <condformateasydlg.hxx>
|
|
#include <xmlsourcedlg.hxx>
|
|
#include <condformatdlgdata.hxx>
|
|
#include <formdata.hxx>
|
|
#include <inputwin.hxx>
|
|
|
|
#include <RandomNumberGeneratorDialog.hxx>
|
|
#include <SamplingDialog.hxx>
|
|
#include <DescriptiveStatisticsDialog.hxx>
|
|
#include <AnalysisOfVarianceDialog.hxx>
|
|
#include <CorrelationDialog.hxx>
|
|
#include <CovarianceDialog.hxx>
|
|
#include <ExponentialSmoothingDialog.hxx>
|
|
#include <MovingAverageDialog.hxx>
|
|
#include <RegressionDialog.hxx>
|
|
#include <TTestDialog.hxx>
|
|
#include <FTestDialog.hxx>
|
|
#include <ZTestDialog.hxx>
|
|
#include <ChiSquareTestDialog.hxx>
|
|
#include <FourierAnalysisDialog.hxx>
|
|
|
|
#include <PivotLayoutDialog.hxx>
|
|
#include <SparklineDialog.hxx>
|
|
#include <SparklineDataRangeDialog.hxx>
|
|
|
|
#include <svtools/colorcfg.hxx>
|
|
#include <comphelper/lok.hxx>
|
|
#include <o3tl/unreachable.hxx>
|
|
#include <o3tl/make_shared.hxx>
|
|
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
|
|
|
|
void ScTabViewShell::SetCurRefDlgId( sal_uInt16 nNew )
|
|
{
|
|
// CurRefDlgId is stored in ScModule to find if a ref dialog is open,
|
|
// and in the view to identify the view that has opened the dialog
|
|
nCurRefDlgId = nNew;
|
|
}
|
|
|
|
//ugly hack to call Define Name from Manage Names
|
|
void ScTabViewShell::SwitchBetweenRefDialogs(SfxModelessDialogController* pDialog)
|
|
{
|
|
ScModule* mod = ScModule::get();
|
|
sal_uInt16 nSlotId = mod->GetCurRefDlgId();
|
|
if( nSlotId == FID_ADD_NAME )
|
|
{
|
|
static_cast<ScNameDefDlg*>(pDialog)->GetNewData(maName, maScope);
|
|
static_cast<ScNameDefDlg*>(pDialog)->Close();
|
|
sal_uInt16 nId = ScNameDlgWrapper::GetChildWindowId();
|
|
SfxViewFrame& rViewFrm = GetViewFrame();
|
|
SfxChildWindow* pWnd = rViewFrm.GetChildWindow( nId );
|
|
|
|
mod->SetRefDialog( nId, pWnd == nullptr );
|
|
}
|
|
else if (nSlotId == FID_DEFINE_NAME)
|
|
{
|
|
mbInSwitch = true;
|
|
static_cast<ScNameDlg*>(pDialog)->GetRangeNames(m_RangeMap);
|
|
static_cast<ScNameDlg*>(pDialog)->Close();
|
|
sal_uInt16 nId = ScNameDefDlgWrapper::GetChildWindowId();
|
|
SfxViewFrame& rViewFrm = GetViewFrame();
|
|
SfxChildWindow* pWnd = rViewFrm.GetChildWindow( nId );
|
|
|
|
mod->SetRefDialog( nId, pWnd == nullptr );
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<SfxModelessDialogController> ScTabViewShell::CreateRefDialogController(
|
|
SfxBindings* pB, SfxChildWindow* pCW,
|
|
SfxChildWinInfo* pInfo,
|
|
weld::Window* pParent, sal_uInt16 nSlotId)
|
|
{
|
|
// only open dialog when called through ScModule::SetRefDialog,
|
|
// so that it does not re appear for instance after a crash (#42341#).
|
|
|
|
if (ScModule::get()->GetCurRefDlgId() != nSlotId)
|
|
return nullptr;
|
|
|
|
if ( nCurRefDlgId != nSlotId )
|
|
{
|
|
if (!(comphelper::LibreOfficeKit::isActive() && nSlotId == SID_OPENDLG_FUNCTION))
|
|
{
|
|
// the dialog has been opened in a different view
|
|
// -> lock the dispatcher for this view (modal mode)
|
|
|
|
GetViewData().GetDispatcher().Lock( true ); // lock is reset when closing dialog
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
std::shared_ptr<SfxModelessDialogController> xResult;
|
|
|
|
if(pCW)
|
|
pCW->SetHideNotDelete(true);
|
|
|
|
ScDocument& rDoc = GetViewData().GetDocument();
|
|
|
|
switch( nSlotId )
|
|
{
|
|
case SID_CORRELATION_DIALOG:
|
|
xResult = std::make_shared<ScCorrelationDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_SAMPLING_DIALOG:
|
|
xResult = std::make_shared<ScSamplingDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_DESCRIPTIVE_STATISTICS_DIALOG:
|
|
xResult = std::make_shared<ScDescriptiveStatisticsDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_ANALYSIS_OF_VARIANCE_DIALOG:
|
|
xResult = std::make_shared<ScAnalysisOfVarianceDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_COVARIANCE_DIALOG:
|
|
xResult = std::make_shared<ScCovarianceDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_EXPONENTIAL_SMOOTHING_DIALOG:
|
|
xResult = std::make_shared<ScExponentialSmoothingDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_MOVING_AVERAGE_DIALOG:
|
|
xResult = std::make_shared<ScMovingAverageDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_REGRESSION_DIALOG:
|
|
xResult = std::make_shared<ScRegressionDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_FTEST_DIALOG:
|
|
xResult = std::make_shared<ScFTestDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_TTEST_DIALOG:
|
|
xResult = std::make_shared<ScTTestDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_ZTEST_DIALOG:
|
|
xResult = std::make_shared<ScZTestDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_CHI_SQUARE_TEST_DIALOG:
|
|
xResult = std::make_shared<ScChiSquareTestDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_FOURIER_ANALYSIS_DIALOG:
|
|
xResult = std::make_shared<ScFourierAnalysisDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case WID_SIMPLE_REF:
|
|
{
|
|
// dialog checks, what is in the cell
|
|
|
|
ScViewData& rViewData = GetViewData();
|
|
rViewData.SetRefTabNo( rViewData.GetTabNo() );
|
|
xResult = std::make_shared<ScSimpleRefDlg>(pB, pCW, pParent);
|
|
break;
|
|
}
|
|
case FID_DEFINE_NAME:
|
|
{
|
|
if (!mbInSwitch)
|
|
{
|
|
xResult = std::make_shared<ScNameDlg>(pB, pCW, pParent, GetViewData(),
|
|
ScAddress( GetViewData().GetCurX(),
|
|
GetViewData().GetCurY(),
|
|
GetViewData().GetTabNo() ) );
|
|
}
|
|
else
|
|
{
|
|
xResult = std::make_shared<ScNameDlg>( pB, pCW, pParent, GetViewData(),
|
|
ScAddress( GetViewData().GetCurX(),
|
|
GetViewData().GetCurY(),
|
|
GetViewData().GetTabNo() ), &m_RangeMap);
|
|
static_cast<ScNameDlg*>(xResult.get())->SetEntry(maName, maScope);
|
|
mbInSwitch = false;
|
|
}
|
|
break;
|
|
}
|
|
case FID_ADD_NAME:
|
|
{
|
|
if (!mbInSwitch)
|
|
{
|
|
std::map<OUString, ScRangeName*> aRangeMap;
|
|
rDoc.GetRangeNameMap(aRangeMap);
|
|
xResult = std::make_shared<ScNameDefDlg>(pB, pCW, pParent, GetViewData(), std::move(aRangeMap),
|
|
ScAddress(GetViewData().GetCurX(),
|
|
GetViewData().GetCurY(),
|
|
GetViewData().GetTabNo()), true);
|
|
}
|
|
else
|
|
{
|
|
std::map<OUString, ScRangeName*> aRangeMap;
|
|
for (auto& itr : m_RangeMap)
|
|
{
|
|
aRangeMap.insert(std::pair<OUString, ScRangeName*>(itr.first, &itr.second));
|
|
}
|
|
xResult = std::make_shared<ScNameDefDlg>(pB, pCW, pParent, GetViewData(), std::move(aRangeMap),
|
|
ScAddress(GetViewData().GetCurX(),
|
|
GetViewData().GetCurY(),
|
|
GetViewData().GetTabNo()), false);
|
|
}
|
|
break;
|
|
}
|
|
case SID_RANDOM_NUMBER_GENERATOR_DIALOG:
|
|
xResult = std::make_shared<ScRandomNumberGeneratorDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_SPARKLINE_DIALOG:
|
|
{
|
|
xResult = std::make_shared<sc::SparklineDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
}
|
|
case SID_SPARKLINE_DATA_RANGE_DIALOG:
|
|
{
|
|
xResult = std::make_shared<sc::SparklineDataRangeDialog>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
}
|
|
case SID_DEFINE_DBNAME:
|
|
{
|
|
// when called for an existing range, then mark
|
|
GetDBData( true, SC_DB_OLD );
|
|
const ScMarkData& rMark = GetViewData().GetMarkData();
|
|
if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
|
|
MarkDataArea( false );
|
|
|
|
xResult = std::make_shared<ScDbNameDlg>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
}
|
|
case SID_OPENDLG_EDIT_PRINTAREA:
|
|
xResult = std::make_shared<ScPrintAreasDlg>(pB, pCW, pParent);
|
|
break;
|
|
case SID_DEFINE_COLROWNAMERANGES:
|
|
xResult = std::make_shared<ScColRowNameRangesDlg>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
case SID_OPENDLG_SOLVE:
|
|
{
|
|
ScViewData& rViewData = GetViewData();
|
|
ScAddress aCurPos( rViewData.GetCurX(),
|
|
rViewData.GetCurY(),
|
|
rViewData.GetTabNo());
|
|
xResult = std::make_shared<ScSolverDlg>(pB, pCW, pParent, &rViewData.GetDocument(), aCurPos);
|
|
break;
|
|
}
|
|
case SID_OPENDLG_TABOP:
|
|
{
|
|
ScViewData& rViewData = GetViewData();
|
|
ScRefAddress aCurPos ( rViewData.GetCurX(),
|
|
rViewData.GetCurY(),
|
|
rViewData.GetTabNo());
|
|
|
|
xResult = std::make_shared<ScTabOpDlg>(pB, pCW, pParent, &rViewData.GetDocument(), aCurPos);
|
|
break;
|
|
}
|
|
case SID_OPENDLG_CONSOLIDATE:
|
|
{
|
|
SfxItemSetFixed<SCITEM_CONSOLIDATEDATA,
|
|
SCITEM_CONSOLIDATEDATA> aArgSet( GetPool() );
|
|
|
|
const ScConsolidateParam* pDlgData =
|
|
rDoc.GetConsolidateDlgData();
|
|
|
|
if ( !pDlgData )
|
|
{
|
|
ScConsolidateParam aConsParam;
|
|
SCCOL nStartCol, nEndCol;
|
|
SCROW nStartRow, nEndRow;
|
|
SCTAB nStartTab, nEndTab;
|
|
|
|
GetViewData().GetSimpleArea( nStartCol, nStartRow, nStartTab,
|
|
nEndCol, nEndRow, nEndTab );
|
|
|
|
PutInOrder( nStartCol, nEndCol );
|
|
PutInOrder( nStartRow, nEndRow );
|
|
PutInOrder( nStartTab, nEndTab );
|
|
|
|
aConsParam.nCol = nStartCol;
|
|
aConsParam.nRow = nStartRow;
|
|
aConsParam.nTab = nStartTab;
|
|
|
|
aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA,
|
|
&aConsParam ) );
|
|
}
|
|
else
|
|
{
|
|
aArgSet.Put( ScConsolidateItem( SCITEM_CONSOLIDATEDATA, pDlgData ) );
|
|
}
|
|
xResult = std::make_shared<ScConsolidateDlg>(pB, pCW, pParent, aArgSet);
|
|
break;
|
|
}
|
|
case SID_EASY_CONDITIONAL_FORMAT_DIALOG:
|
|
{
|
|
xResult = std::make_shared<sc::ConditionalFormatEasyDialog>(pB, pCW, pParent, &GetViewData());
|
|
break;
|
|
}
|
|
case SID_FILTER:
|
|
{
|
|
|
|
ScQueryParam aQueryParam;
|
|
SfxItemSetFixed<SCITEM_QUERYDATA, SCITEM_QUERYDATA> aArgSet( GetPool() );
|
|
|
|
ScDBData* pDBData = GetDBData(false, SC_DB_MAKE, ScGetDBSelection::RowDown);
|
|
pDBData->ExtendDataArea(rDoc);
|
|
pDBData->ExtendBackColorArea(rDoc);
|
|
pDBData->GetQueryParam( aQueryParam );
|
|
|
|
ScRange aArea;
|
|
pDBData->GetArea(aArea);
|
|
MarkRange(aArea, false);
|
|
|
|
aArgSet.Put( ScQueryItem( SCITEM_QUERYDATA,
|
|
&GetViewData(),
|
|
&aQueryParam ) );
|
|
|
|
// mark current sheet (due to RefInput in dialog)
|
|
GetViewData().SetRefTabNo( GetViewData().GetTabNo() );
|
|
|
|
xResult = std::make_shared<ScFilterDlg>(pB, pCW, pParent, aArgSet);
|
|
break;
|
|
}
|
|
case SID_SPECIAL_FILTER:
|
|
{
|
|
ScQueryParam aQueryParam;
|
|
SfxItemSetFixed<SCITEM_QUERYDATA,
|
|
SCITEM_QUERYDATA> aArgSet( GetPool() );
|
|
|
|
ScDBData* pDBData = GetDBData(false, SC_DB_MAKE, ScGetDBSelection::RowDown);
|
|
pDBData->ExtendDataArea(rDoc);
|
|
pDBData->GetQueryParam( aQueryParam );
|
|
|
|
ScRange aArea;
|
|
pDBData->GetArea(aArea);
|
|
MarkRange(aArea, false);
|
|
|
|
ScQueryItem aItem( SCITEM_QUERYDATA, &GetViewData(), &aQueryParam );
|
|
ScRange aAdvSource;
|
|
if (pDBData->GetAdvancedQuerySource(aAdvSource))
|
|
aItem.SetAdvancedQuerySource( &aAdvSource );
|
|
|
|
aArgSet.Put( aItem );
|
|
|
|
// mark current sheet (due to RefInput in dialog)
|
|
GetViewData().SetRefTabNo( GetViewData().GetTabNo() );
|
|
|
|
xResult = std::make_shared<ScSpecialFilterDlg>(pB, pCW, pParent, aArgSet);
|
|
break;
|
|
}
|
|
case SID_OPENDLG_OPTSOLVER:
|
|
{
|
|
ScViewData& rViewData = GetViewData();
|
|
ScAddress aCurPos( rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
|
|
xResult = std::make_shared<ScOptSolverDlg>(pB, pCW, pParent, rViewData.GetDocShell(), aCurPos);
|
|
break;
|
|
}
|
|
case FID_CHG_SHOW:
|
|
{
|
|
// dialog checks, what is in the cell
|
|
xResult = std::make_shared<ScHighlightChgDlg>(pB, pCW, pParent, GetViewData());
|
|
break;
|
|
}
|
|
case SID_MANAGE_XML_SOURCE:
|
|
{
|
|
xResult = std::make_shared<ScXMLSourceDlg>(pB, pCW, pParent, &rDoc);
|
|
break;
|
|
}
|
|
case SID_OPENDLG_PIVOTTABLE:
|
|
{
|
|
// all settings must be in pDialogDPObject
|
|
|
|
if( pDialogDPObject )
|
|
{
|
|
// Check for an existing datapilot output.
|
|
ScViewData& rViewData = GetViewData();
|
|
rViewData.SetRefTabNo( rViewData.GetTabNo() );
|
|
ScDPObject* pObj = rDoc.GetDPAtCursor(rViewData.GetCurX(), rViewData.GetCurY(), rViewData.GetTabNo());
|
|
xResult = std::make_shared<ScPivotLayoutDialog>(pB, pCW, pParent, &rViewData, pDialogDPObject.get(), pObj == nullptr);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case SID_OPENDLG_FUNCTION:
|
|
{
|
|
if (!isLOKMobilePhone())
|
|
{
|
|
// dialog checks, what is in the cell
|
|
xResult = o3tl::make_shared<ScFormulaDlg>(pB, pCW, pParent, GetViewData(), ScGlobal::GetStarCalcFunctionMgr());
|
|
}
|
|
break;
|
|
}
|
|
case WID_CONDFRMT_REF:
|
|
{
|
|
// Get the DialogData stored by Conditional Format Manager Dialog.
|
|
const std::shared_ptr<ScCondFormatDlgData>& rDlgData(getScCondFormatDlgData());
|
|
|
|
if (rDlgData)
|
|
{
|
|
ScViewData& rViewData = GetViewData();
|
|
rViewData.SetRefTabNo( rViewData.GetTabNo() );
|
|
|
|
xResult = std::make_shared<ScCondFormatDlg>(pB, pCW, pParent, &rViewData, rDlgData);
|
|
|
|
// Remove the DialogData stored by Conditional Format Manager Dialog.
|
|
setScCondFormatDlgData(nullptr);
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (xResult)
|
|
{
|
|
pInfo->nFlags = SfxChildWindowFlags::NEVERHIDE;
|
|
xResult->Initialize(pInfo);
|
|
}
|
|
return xResult;
|
|
}
|
|
|
|
int ScTabViewShell::getPart() const
|
|
{
|
|
return GetViewData().GetTabNo();
|
|
}
|
|
|
|
void ScTabViewShell::afterCallbackRegistered()
|
|
{
|
|
// common tasks
|
|
SfxViewShell::afterCallbackRegistered();
|
|
|
|
UpdateInputHandler(true, false);
|
|
|
|
ScInputHandler* pHdl = mpInputHandler ? mpInputHandler.get() : ScModule::get()->GetInputHdl();
|
|
if (pHdl)
|
|
{
|
|
ScInputWindow* pInputWindow = pHdl->GetInputWindow();
|
|
if (pInputWindow)
|
|
{
|
|
pInputWindow->NotifyLOKClient();
|
|
}
|
|
}
|
|
|
|
SfxObjectShell* pDocShell = GetObjectShell();
|
|
if (pDocShell)
|
|
{
|
|
std::shared_ptr<model::ColorSet> pThemeColors = pDocShell->GetThemeColors();
|
|
std::set<Color> aDocumentColors = pDocShell->GetDocColors();
|
|
svx::theme::notifyLOK(pThemeColors, aDocumentColors);
|
|
}
|
|
}
|
|
|
|
void ScTabViewShell::NotifyCursor(SfxViewShell* pOtherShell) const
|
|
{
|
|
ScDrawView* pDrView = const_cast<ScTabViewShell*>(this)->GetScDrawView();
|
|
if (pDrView)
|
|
{
|
|
if (pDrView->GetTextEditObject())
|
|
{
|
|
// Blinking cursor.
|
|
EditView& rEditView = pDrView->GetTextEditOutlinerView()->GetEditView();
|
|
rEditView.RegisterOtherShell(pOtherShell);
|
|
rEditView.ShowCursor();
|
|
rEditView.RegisterOtherShell(nullptr);
|
|
// Text selection, if any.
|
|
rEditView.DrawSelectionXOR(pOtherShell);
|
|
}
|
|
else
|
|
{
|
|
// Graphic selection.
|
|
pDrView->AdjustMarkHdl(pOtherShell);
|
|
}
|
|
}
|
|
|
|
const ScGridWindow* pWin = GetViewData().GetActiveWin();
|
|
if (pWin)
|
|
pWin->updateKitCellCursor(pOtherShell);
|
|
}
|
|
|
|
::Color ScTabViewShell::GetColorConfigColor(svtools::ColorConfigEntry nColorType) const
|
|
{
|
|
switch (nColorType)
|
|
{
|
|
case svtools::ColorConfigEntry::DOCCOLOR:
|
|
{
|
|
const ScViewRenderingOptions& rViewRenderingOptions = GetViewRenderingData();
|
|
return rViewRenderingOptions.GetDocColor();
|
|
}
|
|
// Should never be called for an unimplemented color type
|
|
default:
|
|
{
|
|
O3TL_UNREACHABLE;
|
|
}
|
|
}
|
|
}
|
|
|
|
css::uno::Reference<css::datatransfer::XTransferable2> ScTabViewShell::GetClipData(vcl::Window* pWin)
|
|
{
|
|
SfxViewFrame* pViewFrame = nullptr;
|
|
css::uno::Reference<css::datatransfer::XTransferable2> xTransferable;
|
|
css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard;
|
|
|
|
if (pWin)
|
|
xClipboard = pWin->GetClipboard();
|
|
else if ((pViewFrame = SfxViewFrame::GetFirst(nullptr, false)))
|
|
xClipboard = pViewFrame->GetWindow().GetClipboard();
|
|
|
|
xTransferable.set(xClipboard.is() ? xClipboard->getContents() : nullptr, css::uno::UNO_QUERY);
|
|
|
|
return xTransferable;
|
|
}
|
|
|
|
void ScTabViewShell::notifyAllViewsHeaderInvalidation(const SfxViewShell* pForViewShell, HeaderType eHeaderType, SCTAB nCurrentTabIndex)
|
|
{
|
|
if (!comphelper::LibreOfficeKit::isActive())
|
|
return;
|
|
|
|
OString aPayload;
|
|
switch (eHeaderType)
|
|
{
|
|
case COLUMN_HEADER:
|
|
aPayload = "column"_ostr;
|
|
break;
|
|
case ROW_HEADER:
|
|
aPayload = "row"_ostr;
|
|
break;
|
|
case BOTH_HEADERS:
|
|
default:
|
|
aPayload = "all"_ostr;
|
|
break;
|
|
}
|
|
|
|
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
|
|
while (pViewShell)
|
|
{
|
|
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
|
|
if (pTabViewShell && pViewShell->GetDocId() == pForViewShell->GetDocId()
|
|
&& (nCurrentTabIndex == -1 || pTabViewShell->getPart() == nCurrentTabIndex))
|
|
{
|
|
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_HEADER, aPayload);
|
|
}
|
|
pViewShell = SfxViewShell::GetNext(*pViewShell);
|
|
}
|
|
}
|
|
|
|
bool ScTabViewShell::isAnyEditViewInRange(const SfxViewShell* pForViewShell, bool bColumns, SCCOLROW nStart, SCCOLROW nEnd)
|
|
{
|
|
if (comphelper::LibreOfficeKit::isActive())
|
|
{
|
|
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
|
|
while (pViewShell)
|
|
{
|
|
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
|
|
if (pTabViewShell && pTabViewShell->GetDocId() == pForViewShell->GetDocId())
|
|
{
|
|
ScInputHandler* pInputHandler = pTabViewShell->GetInputHandler();
|
|
if (pInputHandler && pInputHandler->GetActiveView())
|
|
{
|
|
const ScViewData& rViewData = pTabViewShell->GetViewData();
|
|
SCCOLROW nPos = bColumns ? rViewData.GetCurX() : rViewData.GetCurY();
|
|
if (nStart <= nPos && nPos <= nEnd)
|
|
return true;
|
|
}
|
|
}
|
|
pViewShell = SfxViewShell::GetNext(*pViewShell);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void ScTabViewShell::notifyAllViewsSheetGeomInvalidation(const SfxViewShell* pForViewShell, bool bColumns,
|
|
bool bRows, bool bSizes, bool bHidden, bool bFiltered,
|
|
bool bGroups, SCTAB nCurrentTabIndex)
|
|
{
|
|
if (!comphelper::LibreOfficeKit::isActive() ||
|
|
!comphelper::LibreOfficeKit::isCompatFlagSet(
|
|
comphelper::LibreOfficeKit::Compat::scPrintTwipsMsgs))
|
|
return;
|
|
|
|
if (!bColumns && !bRows)
|
|
return;
|
|
|
|
bool bAllTypes = bSizes && bHidden && bFiltered && bGroups;
|
|
bool bAllDims = bColumns && bRows;
|
|
OString aPayload = bAllDims ? "all" : bColumns ? "columns" : "rows";
|
|
|
|
if (!bAllTypes)
|
|
{
|
|
if (bSizes)
|
|
aPayload += " sizes";
|
|
|
|
if (bHidden)
|
|
aPayload += " hidden";
|
|
|
|
if (bFiltered)
|
|
aPayload += " filtered";
|
|
|
|
if (bGroups)
|
|
aPayload += " groups";
|
|
}
|
|
|
|
SfxViewShell* pViewShell = SfxViewShell::GetFirst();
|
|
while (pViewShell)
|
|
{
|
|
ScTabViewShell* pTabViewShell = dynamic_cast<ScTabViewShell*>(pViewShell);
|
|
if (pTabViewShell && pViewShell->GetDocId() == pForViewShell->GetDocId() &&
|
|
(nCurrentTabIndex == -1 || pTabViewShell->getPart() == nCurrentTabIndex))
|
|
{
|
|
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_INVALIDATE_SHEET_GEOMETRY, aPayload);
|
|
}
|
|
pViewShell = SfxViewShell::GetNext(*pViewShell);
|
|
}
|
|
}
|
|
|
|
bool ScTabViewShell::UseSubTotal(ScRangeList* pRangeList)
|
|
{
|
|
bool bSubTotal = false;
|
|
ScDocument& rDoc = GetViewData().GetDocument();
|
|
size_t nRangeCount (pRangeList->size());
|
|
size_t nRangeIndex (0);
|
|
while (!bSubTotal && nRangeIndex < nRangeCount)
|
|
{
|
|
const ScRange& rRange = (*pRangeList)[nRangeIndex];
|
|
SCTAB nTabEnd(rRange.aEnd.Tab());
|
|
SCTAB nTab(rRange.aStart.Tab());
|
|
while (!bSubTotal && nTab <= nTabEnd)
|
|
{
|
|
SCROW nRowEnd(rRange.aEnd.Row());
|
|
SCROW nRow(rRange.aStart.Row());
|
|
while (!bSubTotal && nRow <= nRowEnd)
|
|
{
|
|
if (rDoc.RowFiltered(nRow, nTab))
|
|
bSubTotal = true;
|
|
else
|
|
++nRow;
|
|
}
|
|
++nTab;
|
|
}
|
|
++nRangeIndex;
|
|
}
|
|
|
|
if (!bSubTotal)
|
|
{
|
|
const ScDBCollection::NamedDBs& rDBs = rDoc.GetDBCollection()->getNamedDBs();
|
|
for (const auto& rxDB : rDBs)
|
|
{
|
|
const ScDBData& rDB = *rxDB;
|
|
if (!rDB.HasAutoFilter())
|
|
continue;
|
|
|
|
nRangeIndex = 0;
|
|
while (!bSubTotal && nRangeIndex < nRangeCount)
|
|
{
|
|
const ScRange & rRange = (*pRangeList)[nRangeIndex];
|
|
ScRange aDBArea;
|
|
rDB.GetArea(aDBArea);
|
|
if (aDBArea.Intersects(rRange))
|
|
bSubTotal = true;
|
|
++nRangeIndex;
|
|
}
|
|
|
|
if (bSubTotal)
|
|
break;
|
|
}
|
|
}
|
|
return bSubTotal;
|
|
}
|
|
|
|
OUString ScTabViewShell::DoAutoSum(bool& rRangeFinder, bool& rSubTotal, const OpCode eCode)
|
|
{
|
|
OUString aFormula;
|
|
const ScMarkData& rMark = GetViewData().GetMarkData();
|
|
if ( rMark.IsMarked() || rMark.IsMultiMarked() )
|
|
{
|
|
ScRangeList aMarkRangeList;
|
|
rRangeFinder = rSubTotal = false;
|
|
rMark.FillRangeListWithMarks( &aMarkRangeList, false );
|
|
ScDocument& rDoc = GetViewData().GetDocument();
|
|
|
|
// check if one of the marked ranges is empty
|
|
bool bEmpty = false;
|
|
const size_t nCount = aMarkRangeList.size();
|
|
for ( size_t i = 0; i < nCount; ++i )
|
|
{
|
|
const ScRange & rRange( aMarkRangeList[i] );
|
|
if ( rDoc.IsBlockEmpty( rRange.aStart.Col(), rRange.aStart.Row(),
|
|
rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aStart.Tab() ) )
|
|
{
|
|
bEmpty = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( bEmpty )
|
|
{
|
|
ScRangeList aRangeList;
|
|
const bool bDataFound = GetAutoSumArea( aRangeList );
|
|
if ( bDataFound )
|
|
{
|
|
ScAddress aAddr = aRangeList.back().aEnd;
|
|
aAddr.IncRow();
|
|
const bool bSubTotal( UseSubTotal( &aRangeList ) );
|
|
EnterAutoSum( aRangeList, bSubTotal, aAddr, eCode );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const bool bSubTotal( UseSubTotal( &aMarkRangeList ) );
|
|
for ( size_t i = 0; i < nCount; ++i )
|
|
{
|
|
const ScRange & rRange = aMarkRangeList[i];
|
|
const bool bSetCursor = ( i == nCount - 1 );
|
|
const bool bContinue = ( i != 0 );
|
|
if ( !AutoSum( rRange, bSubTotal, bSetCursor, bContinue, eCode ) )
|
|
{
|
|
MarkRange( rRange, false );
|
|
SetCursor( rRange.aEnd.Col(), rRange.aEnd.Row() );
|
|
const ScRangeList aRangeList;
|
|
ScAddress aAddr = rRange.aEnd;
|
|
aAddr.IncRow();
|
|
aFormula = GetAutoSumFormula( aRangeList, bSubTotal, aAddr , eCode);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else // Only insert into input row
|
|
{
|
|
ScRangeList aRangeList;
|
|
rRangeFinder = GetAutoSumArea( aRangeList );
|
|
rSubTotal = UseSubTotal( &aRangeList );
|
|
ScAddress aAddr = GetViewData().GetCurPos();
|
|
aFormula = GetAutoSumFormula( aRangeList, rSubTotal, aAddr , eCode);
|
|
}
|
|
return aFormula;
|
|
}
|
|
|
|
void ScTabViewShell::InitFormEditData()
|
|
{
|
|
mpFormEditData.reset(new ScFormEditData);
|
|
}
|
|
|
|
void ScTabViewShell::ClearFormEditData()
|
|
{
|
|
mpFormEditData.reset();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|