/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <com/sun/star/ui/dialogs/XSLTFilterDialog.hpp>
#include <comphelper/lok.hxx>
#include <comphelper/processfactory.hxx>
#include <scitems.hxx>
#include <sfx2/app.hxx>
#include <editeng/flditem.hxx>
#include <editeng/outliner.hxx>
#include <sfx2/viewfrm.hxx>
#include <sfx2/objface.hxx>
#include <IAnyRefDialog.hxx>
#include <svtools/ehdl.hxx>
#include <svtools/accessibilityoptions.hxx>
#include <svl/ctloptions.hxx>
#include <unotools/useroptions.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <sfx2/printer.hxx>
#include <editeng/langitem.hxx>
#include <svtools/colorcfg.hxx>
#include <svl/whiter.hxx>
#include <svx/dialogs.hrc>
#include <svl/inethist.hxx>
#include <vcl/svapp.hxx>
#include <svx/svxerr.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <editeng/unolingu.hxx>
#include <unotools/lingucfg.hxx>
#include <i18nlangtag/mslangid.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <com/sun/star/i18n/ScriptType.hpp>
#include <com/sun/star/linguistic2/XThesaurus.hpp>
#include <ooo/vba/XSinkCaller.hpp>
#include <scmod.hxx>
#include <global.hxx>
#include <viewopti.hxx>
#include <docoptio.hxx>
#include <appoptio.hxx>
#include <defaultsoptions.hxx>
#include <formulaopt.hxx>
#include <inputopt.hxx>
#include <printopt.hxx>
#include <navicfg.hxx>
#include <addincfg.hxx>
#include <tabvwsh.hxx>
#include <prevwsh.hxx>
#include <docsh.hxx>
#include <drwlayer.hxx>
#include <uiitems.hxx>
#include <sc.hrc>
#include <scerrors.hrc>
#include <scstyles.hrc>
#include <globstr.hrc>
#include <scresid.hxx>
#include <bitmaps.hlst>
#include <inputhdl.hxx>
#include <inputwin.hxx>
#include <msgpool.hxx>
#include <detfunc.hxx>
#include <preview.hxx>
#include <dragdata.hxx>
#include <markdata.hxx>
#include <transobj.hxx>
#include <funcdesc.hxx>
#define ShellClass_ScModule
#include <scslots.hxx>
#include <scabstdlg.hxx>
#include <formula/errorcodes.hxx>
#include <documentlinkmgr.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <sfx2/lokhelper.hxx>
#define SC_IDLE_MIN 150
#define SC_IDLE_MAX 3000
#define SC_IDLE_STEP 75
#define SC_IDLE_COUNT 50
static sal_uInt16 nIdleCount = 0;
SFX_IMPL_INTERFACE(ScModule, SfxShell)
void ScModule::InitInterface_Impl()
{
GetStaticInterface()->RegisterObjectBar(SFX_OBJECTBAR_APPLICATION,
SfxVisibilityFlags::Standard | SfxVisibilityFlags::Client | SfxVisibilityFlags::Viewer,
ToolbarId::Objectbar_App);
GetStaticInterface()->RegisterStatusBar(StatusBarId::CalcStatusBar);
}
ScModule::ScModule( SfxObjectFactory* pFact ) :
SfxModule("sc"_ostr, {pFact}),
m_aIdleTimer("sc ScModule IdleTimer"),
m_pDragData(new ScDragData),
m_pSelTransfer( nullptr ),
m_pRefInputHandler( nullptr ),
m_nCurRefDlgId( 0 ),
m_bIsWaterCan( false ),
m_bIsInEditCommand( false ),
m_bIsInExecuteDrop( false ),
m_bIsInSharedDocLoading( false ),
m_bIsInSharedDocSaving( false )
{
// The ResManager (DLL data) is not yet initialized in the ctor!
SetName(u"StarCalc"_ustr); // for Basic
ResetDragObject();
// InputHandler does not need to be created
// Create ErrorHandler - was in Init()
// Between OfficeApplication::Init and ScGlobal::Init
SvxErrorHandler::ensure();
m_pErrorHdl.reset( new SfxErrorHandler(RID_ERRHDLSC,
ErrCodeArea::Sc,
ErrCodeArea::Sc,
GetResLocale()) );
m_aIdleTimer.SetTimeout(SC_IDLE_MIN);
m_aIdleTimer.SetInvokeHandler( LINK( this, ScModule, IdleHandler ) );
m_aIdleTimer.Start();
m_pMessagePool = new ScMessagePool;
SetPool( m_pMessagePool.get() );
ScGlobal::InitTextHeight( *m_pMessagePool );
StartListening( *SfxGetpApp() ); // for SfxHintId::Deinitializing
// Initialize the color config
GetColorConfig();
}
ScModule::~ScModule()
{
OSL_ENSURE( !m_pSelTransfer, "Selection Transfer object not deleted" );
// InputHandler does not need to be deleted (there's none in the App anymore)
m_pMessagePool.clear();
m_pDragData.reset();
m_pErrorHdl.reset();
ScGlobal::Clear(); // Also calls ScDocumentPool::DeleteVersionMaps();
ScInterpreterContextPool::ModuleExiting();
DeleteCfg(); // Called from Exit()
}
void ScModule::ConfigurationChanged(utl::ConfigurationBroadcaster* p, ConfigurationHints eHints)
{
if ( p == m_pColorConfig.get() )
{
// Test if detective objects have to be updated with new colors
// (if the detective colors haven't been used yet, there's nothing to update)
if ( ScDetectiveFunc::IsColorsInitialized() )
{
const svtools::ColorConfig& rColors = GetColorConfig();
bool bArrows =
( ScDetectiveFunc::GetArrowColor() != rColors.GetColorValue(svtools::CALCDETECTIVE).nColor ||
ScDetectiveFunc::GetErrorColor() != rColors.GetColorValue(svtools::CALCDETECTIVEERROR).nColor );
bool bComments =
( ScDetectiveFunc::GetCommentColor() != rColors.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor );
if ( bArrows || bComments )
{
ScDetectiveFunc::InitializeColors(); // get the new colors
// update detective objects in all open documents
SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
while ( pObjSh )
{
if ( auto pDocSh = dynamic_cast<ScDocShell * >(pObjSh) )
{
if ( bArrows )
ScDetectiveFunc( pDocSh->GetDocument(), 0 ).UpdateAllArrowColors();
if ( bComments )
ScDetectiveFunc::UpdateAllComments( pDocSh->GetDocument() );
}
pObjSh = SfxObjectShell::GetNext( *pObjSh );
}
}
}
const bool bKit = comphelper::LibreOfficeKit::isActive();
//invalidate only the current view in tiled rendering mode, or all views otherwise
SfxViewShell* pViewShell = bKit ? SfxViewShell::Current() : SfxViewShell::GetFirst();
while (pViewShell)
{
if (ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(pViewShell))
{
ScViewRenderingOptions aViewRenderingOptions(pViewSh->GetViewRenderingData());
Color aFillColor(m_pColorConfig->GetColorValue(svtools::DOCCOLOR).nColor);
aViewRenderingOptions.SetDocColor(aFillColor);
aViewRenderingOptions.SetColorSchemeName(svtools::ColorConfig::GetCurrentSchemeName());
const bool bUnchanged(aViewRenderingOptions == pViewSh->GetViewRenderingData());
if (!bUnchanged)
pViewSh->SetViewRenderingData(aViewRenderingOptions);
if (SfxObjectShell* pKitCurrentObjSh = bKit ? SfxObjectShell::Current() : nullptr)
{
ScModelObj* pScModelObj = comphelper::getFromUnoTunnel<ScModelObj>(pKitCurrentObjSh->GetModel());
SfxLokHelper::notifyViewRenderState(pViewSh, pScModelObj);
// In Online, the document color is the one used for the background, contrary to
// Writer and Draw that use the application background color.
pViewSh->libreOfficeKitViewCallback(LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR,
aFillColor.AsRGBHexString().toUtf8());
}
// if nothing changed, and the hint was OnlyCurrentDocumentColorScheme we can skip invalidate
const bool bSkipInvalidate = bUnchanged && eHints == ConfigurationHints::OnlyCurrentDocumentColorScheme;
if (!bSkipInvalidate)
{
pViewSh->PaintGrid();
pViewSh->PaintTop();
pViewSh->PaintLeft();
pViewSh->PaintExtras();
}
ScInputHandler* pHdl = pViewSh->GetInputHandler();
if ( pHdl )
pHdl->ForgetLastPattern(); // EditEngine BackgroundColor may change
}
else if ( dynamic_cast<const ScPreviewShell*>( pViewShell) != nullptr )
{
vcl::Window* pWin = pViewShell->GetWindow();
if (pWin)
pWin->Invalidate();
}
if (bKit)
break;
pViewShell = SfxViewShell::GetNext( *pViewShell );
}
}
else if ( p == m_pCTLOptions.get() )
{
// for all documents: set digit language for printer, recalc output factor, update row heights
SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
while ( pObjSh )
{
if ( auto pDocSh = dynamic_cast<ScDocShell *>(pObjSh) )
{
OutputDevice* pPrinter = pDocSh->GetPrinter();
if ( pPrinter )
pPrinter->SetDigitLanguage( GetOptDigitLanguage() );
pDocSh->CalcOutputFactor();
SCTAB nTabCount = pDocSh->GetDocument().GetTableCount();
for (SCTAB nTab=0; nTab<nTabCount; nTab++)
pDocSh->AdjustRowHeight( 0, pDocSh->GetDocument().MaxRow(), nTab );
}
pObjSh = SfxObjectShell::GetNext( *pObjSh );
}
// for all views (table and preview): update digit language
SfxViewShell* pSh = SfxViewShell::GetFirst();
while ( pSh )
{
if (ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(pSh))
{
// set ref-device for EditEngine (re-evaluates digit settings)
ScInputHandler* pHdl = GetInputHdl(pViewSh);
if (pHdl)
pHdl->UpdateRefDevice();
pViewSh->DigitLanguageChanged();
pViewSh->PaintGrid();
}
else if (ScPreviewShell* pPreviewSh = dynamic_cast<ScPreviewShell*>(pSh))
{
ScPreview* pPreview = pPreviewSh->GetPreview();
pPreview->GetOutDev()->SetDigitLanguage( GetOptDigitLanguage() );
pPreview->Invalidate();
}
pSh = SfxViewShell::GetNext( *pSh );
}
}
}
void ScModule::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
if ( rHint.GetId() == SfxHintId::Deinitializing )
{
// ConfigItems must be removed before ConfigManager
DeleteCfg();
}
}
void ScModule::DeleteCfg()
{
m_pViewCfg.reset(); // Saving happens automatically before Exit()
m_pDocCfg.reset();
m_pAppCfg.reset();
m_pDefaultsCfg.reset();
m_pFormulaCfg.reset();
m_pInputCfg.reset();
m_pPrintCfg.reset();
m_pNavipiCfg.reset();
m_pAddInCfg.reset();
if ( m_pColorConfig )
{
m_pColorConfig->RemoveListener(this);
m_pColorConfig.reset();
}
if ( m_pCTLOptions )
{
m_pCTLOptions->RemoveListener(this);
m_pCTLOptions.reset();
}
m_pUserOptions.reset();
}
// Moved here from the App
void ScModule::Execute( SfxRequest& rReq )
{
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : nullptr;
const SfxItemSet* pReqArgs = rReq.GetArgs();
sal_uInt16 nSlot = rReq.GetSlot();
switch ( nSlot )
{
case SID_CHOOSE_DESIGN:
SfxApplication::CallAppBasic( u"Template.Samples.ShowStyles"_ustr );
break;
case SID_EURO_CONVERTER:
SfxApplication::CallAppBasic( u"Euro.ConvertRun.Main"_ustr );
break;
case SID_AUTOSPELL_CHECK:
{
bool bSet;
const SfxPoolItem* pItem;
if (pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( FN_PARAM_1, true, &pItem ))
bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
else if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) )
bSet = static_cast<const SfxBoolItem*>(pItem)->GetValue();
else
{ // Toggle
ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current());
if (pViewSh)
bSet = !pViewSh->IsAutoSpell();
else
bSet = !ScModule::GetAutoSpellProperty();
}
SfxItemSetFixed<SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK> aSet( GetPool() );
aSet.Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bSet ) );
ModifyOptions( aSet );
rReq.Done();
}
break;
case SID_ATTR_METRIC:
{
const SfxPoolItem* pItem;
if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) )
{
FieldUnit eUnit = static_cast<FieldUnit>(static_cast<const SfxUInt16Item*>(pItem)->GetValue());
switch( eUnit )
{
case FieldUnit::MM: // Just the units that are also in the dialog
case FieldUnit::CM:
case FieldUnit::INCH:
case FieldUnit::PICA:
case FieldUnit::POINT:
{
PutItem( *pItem );
ScAppOptions aNewOpts( GetAppOptions() );
aNewOpts.SetAppMetric( eUnit );
SetAppOptions( aNewOpts );
rReq.Done();
}
break;
default:
{
// added to avoid warnings
}
}
}
}
break;
case FID_AUTOCOMPLETE:
{
ScAppOptions aNewOpts( GetAppOptions() );
bool bNew = !aNewOpts.GetAutoComplete();
aNewOpts.SetAutoComplete( bNew );
SetAppOptions( aNewOpts );
if (pBindings)
pBindings->Invalidate( FID_AUTOCOMPLETE );
rReq.Done();
}
break;
case SID_DETECTIVE_AUTO:
{
ScAppOptions aNewOpts( GetAppOptions() );
bool bNew = !aNewOpts.GetDetectiveAuto();
const SfxBoolItem* pAuto = rReq.GetArg<SfxBoolItem>(SID_DETECTIVE_AUTO);
if ( pAuto )
bNew = pAuto->GetValue();
aNewOpts.SetDetectiveAuto( bNew );
SetAppOptions( aNewOpts );
if (pBindings)
pBindings->Invalidate( SID_DETECTIVE_AUTO );
rReq.AppendItem( SfxBoolItem( SID_DETECTIVE_AUTO, bNew ) );
rReq.Done();
}
break;
case SID_PSZ_FUNCTION:
if (pReqArgs)
{
const SfxUInt32Item & rItem = pReqArgs->Get(SID_PSZ_FUNCTION);
ScAppOptions aNewOpts( GetAppOptions() );
aNewOpts.SetStatusFunc( rItem.GetValue() );
SetAppOptions( aNewOpts );
if (pBindings)
{
pBindings->Invalidate( SID_TABLE_CELL );
pBindings->Update( SID_TABLE_CELL ); // Immediately
pBindings->Invalidate( SID_PSZ_FUNCTION );
pBindings->Update( SID_PSZ_FUNCTION );
// If the menu is opened again immediately
}
}
break;
case SID_ATTR_LANGUAGE:
case SID_ATTR_CHAR_CJK_LANGUAGE:
case SID_ATTR_CHAR_CTL_LANGUAGE:
{
const SfxPoolItem* pItem;
if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( GetPool().GetWhichIDFromSlotID(nSlot), true, &pItem ) )
{
ScDocShell* pDocSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
if ( pDocSh )
{
ScDocument& rDoc = pDocSh->GetDocument();
LanguageType eNewLang = static_cast<const SvxLanguageItem*>(pItem)->GetLanguage();
LanguageType eLatin, eCjk, eCtl;
rDoc.GetLanguage( eLatin, eCjk, eCtl );
LanguageType eOld = ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE ) ? eCjk :
( ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE ) ? eCtl : eLatin );
if ( eNewLang != eOld )
{
if ( nSlot == SID_ATTR_CHAR_CJK_LANGUAGE )
eCjk = eNewLang;
else if ( nSlot == SID_ATTR_CHAR_CTL_LANGUAGE )
eCtl = eNewLang;
else
eLatin = eNewLang;
rDoc.SetLanguage( eLatin, eCjk, eCtl );
ScInputHandler* pInputHandler = GetInputHdl();
if ( pInputHandler )
pInputHandler->UpdateSpellSettings(); // EditEngine flags
ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
if ( pViewSh )
pViewSh->UpdateDrawTextOutliner(); // EditEngine flags
pDocSh->SetDocumentModified();
}
}
}
}
break;
case FID_FOCUS_POSWND:
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
{
ScInputWindow* pWin = pHdl->GetInputWindow();
if (pWin)
pWin->PosGrabFocus();
}
rReq.Done();
}
break;
case SID_OPEN_XML_FILTERSETTINGS:
{
try
{
css::uno::Reference < css::ui::dialogs::XExecutableDialog > xDialog = css::ui::dialogs::XSLTFilterDialog::create( ::comphelper::getProcessComponentContext());
(void)xDialog->execute();
}
catch( css::uno::RuntimeException& )
{
DBG_UNHANDLED_EXCEPTION("sc.ui");
}
}
break;
default:
OSL_FAIL( "ScApplication: Unknown Message." );
break;
}
}
void ScModule::GetState( SfxItemSet& rSet )
{
ScDocShell* pDocSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
ScTabViewShell* pTabViewShell = pDocSh ? pDocSh->GetBestViewShell() : nullptr;
SfxWhichIter aIter(rSet);
for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich())
{
if (!pTabViewShell)
{
// Not in the normal calc view shell (most likely in preview shell). Disable all actions.
rSet.DisableItem(nWhich);
continue;
}
switch ( nWhich )
{
case FID_AUTOCOMPLETE:
rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetAutoComplete() ) );
break;
case SID_DETECTIVE_AUTO:
rSet.Put( SfxBoolItem( nWhich, GetAppOptions().GetDetectiveAuto() ) );
break;
case SID_PSZ_FUNCTION:
rSet.Put( SfxUInt32Item( nWhich, GetAppOptions().GetStatusFunc() ) );
break;
case SID_ATTR_METRIC:
rSet.Put( SfxUInt16Item( nWhich, sal::static_int_cast<sal_uInt16>(GetAppOptions().GetAppMetric()) ) );
break;
case SID_AUTOSPELL_CHECK:
rSet.Put( SfxBoolItem( nWhich, pTabViewShell->IsAutoSpell()) );
break;
case SID_ATTR_LANGUAGE:
case ATTR_CJK_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CJK_LANGUAGE
case ATTR_CTL_FONT_LANGUAGE: // WID for SID_ATTR_CHAR_CTL_LANGUAGE
{
LanguageType eLatin, eCjk, eCtl;
pDocSh->GetDocument().GetLanguage( eLatin, eCjk, eCtl );
LanguageType eLang = ( nWhich == ATTR_CJK_FONT_LANGUAGE ) ? eCjk :
( ( nWhich == ATTR_CTL_FONT_LANGUAGE ) ? eCtl : eLatin );
rSet.Put( SvxLanguageItem( eLang, nWhich ) );
}
break;
}
}
}
void ScModule::HideDisabledSlots( SfxItemSet& rSet )
{
if( SfxViewFrame* pViewFrm = SfxViewFrame::Current() )
{
SfxBindings& rBindings = pViewFrm->GetBindings();
SfxWhichIter aIter( rSet );
for( sal_uInt16 nWhich = aIter.FirstWhich(); nWhich != 0; nWhich = aIter.NextWhich() )
{
ScViewUtil::HideDisabledSlot( rSet, rBindings, nWhich );
// always disable the slots
rSet.DisableItem( nWhich );
}
}
}
void ScModule::ResetDragObject()
{
if (comphelper::LibreOfficeKit::isActive())
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
pViewShell->ResetDragObject();
}
else
{
m_pDragData->pCellTransfer = nullptr;
m_pDragData->pDrawTransfer = nullptr;
m_pDragData->pJumpLocalDoc = nullptr;
m_pDragData->aLinkDoc.clear();
m_pDragData->aLinkTable.clear();
m_pDragData->aLinkArea.clear();
m_pDragData->aJumpTarget.clear();
m_pDragData->aJumpText.clear();
}
}
const ScDragData& ScModule::GetDragData() const
{
if (comphelper::LibreOfficeKit::isActive())
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
assert(pViewShell);
return pViewShell->GetDragData();
}
else
return *m_pDragData;
}
void ScModule::SetDragObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj )
{
if (comphelper::LibreOfficeKit::isActive())
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
pViewShell->SetDragObject(pCellObj, pDrawObj);
}
else
{
ResetDragObject();
m_pDragData->pCellTransfer = pCellObj;
m_pDragData->pDrawTransfer = pDrawObj;
}
}
void ScModule::SetDragLink(
const OUString& rDoc, const OUString& rTab, const OUString& rArea )
{
if (comphelper::LibreOfficeKit::isActive())
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
pViewShell->SetDragLink(rDoc, rTab, rArea);
}
else
{
ResetDragObject();
m_pDragData->aLinkDoc = rDoc;
m_pDragData->aLinkTable = rTab;
m_pDragData->aLinkArea = rArea;
}
}
void ScModule::SetDragJump(
ScDocument* pLocalDoc, const OUString& rTarget, const OUString& rText )
{
if (comphelper::LibreOfficeKit::isActive())
{
ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
if (pViewShell)
pViewShell->SetDragJump(pLocalDoc, rTarget, rText);
}
else
{
ResetDragObject();
m_pDragData->pJumpLocalDoc = pLocalDoc;
m_pDragData->aJumpTarget = rTarget;
m_pDragData->aJumpText = rText;
}
}
ScDocument* ScModule::GetClipDoc()
{
// called from document
SfxViewFrame* pViewFrame = nullptr;
ScTabViewShell* pViewShell = nullptr;
css::uno::Reference<css::datatransfer::XTransferable2> xTransferable;
if ((pViewShell = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current())))
xTransferable.set(ScTabViewShell::GetClipData(pViewShell->GetViewData().GetActiveWin()));
else if ((pViewShell = dynamic_cast<ScTabViewShell*>(SfxViewShell::GetFirst())))
xTransferable.set(ScTabViewShell::GetClipData(pViewShell->GetViewData().GetActiveWin()));
else if ((pViewFrame = SfxViewFrame::GetFirst()))
{
css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
pViewFrame->GetWindow().GetClipboard();
xTransferable.set(xClipboard.is() ? xClipboard->getContents() : nullptr, css::uno::UNO_QUERY);
}
const ScTransferObj* pObj = ScTransferObj::GetOwnClipboard(xTransferable);
if (pObj)
{
ScDocument* pDoc = pObj->GetDocument();
assert((!pDoc || pDoc->IsClipboard()) && "Document is not clipboard, how can that be?");
return pDoc;
}
return nullptr;
}
void ScModule::SetSelectionTransfer( ScSelectionTransferObj* pNew )
{
m_pSelTransfer = pNew;
}
void ScModule::SetViewOptions( const ScViewOptions& rOpt )
{
if ( !m_pViewCfg )
m_pViewCfg.reset(new ScViewCfg);
m_pViewCfg->SetOptions( rOpt );
}
const ScViewOptions& ScModule::GetViewOptions()
{
if ( !m_pViewCfg )
m_pViewCfg.reset( new ScViewCfg );
return *m_pViewCfg;
}
void ScModule::SetDocOptions( const ScDocOptions& rOpt )
{
if ( !m_pDocCfg )
m_pDocCfg.reset( new ScDocCfg );
m_pDocCfg->SetOptions( rOpt );
}
const ScDocOptions& ScModule::GetDocOptions()
{
if ( !m_pDocCfg )
m_pDocCfg.reset( new ScDocCfg );
return *m_pDocCfg;
}
void ScModule::InsertEntryToLRUList(sal_uInt16 nFIndex)
{
if(nFIndex == 0)
return;
const ScAppOptions& rAppOpt = GetAppOptions();
sal_uInt16 nLRUFuncCount = std::min( rAppOpt.GetLRUFuncListCount(), sal_uInt16(LRU_MAX) );
sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList();
sal_uInt16 aIdxList[LRU_MAX];
sal_uInt16 n = 0;
bool bFound = false;
while ((n < LRU_MAX) && n<nLRUFuncCount) // Iterate through old list
{
if (!bFound && (pLRUListIds[n]== nFIndex))
bFound = true; // First hit!
else if (bFound)
aIdxList[n ] = pLRUListIds[n]; // Copy after hit
else if ((n+1) < LRU_MAX)
aIdxList[n+1] = pLRUListIds[n]; // Move before hit
n++;
}
if (!bFound && (n < LRU_MAX)) // Entry not found?
n++; // One more
aIdxList[0] = nFIndex; // Current on Top
ScAppOptions aNewOpts(rAppOpt); // Let App know
aNewOpts.SetLRUFuncList(aIdxList, n);
SetAppOptions(aNewOpts);
}
void ScModule::SetAppOptions( const ScAppOptions& rOpt )
{
if ( !m_pAppCfg )
m_pAppCfg.reset( new ScAppCfg );
m_pAppCfg->SetOptions( rOpt );
}
void global_InitAppOptions()
{
SC_MOD()->GetAppOptions();
}
const ScAppOptions& ScModule::GetAppOptions()
{
if ( !m_pAppCfg )
m_pAppCfg.reset( new ScAppCfg );
return m_pAppCfg->GetOptions();
}
void ScModule::SetDefaultsOptions( const ScDefaultsOptions& rOpt )
{
if ( !m_pDefaultsCfg )
m_pDefaultsCfg.reset( new ScDefaultsCfg );
m_pDefaultsCfg->SetOptions( rOpt );
}
const ScDefaultsOptions& ScModule::GetDefaultsOptions()
{
if ( !m_pDefaultsCfg )
m_pDefaultsCfg.reset( new ScDefaultsCfg );
return *m_pDefaultsCfg;
}
void ScModule::SetFormulaOptions( const ScFormulaOptions& rOpt )
{
if ( !m_pFormulaCfg )
m_pFormulaCfg.reset( new ScFormulaCfg );
m_pFormulaCfg->SetOptions( rOpt );
}
const ScFormulaOptions& ScModule::GetFormulaOptions()
{
if ( !m_pFormulaCfg )
m_pFormulaCfg.reset( new ScFormulaCfg );
return *m_pFormulaCfg;
}
void ScModule::SetInputOptions( const ScInputOptions& rOpt )
{
if ( !m_pInputCfg )
m_pInputCfg.reset( new ScInputCfg );
m_pInputCfg->SetOptions( rOpt );
}
const ScInputOptions& ScModule::GetInputOptions()
{
if ( !m_pInputCfg )
m_pInputCfg.reset( new ScInputCfg );
return m_pInputCfg->GetOptions();
}
void ScModule::SetPrintOptions( const ScPrintOptions& rOpt )
{
if ( !m_pPrintCfg )
m_pPrintCfg.reset( new ScPrintCfg );
m_pPrintCfg->SetOptions( rOpt );
}
const ScPrintOptions& ScModule::GetPrintOptions()
{
if ( !m_pPrintCfg )
m_pPrintCfg.reset( new ScPrintCfg );
return m_pPrintCfg->GetOptions();
}
ScNavipiCfg& ScModule::GetNavipiCfg()
{
if ( !m_pNavipiCfg )
m_pNavipiCfg.reset( new ScNavipiCfg );
return *m_pNavipiCfg;
}
ScAddInCfg& ScModule::GetAddInCfg()
{
if ( !m_pAddInCfg )
m_pAddInCfg.reset( new ScAddInCfg );
return *m_pAddInCfg;
}
svtools::ColorConfig& ScModule::GetColorConfig()
{
if ( !m_pColorConfig )
{
m_pColorConfig.reset( new svtools::ColorConfig );
m_pColorConfig->AddListener(this);
}
return *m_pColorConfig;
}
bool ScModule::IsLOKViewInDarkMode()
{
SfxViewShell* pKitSh = comphelper::LibreOfficeKit::isActive() ? SfxViewShell::Current() : nullptr;
if( pKitSh )
{
Color aDocColor = pKitSh->GetColorConfigColor(svtools::DOCCOLOR);
if( aDocColor.IsDark() )
return true;
}
return false;
}
SvtUserOptions& ScModule::GetUserOptions()
{
if( !m_pUserOptions )
{
m_pUserOptions.reset( new SvtUserOptions );
}
return *m_pUserOptions;
}
LanguageType ScModule::GetOptDigitLanguage()
{
SvtCTLOptions::TextNumerals eNumerals = SvtCTLOptions::GetCTLTextNumerals();
return ( eNumerals == SvtCTLOptions::NUMERALS_ARABIC ) ? LANGUAGE_ENGLISH_US :
( eNumerals == SvtCTLOptions::NUMERALS_HINDI) ? LANGUAGE_ARABIC_SAUDI_ARABIA :
LANGUAGE_SYSTEM;
}
/**
* Options
*
* Items from Calc options dialog and SID_AUTOSPELL_CHECK
*/
void ScModule::ModifyOptions( const SfxItemSet& rOptSet )
{
bool bOldAutoSpell = GetAutoSpellProperty();
LanguageType nOldSpellLang, nOldCjkLang, nOldCtlLang;
GetSpellSettings( nOldSpellLang, nOldCjkLang, nOldCtlLang );
if (!m_pAppCfg)
GetAppOptions();
OSL_ENSURE( m_pAppCfg, "AppOptions not initialised :-(" );
if (!m_pInputCfg)
GetInputOptions();
OSL_ENSURE( m_pInputCfg, "InputOptions not initialised :-(" );
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : nullptr;
ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
ScDocShell* pDocSh = dynamic_cast<ScDocShell*>( SfxObjectShell::Current() );
ScDocument* pDoc = pDocSh ? &pDocSh->GetDocument() : nullptr;
bool bRepaint = false;
bool bUpdateMarks = false;
bool bUpdateRefDev = false;
bool bCalcAll = false;
bool bSaveAppOptions = false;
bool bSaveInputOptions = false;
bool bCompileErrorCells = false;
// SfxGetpApp()->SetOptions( rOptSet );
ScAppOptions aAppOptions = m_pAppCfg->GetOptions();
// No more linguistics
if (const SfxUInt16Item* pItem = rOptSet.GetItemIfSet(SID_ATTR_METRIC))
{
PutItem( *pItem );
aAppOptions.SetAppMetric( static_cast<FieldUnit>(pItem->GetValue()) );
bSaveAppOptions = true;
}
if (const ScUserListItem* pItem = rOptSet.GetItemIfSet(SCITEM_USERLIST))
{
ScGlobal::SetUserList( pItem->GetUserList() );
bSaveAppOptions = true;
}
if (const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_SYNCZOOM))
{
aAppOptions.SetSynchronizeZoom( pItem->GetValue() );
bSaveAppOptions = true;
}
if (const SfxUInt16Item* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_KEY_BINDING_COMPAT))
{
sal_uInt16 nVal = pItem->GetValue();
ScOptionsUtil::KeyBindingType eOld = aAppOptions.GetKeyBindingType();
ScOptionsUtil::KeyBindingType eNew = static_cast<ScOptionsUtil::KeyBindingType>(nVal);
if (eOld != eNew)
{
aAppOptions.SetKeyBindingType(eNew);
bSaveAppOptions = true;
ScDocShell::ResetKeyBindings(eNew);
}
}
if (const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_LINKS))
{
aAppOptions.SetLinksInsertedLikeMSExcel(pItem->GetValue());
bSaveAppOptions = true;
}
// DefaultsOptions
if (const ScTpDefaultsItem* pItem = rOptSet.GetItemIfSet(SID_SCDEFAULTSOPTIONS))
{
const ScDefaultsOptions& rOpt = pItem->GetDefaultsOptions();
SetDefaultsOptions( rOpt );
}
// FormulaOptions
if (const ScTpFormulaItem* pItem = rOptSet.GetItemIfSet(SID_SCFORMULAOPTIONS))
{
const ScFormulaOptions& rOpt = pItem->GetFormulaOptions();
if (!m_pFormulaCfg || (*m_pFormulaCfg != rOpt))
// Formula options have changed. Repaint the column headers.
bRepaint = true;
if (m_pFormulaCfg && m_pFormulaCfg->GetUseEnglishFuncName() != rOpt.GetUseEnglishFuncName())
{
// Re-compile formula cells with error as the error may have been
// caused by unresolved function names.
bCompileErrorCells = true;
}
// Recalc for interpreter options changes.
if (m_pFormulaCfg && m_pFormulaCfg->GetCalcConfig() != rOpt.GetCalcConfig())
bCalcAll = true;
if ( pDocSh )
{
pDocSh->SetFormulaOptions( rOpt );
pDocSh->SetDocumentModified();
}
// ScDocShell::SetFormulaOptions() may check for changed settings, so
// set the new options here after that has been called.
if (!bCalcAll || rOpt.GetWriteCalcConfig())
{
// CalcConfig is new, didn't change or is global, simply set all.
SetFormulaOptions( rOpt );
}
else
{
// If "only for current document" was checked, reset those affected
// by that setting to previous values.
ScFormulaOptions aNewOpt( rOpt);
aNewOpt.GetCalcConfig().MergeDocumentSpecific( m_pFormulaCfg->GetCalcConfig());
SetFormulaOptions( aNewOpt);
}
}
// ViewOptions
if (const ScTpViewItem* pItem = rOptSet.GetItemIfSet(SID_SCVIEWOPTIONS))
{
const ScViewOptions& rNewOpt = pItem->GetViewOptions();
if ( pViewSh )
{
ScViewData& rViewData = pViewSh->GetViewData();
const ScViewOptions& rOldOpt = rViewData.GetOptions();
bool bAnchorList = ( rOldOpt.GetOption( VOPT_ANCHOR ) !=
rNewOpt.GetOption( VOPT_ANCHOR ) );
if ( rOldOpt != rNewOpt )
{
rViewData.SetOptions( rNewOpt ); // Changes rOldOpt
rViewData.GetDocument().SetViewOptions( rNewOpt );
if (pDocSh)
pDocSh->SetDocumentModified();
bRepaint = true;
}
if ( bAnchorList )
pViewSh->UpdateAnchorHandles();
}
SetViewOptions( rNewOpt );
if (pBindings)
{
pBindings->Invalidate(SID_HELPLINES_MOVE);
}
}
// GridOptions
// Evaluate after ViewOptions, as GridOptions is a member of ViewOptions
if ( const SvxGridItem* pItem = rOptSet.GetItemIfSet(SID_ATTR_GRID_OPTIONS) )
{
ScGridOptions aNewGridOpt( *pItem );
if ( pViewSh )
{
ScViewData& rViewData = pViewSh->GetViewData();
ScViewOptions aNewViewOpt( rViewData.GetOptions() );
const ScGridOptions& rOldGridOpt = aNewViewOpt.GetGridOptions();
if ( rOldGridOpt != aNewGridOpt )
{
aNewViewOpt.SetGridOptions( aNewGridOpt );
rViewData.SetOptions( aNewViewOpt );
rViewData.GetDocument().SetViewOptions( aNewViewOpt );
if (pDocSh)
pDocSh->SetDocumentModified();
bRepaint = true;
}
}
ScViewOptions aNewViewOpt ( GetViewOptions() );
aNewViewOpt.SetGridOptions( aNewGridOpt );
SetViewOptions( aNewViewOpt );
if (pBindings)
{
pBindings->Invalidate(SID_GRID_VISIBLE);
pBindings->Invalidate(SID_GRID_USE);
}
}
// DocOptions
if ( const ScTpCalcItem* pItem = rOptSet.GetItemIfSet(SID_SCDOCOPTIONS) )
{
const ScDocOptions& rNewOpt = pItem->GetDocOptions();
if ( pDoc )
{
const ScDocOptions& rOldOpt = pDoc->GetDocOptions();
bRepaint = ( bRepaint || ( rOldOpt != rNewOpt ) );
bCalcAll = bRepaint &&
( rOldOpt.IsIter() != rNewOpt.IsIter()
|| rOldOpt.GetIterCount() != rNewOpt.GetIterCount()
|| rOldOpt.GetIterEps() != rNewOpt.GetIterEps()
|| rOldOpt.IsIgnoreCase() != rNewOpt.IsIgnoreCase()
|| rOldOpt.IsCalcAsShown() != rNewOpt.IsCalcAsShown()
|| (rNewOpt.IsCalcAsShown() &&
rOldOpt.GetStdPrecision() != rNewOpt.GetStdPrecision())
|| rOldOpt.IsMatchWholeCell() != rNewOpt.IsMatchWholeCell()
|| rOldOpt.GetYear2000() != rNewOpt.GetYear2000()
|| rOldOpt.IsFormulaRegexEnabled() != rNewOpt.IsFormulaRegexEnabled()
|| rOldOpt.IsFormulaWildcardsEnabled() != rNewOpt.IsFormulaWildcardsEnabled()
);
pDoc->SetDocOptions( rNewOpt );
pDocSh->SetDocumentModified();
}
SetDocOptions( rNewOpt );
}
// Set TabDistance after the actual DocOptions
if ( const SfxUInt16Item* pItem = rOptSet.GetItemIfSet(SID_ATTR_DEFTABSTOP) )
{
sal_uInt16 nTabDist = pItem->GetValue();
ScDocOptions aOpt(GetDocOptions());
aOpt.SetTabDistance(nTabDist);
SetDocOptions( aOpt );
if ( pDoc )
{
ScDocOptions aDocOpt(pDoc->GetDocOptions());
aDocOpt.SetTabDistance(nTabDist);
pDoc->SetDocOptions( aDocOpt );
pDocSh->SetDocumentModified();
if(pDoc->GetDrawLayer())
pDoc->GetDrawLayer()->SetDefaultTabulator(nTabDist);
}
}
// AutoSpell after the DocOptions (due to being a member)
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_AUTOSPELL_CHECK) ) // At DocOptions
{
bool bDoAutoSpell = pItem->GetValue();
if (pViewSh)
{
if (pViewSh->IsAutoSpell() != bDoAutoSpell)
{
pViewSh->EnableAutoSpell(bDoAutoSpell);
bRepaint = true; // Because HideAutoSpell might be invalid
//TODO: Paint all Views?
}
}
if ( bOldAutoSpell != bDoAutoSpell )
SetAutoSpellProperty( bDoAutoSpell );
if ( pDocSh )
pDocSh->PostPaintGridAll(); // Due to marks
ScInputHandler* pInputHandler = GetInputHdl();
if ( pInputHandler )
pInputHandler->UpdateSpellSettings(); // EditEngine flags
if ( pViewSh )
pViewSh->UpdateDrawTextOutliner(); // EditEngine flags
if (pBindings)
pBindings->Invalidate( SID_AUTOSPELL_CHECK );
}
// InputOptions
ScInputOptions aInputOptions = m_pInputCfg->GetOptions();
if ( const SfxUInt16Item* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_SELECTIONPOS) )
{
aInputOptions.SetMoveDir( pItem->GetValue() );
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_SELECTION) )
{
aInputOptions.SetMoveSelection( pItem->GetValue() );
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_EDITMODE) )
{
aInputOptions.SetEnterEdit( pItem->GetValue() );
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_FMT_EXPAND) )
{
aInputOptions.SetExtendFormat( pItem->GetValue() );
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_RANGEFINDER) )
{
aInputOptions.SetRangeFinder( pItem->GetValue() );
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_REF_EXPAND) )
{
aInputOptions.SetExpandRefs( pItem->GetValue() );
bSaveInputOptions = true;
}
if (const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_SORT_REF_UPDATE))
{
aInputOptions.SetSortRefUpdate( pItem->GetValue());
bSaveInputOptions = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_MARK_HEADER) )
{
aInputOptions.SetMarkHeader( pItem->GetValue() );
bSaveInputOptions = true;
bUpdateMarks = true;
}
if ( const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_INPUT_TEXTWYSIWYG) )
{
bool bNew = pItem->GetValue();
if ( bNew != aInputOptions.GetTextWysiwyg() )
{
aInputOptions.SetTextWysiwyg( bNew );
bSaveInputOptions = true;
bUpdateRefDev = true;
}
}
if( const SfxBoolItem* pItem = rOptSet.GetItemIfSet( SID_SC_INPUT_REPLCELLSWARN ) )
{
aInputOptions.SetReplaceCellsWarn( pItem->GetValue() );
bSaveInputOptions = true;
}
if( const SfxBoolItem* pItem = rOptSet.GetItemIfSet( SID_SC_INPUT_LEGACY_CELL_SELECTION ) )
{
aInputOptions.SetLegacyCellSelection( pItem->GetValue() );
bSaveInputOptions = true;
}
if( const SfxBoolItem* pItem = rOptSet.GetItemIfSet( SID_SC_INPUT_ENTER_PASTE_MODE ) )
{
aInputOptions.SetEnterPasteMode( pItem->GetValue() );
bSaveInputOptions = true;
}
if( const SfxBoolItem* pItem = rOptSet.GetItemIfSet( SID_SC_INPUT_WARNACTIVESHEET ) )
{
aInputOptions.SetWarnActiveSheet( pItem->GetValue() );
bSaveInputOptions = true;
}
// PrintOptions
if ( const ScTpPrintItem* pItem = rOptSet.GetItemIfSet(SID_SCPRINTOPTIONS) )
{
const ScPrintOptions& rNewOpt = pItem->GetPrintOptions();
SetPrintOptions( rNewOpt );
// broadcast causes all previews to recalc page numbers
SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScPrintOptions ) );
}
if ( bSaveAppOptions )
m_pAppCfg->SetOptions(aAppOptions);
if ( bSaveInputOptions )
m_pInputCfg->SetOptions(aInputOptions);
// Kick off recalculation?
if (pDoc && bCompileErrorCells)
{
// Re-compile cells with name error, and recalc if at least one cell
// has been re-compiled. In the future we may want to find a way to
// recalc only those that are affected.
if (pDoc->CompileErrorCells(FormulaError::NoName))
bCalcAll = true;
}
if ( pDoc && bCalcAll )
{
weld::WaitObject aWait( ScDocShell::GetActiveDialogParent() );
pDoc->CalcAll();
if ( pViewSh )
pViewSh->UpdateCharts( true );
else
ScDBFunc::DoUpdateCharts( ScAddress(), *pDoc, true );
if (pBindings)
pBindings->Invalidate( SID_ATTR_SIZE ); //SvxPosSize StatusControl Update
}
if ( pViewSh && bUpdateMarks )
pViewSh->UpdateAutoFillMark();
// Repaint View?
if ( pViewSh && bRepaint )
{
pViewSh->UpdateFixPos();
pViewSh->PaintGrid();
pViewSh->PaintTop();
pViewSh->PaintLeft();
pViewSh->PaintExtras();
pViewSh->InvalidateBorder();
if (pBindings)
{
pBindings->Invalidate( FID_TOGGLEHEADERS ); // -> Checks in menu
pBindings->Invalidate( FID_TOGGLESYNTAX );
}
}
// update ref device (for all documents)
if ( !bUpdateRefDev )
return;
// for all documents: recalc output factor, update row heights
SfxObjectShell* pObjSh = SfxObjectShell::GetFirst();
while ( pObjSh )
{
if ( auto pOneDocSh = dynamic_cast<ScDocShell *>(pObjSh) )
{
pOneDocSh->CalcOutputFactor();
SCTAB nTabCount = pOneDocSh->GetDocument().GetTableCount();
for (SCTAB nTab=0; nTab<nTabCount; nTab++)
pOneDocSh->AdjustRowHeight( 0, pDocSh->GetDocument().MaxRow(), nTab );
}
pObjSh = SfxObjectShell::GetNext( *pObjSh );
}
// for all (tab-) views:
SfxViewShell* pSh = SfxViewShell::GetFirst( true, checkSfxViewShell<ScTabViewShell> );
while ( pSh )
{
ScTabViewShell* pOneViewSh = static_cast<ScTabViewShell*>(pSh);
// set ref-device for EditEngine
ScInputHandler* pHdl = GetInputHdl(pOneViewSh);
if (pHdl)
pHdl->UpdateRefDevice();
// update view scale
ScViewData& rViewData = pOneViewSh->GetViewData();
pOneViewSh->SetZoom( rViewData.GetZoomX(), rViewData.GetZoomY(), false );
// repaint
pOneViewSh->PaintGrid();
pOneViewSh->PaintTop();
pOneViewSh->PaintLeft();
pSh = SfxViewShell::GetNext( *pSh, true, checkSfxViewShell<ScTabViewShell> );
}
}
/**
* Input-Handler
*/
ScInputHandler* ScModule::GetInputHdl( ScTabViewShell* pViewSh, bool bUseRef )
{
if ( !comphelper::LibreOfficeKit::isActive() && m_pRefInputHandler && bUseRef )
return m_pRefInputHandler;
ScInputHandler* pHdl = nullptr;
if ( !pViewSh )
{
// in case a UIActive embedded object has no ViewShell (UNO component)
// the own calc view shell will be set as current, but no handling should happen
ScTabViewShell* pCurViewSh = dynamic_cast<ScTabViewShell*>( SfxViewShell::Current() );
if ( pCurViewSh && !pCurViewSh->GetUIActiveClient() )
pViewSh = pCurViewSh;
}
if ( pViewSh )
pHdl = pViewSh->GetInputHandler(); // Viewshell always has one, from now on
// If no ViewShell passed or active, we can get NULL
OSL_ENSURE( pHdl || !pViewSh, "GetInputHdl: no InputHandler found!" );
return pHdl;
}
void ScModule::ViewShellChanged(bool bStopEditing /*=true*/)
{
ScInputHandler* pHdl = GetInputHdl();
ScTabViewShell* pShell = ScTabViewShell::GetActiveViewShell();
if ( pShell && pHdl )
pShell->UpdateInputHandler(false, bStopEditing);
}
void ScModule::SetInputMode( ScInputMode eMode, const OUString* pInitText )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->SetMode(eMode, pInitText);
}
bool ScModule::IsEditMode()
{
ScInputHandler* pHdl = GetInputHdl();
return pHdl && pHdl->IsEditMode();
}
bool ScModule::IsInputMode()
{
ScInputHandler* pHdl = GetInputHdl();
return pHdl && pHdl->IsInputMode();
}
bool ScModule::InputKeyEvent( const KeyEvent& rKEvt, bool bStartEdit )
{
ScInputHandler* pHdl = GetInputHdl();
return pHdl && pHdl->KeyInput( rKEvt, bStartEdit );
}
void ScModule::InputEnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInLOK )
{
if ( !SfxGetpApp()->IsDowning() ) // Not when quitting the program
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->EnterHandler( nBlockMode, bBeforeSavingInLOK );
}
}
void ScModule::InputCancelHandler()
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->CancelHandler();
}
void ScModule::InputSelection( const EditView* pView )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputSelection( pView );
}
void ScModule::InputChanged( const EditView* pView )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputChanged( pView, false );
}
void ScModule::ViewShellGone( const ScTabViewShell* pViewSh )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->ViewShellGone( pViewSh );
}
void ScModule::SetRefInputHdl( ScInputHandler* pNew )
{
m_pRefInputHandler = pNew;
}
void ScModule::InputGetSelection( sal_Int32& rStart, sal_Int32& rEnd )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputGetSelection( rStart, rEnd );
}
void ScModule::InputSetSelection( sal_Int32 nStart, sal_Int32 nEnd )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputSetSelection( nStart, nEnd );
}
void ScModule::InputReplaceSelection( std::u16string_view aStr )
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputReplaceSelection( aStr );
}
void ScModule::InputTurnOffWinEngine()
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->InputTurnOffWinEngine();
}
void ScModule::ActivateInputWindow( const OUString* pStrFormula, bool bMatrix )
{
ScInputHandler* pHdl = GetInputHdl();
if ( !pHdl )
return;
ScInputWindow* pWin = pHdl->GetInputWindow();
if ( pStrFormula )
{
// Take over formula
if ( pWin )
{
pWin->SetFuncString( *pStrFormula, false );
// SetSumAssignMode due to sal_False not necessary
}
ScEnterMode nMode = bMatrix ? ScEnterMode::MATRIX : ScEnterMode::NORMAL;
pHdl->EnterHandler( nMode );
// Without Invalidate the selection remains active, if the formula has not changed
if (pWin)
pWin->TextInvalidate();
}
else
{
// Cancel
if ( pWin )
{
pWin->SetFuncString( OUString(), false );
// SetSumAssignMode due to sal_False no necessary
}
pHdl->CancelHandler();
}
}
/**
* Reference dialogs
*/
void ScModule::SetRefDialog( sal_uInt16 nId, bool bVis, SfxViewFrame* pViewFrm )
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
if ( !(m_nCurRefDlgId == 0 || ( nId == m_nCurRefDlgId && !bVis )
|| ( comphelper::LibreOfficeKit::isActive() )) )
return;
if ( !pViewFrm )
pViewFrm = SfxViewFrame::Current();
// bindings update causes problems with update of stylist if
// current style family has changed
//if ( pViewFrm )
// pViewFrm->GetBindings().Update(); // to avoid trouble in LockDispatcher
// before SetChildWindow
if ( comphelper::LibreOfficeKit::isActive() )
{
if ( bVis )
m_nCurRefDlgId = nId;
}
else
{
m_nCurRefDlgId = bVis ? nId : 0;
}
if ( pViewFrm )
{
// store the dialog id also in the view shell
SfxViewShell* pViewSh = pViewFrm->GetViewShell();
if (ScTabViewShell* pTabViewSh = dynamic_cast<ScTabViewShell*>(pViewSh))
pTabViewSh->SetCurRefDlgId(m_nCurRefDlgId);
else
{
// no ScTabViewShell - possible for example from a Basic macro
bVis = false;
m_nCurRefDlgId = 0; // don't set nCurRefDlgId if no dialog is created
}
pViewFrm->SetChildWindow( nId, bVis );
}
SfxApplication* pSfxApp = SfxGetpApp();
pSfxApp->Broadcast( SfxHint( SfxHintId::ScRefModeChanged ) );
}
static SfxChildWindow* lcl_GetChildWinFromCurrentView( sal_uInt16 nId )
{
SfxViewFrame* pViewFrm = SfxViewFrame::Current();
// #i46999# current view frame can be null (for example, when closing help)
return pViewFrm ? pViewFrm->GetChildWindow( nId ) : nullptr;
}
static SfxChildWindow* lcl_GetChildWinFromAnyView( sal_uInt16 nId )
{
// First, try the current view
SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nId );
if ( pChildWnd )
return pChildWnd; // found in the current view
// if not found there, get the child window from any open view
// it can be open only in one view because nCurRefDlgId is global
SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
while ( pViewFrm )
{
pChildWnd = pViewFrm->GetChildWindow( nId );
if ( pChildWnd )
return pChildWnd; // found in any view
pViewFrm = SfxViewFrame::GetNext( *pViewFrm );
}
return nullptr; // none found
}
bool ScModule::IsModalMode(SfxObjectShell* pDocSh)
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
bool bIsModal = false;
if ( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
if ( pChildWnd )
{
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
bIsModal = pChildWnd->IsVisible() && pRefDlg &&
!( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(pDocSh) );
}
}
else if ( pDocSh && comphelper::LibreOfficeKit::isActive() )
{
// m_nCurRefDlgId is not deglobalized so it can be set by other view
// in LOK case when no ChildWindow for this view was detected -> fallback
ScInputHandler* pHdl = GetInputHdl();
if ( pHdl )
bIsModal = pHdl->IsModalMode(pDocSh);
}
}
else if (pDocSh)
{
ScInputHandler* pHdl = GetInputHdl();
if ( pHdl )
bIsModal = pHdl->IsModalMode(pDocSh);
}
return bIsModal;
}
bool ScModule::IsTableLocked()
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
bool bLocked = false;
// Up until now just for ScAnyRefDlg
if ( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( m_nCurRefDlgId );
if ( pChildWnd )
{
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
if (pRefDlg)
bLocked = pRefDlg->IsTableLocked();
}
}
else if (!comphelper::LibreOfficeKit::isActive())
bLocked = true; // for other views, see IsModalMode
}
// We can't stop LOK clients from switching part, and getting out of sync.
assert(!bLocked || !comphelper::LibreOfficeKit::isActive());
return bLocked;
}
bool ScModule::IsRefDialogOpen()
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
bool bIsOpen = false;
if ( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
if ( pChildWnd )
bIsOpen = pChildWnd->IsVisible();
}
return bIsOpen;
}
bool ScModule::IsFormulaMode()
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
bool bIsFormula = false;
if ( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = nullptr;
if ( comphelper::LibreOfficeKit::isActive() )
pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
else
pChildWnd = lcl_GetChildWinFromAnyView( m_nCurRefDlgId );
if ( pChildWnd )
{
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode();
}
}
else if ( comphelper::LibreOfficeKit::isActive() )
{
// m_nCurRefDlgId is not deglobalized so it can be set by other view
// in LOK case when no ChildWindow for this view was detected -> fallback
ScInputHandler* pHdl = GetInputHdl();
if ( pHdl )
bIsFormula = pHdl->IsFormulaMode();
}
}
else
{
ScInputHandler* pHdl = GetInputHdl();
if ( pHdl )
bIsFormula = pHdl->IsFormulaMode();
}
if (m_bIsInEditCommand)
bIsFormula = true;
return bIsFormula;
}
static void lcl_MarkedTabs( const ScMarkData& rMark, SCTAB& rStartTab, SCTAB& rEndTab )
{
if (rMark.GetSelectCount() > 1)
{
rEndTab = rMark.GetLastSelected();
rStartTab = rMark.GetFirstSelected();
}
}
void ScModule::SetReference( const ScRange& rRef, ScDocument& rDoc,
const ScMarkData* pMarkData )
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
// In RefDialogs we also trigger the ZoomIn, if the Ref's Start and End are different
ScRange aNew = rRef;
aNew.PutInOrder(); // Always in the right direction
if( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = nullptr;
if ( comphelper::LibreOfficeKit::isActive() )
pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
else
pChildWnd = lcl_GetChildWinFromAnyView( m_nCurRefDlgId );
OSL_ENSURE( pChildWnd, "NoChildWin" );
if ( pChildWnd )
{
if ( m_nCurRefDlgId == SID_OPENDLG_CONSOLIDATE && pMarkData )
{
SCTAB nStartTab = aNew.aStart.Tab();
SCTAB nEndTab = aNew.aEnd.Tab();
lcl_MarkedTabs( *pMarkData, nStartTab, nEndTab );
aNew.aStart.SetTab(nStartTab);
aNew.aEnd.SetTab(nEndTab);
}
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
if(pRefDlg)
{
// hide the (color) selection now instead of later from LoseFocus,
// don't abort the ref input that causes this call (bDoneRefMode = sal_False)
pRefDlg->HideReference( false );
pRefDlg->SetReference( aNew, rDoc );
}
}
}
else if ( comphelper::LibreOfficeKit::isActive() )
{
// m_nCurRefDlgId is not deglobalized so it can be set by other view
// in LOK case when no ChildWindow for this view was detected -> fallback
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->SetReference( aNew, rDoc );
}
}
else
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->SetReference( aNew, rDoc );
else
{
OSL_FAIL("SetReference without receiver");
}
}
}
/**
* Multiple selection
*/
void ScModule::AddRefEntry()
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
if ( m_nCurRefDlgId )
{
SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( m_nCurRefDlgId );
OSL_ENSURE( pChildWnd, "NoChildWin" );
if ( pChildWnd )
{
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
if (pRefDlg)
{
pRefDlg->AddRefEntry();
}
}
}
}
else
{
ScInputHandler* pHdl = GetInputHdl();
if (pHdl)
pHdl->AddRefEntry();
}
}
void ScModule::EndReference()
{
//TODO: Move reference dialog handling to view
// Just keep function autopilot here for references to other documents
// We also annul the ZoomIn again in RefDialogs
//FIXME: ShowRefFrame at InputHdl, if the Function AutoPilot is open?
if ( !m_nCurRefDlgId )
return;
SfxChildWindow* pChildWnd = nullptr;
if ( comphelper::LibreOfficeKit::isActive() )
pChildWnd = lcl_GetChildWinFromCurrentView( m_nCurRefDlgId );
else
pChildWnd = lcl_GetChildWinFromAnyView( m_nCurRefDlgId );
OSL_ENSURE( pChildWnd, "NoChildWin" );
if ( pChildWnd )
{
if (pChildWnd->GetController())
{
IAnyRefDialog* pRefDlg = dynamic_cast<IAnyRefDialog*>(pChildWnd->GetController().get());
assert(pRefDlg);
if(pRefDlg)
{
pRefDlg->SetActive();
}
}
}
}
/**
* Idle/OnlineSpelling
*/
void ScModule::AnythingChanged()
{
sal_uInt64 nOldTime = m_aIdleTimer.GetTimeout();
if ( nOldTime != SC_IDLE_MIN )
m_aIdleTimer.SetTimeout( SC_IDLE_MIN );
nIdleCount = 0;
}
static void lcl_CheckNeedsRepaint( const ScDocShell* pDocShell )
{
SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell );
while ( pFrame )
{
SfxViewShell* p = pFrame->GetViewShell();
ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( p );
if ( pViewSh )
pViewSh->CheckNeedsRepaint();
pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell );
}
}
IMPL_LINK_NOARG(ScModule, IdleHandler, Timer *, void)
{
if ( Application::AnyInput( VclInputFlags::MOUSE | VclInputFlags::KEYBOARD ) )
{
m_aIdleTimer.Start(); // Timeout unchanged
return;
}
bool bMore = false;
ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(SfxObjectShell::Current());
if ( pDocSh )
{
ScDocument& rDoc = pDocSh->GetDocument();
sc::DocumentLinkManager& rLinkMgr = rDoc.GetDocLinkManager();
bool bLinks = rLinkMgr.idleCheckLinks();
bool bWidth = rDoc.IdleCalcTextWidth();
bMore = bLinks || bWidth; // Still something at all?
// While calculating a Basic formula, a paint event may have occurred,
// so check the bNeedsRepaint flags for this document's views
if (bWidth)
lcl_CheckNeedsRepaint( pDocSh );
}
sal_uInt64 nOldTime = m_aIdleTimer.GetTimeout();
sal_uInt64 nNewTime = nOldTime;
if ( bMore )
{
nNewTime = SC_IDLE_MIN;
nIdleCount = 0;
}
else
{
// Set SC_IDLE_COUNT to initial Timeout - increase afterwards
if ( nIdleCount < SC_IDLE_COUNT )
++nIdleCount;
else
{
nNewTime += SC_IDLE_STEP;
if ( nNewTime > SC_IDLE_MAX )
nNewTime = SC_IDLE_MAX;
}
}
if ( nNewTime != nOldTime )
m_aIdleTimer.SetTimeout( nNewTime );
m_aIdleTimer.Start();
}
/**
* Virtual methods for the OptionsDialog
*/
std::optional<SfxItemSet> ScModule::CreateItemSet( sal_uInt16 nId )
{
std::optional<SfxItemSet> pRet;
if(SID_SC_EDITOPTIONS == nId)
{
pRet.emplace(
GetPool(),
svl::Items<
// TP_USERLISTS:
SCITEM_USERLIST, SCITEM_USERLIST,
// TP_GRID:
SID_ATTR_GRID_OPTIONS, SID_ATTR_GRID_OPTIONS,
SID_ATTR_METRIC, SID_ATTR_METRIC,
SID_ATTR_DEFTABSTOP, SID_ATTR_DEFTABSTOP,
// TP_INPUT:
SID_SC_INPUT_LEGACY_CELL_SELECTION, SID_SC_OPT_SORT_REF_UPDATE,
// TP_FORMULA, TP_DEFAULTS:
SID_SCFORMULAOPTIONS, SID_SCDEFAULTSOPTIONS,
// TP_VIEW, TP_CALC:
SID_SCVIEWOPTIONS, SID_SCDOCOPTIONS,
// TP_INPUT:
SID_SC_INPUT_WARNACTIVESHEET, SID_SC_INPUT_ENTER_PASTE_MODE,
// TP_PRINT:
SID_SCPRINTOPTIONS, SID_SCPRINTOPTIONS,
// TP_INPUT:
SID_SC_INPUT_SELECTION, SID_SC_INPUT_MARK_HEADER,
SID_SC_INPUT_TEXTWYSIWYG, SID_SC_INPUT_TEXTWYSIWYG,
SID_SC_INPUT_REPLCELLSWARN, SID_SC_INPUT_REPLCELLSWARN,
// TP_VIEW:
SID_SC_OPT_SYNCZOOM, SID_SC_OPT_KEY_BINDING_COMPAT,
SID_SC_OPT_LINKS, SID_SC_OPT_LINKS>);
const ScAppOptions& rAppOpt = GetAppOptions();
ScDocShell* pDocSh = dynamic_cast< ScDocShell *>( SfxObjectShell::Current() );
ScDocOptions aCalcOpt = pDocSh
? pDocSh->GetDocument().GetDocOptions()
: GetDocOptions();
ScTabViewShell* pViewSh = dynamic_cast< ScTabViewShell *>( SfxViewShell::Current() );
ScViewOptions aViewOpt = pViewSh
? pViewSh->GetViewData().GetOptions()
: GetViewOptions();
ScUserListItem aULItem( SCITEM_USERLIST );
const ScUserList& rUL = ScGlobal::GetUserList();
// SfxGetpApp()->GetOptions( aSet );
pRet->Put( SfxUInt16Item( SID_ATTR_METRIC,
sal::static_int_cast<sal_uInt16>(rAppOpt.GetAppMetric()) ) );
// TP_CALC
pRet->Put( SfxUInt16Item( SID_ATTR_DEFTABSTOP,
aCalcOpt.GetTabDistance()));
pRet->Put( ScTpCalcItem( SID_SCDOCOPTIONS, aCalcOpt ) );
// TP_VIEW
pRet->Put( ScTpViewItem( aViewOpt ) );
pRet->Put( SfxBoolItem( SID_SC_OPT_SYNCZOOM, rAppOpt.GetSynchronizeZoom() ) );
// TP_INPUT
const ScInputOptions& rInpOpt = GetInputOptions();
pRet->Put( SfxUInt16Item( SID_SC_INPUT_SELECTIONPOS,
rInpOpt.GetMoveDir() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_SELECTION,
rInpOpt.GetMoveSelection() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_EDITMODE,
rInpOpt.GetEnterEdit() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_FMT_EXPAND,
rInpOpt.GetExtendFormat() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_RANGEFINDER,
rInpOpt.GetRangeFinder() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_REF_EXPAND,
rInpOpt.GetExpandRefs() ) );
pRet->Put( SfxBoolItem(SID_SC_OPT_SORT_REF_UPDATE, rInpOpt.GetSortRefUpdate()));
pRet->Put( SfxBoolItem( SID_SC_INPUT_MARK_HEADER,
rInpOpt.GetMarkHeader() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_TEXTWYSIWYG,
rInpOpt.GetTextWysiwyg() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_REPLCELLSWARN,
rInpOpt.GetReplaceCellsWarn() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_LEGACY_CELL_SELECTION,
rInpOpt.GetLegacyCellSelection() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_ENTER_PASTE_MODE,
rInpOpt.GetEnterPasteMode() ) );
pRet->Put( SfxBoolItem( SID_SC_INPUT_WARNACTIVESHEET,
rInpOpt.GetWarnActiveSheet() ) );
// RID_SC_TP_PRINT
pRet->Put( ScTpPrintItem( GetPrintOptions() ) );
// TP_GRID
pRet->Put( aViewOpt.CreateGridItem() );
// TP_USERLISTS
aULItem.SetUserList(rUL);
pRet->Put(aULItem);
// TP_COMPATIBILITY
pRet->Put( SfxUInt16Item( SID_SC_OPT_KEY_BINDING_COMPAT,
rAppOpt.GetKeyBindingType() ) );
pRet->Put( SfxBoolItem( SID_SC_OPT_LINKS, rAppOpt.GetLinksInsertedLikeMSExcel()));
// TP_DEFAULTS
pRet->Put( ScTpDefaultsItem( GetDefaultsOptions() ) );
// TP_FORMULA
ScFormulaOptions aOptions = GetFormulaOptions();
if (pDocSh)
{
ScCalcConfig aConfig( aOptions.GetCalcConfig());
aConfig.MergeDocumentSpecific( pDocSh->GetDocument().GetCalcConfig());
aOptions.SetCalcConfig( aConfig);
}
pRet->Put( ScTpFormulaItem( std::move(aOptions) ) );
}
return pRet;
}
void ScModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
{
if(SID_SC_EDITOPTIONS == nId)
{
ModifyOptions( rSet );
}
}
std::unique_ptr<SfxTabPage> ScModule::CreateTabPage( sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet )
{
std::unique_ptr<SfxTabPage> xRet;
ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
switch(nId)
{
case SID_SC_TP_LAYOUT:
{
::CreateTabPage ScTpLayoutOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_LAYOUT);
if (ScTpLayoutOptionsCreate)
xRet = (*ScTpLayoutOptionsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_CONTENT:
{
::CreateTabPage ScTpContentOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CONTENT);
if (ScTpContentOptionsCreate)
xRet = (*ScTpContentOptionsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_GRID:
xRet = SvxGridTabPage::Create(pPage, pController, rSet);
break;
case SID_SC_TP_USERLISTS:
{
::CreateTabPage ScTpUserListsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_USERLISTS);
if (ScTpUserListsCreate)
xRet = (*ScTpUserListsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_CALC:
{
::CreateTabPage ScTpCalcOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CALC);
if (ScTpCalcOptionsCreate)
xRet = (*ScTpCalcOptionsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_FORMULA:
{
::CreateTabPage ScTpFormulaOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_FORMULA);
if (ScTpFormulaOptionsCreate)
xRet = (*ScTpFormulaOptionsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_COMPATIBILITY:
{
::CreateTabPage ScTpCompatOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_COMPATIBILITY);
if (ScTpCompatOptionsCreate)
xRet = (*ScTpCompatOptionsCreate)(pPage, pController, &rSet);
break;
}
case SID_SC_TP_CHANGES:
{
::CreateTabPage ScRedlineOptionsTabPageCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CHANGES);
if (ScRedlineOptionsTabPageCreate)
xRet =(*ScRedlineOptionsTabPageCreate)(pPage, pController, &rSet);
break;
}
case RID_SC_TP_PRINT:
{
::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_PRINT);
if (ScTpPrintOptionsCreate)
xRet = (*ScTpPrintOptionsCreate)(pPage, pController, &rSet);
break;
}
case RID_SC_TP_DEFAULTS:
{
::CreateTabPage ScTpDefaultsOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_DEFAULTS);
if (ScTpDefaultsOptionsCreate)
xRet = (*ScTpDefaultsOptionsCreate)(pPage, pController, &rSet);
break;
}
}
OSL_ENSURE( xRet, "ScModule::CreateTabPage(): no valid ID for TabPage!" );
return xRet;
}
IMPL_LINK( ScModule, CalcFieldValueHdl, EditFieldInfo*, pInfo, void )
{
//TODO: Merge with ScFieldEditEngine!
if (!pInfo)
return;
const SvxFieldItem& rField = pInfo->GetField();
const SvxFieldData* pField = rField.GetField();
if (const SvxURLField* pURLField = dynamic_cast<const SvxURLField*>(pField))
{
// URLField
const OUString& aURL = pURLField->GetURL();
switch ( pURLField->GetFormat() )
{
case SvxURLFormat::AppDefault: //TODO: Settable in the App?
case SvxURLFormat::Repr:
{
pInfo->SetRepresentation( pURLField->GetRepresentation() );
}
break;
case SvxURLFormat::Url:
{
pInfo->SetRepresentation( aURL );
}
break;
}
svtools::ColorConfigEntry eEntry =
INetURLHistory::GetOrCreate()->QueryUrl( aURL ) ? svtools::LINKSVISITED : svtools::LINKS;
pInfo->SetTextColor( GetColorConfig().GetColorValue(eEntry).nColor );
}
else
{
OSL_FAIL("Unknown Field");
pInfo->SetRepresentation(OUString('?'));
}
}
void ScModule::RegisterRefController(sal_uInt16 nSlotId, std::shared_ptr<SfxDialogController>& rWnd, weld::Window* pWndAncestor)
{
std::vector<std::pair<std::shared_ptr<SfxDialogController>, weld::Window*>> & rlRefWindow = m_mapRefController[nSlotId];
if (std::none_of(rlRefWindow.begin(), rlRefWindow.end(),
[rWnd](const std::pair<std::shared_ptr<SfxDialogController>, weld::Window*>& rCandidate)
{
return rCandidate.first.get() == rWnd.get();
}))
{
rlRefWindow.emplace_back(rWnd, pWndAncestor);
}
}
void ScModule::UnregisterRefController(sal_uInt16 nSlotId, const std::shared_ptr<SfxDialogController>& rWnd)
{
auto iSlot = m_mapRefController.find( nSlotId );
if( iSlot == m_mapRefController.end() )
return;
std::vector<std::pair<std::shared_ptr<SfxDialogController>, weld::Window*>> & rlRefWindow = iSlot->second;
auto i = std::find_if(rlRefWindow.begin(), rlRefWindow.end(),
[rWnd](const std::pair<std::shared_ptr<SfxDialogController>, weld::Window*>& rCandidate)
{
return rCandidate.first.get() == rWnd.get();
});
if( i == rlRefWindow.end() )
return;
rlRefWindow.erase( i );
if( rlRefWindow.empty() )
m_mapRefController.erase( nSlotId );
}
std::shared_ptr<SfxDialogController> ScModule::Find1RefWindow(sal_uInt16 nSlotId, const weld::Window *pWndAncestor)
{
if (!pWndAncestor)
return nullptr;
auto iSlot = m_mapRefController.find( nSlotId );
if( iSlot == m_mapRefController.end() )
return nullptr;
std::vector<std::pair<std::shared_ptr<SfxDialogController>, weld::Window*>> & rlRefWindow = iSlot->second;
for (auto const& refWindow : rlRefWindow)
if ( refWindow.second == pWndAncestor )
return refWindow.first;
return nullptr;
}
using namespace com::sun::star;
constexpr OUStringLiteral LINGUPROP_AUTOSPELL = u"IsSpellAuto";
void ScModule::GetSpellSettings( LanguageType& rDefLang, LanguageType& rCjkLang, LanguageType& rCtlLang )
{
// use SvtLinguConfig instead of service LinguProperties to avoid
// loading the linguistic component
SvtLinguConfig aConfig;
SvtLinguOptions aOptions;
aConfig.GetOptions( aOptions );
rDefLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage, css::i18n::ScriptType::LATIN);
rCjkLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CJK, css::i18n::ScriptType::ASIAN);
rCtlLang = MsLangId::resolveSystemLanguageByScriptType(aOptions.nDefaultLanguage_CTL, css::i18n::ScriptType::COMPLEX);
}
void ScModule::SetAutoSpellProperty( bool bSet )
{
// use SvtLinguConfig instead of service LinguProperties to avoid
// loading the linguistic component
SvtLinguConfig aConfig;
aConfig.SetProperty( LINGUPROP_AUTOSPELL, uno::Any(bSet) );
}
bool ScModule::GetAutoSpellProperty()
{
// use SvtLinguConfig instead of service LinguProperties to avoid
// loading the linguistic component
SvtLinguConfig aConfig;
SvtLinguOptions aOptions;
aConfig.GetOptions( aOptions );
return aOptions.bIsSpellAuto;
}
bool ScModule::HasThesaurusLanguage( LanguageType nLang )
{
if ( nLang == LANGUAGE_NONE )
return false;
bool bHasLang = false;
try
{
uno::Reference< linguistic2::XThesaurus > xThes(LinguMgr::GetThesaurus());
if ( xThes.is() )
bHasLang = xThes->hasLocale( LanguageTag::convertToLocale( nLang ) );
}
catch( uno::Exception& )
{
OSL_FAIL("Error in Thesaurus");
}
return bHasLang;
}
std::optional<SfxStyleFamilies> ScModule::CreateStyleFamilies()
{
SfxStyleFamilies aStyleFamilies;
aStyleFamilies.emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Para,
ScResId(STR_STYLE_FAMILY_CELL),
BMP_STYLES_FAMILY_CELL,
RID_CELLSTYLEFAMILY, SC_MOD()->GetResLocale()));
aStyleFamilies.emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Page,
ScResId(STR_STYLE_FAMILY_PAGE),
BMP_STYLES_FAMILY_PAGE,
RID_PAGESTYLEFAMILY, SC_MOD()->GetResLocale()));
aStyleFamilies.emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Frame,
ScResId(STR_STYLE_FAMILY_GRAPHICS),
BMP_STYLES_FAMILY_GRAPHICS,
RID_GRAPHICSTYLEFAMILY, SC_MOD()->GetResLocale()));
return aStyleFamilies;
}
void ScModule::RegisterAutomationApplicationEventsCaller(css::uno::Reference< ooo::vba::XSinkCaller > const& xCaller)
{
mxAutomationApplicationEventsCaller = xCaller;
}
void ScModule::CallAutomationApplicationEventSinks(const OUString& Method, css::uno::Sequence< css::uno::Any >& Arguments)
{
if (mxAutomationApplicationEventsCaller.is())
mxAutomationApplicationEventsCaller->CallSinks(Method, Arguments);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'GetColorConfig' is required to be utilized.
↑ V530 The return value of function 'CallAppBasic' is required to be utilized.
↑ V530 The return value of function 'CallAppBasic' is required to be utilized.
↑ V595 The 'pDocSh' pointer was utilized before it was verified against nullptr. Check lines: 1160, 1184.
↑ V522 There might be dereferencing of a potential null pointer 'pDocSh'.
↑ V522 There might be dereferencing of a potential null pointer 'pDocSh'.