/* -*- 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define ShellClass_ScModule #include #include #include #include #include #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", {pFact}), aIdleTimer("sc ScModule IdleTimer"), aSpellIdle("sc ScModule SpellIdle"), mpDragData(new ScDragData), pSelTransfer( nullptr ), pMessagePool( nullptr ), pRefInputHandler( nullptr ), pViewCfg( nullptr ), pDocCfg( nullptr ), pAppCfg( nullptr ), pDefaultsCfg( nullptr ), pFormulaCfg( nullptr ), pInputCfg( nullptr ), pPrintCfg( nullptr ), pNavipiCfg( nullptr ), pAddInCfg( nullptr ), pColorConfig( nullptr ), pAccessOptions( nullptr ), pCTLOptions( nullptr ), pUserOptions( nullptr ), pErrorHdl( nullptr ), pFormEditData( nullptr ), nCurRefDlgId( 0 ), bIsWaterCan( false ), bIsInEditCommand( false ), bIsInExecuteDrop( false ), mbIsInSharedDocLoading( false ), mbIsInSharedDocSaving( false ) { // The ResManager (DLL data) is not yet initialized in the ctor! SetName("StarCalc"); // for Basic ResetDragObject(); // InputHandler does not need to be created // Create ErrorHandler - was in Init() // Between OfficeApplication::Init and ScGlobal::Init SvxErrorHandler::ensure(); pErrorHdl = new SfxErrorHandler(RID_ERRHDLSC, ErrCodeArea::Sc, ErrCodeArea::Sc, GetResLocale()); aSpellIdle.SetInvokeHandler( LINK( this, ScModule, SpellTimerHdl ) ); aIdleTimer.SetTimeout(SC_IDLE_MIN); aIdleTimer.SetInvokeHandler( LINK( this, ScModule, IdleHandler ) ); aIdleTimer.Start(); pMessagePool = new ScMessagePool; pMessagePool->FreezeIdRanges(); SetPool( pMessagePool ); ScGlobal::InitTextHeight( pMessagePool ); StartListening( *SfxGetpApp() ); // for SfxHintId::Deinitializing } ScModule::~ScModule() { OSL_ENSURE( !pSelTransfer, "Selection Transfer object not deleted" ); // InputHandler does not need to be deleted (there's none in the App anymore) SfxItemPool::Free(pMessagePool); DELETEZ( pFormEditData ); delete mpDragData; delete pErrorHdl; ScGlobal::Clear(); // Also calls ScDocumentPool::DeleteVersionMaps(); DeleteCfg(); // Called from Exit() } void ScModule::ConfigurationChanged( utl::ConfigurationBroadcaster* p, ConfigurationHints ) { if ( p == pColorConfig || p == pAccessOptions ) { // 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 ( dynamic_cast(pObjSh) != nullptr ) { ScDocShell* pDocSh = static_cast(pObjSh); if ( bArrows ) ScDetectiveFunc( &pDocSh->GetDocument(), 0 ).UpdateAllArrowColors(); if ( bComments ) ScDetectiveFunc::UpdateAllComments( pDocSh->GetDocument() ); } pObjSh = SfxObjectShell::GetNext( *pObjSh ); } } } // force all views to repaint, using the new options SfxViewShell* pViewShell = SfxViewShell::GetFirst(); while(pViewShell) { if (ScTabViewShell* pViewSh = dynamic_cast(pViewShell)) { pViewSh->PaintGrid(); pViewSh->PaintTop(); pViewSh->PaintLeft(); pViewSh->PaintExtras(); ScInputHandler* pHdl = pViewSh->GetInputHandler(); if ( pHdl ) pHdl->ForgetLastPattern(); // EditEngine BackgroundColor may change } else if ( dynamic_cast( pViewShell) != nullptr ) { vcl::Window* pWin = pViewShell->GetWindow(); if (pWin) pWin->Invalidate(); } pViewShell = SfxViewShell::GetNext( *pViewShell ); } } else if ( p == pCTLOptions ) { // for all documents: set digit language for printer, recalc output factor, update row heights SfxObjectShell* pObjSh = SfxObjectShell::GetFirst(); while ( pObjSh ) { if ( dynamic_cast(pObjSh) != nullptr ) { ScDocShell* pDocSh = static_cast(pObjSh); OutputDevice* pPrinter = pDocSh->GetPrinter(); if ( pPrinter ) pPrinter->SetDigitLanguage( GetOptDigitLanguage() ); pDocSh->CalcOutputFactor(); SCTAB nTabCount = pDocSh->GetDocument().GetTableCount(); for (SCTAB nTab=0; nTabAdjustRowHeight( 0, 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(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(pSh)) { ScPreview* pPreview = pPreviewSh->GetPreview(); pPreview->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() { DELETEZ( pViewCfg ); // Saving happens automatically before Exit() DELETEZ( pDocCfg ); DELETEZ( pAppCfg ); DELETEZ( pDefaultsCfg ); DELETEZ( pFormulaCfg ); DELETEZ( pInputCfg ); DELETEZ( pPrintCfg ); DELETEZ( pNavipiCfg ); DELETEZ( pAddInCfg ); if ( pColorConfig ) { pColorConfig->RemoveListener(this); DELETEZ( pColorConfig ); } if ( pAccessOptions ) { pAccessOptions->RemoveListener(this); DELETEZ( pAccessOptions ); } if ( pCTLOptions ) { pCTLOptions->RemoveListener(this); DELETEZ( pCTLOptions ); } if( pUserOptions ) { DELETEZ( pUserOptions ); } } // 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( "Template.Samples.ShowStyles" ); break; case SID_EURO_CONVERTER: SfxApplication::CallAppBasic( "Euro.ConvertRun.Main" ); break; case SID_AUTOSPELL_CHECK: { bool bSet; const SfxPoolItem* pItem; if ( pReqArgs && SfxItemState::SET == pReqArgs->GetItemState( nSlot, true, &pItem ) ) bSet = static_cast(pItem)->GetValue(); else { // Toggle ScDocShell* pDocSh = dynamic_cast( SfxObjectShell::Current() ); if ( pDocSh ) bSet = !pDocSh->GetDocument().GetDocOptions().IsAutoSpell(); else bSet = !GetDocOptions().IsAutoSpell(); } SfxItemSet aSet( GetPool(), svl::Items{} ); 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(static_cast(pItem)->GetValue()); switch( eUnit ) { case FUNIT_MM: // Just the units that are also in the dialog case FUNIT_CM: case FUNIT_INCH: case FUNIT_PICA: case FUNIT_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 ); ScInputHandler::SetAutoComplete( bNew ); 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(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) { auto const & p = pReqArgs->Get(SID_PSZ_FUNCTION); OSL_ENSURE(dynamic_cast(&p) != nullptr,"wrong Parameter"); const SfxUInt32Item& rItem = static_cast(p); 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().GetWhich(nSlot), true, &pItem ) ) { ScDocShell* pDocSh = dynamic_cast( SfxObjectShell::Current() ); if ( pDocSh ) { ScDocument& rDoc = pDocSh->GetDocument(); LanguageType eNewLang = static_cast(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( 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()); 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( SfxObjectShell::Current() ); bool bTabView = pDocSh && (pDocSh->GetBestViewShell() != nullptr); SfxWhichIter aIter(rSet); for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich()) { if (!bTabView) { // 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(GetAppOptions().GetAppMetric()) ) ); break; case SID_AUTOSPELL_CHECK: rSet.Put( SfxBoolItem( nWhich, pDocSh->GetDocument().GetDocOptions().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() { mpDragData->pCellTransfer = nullptr; mpDragData->pDrawTransfer = nullptr; mpDragData->pJumpLocalDoc = nullptr; mpDragData->aLinkDoc.clear(); mpDragData->aLinkTable.clear(); mpDragData->aLinkArea.clear(); mpDragData->aJumpTarget.clear(); mpDragData->aJumpText.clear(); } void ScModule::SetDragObject( ScTransferObj* pCellObj, ScDrawTransferObj* pDrawObj ) { ResetDragObject(); mpDragData->pCellTransfer = pCellObj; mpDragData->pDrawTransfer = pDrawObj; } void ScModule::SetDragLink( const OUString& rDoc, const OUString& rTab, const OUString& rArea ) { ResetDragObject(); mpDragData->aLinkDoc = rDoc; mpDragData->aLinkTable = rTab; mpDragData->aLinkArea = rArea; } void ScModule::SetDragJump( ScDocument* pLocalDoc, const OUString& rTarget, const OUString& rText ) { ResetDragObject(); mpDragData->pJumpLocalDoc = pLocalDoc; mpDragData->aJumpTarget = rTarget; mpDragData->aJumpText = rText; } ScDocument* ScModule::GetClipDoc() { // called from document vcl::Window* pWin = nullptr; if( ScTabViewShell* pViewShell = dynamic_cast( SfxViewShell::Current() )) pWin = pViewShell->GetViewData().GetActiveWin(); ScTransferObj* pObj = ScTransferObj::GetOwnClipboard( pWin ); 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 ) { pSelTransfer = pNew; } void ScModule::InitFormEditData() { pFormEditData = new ScFormEditData; } void ScModule::ClearFormEditData() { DELETEZ( pFormEditData ); } void ScModule::SetViewOptions( const ScViewOptions& rOpt ) { if ( !pViewCfg ) pViewCfg = new ScViewCfg; pViewCfg->SetOptions( rOpt ); } const ScViewOptions& ScModule::GetViewOptions() { if ( !pViewCfg ) pViewCfg = new ScViewCfg; return *pViewCfg; } void ScModule::SetDocOptions( const ScDocOptions& rOpt ) { if ( !pDocCfg ) pDocCfg = new ScDocCfg; pDocCfg->SetOptions( rOpt ); } const ScDocOptions& ScModule::GetDocOptions() { if ( !pDocCfg ) pDocCfg = new ScDocCfg; return *pDocCfg; } #ifndef LRU_MAX #define LRU_MAX 10 #endif void ScModule::InsertEntryToLRUList(sal_uInt16 nFIndex) { if(nFIndex != 0) { 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) && nSetOptions( rOpt ); } void global_InitAppOptions() { SC_MOD()->GetAppOptions(); } const ScAppOptions& ScModule::GetAppOptions() { if ( !pAppCfg ) pAppCfg = new ScAppCfg; return *pAppCfg; } void ScModule::SetDefaultsOptions( const ScDefaultsOptions& rOpt ) { if ( !pDefaultsCfg ) pDefaultsCfg = new ScDefaultsCfg; pDefaultsCfg->SetOptions( rOpt ); } const ScDefaultsOptions& ScModule::GetDefaultsOptions() { if ( !pDefaultsCfg ) pDefaultsCfg = new ScDefaultsCfg; return *pDefaultsCfg; } void ScModule::SetFormulaOptions( const ScFormulaOptions& rOpt ) { if ( !pFormulaCfg ) pFormulaCfg = new ScFormulaCfg; pFormulaCfg->SetOptions( rOpt ); } const ScFormulaOptions& ScModule::GetFormulaOptions() { if ( !pFormulaCfg ) pFormulaCfg = new ScFormulaCfg; return *pFormulaCfg; } void ScModule::SetInputOptions( const ScInputOptions& rOpt ) { if ( !pInputCfg ) pInputCfg = new ScInputCfg; pInputCfg->SetOptions( rOpt ); } const ScInputOptions& ScModule::GetInputOptions() { if ( !pInputCfg ) pInputCfg = new ScInputCfg; return *pInputCfg; } void ScModule::SetPrintOptions( const ScPrintOptions& rOpt ) { if ( !pPrintCfg ) pPrintCfg = new ScPrintCfg; pPrintCfg->SetOptions( rOpt ); } const ScPrintOptions& ScModule::GetPrintOptions() { if ( !pPrintCfg ) pPrintCfg = new ScPrintCfg; return *pPrintCfg; } ScNavipiCfg& ScModule::GetNavipiCfg() { if ( !pNavipiCfg ) pNavipiCfg = new ScNavipiCfg; return *pNavipiCfg; } ScAddInCfg& ScModule::GetAddInCfg() { if ( !pAddInCfg ) pAddInCfg = new ScAddInCfg; return *pAddInCfg; } svtools::ColorConfig& ScModule::GetColorConfig() { if ( !pColorConfig ) { pColorConfig = new svtools::ColorConfig; pColorConfig->AddListener(this); } return *pColorConfig; } SvtAccessibilityOptions& ScModule::GetAccessOptions() { if ( !pAccessOptions ) { pAccessOptions = new SvtAccessibilityOptions; pAccessOptions->AddListener(this); } return *pAccessOptions; } SvtCTLOptions& ScModule::GetCTLOptions() { if ( !pCTLOptions ) { pCTLOptions = new SvtCTLOptions; pCTLOptions->AddListener(this); } return *pCTLOptions; } SvtUserOptions& ScModule::GetUserOptions() { if( !pUserOptions ) { pUserOptions = new SvtUserOptions; } return *pUserOptions; } LanguageType ScModule::GetOptDigitLanguage() { SvtCTLOptions::TextNumerals eNumerals = GetCTLOptions().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 ) { LanguageType nOldSpellLang, nOldCjkLang, nOldCtlLang; bool bOldAutoSpell; GetSpellSettings( nOldSpellLang, nOldCjkLang, nOldCtlLang, bOldAutoSpell ); if (!pAppCfg) GetAppOptions(); OSL_ENSURE( pAppCfg, "AppOptions not initialised :-(" ); if (!pInputCfg) GetInputOptions(); OSL_ENSURE( pInputCfg, "InputOptions not initialised :-(" ); SfxViewFrame* pViewFrm = SfxViewFrame::Current(); SfxBindings* pBindings = pViewFrm ? &pViewFrm->GetBindings() : nullptr; ScTabViewShell* pViewSh = dynamic_cast( SfxViewShell::Current() ); ScDocShell* pDocSh = dynamic_cast( SfxObjectShell::Current() ); ScDocument* pDoc = pDocSh ? &pDocSh->GetDocument() : nullptr; const SfxPoolItem* pItem = 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 ); // No more linguistics if (rOptSet.HasItem(SID_ATTR_METRIC, &pItem)) { PutItem( *pItem ); pAppCfg->SetAppMetric( static_cast(static_cast(pItem)->GetValue()) ); bSaveAppOptions = true; } if (rOptSet.HasItem(SCITEM_USERLIST, &pItem)) { ScGlobal::SetUserList( static_cast(pItem)->GetUserList() ); bSaveAppOptions = true; } if (rOptSet.HasItem(SID_SC_OPT_SYNCZOOM, &pItem)) { pAppCfg->SetSynchronizeZoom( static_cast(pItem)->GetValue() ); bSaveAppOptions = true; } if (rOptSet.HasItem(SID_SC_OPT_KEY_BINDING_COMPAT, &pItem)) { sal_uInt16 nVal = static_cast(pItem)->GetValue(); ScOptionsUtil::KeyBindingType eOld = pAppCfg->GetKeyBindingType(); ScOptionsUtil::KeyBindingType eNew = static_cast(nVal); if (eOld != eNew) { pAppCfg->SetKeyBindingType(eNew); bSaveAppOptions = true; ScDocShell::ResetKeyBindings(eNew); } } // DefaultsOptions if (rOptSet.HasItem(SID_SCDEFAULTSOPTIONS, &pItem)) { const ScDefaultsOptions& rOpt = static_cast(pItem)->GetDefaultsOptions(); SetDefaultsOptions( rOpt ); } // FormulaOptions if (rOptSet.HasItem(SID_SCFORMULAOPTIONS, &pItem)) { const ScFormulaOptions& rOpt = static_cast(pItem)->GetFormulaOptions(); if (!pFormulaCfg || (*pFormulaCfg != rOpt)) // Formula options have changed. Repaint the column headers. bRepaint = true; if (pFormulaCfg && 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 (pFormulaCfg && 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( pFormulaCfg->GetCalcConfig()); SetFormulaOptions( aNewOpt); } } // ViewOptions if (rOptSet.HasItem(SID_SCVIEWOPTIONS, &pItem)) { const ScViewOptions& rNewOpt = static_cast(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 ( rOptSet.HasItem(SID_ATTR_GRID_OPTIONS,&pItem) ) { ScGridOptions aNewGridOpt( static_cast(*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 ); 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 ( rOptSet.HasItem(SID_SCDOCOPTIONS,&pItem) ) { const ScDocOptions& rNewOpt = static_cast(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 ( rOptSet.HasItem(SID_ATTR_DEFTABSTOP,&pItem) ) { sal_uInt16 nTabDist = static_cast(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 ( rOptSet.HasItem(SID_AUTOSPELL_CHECK,&pItem) ) // At DocOptions { bool bDoAutoSpell = static_cast(pItem)->GetValue(); if (pDoc) { ScDocOptions aNewOpt = pDoc->GetDocOptions(); if ( aNewOpt.IsAutoSpell() != bDoAutoSpell ) { aNewOpt.SetAutoSpell( bDoAutoSpell ); pDoc->SetDocOptions( aNewOpt ); if (pViewSh) 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 if ( rOptSet.HasItem(SID_SC_INPUT_SELECTIONPOS,&pItem) ) { pInputCfg->SetMoveDir( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_SELECTION,&pItem) ) { pInputCfg->SetMoveSelection( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_EDITMODE,&pItem) ) { pInputCfg->SetEnterEdit( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_FMT_EXPAND,&pItem) ) { pInputCfg->SetExtendFormat( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_RANGEFINDER,&pItem) ) { pInputCfg->SetRangeFinder( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_REF_EXPAND,&pItem) ) { pInputCfg->SetExpandRefs( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if (rOptSet.HasItem(SID_SC_OPT_SORT_REF_UPDATE, &pItem)) { pInputCfg->SetSortRefUpdate(static_cast(pItem)->GetValue()); bSaveInputOptions = true; } if ( rOptSet.HasItem(SID_SC_INPUT_MARK_HEADER,&pItem) ) { pInputCfg->SetMarkHeader( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; bUpdateMarks = true; } if ( rOptSet.HasItem(SID_SC_INPUT_TEXTWYSIWYG,&pItem) ) { bool bNew = static_cast(pItem)->GetValue(); if ( bNew != pInputCfg->GetTextWysiwyg() ) { pInputCfg->SetTextWysiwyg( bNew ); bSaveInputOptions = true; bUpdateRefDev = true; } } if( rOptSet.HasItem( SID_SC_INPUT_REPLCELLSWARN, &pItem ) ) { pInputCfg->SetReplaceCellsWarn( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } if( rOptSet.HasItem( SID_SC_INPUT_LEGACY_CELL_SELECTION, &pItem ) ) { pInputCfg->SetLegacyCellSelection( static_cast(pItem)->GetValue() ); bSaveInputOptions = true; } // PrintOptions if ( rOptSet.HasItem(SID_SCPRINTOPTIONS,&pItem) ) { const ScPrintOptions& rNewOpt = static_cast(pItem)->GetPrintOptions(); SetPrintOptions( rNewOpt ); // broadcast causes all previews to recalc page numbers SfxGetpApp()->Broadcast( SfxHint( SfxHintId::ScPrintOptions ) ); } if ( bSaveAppOptions ) pAppCfg->OptionsChanged(); if ( bSaveInputOptions ) pInputCfg->OptionsChanged(); // 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 ) { 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 ) { // for all documents: recalc output factor, update row heights SfxObjectShell* pObjSh = SfxObjectShell::GetFirst(); while ( pObjSh ) { if ( dynamic_cast(pObjSh) != nullptr ) { ScDocShell* pOneDocSh = static_cast(pObjSh); pOneDocSh->CalcOutputFactor(); SCTAB nTabCount = pOneDocSh->GetDocument().GetTableCount(); for (SCTAB nTab=0; nTabAdjustRowHeight( 0, MAXROW, nTab ); } pObjSh = SfxObjectShell::GetNext( *pObjSh ); } // for all (tab-) views: SfxViewShell* pSh = SfxViewShell::GetFirst( true, checkSfxViewShell ); while ( pSh ) { ScTabViewShell* pOneViewSh = static_cast(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 ); } } } /** * Input-Handler */ ScInputHandler* ScModule::GetInputHdl( ScTabViewShell* pViewSh, bool bUseRef ) { if ( pRefInputHandler && bUseRef ) return 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( 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 ) { if ( !SfxGetpApp()->IsDowning() ) // Not when quitting the program { ScInputHandler* pHdl = GetInputHdl(); if (pHdl) pHdl->EnterHandler( nBlockMode ); } } 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 ) { 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( const OUString& rStr ) { ScInputHandler* pHdl = GetInputHdl(); if (pHdl) pHdl->InputReplaceSelection( rStr ); } void ScModule::InputTurnOffWinEngine() { ScInputHandler* pHdl = GetInputHdl(); if (pHdl) pHdl->InputTurnOffWinEngine(); } OUString ScModule::InputGetFormulaStr() { ScInputHandler* pHdl = GetInputHdl(); OUString aStr; if ( pHdl ) aStr = pHdl->GetFormString(); return aStr; } void ScModule::ActivateInputWindow( const OUString* pStrFormula, bool bMatrix ) { ScInputHandler* pHdl = GetInputHdl(); if ( pHdl ) { 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( EMPTY_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(nCurRefDlgId==0 || (nId==nCurRefDlgId && !bVis)) { 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 nCurRefDlgId = bVis ? nId : 0 ; // before SetChildWindow if ( pViewFrm ) { // store the dialog id also in the view shell SfxViewShell* pViewSh = pViewFrm->GetViewShell(); if (ScTabViewShell* pTabViewSh = dynamic_cast(pViewSh)) pTabViewSh->SetCurRefDlgId(nCurRefDlgId); else { // no ScTabViewShell - possible for example from a Basic macro bVis = false; nCurRefDlgId = 0; // don't set nCurRefDlgId if no dialog is created } pViewFrm->SetChildWindow( nId, bVis ); } SfxApplication* pSfxApp = SfxGetpApp(); pSfxApp->Broadcast( SfxHint( SfxHintId::ScRefModeChanged ) ); } } static inline 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 ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nCurRefDlgId ); if ( pChildWnd ) { IAnyRefDialog* pRefDlg = dynamic_cast(pChildWnd->GetWindow()); assert(pRefDlg); bIsModal = pChildWnd->IsVisible() && pRefDlg && !( pRefDlg->IsRefInputMode() && pRefDlg->IsDocAllowed(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 ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); if ( pChildWnd ) { IAnyRefDialog* pRefDlg(dynamic_cast(pChildWnd->GetWindow())); assert(pRefDlg); if(pRefDlg) { bLocked = pRefDlg->IsTableLocked(); } } else bLocked = true; // for other views, see IsModalMode } 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 ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( 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; // formula mode in online is not usable in collaborative mode, // this is a workaround for disabling formula mode in online // when there is more than a single view if (comphelper::LibreOfficeKit::isActive() && SfxViewShell::GetActiveShells() > 1) return false; if ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromCurrentView( nCurRefDlgId ); if ( pChildWnd ) { IAnyRefDialog* pRefDlg = dynamic_cast(pChildWnd->GetWindow()); assert(pRefDlg); bIsFormula = pChildWnd->IsVisible() && pRefDlg && pRefDlg->IsRefInputMode(); } } else { ScInputHandler* pHdl = GetInputHdl(); if ( pHdl ) bIsFormula = pHdl->IsFormulaMode(); } if (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* pDoc, 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( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); OSL_ENSURE( pChildWnd, "NoChildWin" ); if ( pChildWnd ) { if ( 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); } IAnyRefDialog* pRefDlg = dynamic_cast(pChildWnd->GetWindow()); 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, pDoc ); } } } else { ScInputHandler* pHdl = GetInputHdl(); if (pHdl) pHdl->SetReference( aNew, pDoc ); 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 ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); OSL_ENSURE( pChildWnd, "NoChildWin" ); if ( pChildWnd ) { IAnyRefDialog* pRefDlg = dynamic_cast(pChildWnd->GetWindow()); 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 ( nCurRefDlgId ) { SfxChildWindow* pChildWnd = lcl_GetChildWinFromAnyView( nCurRefDlgId ); OSL_ENSURE( pChildWnd, "NoChildWin" ); if ( pChildWnd ) { IAnyRefDialog* pRefDlg = dynamic_cast(pChildWnd->GetWindow()); assert(pRefDlg); if(pRefDlg) { pRefDlg->SetActive(); } } } } /** * Idle/OnlineSpelling */ void ScModule::AnythingChanged() { sal_uLong nOldTime = aIdleTimer.GetTimeout(); if ( nOldTime != SC_IDLE_MIN ) 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 ) ) { aIdleTimer.Start(); // Timeout unchanged return; } bool bMore = false; bool bAutoSpell = false; ScDocShell* pDocSh = dynamic_cast(SfxObjectShell::Current()); if ( pDocSh ) { ScDocument& rDoc = pDocSh->GetDocument(); bAutoSpell = rDoc.GetDocOptions().IsAutoSpell(); if (pDocSh->IsReadOnly()) bAutoSpell = false; 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 ); } if (bAutoSpell) { ScTabViewShell* pViewSh = dynamic_cast(SfxViewShell::Current()); if (pViewSh) { bool bSpell = pViewSh->ContinueOnlineSpelling(); if (bSpell) { aSpellIdle.Start(); bMore = true; } } } sal_uLong nOldTime = aIdleTimer.GetTimeout(); sal_uLong 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 ) aIdleTimer.SetTimeout( nNewTime ); aIdleTimer.Start(); } IMPL_LINK_NOARG(ScModule, SpellTimerHdl, Timer *, void) { if ( Application::AnyInput( VclInputFlags::KEYBOARD ) ) { aSpellIdle.Start(); return; // Later again ... } ScTabViewShell* pViewSh = dynamic_cast(SfxViewShell::Current()); if (pViewSh) { if (pViewSh->ContinueOnlineSpelling()) aSpellIdle.Start(); } } /** * Virtual methods for the OptionsDialog */ std::unique_ptr ScModule::CreateItemSet( sal_uInt16 nId ) { std::unique_ptr pRet; if(SID_SC_EDITOPTIONS == nId) { pRet = o3tl::make_unique( 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_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>{}); 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 ); ScUserList* pUL = ScGlobal::GetUserList(); // SfxGetpApp()->GetOptions( aSet ); pRet->Put( SfxUInt16Item( SID_ATTR_METRIC, sal::static_int_cast(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() ) ); // RID_SC_TP_PRINT pRet->Put( ScTpPrintItem( GetPrintOptions() ) ); // TP_GRID SvxGridItem* pSvxGridItem = aViewOpt.CreateGridItem(); pRet->Put( *pSvxGridItem ); delete pSvxGridItem; // TP_USERLISTS if ( pUL ) { aULItem.SetUserList( *pUL ); pRet->Put(aULItem); } // TP_COMPATIBILITY pRet->Put( SfxUInt16Item( SID_SC_OPT_KEY_BINDING_COMPAT, rAppOpt.GetKeyBindingType() ) ); // 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( aOptions ) ); } return pRet; } void ScModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet ) { if(SID_SC_EDITOPTIONS == nId) { ModifyOptions( rSet ); } } VclPtr ScModule::CreateTabPage( sal_uInt16 nId, TabPageParent pParent, const SfxItemSet& rSet ) { VclPtr pRet; ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); OSL_ENSURE(pFact, "ScAbstractFactory create fail!"); switch(nId) { case SID_SC_TP_LAYOUT: { ::CreateTabPage ScTpLayoutOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_LAYOUT); if (ScTpLayoutOptionsCreate) pRet = (*ScTpLayoutOptionsCreate)(pParent, &rSet); break; } case SID_SC_TP_CONTENT: { ::CreateTabPage ScTpContentOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CONTENT); if (ScTpContentOptionsCreate) pRet = (*ScTpContentOptionsCreate)(pParent, &rSet); break; } case SID_SC_TP_GRID: pRet = SvxGridTabPage::Create(pParent.pParent, rSet); break; case SID_SC_TP_USERLISTS: { ::CreateTabPage ScTpUserListsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_USERLISTS); if (ScTpUserListsCreate) pRet = (*ScTpUserListsCreate)(pParent, &rSet); break; } case SID_SC_TP_CALC: { ::CreateTabPage ScTpCalcOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CALC); if (ScTpCalcOptionsCreate) pRet = (*ScTpCalcOptionsCreate)(pParent, &rSet); break; } case SID_SC_TP_FORMULA: { ::CreateTabPage ScTpFormulaOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_FORMULA); if (ScTpFormulaOptionsCreate) pRet = (*ScTpFormulaOptionsCreate)(pParent, &rSet); break; } case SID_SC_TP_COMPATIBILITY: { ::CreateTabPage ScTpCompatOptionsCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_COMPATIBILITY); if (ScTpCompatOptionsCreate) pRet = (*ScTpCompatOptionsCreate)(pParent, &rSet); break; } case SID_SC_TP_CHANGES: { ::CreateTabPage ScRedlineOptionsTabPageCreate = pFact->GetTabPageCreatorFunc(SID_SC_TP_CHANGES); if (ScRedlineOptionsTabPageCreate) pRet =(*ScRedlineOptionsTabPageCreate)(pParent, &rSet); break; } case RID_SC_TP_PRINT: { ::CreateTabPage ScTpPrintOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_PRINT); if (ScTpPrintOptionsCreate) pRet = (*ScTpPrintOptionsCreate)(pParent, &rSet); break; } case RID_SC_TP_DEFAULTS: { ::CreateTabPage ScTpDefaultsOptionsCreate = pFact->GetTabPageCreatorFunc(RID_SC_TP_DEFAULTS); if (ScTpDefaultsOptionsCreate) pRet = (*ScTpDefaultsOptionsCreate)(pParent, &rSet); break; } } OSL_ENSURE( pRet, "ScModule::CreateTabPage(): no valid ID for TabPage!" ); return pRet; } 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(pField)) { // URLField 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::RegisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd ) { std::vector > & rlRefWindow = m_mapRefWindow[nSlotId]; if( std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ) == rlRefWindow.end() ) { rlRefWindow.emplace_back(pWnd ); } } void ScModule::UnregisterRefWindow( sal_uInt16 nSlotId, vcl::Window *pWnd ) { auto iSlot = m_mapRefWindow.find( nSlotId ); if( iSlot == m_mapRefWindow.end() ) return; std::vector > & rlRefWindow = iSlot->second; auto i = std::find( rlRefWindow.begin(), rlRefWindow.end(), pWnd ); if( i == rlRefWindow.end() ) return; rlRefWindow.erase( i ); if( rlRefWindow.empty() ) m_mapRefWindow.erase( nSlotId ); } vcl::Window * ScModule::Find1RefWindow( sal_uInt16 nSlotId, vcl::Window *pWndAncestor ) { if (!pWndAncestor) return nullptr; auto iSlot = m_mapRefWindow.find( nSlotId ); if( iSlot == m_mapRefWindow.end() ) return nullptr; std::vector > & rlRefWindow = iSlot->second; while( vcl::Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent; for (auto const& refWindow : rlRefWindow) if ( pWndAncestor->IsWindowOrChild( refWindow, refWindow->IsSystemWindow() ) ) return refWindow; return nullptr; } using namespace com::sun::star; #define LINGUPROP_AUTOSPELL "IsSpellAuto" void ScModule::GetSpellSettings( LanguageType& rDefLang, LanguageType& rCjkLang, LanguageType& rCtlLang, bool& rAutoSpell ) { // 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); rAutoSpell = aOptions.bIsSpellAuto; } void ScModule::SetAutoSpellProperty( bool bSet ) { // use SvtLinguConfig instead of service LinguProperties to avoid // loading the linguistic component SvtLinguConfig aConfig; aConfig.SetProperty( OUString( LINGUPROP_AUTOSPELL ), uno::Any(bSet) ); } 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; } SfxStyleFamilies* ScModule::CreateStyleFamilies() { SfxStyleFamilies *pStyleFamilies = new SfxStyleFamilies; pStyleFamilies->emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Para, ScGlobal::GetRscString(STR_STYLE_FAMILY_CELL), Image(BitmapEx(BMP_STYLES_FAMILY_CELL)), RID_CELLSTYLEFAMILY, SC_MOD()->GetResLocale())); pStyleFamilies->emplace_back(SfxStyleFamilyItem(SfxStyleFamily::Page, ScGlobal::GetRscString(STR_STYLE_FAMILY_PAGE), Image(BitmapEx(BMP_STYLES_FAMILY_PAGE)), RID_PAGESTYLEFAMILY, SC_MOD()->GetResLocale())); return pStyleFamilies; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */